1 /*
2 * This program is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU General Public License
4 * as published by the Free Software Foundation; either version 2
5 * of the License, or (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software Foundation,
14 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15 *
16 * Copyright 2019, Blender Foundation.
17 */
18
19 /** \file
20 * \ingroup draw_engine
21 */
22
23 #include "DRW_render.h"
24
25 #include "UI_resources.h"
26
27 #include "BKE_anim_path.h"
28 #include "BKE_camera.h"
29 #include "BKE_constraint.h"
30 #include "BKE_curve.h"
31 #include "BKE_global.h"
32 #include "BKE_mball.h"
33 #include "BKE_mesh.h"
34 #include "BKE_modifier.h"
35 #include "BKE_movieclip.h"
36 #include "BKE_object.h"
37 #include "BKE_tracking.h"
38
39 #include "BLI_listbase.h"
40
41 #include "DNA_camera_types.h"
42 #include "DNA_constraint_types.h"
43 #include "DNA_curve_types.h"
44 #include "DNA_fluid_types.h"
45 #include "DNA_lightprobe_types.h"
46 #include "DNA_mesh_types.h"
47 #include "DNA_meta_types.h"
48 #include "DNA_modifier_types.h"
49 #include "DNA_pointcache_types.h"
50 #include "DNA_rigidbody_types.h"
51
52 #include "DEG_depsgraph_query.h"
53
54 #include "ED_view3d.h"
55
56 #include "overlay_private.h"
57
58 #include "draw_common.h"
59 #include "draw_manager_text.h"
60
OVERLAY_extra_cache_init(OVERLAY_Data * vedata)61 void OVERLAY_extra_cache_init(OVERLAY_Data *vedata)
62 {
63 OVERLAY_PassList *psl = vedata->psl;
64 OVERLAY_TextureList *txl = vedata->txl;
65 OVERLAY_PrivateData *pd = vedata->stl->pd;
66 const bool is_select = DRW_state_is_select();
67
68 DRWState state_blend = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ALPHA;
69 DRW_PASS_CREATE(psl->extra_blend_ps, state_blend | pd->clipping_state);
70 DRW_PASS_CREATE(psl->extra_centers_ps, state_blend | pd->clipping_state);
71
72 {
73 DRWState state = DRW_STATE_WRITE_COLOR;
74
75 DRW_PASS_CREATE(psl->extra_grid_ps, state | pd->clipping_state);
76 DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
77 DRWShadingGroup *grp;
78 struct GPUShader *sh = OVERLAY_shader_extra_grid();
79 struct GPUTexture *tex = DRW_state_is_fbo() ? dtxl->depth : txl->dummy_depth_tx;
80
81 pd->extra_grid_grp = grp = DRW_shgroup_create(sh, psl->extra_grid_ps);
82 DRW_shgroup_uniform_texture(grp, "depthBuffer", tex);
83 DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
84 DRW_shgroup_uniform_bool_copy(grp, "isTransform", (G.moving & G_TRANSFORM_OBJ) != 0);
85 }
86
87 for (int i = 0; i < 2; i++) {
88 /* Non Meshes Pass (Camera, empties, lights ...) */
89 struct GPUShader *sh;
90 struct GPUVertFormat *format;
91 DRWShadingGroup *grp, *grp_sub;
92
93 OVERLAY_InstanceFormats *formats = OVERLAY_shader_instance_formats_get();
94 OVERLAY_ExtraCallBuffers *cb = &pd->extra_call_buffers[i];
95 DRWPass **p_extra_ps = &psl->extra_ps[i];
96
97 DRWState infront_state = (DRW_state_is_select() && (i == 1)) ? DRW_STATE_IN_FRONT_SELECT : 0;
98 DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL;
99 DRW_PASS_CREATE(*p_extra_ps, state | pd->clipping_state | infront_state);
100
101 DRWPass *extra_ps = *p_extra_ps;
102
103 #define BUF_INSTANCE DRW_shgroup_call_buffer_instance
104 #define BUF_POINT(grp, format) DRW_shgroup_call_buffer(grp, format, GPU_PRIM_POINTS)
105 #define BUF_LINE(grp, format) DRW_shgroup_call_buffer(grp, format, GPU_PRIM_LINES)
106
107 /* Sorted by shader to avoid state changes during render. */
108 {
109 format = formats->instance_extra;
110 sh = OVERLAY_shader_extra(is_select);
111
112 grp = DRW_shgroup_create(sh, extra_ps);
113 DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
114
115 grp_sub = DRW_shgroup_create_sub(grp);
116 cb->camera_distances = BUF_INSTANCE(grp_sub, format, DRW_cache_camera_distances_get());
117 cb->camera_frame = BUF_INSTANCE(grp_sub, format, DRW_cache_camera_frame_get());
118 cb->camera_tria[0] = BUF_INSTANCE(grp_sub, format, DRW_cache_camera_tria_wire_get());
119 cb->camera_tria[1] = BUF_INSTANCE(grp_sub, format, DRW_cache_camera_tria_get());
120 cb->empty_axes = BUF_INSTANCE(grp_sub, format, DRW_cache_bone_arrows_get());
121 cb->empty_capsule_body = BUF_INSTANCE(grp_sub, format, DRW_cache_empty_capsule_body_get());
122 cb->empty_capsule_cap = BUF_INSTANCE(grp_sub, format, DRW_cache_empty_capsule_cap_get());
123 cb->empty_circle = BUF_INSTANCE(grp_sub, format, DRW_cache_circle_get());
124 cb->empty_cone = BUF_INSTANCE(grp_sub, format, DRW_cache_empty_cone_get());
125 cb->empty_cube = BUF_INSTANCE(grp_sub, format, DRW_cache_empty_cube_get());
126 cb->empty_cylinder = BUF_INSTANCE(grp_sub, format, DRW_cache_empty_cylinder_get());
127 cb->empty_image_frame = BUF_INSTANCE(grp_sub, format, DRW_cache_quad_wires_get());
128 cb->empty_plain_axes = BUF_INSTANCE(grp_sub, format, DRW_cache_plain_axes_get());
129 cb->empty_single_arrow = BUF_INSTANCE(grp_sub, format, DRW_cache_single_arrow_get());
130 cb->empty_sphere = BUF_INSTANCE(grp_sub, format, DRW_cache_empty_sphere_get());
131 cb->empty_sphere_solid = BUF_INSTANCE(grp_sub, format, DRW_cache_sphere_get());
132 cb->field_cone_limit = BUF_INSTANCE(grp_sub, format, DRW_cache_field_cone_limit_get());
133 cb->field_curve = BUF_INSTANCE(grp_sub, format, DRW_cache_field_curve_get());
134 cb->field_force = BUF_INSTANCE(grp_sub, format, DRW_cache_field_force_get());
135 cb->field_sphere_limit = BUF_INSTANCE(grp_sub, format, DRW_cache_field_sphere_limit_get());
136 cb->field_tube_limit = BUF_INSTANCE(grp_sub, format, DRW_cache_field_tube_limit_get());
137 cb->field_vortex = BUF_INSTANCE(grp_sub, format, DRW_cache_field_vortex_get());
138 cb->field_wind = BUF_INSTANCE(grp_sub, format, DRW_cache_field_wind_get());
139 cb->light_area[0] = BUF_INSTANCE(grp_sub, format, DRW_cache_light_area_disk_lines_get());
140 cb->light_area[1] = BUF_INSTANCE(grp_sub, format, DRW_cache_light_area_square_lines_get());
141 cb->light_point = BUF_INSTANCE(grp_sub, format, DRW_cache_light_point_lines_get());
142 cb->light_spot = BUF_INSTANCE(grp_sub, format, DRW_cache_light_spot_lines_get());
143 cb->light_sun = BUF_INSTANCE(grp_sub, format, DRW_cache_light_sun_lines_get());
144 cb->probe_cube = BUF_INSTANCE(grp_sub, format, DRW_cache_lightprobe_cube_get());
145 cb->probe_grid = BUF_INSTANCE(grp_sub, format, DRW_cache_lightprobe_grid_get());
146 cb->probe_planar = BUF_INSTANCE(grp_sub, format, DRW_cache_lightprobe_planar_get());
147 cb->solid_quad = BUF_INSTANCE(grp_sub, format, DRW_cache_quad_get());
148 cb->speaker = BUF_INSTANCE(grp_sub, format, DRW_cache_speaker_get());
149
150 grp_sub = DRW_shgroup_create_sub(grp);
151 DRW_shgroup_state_enable(grp_sub, DRW_STATE_DEPTH_ALWAYS);
152 DRW_shgroup_state_disable(grp_sub, DRW_STATE_DEPTH_LESS_EQUAL);
153 cb->origin_xform = BUF_INSTANCE(grp_sub, format, DRW_cache_bone_arrows_get());
154 }
155 {
156 format = formats->instance_extra;
157 grp = DRW_shgroup_create(sh, psl->extra_blend_ps); /* NOTE: not the same pass! */
158 DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
159
160 grp_sub = DRW_shgroup_create_sub(grp);
161 DRW_shgroup_state_enable(grp_sub, DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_CULL_BACK);
162 cb->camera_volume = BUF_INSTANCE(grp_sub, format, DRW_cache_camera_volume_get());
163 cb->camera_volume_frame = BUF_INSTANCE(grp_sub, format, DRW_cache_camera_volume_wire_get());
164 cb->light_spot_cone_back = BUF_INSTANCE(grp_sub, format, DRW_cache_light_spot_volume_get());
165
166 grp_sub = DRW_shgroup_create_sub(grp);
167 DRW_shgroup_state_enable(grp_sub, DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_CULL_FRONT);
168 cb->light_spot_cone_front = BUF_INSTANCE(grp_sub, format, DRW_cache_light_spot_volume_get());
169 }
170 {
171 format = formats->instance_pos;
172 sh = OVERLAY_shader_extra_groundline();
173
174 grp = DRW_shgroup_create(sh, extra_ps);
175 DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
176 DRW_shgroup_state_enable(grp, DRW_STATE_BLEND_ALPHA);
177
178 cb->groundline = BUF_INSTANCE(grp, format, DRW_cache_groundline_get());
179 }
180 {
181 sh = OVERLAY_shader_extra_wire(false, is_select);
182
183 grp = DRW_shgroup_create(sh, extra_ps);
184 DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
185
186 cb->extra_dashed_lines = BUF_LINE(grp, formats->pos_color);
187 cb->extra_lines = BUF_LINE(grp, formats->wire_extra);
188 }
189 {
190 sh = OVERLAY_shader_extra_wire(true, is_select);
191
192 cb->extra_wire = grp = DRW_shgroup_create(sh, extra_ps);
193 DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
194 }
195 {
196 sh = OVERLAY_shader_extra_loose_point();
197
198 cb->extra_loose_points = grp = DRW_shgroup_create(sh, extra_ps);
199 DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
200
201 /* Buffer access for drawing isolated points, matching `extra_lines`. */
202 cb->extra_points = BUF_POINT(grp, formats->point_extra);
203 }
204 {
205 format = formats->pos;
206 sh = OVERLAY_shader_extra_point();
207
208 grp = DRW_shgroup_create(sh, psl->extra_centers_ps); /* NOTE: not the same pass! */
209 DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
210
211 grp_sub = DRW_shgroup_create_sub(grp);
212 DRW_shgroup_uniform_vec4_copy(grp_sub, "color", G_draw.block.colorActive);
213 cb->center_active = BUF_POINT(grp_sub, format);
214
215 grp_sub = DRW_shgroup_create_sub(grp);
216 DRW_shgroup_uniform_vec4_copy(grp_sub, "color", G_draw.block.colorSelect);
217 cb->center_selected = BUF_POINT(grp_sub, format);
218
219 grp_sub = DRW_shgroup_create_sub(grp);
220 DRW_shgroup_uniform_vec4_copy(grp_sub, "color", G_draw.block.colorDeselect);
221 cb->center_deselected = BUF_POINT(grp_sub, format);
222
223 grp_sub = DRW_shgroup_create_sub(grp);
224 DRW_shgroup_uniform_vec4_copy(grp_sub, "color", G_draw.block.colorLibrarySelect);
225 cb->center_selected_lib = BUF_POINT(grp_sub, format);
226
227 grp_sub = DRW_shgroup_create_sub(grp);
228 DRW_shgroup_uniform_vec4_copy(grp_sub, "color", G_draw.block.colorLibrary);
229 cb->center_deselected_lib = BUF_POINT(grp_sub, format);
230 }
231 }
232 }
233
OVERLAY_extra_point(OVERLAY_ExtraCallBuffers * cb,const float point[3],const float color[4])234 void OVERLAY_extra_point(OVERLAY_ExtraCallBuffers *cb, const float point[3], const float color[4])
235 {
236 DRW_buffer_add_entry(cb->extra_points, point, color);
237 }
238
OVERLAY_extra_line_dashed(OVERLAY_ExtraCallBuffers * cb,const float start[3],const float end[3],const float color[4])239 void OVERLAY_extra_line_dashed(OVERLAY_ExtraCallBuffers *cb,
240 const float start[3],
241 const float end[3],
242 const float color[4])
243 {
244 DRW_buffer_add_entry(cb->extra_dashed_lines, end, color);
245 DRW_buffer_add_entry(cb->extra_dashed_lines, start, color);
246 }
247
OVERLAY_extra_line(OVERLAY_ExtraCallBuffers * cb,const float start[3],const float end[3],const int color_id)248 void OVERLAY_extra_line(OVERLAY_ExtraCallBuffers *cb,
249 const float start[3],
250 const float end[3],
251 const int color_id)
252 {
253 DRW_buffer_add_entry(cb->extra_lines, start, &color_id);
254 DRW_buffer_add_entry(cb->extra_lines, end, &color_id);
255 }
256
OVERLAY_extra_call_buffer_get(OVERLAY_Data * vedata,Object * ob)257 OVERLAY_ExtraCallBuffers *OVERLAY_extra_call_buffer_get(OVERLAY_Data *vedata, Object *ob)
258 {
259 bool do_in_front = (ob->dtx & OB_DRAW_IN_FRONT) != 0;
260 OVERLAY_PrivateData *pd = vedata->stl->pd;
261 return &pd->extra_call_buffers[do_in_front];
262 }
263
OVERLAY_extra_loose_points(OVERLAY_ExtraCallBuffers * cb,struct GPUBatch * geom,const float mat[4][4],const float color[4])264 void OVERLAY_extra_loose_points(OVERLAY_ExtraCallBuffers *cb,
265 struct GPUBatch *geom,
266 const float mat[4][4],
267 const float color[4])
268 {
269 float draw_mat[4][4];
270 pack_v4_in_mat4(draw_mat, mat, color);
271 DRW_shgroup_call_obmat(cb->extra_loose_points, geom, draw_mat);
272 }
273
OVERLAY_extra_wire(OVERLAY_ExtraCallBuffers * cb,struct GPUBatch * geom,const float mat[4][4],const float color[4])274 void OVERLAY_extra_wire(OVERLAY_ExtraCallBuffers *cb,
275 struct GPUBatch *geom,
276 const float mat[4][4],
277 const float color[4])
278 {
279 float draw_mat[4][4];
280 const float col[4] = {UNPACK3(color), 0.0f /* No stipples. */};
281 pack_v4_in_mat4(draw_mat, mat, col);
282 DRW_shgroup_call_obmat(cb->extra_wire, geom, draw_mat);
283 }
284
285 /* -------------------------------------------------------------------- */
286 /** \name Empties
287 * \{ */
288
OVERLAY_empty_shape(OVERLAY_ExtraCallBuffers * cb,const float mat[4][4],const float draw_size,const char draw_type,const float color[4])289 void OVERLAY_empty_shape(OVERLAY_ExtraCallBuffers *cb,
290 const float mat[4][4],
291 const float draw_size,
292 const char draw_type,
293 const float color[4])
294 {
295 float instdata[4][4];
296 pack_fl_in_mat4(instdata, mat, draw_size);
297
298 switch (draw_type) {
299 case OB_PLAINAXES:
300 DRW_buffer_add_entry(cb->empty_plain_axes, color, instdata);
301 break;
302 case OB_SINGLE_ARROW:
303 DRW_buffer_add_entry(cb->empty_single_arrow, color, instdata);
304 break;
305 case OB_CUBE:
306 DRW_buffer_add_entry(cb->empty_cube, color, instdata);
307 break;
308 case OB_CIRCLE:
309 DRW_buffer_add_entry(cb->empty_circle, color, instdata);
310 break;
311 case OB_EMPTY_SPHERE:
312 DRW_buffer_add_entry(cb->empty_sphere, color, instdata);
313 break;
314 case OB_EMPTY_CONE:
315 DRW_buffer_add_entry(cb->empty_cone, color, instdata);
316 break;
317 case OB_ARROWS:
318 DRW_buffer_add_entry(cb->empty_axes, color, instdata);
319 break;
320 case OB_EMPTY_IMAGE:
321 /* This only show the frame. See OVERLAY_image_empty_cache_populate() for the image. */
322 DRW_buffer_add_entry(cb->empty_image_frame, color, instdata);
323 break;
324 }
325 }
326
OVERLAY_empty_cache_populate(OVERLAY_Data * vedata,Object * ob)327 void OVERLAY_empty_cache_populate(OVERLAY_Data *vedata, Object *ob)
328 {
329 if (((ob->base_flag & BASE_FROM_DUPLI) != 0) && ((ob->transflag & OB_DUPLICOLLECTION) != 0) &&
330 ob->instance_collection) {
331 return;
332 }
333
334 OVERLAY_ExtraCallBuffers *cb = OVERLAY_extra_call_buffer_get(vedata, ob);
335 const DRWContextState *draw_ctx = DRW_context_state_get();
336 ViewLayer *view_layer = draw_ctx->view_layer;
337 float *color;
338
339 switch (ob->empty_drawtype) {
340 case OB_PLAINAXES:
341 case OB_SINGLE_ARROW:
342 case OB_CUBE:
343 case OB_CIRCLE:
344 case OB_EMPTY_SPHERE:
345 case OB_EMPTY_CONE:
346 case OB_ARROWS:
347 DRW_object_wire_theme_get(ob, view_layer, &color);
348 OVERLAY_empty_shape(cb, ob->obmat, ob->empty_drawsize, ob->empty_drawtype, color);
349 break;
350 case OB_EMPTY_IMAGE:
351 OVERLAY_image_empty_cache_populate(vedata, ob);
352 break;
353 }
354 }
355
OVERLAY_bounds(OVERLAY_ExtraCallBuffers * cb,Object * ob,const float * color,char boundtype,bool around_origin)356 static void OVERLAY_bounds(OVERLAY_ExtraCallBuffers *cb,
357 Object *ob,
358 const float *color,
359 char boundtype,
360 bool around_origin)
361 {
362 float center[3], size[3], tmp[4][4], final_mat[4][4];
363 BoundBox bb_local;
364
365 if (ob->type == OB_MBALL && !BKE_mball_is_basis(ob)) {
366 return;
367 }
368
369 BoundBox *bb = BKE_object_boundbox_get(ob);
370
371 if (bb == NULL) {
372 const float min[3] = {-1.0f, -1.0f, -1.0f}, max[3] = {1.0f, 1.0f, 1.0f};
373 bb = &bb_local;
374 BKE_boundbox_init_from_minmax(bb, min, max);
375 }
376
377 BKE_boundbox_calc_size_aabb(bb, size);
378
379 if (around_origin) {
380 zero_v3(center);
381 }
382 else {
383 BKE_boundbox_calc_center_aabb(bb, center);
384 }
385
386 switch (boundtype) {
387 case OB_BOUND_BOX:
388 size_to_mat4(tmp, size);
389 copy_v3_v3(tmp[3], center);
390 mul_m4_m4m4(tmp, ob->obmat, tmp);
391 DRW_buffer_add_entry(cb->empty_cube, color, tmp);
392 break;
393 case OB_BOUND_SPHERE:
394 size[0] = max_fff(size[0], size[1], size[2]);
395 size[1] = size[2] = size[0];
396 size_to_mat4(tmp, size);
397 copy_v3_v3(tmp[3], center);
398 mul_m4_m4m4(tmp, ob->obmat, tmp);
399 DRW_buffer_add_entry(cb->empty_sphere, color, tmp);
400 break;
401 case OB_BOUND_CYLINDER:
402 size[0] = max_ff(size[0], size[1]);
403 size[1] = size[0];
404 size_to_mat4(tmp, size);
405 copy_v3_v3(tmp[3], center);
406 mul_m4_m4m4(tmp, ob->obmat, tmp);
407 DRW_buffer_add_entry(cb->empty_cylinder, color, tmp);
408 break;
409 case OB_BOUND_CONE:
410 size[0] = max_ff(size[0], size[1]);
411 size[1] = size[0];
412 size_to_mat4(tmp, size);
413 copy_v3_v3(tmp[3], center);
414 /* Cone batch has base at 0 and is pointing towards +Y. */
415 swap_v3_v3(tmp[1], tmp[2]);
416 tmp[3][2] -= size[2];
417 mul_m4_m4m4(tmp, ob->obmat, tmp);
418 DRW_buffer_add_entry(cb->empty_cone, color, tmp);
419 break;
420 case OB_BOUND_CAPSULE:
421 size[0] = max_ff(size[0], size[1]);
422 size[1] = size[0];
423 scale_m4_fl(tmp, size[0]);
424 copy_v2_v2(tmp[3], center);
425 tmp[3][2] = center[2] + max_ff(0.0f, size[2] - size[0]);
426 mul_m4_m4m4(final_mat, ob->obmat, tmp);
427 DRW_buffer_add_entry(cb->empty_capsule_cap, color, final_mat);
428 negate_v3(tmp[2]);
429 tmp[3][2] = center[2] - max_ff(0.0f, size[2] - size[0]);
430 mul_m4_m4m4(final_mat, ob->obmat, tmp);
431 DRW_buffer_add_entry(cb->empty_capsule_cap, color, final_mat);
432 tmp[2][2] = max_ff(0.0f, size[2] * 2.0f - size[0] * 2.0f);
433 mul_m4_m4m4(final_mat, ob->obmat, tmp);
434 DRW_buffer_add_entry(cb->empty_capsule_body, color, final_mat);
435 break;
436 }
437 }
438
OVERLAY_collision(OVERLAY_ExtraCallBuffers * cb,Object * ob,const float * color)439 static void OVERLAY_collision(OVERLAY_ExtraCallBuffers *cb, Object *ob, const float *color)
440 {
441 switch (ob->rigidbody_object->shape) {
442 case RB_SHAPE_BOX:
443 OVERLAY_bounds(cb, ob, color, OB_BOUND_BOX, true);
444 break;
445 case RB_SHAPE_SPHERE:
446 OVERLAY_bounds(cb, ob, color, OB_BOUND_SPHERE, true);
447 break;
448 case RB_SHAPE_CONE:
449 OVERLAY_bounds(cb, ob, color, OB_BOUND_CONE, true);
450 break;
451 case RB_SHAPE_CYLINDER:
452 OVERLAY_bounds(cb, ob, color, OB_BOUND_CYLINDER, true);
453 break;
454 case RB_SHAPE_CAPSULE:
455 OVERLAY_bounds(cb, ob, color, OB_BOUND_CAPSULE, true);
456 break;
457 }
458 }
459
OVERLAY_texture_space(OVERLAY_ExtraCallBuffers * cb,Object * ob,const float * color)460 static void OVERLAY_texture_space(OVERLAY_ExtraCallBuffers *cb, Object *ob, const float *color)
461 {
462 if (ob->data == NULL) {
463 return;
464 }
465
466 ID *ob_data = ob->data;
467 float *texcoloc = NULL;
468 float *texcosize = NULL;
469
470 switch (GS(ob_data->name)) {
471 case ID_ME:
472 BKE_mesh_texspace_get_reference((Mesh *)ob_data, NULL, &texcoloc, &texcosize);
473 break;
474 case ID_CU: {
475 Curve *cu = (Curve *)ob_data;
476 BKE_curve_texspace_ensure(cu);
477 texcoloc = cu->loc;
478 texcosize = cu->size;
479 break;
480 }
481 case ID_MB: {
482 MetaBall *mb = (MetaBall *)ob_data;
483 texcoloc = mb->loc;
484 texcosize = mb->size;
485 break;
486 }
487 case ID_HA:
488 case ID_PT:
489 case ID_VO: {
490 /* No user defined texture space support. */
491 break;
492 }
493 default:
494 BLI_assert(0);
495 }
496
497 float mat[4][4];
498
499 if (texcoloc != NULL && texcosize != NULL) {
500 size_to_mat4(mat, texcosize);
501 copy_v3_v3(mat[3], texcoloc);
502 }
503 else {
504 unit_m4(mat);
505 }
506
507 mul_m4_m4m4(mat, ob->obmat, mat);
508
509 DRW_buffer_add_entry(cb->empty_cube, color, mat);
510 }
511
OVERLAY_forcefield(OVERLAY_ExtraCallBuffers * cb,Object * ob,ViewLayer * view_layer)512 static void OVERLAY_forcefield(OVERLAY_ExtraCallBuffers *cb, Object *ob, ViewLayer *view_layer)
513 {
514 int theme_id = DRW_object_wire_theme_get(ob, view_layer, NULL);
515 float *color = DRW_color_background_blend_get(theme_id);
516 PartDeflect *pd = ob->pd;
517 Curve *cu = (ob->type == OB_CURVE) ? ob->data : NULL;
518
519 union {
520 float mat[4][4];
521 struct {
522 float _pad00[3], size_x;
523 float _pad01[3], size_y;
524 float _pad02[3], size_z;
525 float pos[3], _pad03[1];
526 };
527 } instdata;
528
529 copy_m4_m4(instdata.mat, ob->obmat);
530 instdata.size_x = instdata.size_y = instdata.size_z = ob->empty_drawsize;
531
532 switch (pd->forcefield) {
533 case PFIELD_FORCE:
534 DRW_buffer_add_entry(cb->field_force, color, &instdata);
535 break;
536 case PFIELD_WIND:
537 instdata.size_z = pd->f_strength;
538 DRW_buffer_add_entry(cb->field_wind, color, &instdata);
539 break;
540 case PFIELD_VORTEX:
541 instdata.size_y = (pd->f_strength < 0.0f) ? -instdata.size_y : instdata.size_y;
542 DRW_buffer_add_entry(cb->field_vortex, color, &instdata);
543 break;
544 case PFIELD_GUIDE:
545 if (cu && (cu->flag & CU_PATH) && ob->runtime.curve_cache->path &&
546 ob->runtime.curve_cache->path->data) {
547 instdata.size_x = instdata.size_y = instdata.size_z = pd->f_strength;
548 float pos[4], tmp[3];
549 where_on_path(ob, 0.0f, pos, tmp, NULL, NULL, NULL);
550 copy_v3_v3(instdata.pos, ob->obmat[3]);
551 translate_m4(instdata.mat, pos[0], pos[1], pos[2]);
552 DRW_buffer_add_entry(cb->field_curve, color, &instdata);
553
554 where_on_path(ob, 1.0f, pos, tmp, NULL, NULL, NULL);
555 copy_v3_v3(instdata.pos, ob->obmat[3]);
556 translate_m4(instdata.mat, pos[0], pos[1], pos[2]);
557 DRW_buffer_add_entry(cb->field_sphere_limit, color, &instdata);
558 /* Restore */
559 copy_v3_v3(instdata.pos, ob->obmat[3]);
560 }
561 break;
562 }
563
564 if (pd->falloff == PFIELD_FALL_TUBE) {
565 if (pd->flag & (PFIELD_USEMAX | PFIELD_USEMAXR)) {
566 instdata.size_z = (pd->flag & PFIELD_USEMAX) ? pd->maxdist : 0.0f;
567 instdata.size_x = (pd->flag & PFIELD_USEMAXR) ? pd->maxrad : 1.0f;
568 instdata.size_y = instdata.size_x;
569 DRW_buffer_add_entry(cb->field_tube_limit, color, &instdata);
570 }
571 if (pd->flag & (PFIELD_USEMIN | PFIELD_USEMINR)) {
572 instdata.size_z = (pd->flag & PFIELD_USEMIN) ? pd->mindist : 0.0f;
573 instdata.size_x = (pd->flag & PFIELD_USEMINR) ? pd->minrad : 1.0f;
574 instdata.size_y = instdata.size_x;
575 DRW_buffer_add_entry(cb->field_tube_limit, color, &instdata);
576 }
577 }
578 else if (pd->falloff == PFIELD_FALL_CONE) {
579 if (pd->flag & (PFIELD_USEMAX | PFIELD_USEMAXR)) {
580 float radius = DEG2RADF((pd->flag & PFIELD_USEMAXR) ? pd->maxrad : 1.0f);
581 float distance = (pd->flag & PFIELD_USEMAX) ? pd->maxdist : 0.0f;
582 instdata.size_x = distance * sinf(radius);
583 instdata.size_z = distance * cosf(radius);
584 instdata.size_y = instdata.size_x;
585 DRW_buffer_add_entry(cb->field_cone_limit, color, &instdata);
586 }
587 if (pd->flag & (PFIELD_USEMIN | PFIELD_USEMINR)) {
588 float radius = DEG2RADF((pd->flag & PFIELD_USEMINR) ? pd->minrad : 1.0f);
589 float distance = (pd->flag & PFIELD_USEMIN) ? pd->mindist : 0.0f;
590 instdata.size_x = distance * sinf(radius);
591 instdata.size_z = distance * cosf(radius);
592 instdata.size_y = instdata.size_x;
593 DRW_buffer_add_entry(cb->field_cone_limit, color, &instdata);
594 }
595 }
596 else if (pd->falloff == PFIELD_FALL_SPHERE) {
597 if (pd->flag & PFIELD_USEMAX) {
598 instdata.size_x = instdata.size_y = instdata.size_z = pd->maxdist;
599 DRW_buffer_add_entry(cb->field_sphere_limit, color, &instdata);
600 }
601 if (pd->flag & PFIELD_USEMIN) {
602 instdata.size_x = instdata.size_y = instdata.size_z = pd->mindist;
603 DRW_buffer_add_entry(cb->field_sphere_limit, color, &instdata);
604 }
605 }
606 }
607
608 /** \} */
609
610 /* -------------------------------------------------------------------- */
611 /** \name Lights
612 * \{ */
613
OVERLAY_light_cache_populate(OVERLAY_Data * vedata,Object * ob)614 void OVERLAY_light_cache_populate(OVERLAY_Data *vedata, Object *ob)
615 {
616 OVERLAY_ExtraCallBuffers *cb = OVERLAY_extra_call_buffer_get(vedata, ob);
617 const DRWContextState *draw_ctx = DRW_context_state_get();
618 ViewLayer *view_layer = draw_ctx->view_layer;
619
620 Light *la = ob->data;
621 float *color_p;
622 DRW_object_wire_theme_get(ob, view_layer, &color_p);
623 /* Remove the alpha. */
624 float color[4] = {UNPACK3(color_p), 1.0f};
625 /* Pack render data into object matrix. */
626 union {
627 float mat[4][4];
628 struct {
629 float _pad00[3];
630 union {
631 float area_size_x;
632 float spot_cosine;
633 };
634 float _pad01[3];
635 union {
636 float area_size_y;
637 float spot_blend;
638 };
639 float _pad02[3], clip_sta;
640 float pos[3], clip_end;
641 };
642 } instdata;
643
644 copy_m4_m4(instdata.mat, ob->obmat);
645 /* FIXME / TODO: clipend has no meaning nowadays.
646 * In EEVEE, Only clipsta is used shadowmaping.
647 * Clip end is computed automatically based on light power.
648 * For now, always use the custom distance as clipend. */
649 instdata.clip_end = la->att_dist;
650 instdata.clip_sta = la->clipsta;
651
652 DRW_buffer_add_entry(cb->groundline, instdata.pos);
653
654 if (la->type == LA_LOCAL) {
655 instdata.area_size_x = instdata.area_size_y = la->area_size;
656 DRW_buffer_add_entry(cb->light_point, color, &instdata);
657 }
658 else if (la->type == LA_SUN) {
659 DRW_buffer_add_entry(cb->light_sun, color, &instdata);
660 }
661 else if (la->type == LA_SPOT) {
662 /* Previous implementation was using the clipend distance as cone size.
663 * We cannot do this anymore so we use a fixed size of 10. (see T72871) */
664 rescale_m4(instdata.mat, (float[3]){10.0f, 10.0f, 10.0f});
665 /* For cycles and eevee the spot attenuation is
666 * y = (1/(1 + x^2) - a)/((1 - a) b)
667 * We solve the case where spot attenuation y = 1 and y = 0
668 * root for y = 1 is (-1 - c) / c
669 * root for y = 0 is (1 - a) / a
670 * and use that to position the blend circle. */
671 float a = cosf(la->spotsize * 0.5f);
672 float b = la->spotblend;
673 float c = a * b - a - b;
674 /* Optimized version or root1 / root0 */
675 instdata.spot_blend = sqrtf((-a - c * a) / (c - c * a));
676 instdata.spot_cosine = a;
677 /* HACK: We pack the area size in alpha color. This is decoded by the shader. */
678 color[3] = -max_ff(la->area_size, FLT_MIN);
679 DRW_buffer_add_entry(cb->light_spot, color, &instdata);
680
681 if ((la->mode & LA_SHOW_CONE) && !DRW_state_is_select()) {
682 const float color_inside[4] = {0.0f, 0.0f, 0.0f, 0.5f};
683 const float color_outside[4] = {1.0f, 1.0f, 1.0f, 0.3f};
684 DRW_buffer_add_entry(cb->light_spot_cone_front, color_inside, &instdata);
685 DRW_buffer_add_entry(cb->light_spot_cone_back, color_outside, &instdata);
686 }
687 }
688 else if (la->type == LA_AREA) {
689 bool uniform_scale = !ELEM(la->area_shape, LA_AREA_RECT, LA_AREA_ELLIPSE);
690 int sqr = ELEM(la->area_shape, LA_AREA_SQUARE, LA_AREA_RECT);
691 instdata.area_size_x = la->area_size;
692 instdata.area_size_y = uniform_scale ? la->area_size : la->area_sizey;
693 DRW_buffer_add_entry(cb->light_area[sqr], color, &instdata);
694 }
695 }
696
697 /** \} */
698
699 /* -------------------------------------------------------------------- */
700 /** \name Lightprobe
701 * \{ */
702
OVERLAY_lightprobe_cache_populate(OVERLAY_Data * vedata,Object * ob)703 void OVERLAY_lightprobe_cache_populate(OVERLAY_Data *vedata, Object *ob)
704 {
705 OVERLAY_ExtraCallBuffers *cb = OVERLAY_extra_call_buffer_get(vedata, ob);
706 const DRWContextState *draw_ctx = DRW_context_state_get();
707 ViewLayer *view_layer = draw_ctx->view_layer;
708 float *color_p;
709 int theme_id = DRW_object_wire_theme_get(ob, view_layer, &color_p);
710 const LightProbe *prb = (LightProbe *)ob->data;
711 const bool show_clipping = (prb->flag & LIGHTPROBE_FLAG_SHOW_CLIP_DIST) != 0;
712 const bool show_parallax = (prb->flag & LIGHTPROBE_FLAG_SHOW_PARALLAX) != 0;
713 const bool show_influence = (prb->flag & LIGHTPROBE_FLAG_SHOW_INFLUENCE) != 0;
714 const bool show_data = (ob->base_flag & BASE_SELECTED) || DRW_state_is_select();
715
716 union {
717 float mat[4][4];
718 struct {
719 float _pad00[4];
720 float _pad01[4];
721 float _pad02[3], clip_sta;
722 float pos[3], clip_end;
723 };
724 } instdata;
725
726 copy_m4_m4(instdata.mat, ob->obmat);
727
728 switch (prb->type) {
729 case LIGHTPROBE_TYPE_CUBE:
730 instdata.clip_sta = show_clipping ? prb->clipsta : -1.0;
731 instdata.clip_end = show_clipping ? prb->clipend : -1.0;
732 DRW_buffer_add_entry(cb->probe_cube, color_p, &instdata);
733 DRW_buffer_add_entry(cb->groundline, instdata.pos);
734
735 if (show_influence) {
736 char shape = (prb->attenuation_type == LIGHTPROBE_SHAPE_BOX) ? OB_CUBE : OB_EMPTY_SPHERE;
737 float f = 1.0f - prb->falloff;
738 OVERLAY_empty_shape(cb, ob->obmat, prb->distinf, shape, color_p);
739 OVERLAY_empty_shape(cb, ob->obmat, prb->distinf * f, shape, color_p);
740 }
741
742 if (show_parallax) {
743 char shape = (prb->parallax_type == LIGHTPROBE_SHAPE_BOX) ? OB_CUBE : OB_EMPTY_SPHERE;
744 float dist = ((prb->flag & LIGHTPROBE_FLAG_CUSTOM_PARALLAX) != 0) ? prb->distpar :
745 prb->distinf;
746 OVERLAY_empty_shape(cb, ob->obmat, dist, shape, color_p);
747 }
748 break;
749 case LIGHTPROBE_TYPE_GRID:
750 instdata.clip_sta = show_clipping ? prb->clipsta : -1.0;
751 instdata.clip_end = show_clipping ? prb->clipend : -1.0;
752 DRW_buffer_add_entry(cb->probe_grid, color_p, &instdata);
753
754 if (show_influence) {
755 float f = 1.0f - prb->falloff;
756 OVERLAY_empty_shape(cb, ob->obmat, 1.0 + prb->distinf, OB_CUBE, color_p);
757 OVERLAY_empty_shape(cb, ob->obmat, 1.0 + prb->distinf * f, OB_CUBE, color_p);
758 }
759
760 /* Data dots */
761 if (show_data) {
762 instdata.mat[0][3] = prb->grid_resolution_x;
763 instdata.mat[1][3] = prb->grid_resolution_y;
764 instdata.mat[2][3] = prb->grid_resolution_z;
765 /* Put theme id in matrix. */
766 if (UNLIKELY(ob->base_flag & BASE_FROM_DUPLI)) {
767 instdata.mat[3][3] = 0.0;
768 }
769 else if (theme_id == TH_ACTIVE) {
770 instdata.mat[3][3] = 1.0;
771 }
772 else /* TH_SELECT */ {
773 instdata.mat[3][3] = 2.0;
774 }
775
776 uint cell_count = prb->grid_resolution_x * prb->grid_resolution_y * prb->grid_resolution_z;
777 DRWShadingGroup *grp = DRW_shgroup_create_sub(vedata->stl->pd->extra_grid_grp);
778 DRW_shgroup_uniform_vec4_array_copy(grp, "gridModelMatrix", instdata.mat, 4);
779 DRW_shgroup_call_procedural_points(grp, NULL, cell_count);
780 }
781 break;
782 case LIGHTPROBE_TYPE_PLANAR:
783 DRW_buffer_add_entry(cb->probe_planar, color_p, &instdata);
784
785 if (DRW_state_is_select() && (prb->flag & LIGHTPROBE_FLAG_SHOW_DATA)) {
786 DRW_buffer_add_entry(cb->solid_quad, color_p, &instdata);
787 }
788
789 if (show_influence) {
790 normalize_v3_length(instdata.mat[2], prb->distinf);
791 DRW_buffer_add_entry(cb->empty_cube, color_p, &instdata);
792 mul_v3_fl(instdata.mat[2], 1.0f - prb->falloff);
793 DRW_buffer_add_entry(cb->empty_cube, color_p, &instdata);
794 }
795 zero_v3(instdata.mat[2]);
796 DRW_buffer_add_entry(cb->empty_cube, color_p, &instdata);
797
798 normalize_m4_m4(instdata.mat, ob->obmat);
799 OVERLAY_empty_shape(cb, instdata.mat, ob->empty_drawsize, OB_SINGLE_ARROW, color_p);
800 break;
801 }
802 }
803
804 /** \} */
805
806 /* -------------------------------------------------------------------- */
807 /** \name Speaker
808 * \{ */
809
OVERLAY_speaker_cache_populate(OVERLAY_Data * vedata,Object * ob)810 void OVERLAY_speaker_cache_populate(OVERLAY_Data *vedata, Object *ob)
811 {
812 OVERLAY_ExtraCallBuffers *cb = OVERLAY_extra_call_buffer_get(vedata, ob);
813 const DRWContextState *draw_ctx = DRW_context_state_get();
814 ViewLayer *view_layer = draw_ctx->view_layer;
815 float *color_p;
816 DRW_object_wire_theme_get(ob, view_layer, &color_p);
817
818 DRW_buffer_add_entry(cb->speaker, color_p, ob->obmat);
819 }
820
821 /** \} */
822
823 /* -------------------------------------------------------------------- */
824 /** \name Camera
825 * \{ */
826
827 typedef union OVERLAY_CameraInstanceData {
828 /* Pack render data into object matrix and object color. */
829 struct {
830 float color[4];
831 float mat[4][4];
832 };
833 struct {
834 float _pad0[2];
835 float volume_sta;
836 union {
837 float depth;
838 float focus;
839 float volume_end;
840 };
841 float _pad00[3];
842 union {
843 float corner_x;
844 float dist_color_id;
845 };
846 float _pad01[3];
847 union {
848 float corner_y;
849 };
850 float _pad02[3];
851 union {
852 float center_x;
853 float clip_sta;
854 float mist_sta;
855 };
856 float pos[3];
857 union {
858 float center_y;
859 float clip_end;
860 float mist_end;
861 };
862 };
863 } OVERLAY_CameraInstanceData;
864
camera_view3d_reconstruction(OVERLAY_ExtraCallBuffers * cb,Scene * scene,View3D * v3d,Object * camera_object,Object * ob,const float color[4])865 static void camera_view3d_reconstruction(OVERLAY_ExtraCallBuffers *cb,
866 Scene *scene,
867 View3D *v3d,
868 Object *camera_object,
869 Object *ob,
870 const float color[4])
871 {
872 const DRWContextState *draw_ctx = DRW_context_state_get();
873 const bool is_select = DRW_state_is_select();
874 const Object *orig_camera_object = DEG_get_original_object(camera_object);
875
876 MovieClip *clip = BKE_object_movieclip_get(scene, ob, false);
877 if (clip == NULL) {
878 return;
879 }
880
881 const bool is_solid_bundle = (v3d->bundle_drawtype == OB_EMPTY_SPHERE) &&
882 ((v3d->shading.type != OB_SOLID) || !XRAY_FLAG_ENABLED(v3d));
883
884 MovieTracking *tracking = &clip->tracking;
885 /* Index must start in 1, to mimic BKE_tracking_track_get_indexed. */
886 int track_index = 1;
887
888 float bundle_color_custom[3];
889 float *bundle_color_solid = G_draw.block.colorBundleSolid;
890 float *bundle_color_unselected = G_draw.block.colorWire;
891 uchar text_color_selected[4], text_color_unselected[4];
892 /* Color Management: Exception here as texts are drawn in sRGB space directly. */
893 UI_GetThemeColor4ubv(TH_SELECT, text_color_selected);
894 UI_GetThemeColor4ubv(TH_TEXT, text_color_unselected);
895
896 float camera_mat[4][4];
897 BKE_tracking_get_camera_object_matrix(ob, camera_mat);
898
899 LISTBASE_FOREACH (MovieTrackingObject *, tracking_object, &tracking->objects) {
900 float tracking_object_mat[4][4];
901
902 if (tracking_object->flag & TRACKING_OBJECT_CAMERA) {
903 copy_m4_m4(tracking_object_mat, camera_mat);
904 }
905 else {
906 const int framenr = BKE_movieclip_remap_scene_to_clip_frame(
907 clip, DEG_get_ctime(draw_ctx->depsgraph));
908
909 float object_mat[4][4];
910 BKE_tracking_camera_get_reconstructed_interpolate(
911 tracking, tracking_object, framenr, object_mat);
912
913 float object_imat[4][4];
914 invert_m4_m4(object_imat, object_mat);
915
916 mul_m4_m4m4(tracking_object_mat, ob->obmat, object_imat);
917 }
918
919 ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, tracking_object);
920 LISTBASE_FOREACH (MovieTrackingTrack *, track, tracksbase) {
921 if ((track->flag & TRACK_HAS_BUNDLE) == 0) {
922 continue;
923 }
924 bool is_selected = TRACK_SELECTED(track);
925
926 float bundle_mat[4][4];
927 copy_m4_m4(bundle_mat, tracking_object_mat);
928 translate_m4(bundle_mat, track->bundle_pos[0], track->bundle_pos[1], track->bundle_pos[2]);
929
930 const float *bundle_color;
931 if (track->flag & TRACK_CUSTOMCOLOR) {
932 /* Meh, hardcoded srgb transform here. */
933 /* TODO change the actual DNA color to be linear. */
934 srgb_to_linearrgb_v3_v3(bundle_color_custom, track->color);
935 bundle_color = bundle_color_custom;
936 }
937 else if (is_solid_bundle) {
938 bundle_color = bundle_color_solid;
939 }
940 else if (is_selected) {
941 bundle_color = color;
942 }
943 else {
944 bundle_color = bundle_color_unselected;
945 }
946
947 if (is_select) {
948 DRW_select_load_id(orig_camera_object->runtime.select_id | (track_index << 16));
949 track_index++;
950 }
951
952 if (is_solid_bundle) {
953 if (is_selected) {
954 OVERLAY_empty_shape(cb, bundle_mat, v3d->bundle_size, v3d->bundle_drawtype, color);
955 }
956
957 const float bundle_color_v4[4] = {
958 bundle_color[0],
959 bundle_color[1],
960 bundle_color[2],
961 1.0f,
962 };
963
964 bundle_mat[3][3] = v3d->bundle_size; /* See shader. */
965 DRW_buffer_add_entry(cb->empty_sphere_solid, bundle_color_v4, bundle_mat);
966 }
967 else {
968 OVERLAY_empty_shape(cb, bundle_mat, v3d->bundle_size, v3d->bundle_drawtype, bundle_color);
969 }
970
971 if ((v3d->flag2 & V3D_SHOW_BUNDLENAME) && !is_select) {
972 struct DRWTextStore *dt = DRW_text_cache_ensure();
973
974 DRW_text_cache_add(dt,
975 bundle_mat[3],
976 track->name,
977 strlen(track->name),
978 10,
979 0,
980 DRW_TEXT_CACHE_GLOBALSPACE | DRW_TEXT_CACHE_STRING_PTR,
981 is_selected ? text_color_selected : text_color_unselected);
982 }
983 }
984
985 if ((v3d->flag2 & V3D_SHOW_CAMERAPATH) && (tracking_object->flag & TRACKING_OBJECT_CAMERA) &&
986 !is_select) {
987 MovieTrackingReconstruction *reconstruction;
988 reconstruction = BKE_tracking_object_get_reconstruction(tracking, tracking_object);
989
990 if (reconstruction->camnr) {
991 MovieReconstructedCamera *camera = reconstruction->cameras;
992 float v0[3], v1[3];
993 for (int a = 0; a < reconstruction->camnr; a++, camera++) {
994 copy_v3_v3(v0, v1);
995 copy_v3_v3(v1, camera->mat[3]);
996 mul_m4_v3(camera_mat, v1);
997 if (a > 0) {
998 /* This one is suboptimal (gl_lines instead of gl_line_strip)
999 * but we keep this for simplicity */
1000 OVERLAY_extra_line(cb, v0, v1, TH_CAMERA_PATH);
1001 }
1002 }
1003 }
1004 }
1005 }
1006 }
1007
camera_offaxis_shiftx_get(Scene * scene,Object * ob,const OVERLAY_CameraInstanceData * instdata,bool right_eye)1008 static float camera_offaxis_shiftx_get(Scene *scene,
1009 Object *ob,
1010 const OVERLAY_CameraInstanceData *instdata,
1011 bool right_eye)
1012 {
1013 Camera *cam = ob->data;
1014 if (cam->stereo.convergence_mode == CAM_S3D_OFFAXIS) {
1015 const char *viewnames[2] = {STEREO_LEFT_NAME, STEREO_RIGHT_NAME};
1016 const float shiftx = BKE_camera_multiview_shift_x(&scene->r, ob, viewnames[right_eye]);
1017 const float delta_shiftx = shiftx - cam->shiftx;
1018 const float width = instdata->corner_x * 2.0f;
1019 return delta_shiftx * width;
1020 }
1021
1022 return 0.0;
1023 }
1024 /**
1025 * Draw the stereo 3d support elements (cameras, plane, volume).
1026 * They are only visible when not looking through the camera:
1027 */
camera_stereoscopy_extra(OVERLAY_ExtraCallBuffers * cb,Scene * scene,View3D * v3d,Object * ob,const OVERLAY_CameraInstanceData * instdata)1028 static void camera_stereoscopy_extra(OVERLAY_ExtraCallBuffers *cb,
1029 Scene *scene,
1030 View3D *v3d,
1031 Object *ob,
1032 const OVERLAY_CameraInstanceData *instdata)
1033 {
1034 OVERLAY_CameraInstanceData stereodata = *instdata;
1035 Camera *cam = ob->data;
1036 const bool is_select = DRW_state_is_select();
1037 const char *viewnames[2] = {STEREO_LEFT_NAME, STEREO_RIGHT_NAME};
1038
1039 const bool is_stereo3d_cameras = (v3d->stereo3d_flag & V3D_S3D_DISPCAMERAS) != 0;
1040 const bool is_stereo3d_plane = (v3d->stereo3d_flag & V3D_S3D_DISPPLANE) != 0;
1041 const bool is_stereo3d_volume = (v3d->stereo3d_flag & V3D_S3D_DISPVOLUME) != 0;
1042
1043 if (!is_stereo3d_cameras) {
1044 /* Draw single camera. */
1045 DRW_buffer_add_entry_struct(cb->camera_frame, instdata);
1046 }
1047
1048 for (int eye = 0; eye < 2; eye++) {
1049 ob = BKE_camera_multiview_render(scene, ob, viewnames[eye]);
1050 BKE_camera_multiview_model_matrix(&scene->r, ob, viewnames[eye], stereodata.mat);
1051
1052 stereodata.corner_x = instdata->corner_x;
1053 stereodata.corner_y = instdata->corner_y;
1054 stereodata.center_x = instdata->center_x + camera_offaxis_shiftx_get(scene, ob, instdata, eye);
1055 stereodata.center_y = instdata->center_y;
1056 stereodata.depth = instdata->depth;
1057
1058 if (is_stereo3d_cameras) {
1059 DRW_buffer_add_entry_struct(cb->camera_frame, &stereodata);
1060
1061 /* Connecting line between cameras. */
1062 OVERLAY_extra_line_dashed(cb, stereodata.pos, instdata->pos, G_draw.block.colorWire);
1063 }
1064
1065 if (is_stereo3d_volume && !is_select) {
1066 float r = (eye == 1) ? 2.0f : 1.0f;
1067
1068 stereodata.volume_sta = -cam->clip_start;
1069 stereodata.volume_end = -cam->clip_end;
1070 /* Encode eye + intensity and alpha (see shader) */
1071 copy_v2_fl2(stereodata.color, r + 0.15f, 1.0f);
1072 DRW_buffer_add_entry_struct(cb->camera_volume_frame, &stereodata);
1073
1074 if (v3d->stereo3d_volume_alpha > 0.0f) {
1075 /* Encode eye + intensity and alpha (see shader) */
1076 copy_v2_fl2(stereodata.color, r + 0.999f, v3d->stereo3d_volume_alpha);
1077 DRW_buffer_add_entry_struct(cb->camera_volume, &stereodata);
1078 }
1079 /* restore */
1080 copy_v3_v3(stereodata.color, instdata->color);
1081 }
1082 }
1083
1084 if (is_stereo3d_plane && !is_select) {
1085 if (cam->stereo.convergence_mode == CAM_S3D_TOE) {
1086 /* There is no real convergence plane but we highlight the center
1087 * point where the views are pointing at. */
1088 // zero_v3(stereodata.mat[0]); /* We reconstruct from Z and Y */
1089 // zero_v3(stereodata.mat[1]); /* Y doesn't change */
1090 zero_v3(stereodata.mat[2]);
1091 zero_v3(stereodata.mat[3]);
1092 for (int i = 0; i < 2; i++) {
1093 float mat[4][4];
1094 /* Need normalized version here. */
1095 BKE_camera_multiview_model_matrix(&scene->r, ob, viewnames[i], mat);
1096 add_v3_v3(stereodata.mat[2], mat[2]);
1097 madd_v3_v3fl(stereodata.mat[3], mat[3], 0.5f);
1098 }
1099 normalize_v3(stereodata.mat[2]);
1100 cross_v3_v3v3(stereodata.mat[0], stereodata.mat[1], stereodata.mat[2]);
1101 }
1102 else if (cam->stereo.convergence_mode == CAM_S3D_PARALLEL) {
1103 /* Show plane at the given distance between the views even if it makes no sense. */
1104 zero_v3(stereodata.pos);
1105 for (int i = 0; i < 2; i++) {
1106 float mat[4][4];
1107 BKE_camera_multiview_model_matrix_scaled(&scene->r, ob, viewnames[i], mat);
1108 madd_v3_v3fl(stereodata.pos, mat[3], 0.5f);
1109 }
1110 }
1111 else if (cam->stereo.convergence_mode == CAM_S3D_OFFAXIS) {
1112 /* Nothing to do. Everything is already setup. */
1113 }
1114 stereodata.volume_sta = -cam->stereo.convergence_distance;
1115 stereodata.volume_end = -cam->stereo.convergence_distance;
1116 /* Encode eye + intensity and alpha (see shader) */
1117 copy_v2_fl2(stereodata.color, 0.1f, 1.0f);
1118 DRW_buffer_add_entry_struct(cb->camera_volume_frame, &stereodata);
1119
1120 if (v3d->stereo3d_convergence_alpha > 0.0f) {
1121 /* Encode eye + intensity and alpha (see shader) */
1122 copy_v2_fl2(stereodata.color, 0.0f, v3d->stereo3d_convergence_alpha);
1123 DRW_buffer_add_entry_struct(cb->camera_volume, &stereodata);
1124 }
1125 }
1126 }
1127
OVERLAY_camera_cache_populate(OVERLAY_Data * vedata,Object * ob)1128 void OVERLAY_camera_cache_populate(OVERLAY_Data *vedata, Object *ob)
1129 {
1130 OVERLAY_ExtraCallBuffers *cb = OVERLAY_extra_call_buffer_get(vedata, ob);
1131 OVERLAY_CameraInstanceData instdata;
1132
1133 const DRWContextState *draw_ctx = DRW_context_state_get();
1134 ViewLayer *view_layer = draw_ctx->view_layer;
1135 View3D *v3d = draw_ctx->v3d;
1136 Scene *scene = draw_ctx->scene;
1137 RegionView3D *rv3d = draw_ctx->rv3d;
1138
1139 Camera *cam = ob->data;
1140 Object *camera_object = DEG_get_evaluated_object(draw_ctx->depsgraph, v3d->camera);
1141 const bool is_select = DRW_state_is_select();
1142 const bool is_active = (ob == camera_object);
1143 const bool look_through = (is_active && (rv3d->persp == RV3D_CAMOB));
1144
1145 const bool is_multiview = (scene->r.scemode & R_MULTIVIEW) != 0;
1146 const bool is_stereo3d_view = (scene->r.views_format == SCE_VIEWS_FORMAT_STEREO_3D);
1147 const bool is_stereo3d_display_extra = is_active && is_multiview && (!look_through) &&
1148 ((v3d->stereo3d_flag) != 0);
1149 const bool is_selection_camera_stereo = is_select && look_through && is_multiview &&
1150 is_stereo3d_view;
1151
1152 float vec[4][3], asp[2], shift[2], scale[3], drawsize, center[2], corner[2];
1153
1154 float *color_p;
1155 DRW_object_wire_theme_get(ob, view_layer, &color_p);
1156 copy_v4_v4(instdata.color, color_p);
1157
1158 normalize_m4_m4(instdata.mat, ob->obmat);
1159
1160 /* BKE_camera_multiview_model_matrix already accounts for scale, don't do it here. */
1161 if (is_selection_camera_stereo) {
1162 copy_v3_fl(scale, 1.0f);
1163 }
1164 else {
1165 copy_v3_fl3(scale, len_v3(ob->obmat[0]), len_v3(ob->obmat[1]), len_v3(ob->obmat[2]));
1166 /* Avoid division by 0. */
1167 if (ELEM(0.0f, scale[0], scale[1], scale[2])) {
1168 return;
1169 }
1170 invert_v3(scale);
1171 }
1172
1173 BKE_camera_view_frame_ex(
1174 scene, cam, cam->drawsize, look_through, scale, asp, shift, &drawsize, vec);
1175
1176 /* Apply scale to simplify the rest of the drawing. */
1177 invert_v3(scale);
1178 for (int i = 0; i < 4; i++) {
1179 mul_v3_v3(vec[i], scale);
1180 /* Project to z=-1 plane. Makes positionning / scaling easier. (see shader) */
1181 mul_v2_fl(vec[i], 1.0f / fabsf(vec[i][2]));
1182 }
1183
1184 /* Frame coords */
1185 mid_v2_v2v2(center, vec[0], vec[2]);
1186 sub_v2_v2v2(corner, vec[0], center);
1187 instdata.corner_x = corner[0];
1188 instdata.corner_y = corner[1];
1189 instdata.center_x = center[0];
1190 instdata.center_y = center[1];
1191 instdata.depth = vec[0][2];
1192
1193 if (look_through) {
1194 if (!DRW_state_is_image_render()) {
1195 /* Only draw the frame. */
1196 if (is_multiview) {
1197 float mat[4][4];
1198 const bool is_right = v3d->multiview_eye == STEREO_RIGHT_ID;
1199 const char *view_name = is_right ? STEREO_RIGHT_NAME : STEREO_LEFT_NAME;
1200 BKE_camera_multiview_model_matrix(&scene->r, ob, view_name, mat);
1201 instdata.center_x += camera_offaxis_shiftx_get(scene, ob, &instdata, is_right);
1202 for (int i = 0; i < 4; i++) {
1203 /* Partial copy to avoid overriding packed data. */
1204 copy_v3_v3(instdata.mat[i], mat[i]);
1205 }
1206 }
1207 instdata.depth = -instdata.depth; /* Hides the back of the camera wires (see shader). */
1208 DRW_buffer_add_entry_struct(cb->camera_frame, &instdata);
1209 }
1210 }
1211 else {
1212 /* Stereo cameras, volumes, plane drawing. */
1213 if (is_stereo3d_display_extra) {
1214 camera_stereoscopy_extra(cb, scene, v3d, ob, &instdata);
1215 }
1216 else {
1217 DRW_buffer_add_entry_struct(cb->camera_frame, &instdata);
1218 }
1219 }
1220
1221 if (!look_through) {
1222 /* Triangle. */
1223 float tria_size = 0.7f * drawsize / fabsf(instdata.depth);
1224 float tria_margin = 0.1f * drawsize / fabsf(instdata.depth);
1225 instdata.center_x = center[0];
1226 instdata.center_y = center[1] + instdata.corner_y + tria_margin + tria_size;
1227 instdata.corner_x = instdata.corner_y = -tria_size;
1228 DRW_buffer_add_entry_struct(cb->camera_tria[is_active], &instdata);
1229 }
1230
1231 if (cam->flag & CAM_SHOWLIMITS) {
1232 /* Scale focus point. */
1233 mul_v3_fl(instdata.mat[0], cam->drawsize);
1234 mul_v3_fl(instdata.mat[1], cam->drawsize);
1235
1236 instdata.dist_color_id = (is_active) ? 3 : 2;
1237 instdata.focus = -BKE_camera_object_dof_distance(ob);
1238 instdata.clip_sta = cam->clip_start;
1239 instdata.clip_end = cam->clip_end;
1240 DRW_buffer_add_entry_struct(cb->camera_distances, &instdata);
1241 }
1242
1243 if (cam->flag & CAM_SHOWMIST) {
1244 World *world = scene->world;
1245 if (world) {
1246 instdata.dist_color_id = (is_active) ? 1 : 0;
1247 instdata.focus = 1.0f; /* Disable */
1248 instdata.mist_sta = world->miststa;
1249 instdata.mist_end = world->miststa + world->mistdist;
1250 DRW_buffer_add_entry_struct(cb->camera_distances, &instdata);
1251 }
1252 }
1253
1254 /* Motion Tracking. */
1255 if ((v3d->flag2 & V3D_SHOW_RECONSTRUCTION) != 0) {
1256 camera_view3d_reconstruction(cb, scene, v3d, camera_object, ob, color_p);
1257 }
1258
1259 /* Background images. */
1260 if (look_through && (cam->flag & CAM_SHOW_BG_IMAGE) && !BLI_listbase_is_empty(&cam->bg_images)) {
1261 OVERLAY_image_camera_cache_populate(vedata, ob);
1262 }
1263 }
1264
1265 /** \} */
1266
1267 /* -------------------------------------------------------------------- */
1268 /** \name Relationships & constraints
1269 * \{ */
1270
OVERLAY_relationship_lines(OVERLAY_ExtraCallBuffers * cb,Depsgraph * depsgraph,Scene * scene,Object * ob)1271 static void OVERLAY_relationship_lines(OVERLAY_ExtraCallBuffers *cb,
1272 Depsgraph *depsgraph,
1273 Scene *scene,
1274 Object *ob)
1275 {
1276 float *relation_color = G_draw.block.colorWire;
1277 float *constraint_color = G_draw.block.colorGridAxisZ; /* ? */
1278
1279 if (ob->parent && (DRW_object_visibility_in_active_context(ob->parent) & OB_VISIBLE_SELF)) {
1280 float *parent_pos = ob->runtime.parent_display_origin;
1281 OVERLAY_extra_line_dashed(cb, parent_pos, ob->obmat[3], relation_color);
1282 }
1283
1284 /* Drawing the hook lines. */
1285 for (ModifierData *md = ob->modifiers.first; md; md = md->next) {
1286 if (md->type == eModifierType_Hook) {
1287 HookModifierData *hmd = (HookModifierData *)md;
1288 float center[3];
1289 mul_v3_m4v3(center, ob->obmat, hmd->cent);
1290 if (hmd->object) {
1291 OVERLAY_extra_line_dashed(cb, hmd->object->obmat[3], center, relation_color);
1292 }
1293 OVERLAY_extra_point(cb, center, relation_color);
1294 }
1295 }
1296
1297 if (ob->rigidbody_constraint) {
1298 Object *rbc_ob1 = ob->rigidbody_constraint->ob1;
1299 Object *rbc_ob2 = ob->rigidbody_constraint->ob2;
1300 if (rbc_ob1 && (DRW_object_visibility_in_active_context(rbc_ob1) & OB_VISIBLE_SELF)) {
1301 OVERLAY_extra_line_dashed(cb, rbc_ob1->obmat[3], ob->obmat[3], relation_color);
1302 }
1303 if (rbc_ob2 && (DRW_object_visibility_in_active_context(rbc_ob2) & OB_VISIBLE_SELF)) {
1304 OVERLAY_extra_line_dashed(cb, rbc_ob2->obmat[3], ob->obmat[3], relation_color);
1305 }
1306 }
1307
1308 /* Drawing the constraint lines */
1309 if (!BLI_listbase_is_empty(&ob->constraints)) {
1310 bConstraint *curcon;
1311 bConstraintOb *cob;
1312 ListBase *list = &ob->constraints;
1313
1314 cob = BKE_constraints_make_evalob(depsgraph, scene, ob, NULL, CONSTRAINT_OBTYPE_OBJECT);
1315
1316 for (curcon = list->first; curcon; curcon = curcon->next) {
1317 if (ELEM(curcon->type, CONSTRAINT_TYPE_FOLLOWTRACK, CONSTRAINT_TYPE_OBJECTSOLVER)) {
1318 /* special case for object solver and follow track constraints because they don't fill
1319 * constraint targets properly (design limitation -- scene is needed for their target
1320 * but it can't be accessed from get_targets callback) */
1321 Object *camob = NULL;
1322
1323 if (curcon->type == CONSTRAINT_TYPE_FOLLOWTRACK) {
1324 bFollowTrackConstraint *data = (bFollowTrackConstraint *)curcon->data;
1325 camob = data->camera ? data->camera : scene->camera;
1326 }
1327 else if (curcon->type == CONSTRAINT_TYPE_OBJECTSOLVER) {
1328 bObjectSolverConstraint *data = (bObjectSolverConstraint *)curcon->data;
1329 camob = data->camera ? data->camera : scene->camera;
1330 }
1331
1332 if (camob) {
1333 OVERLAY_extra_line_dashed(cb, camob->obmat[3], ob->obmat[3], constraint_color);
1334 }
1335 }
1336 else {
1337 const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(curcon);
1338
1339 if ((cti && cti->get_constraint_targets) && (curcon->ui_expand_flag & (1 << 0))) {
1340 ListBase targets = {NULL, NULL};
1341 bConstraintTarget *ct;
1342
1343 cti->get_constraint_targets(curcon, &targets);
1344
1345 for (ct = targets.first; ct; ct = ct->next) {
1346 /* calculate target's matrix */
1347 if (cti->get_target_matrix) {
1348 cti->get_target_matrix(depsgraph, curcon, cob, ct, DEG_get_ctime(depsgraph));
1349 }
1350 else {
1351 unit_m4(ct->matrix);
1352 }
1353 OVERLAY_extra_line_dashed(cb, ct->matrix[3], ob->obmat[3], constraint_color);
1354 }
1355
1356 if (cti->flush_constraint_targets) {
1357 cti->flush_constraint_targets(curcon, &targets, 1);
1358 }
1359 }
1360 }
1361 }
1362 BKE_constraints_clear_evalob(cob);
1363 }
1364 }
1365
1366 /** \} */
1367
1368 /* -------------------------------------------------------------------- */
1369 /** \name Volumetric / Smoke sim
1370 * \{ */
1371
OVERLAY_volume_extra(OVERLAY_ExtraCallBuffers * cb,OVERLAY_Data * data,Object * ob,ModifierData * md,Scene * scene,const float * color)1372 static void OVERLAY_volume_extra(OVERLAY_ExtraCallBuffers *cb,
1373 OVERLAY_Data *data,
1374 Object *ob,
1375 ModifierData *md,
1376 Scene *scene,
1377 const float *color)
1378 {
1379 FluidModifierData *fmd = (FluidModifierData *)md;
1380 FluidDomainSettings *fds = fmd->domain;
1381
1382 /* Don't show smoke before simulation starts, this could be made an option in the future. */
1383 const bool draw_velocity = (fds->draw_velocity && fds->fluid &&
1384 CFRA >= fds->point_cache[0]->startframe);
1385
1386 /* Show gridlines only for slices with no interpolation. */
1387 const bool show_gridlines = (fds->show_gridlines && fds->fluid &&
1388 fds->axis_slice_method == AXIS_SLICE_SINGLE &&
1389 (fds->interp_method == FLUID_DISPLAY_INTERP_CLOSEST ||
1390 fds->coba_field == FLUID_DOMAIN_FIELD_FLAGS));
1391
1392 const bool color_with_flags = (fds->gridlines_color_field == FLUID_GRIDLINE_COLOR_TYPE_FLAGS);
1393
1394 const bool color_range = (fds->gridlines_color_field == FLUID_GRIDLINE_COLOR_TYPE_RANGE &&
1395 fds->use_coba && fds->coba_field != FLUID_DOMAIN_FIELD_FLAGS);
1396
1397 /* Small cube showing voxel size. */
1398 {
1399 float min[3];
1400 madd_v3fl_v3fl_v3fl_v3i(min, fds->p0, fds->cell_size, fds->res_min);
1401 float voxel_cubemat[4][4] = {{0.0f}};
1402 /* scale small cube to voxel size */
1403 voxel_cubemat[0][0] = fds->cell_size[0] / 2.0f;
1404 voxel_cubemat[1][1] = fds->cell_size[1] / 2.0f;
1405 voxel_cubemat[2][2] = fds->cell_size[2] / 2.0f;
1406 voxel_cubemat[3][3] = 1.0f;
1407 /* translate small cube to corner */
1408 copy_v3_v3(voxel_cubemat[3], min);
1409 /* move small cube into the domain (otherwise its centered on vertex of domain object) */
1410 translate_m4(voxel_cubemat, 1.0f, 1.0f, 1.0f);
1411 mul_m4_m4m4(voxel_cubemat, ob->obmat, voxel_cubemat);
1412
1413 DRW_buffer_add_entry(cb->empty_cube, color, voxel_cubemat);
1414 }
1415
1416 int slice_axis = -1;
1417
1418 if (fds->axis_slice_method == AXIS_SLICE_SINGLE) {
1419 float viewinv[4][4];
1420 DRW_view_viewmat_get(NULL, viewinv, true);
1421
1422 const int axis = (fds->slice_axis == SLICE_AXIS_AUTO) ? axis_dominant_v3_single(viewinv[2]) :
1423 fds->slice_axis - 1;
1424 slice_axis = axis;
1425 }
1426
1427 if (draw_velocity) {
1428 const bool use_needle = (fds->vector_draw_type == VECTOR_DRAW_NEEDLE);
1429 const bool use_mac = (fds->vector_draw_type == VECTOR_DRAW_MAC);
1430 const bool draw_mac_x = (fds->vector_draw_mac_components & VECTOR_DRAW_MAC_X);
1431 const bool draw_mac_y = (fds->vector_draw_mac_components & VECTOR_DRAW_MAC_Y);
1432 const bool draw_mac_z = (fds->vector_draw_mac_components & VECTOR_DRAW_MAC_Z);
1433 const bool cell_centered = (fds->vector_field == FLUID_DOMAIN_VECTOR_FIELD_FORCE);
1434 int line_count = 1;
1435 if (use_needle) {
1436 line_count = 6;
1437 }
1438 else if (use_mac) {
1439 line_count = 3;
1440 }
1441 line_count *= fds->res[0] * fds->res[1] * fds->res[2];
1442
1443 if (fds->axis_slice_method == AXIS_SLICE_SINGLE) {
1444 line_count /= fds->res[slice_axis];
1445 }
1446
1447 DRW_smoke_ensure_velocity(fmd);
1448
1449 GPUShader *sh = OVERLAY_shader_volume_velocity(use_needle, use_mac);
1450 DRWShadingGroup *grp = DRW_shgroup_create(sh, data->psl->extra_ps[0]);
1451 DRW_shgroup_uniform_texture(grp, "velocityX", fds->tex_velocity_x);
1452 DRW_shgroup_uniform_texture(grp, "velocityY", fds->tex_velocity_y);
1453 DRW_shgroup_uniform_texture(grp, "velocityZ", fds->tex_velocity_z);
1454 DRW_shgroup_uniform_float_copy(grp, "displaySize", fds->vector_scale);
1455 DRW_shgroup_uniform_float_copy(grp, "slicePosition", fds->slice_depth);
1456 DRW_shgroup_uniform_vec3_copy(grp, "cellSize", fds->cell_size);
1457 DRW_shgroup_uniform_vec3_copy(grp, "domainOriginOffset", fds->p0);
1458 DRW_shgroup_uniform_ivec3_copy(grp, "adaptiveCellOffset", fds->res_min);
1459 DRW_shgroup_uniform_int_copy(grp, "sliceAxis", slice_axis);
1460 DRW_shgroup_uniform_bool_copy(grp, "scaleWithMagnitude", fds->vector_scale_with_magnitude);
1461 DRW_shgroup_uniform_bool_copy(grp, "isCellCentered", cell_centered);
1462
1463 if (use_mac) {
1464 DRW_shgroup_uniform_bool_copy(grp, "drawMACX", draw_mac_x);
1465 DRW_shgroup_uniform_bool_copy(grp, "drawMACY", draw_mac_y);
1466 DRW_shgroup_uniform_bool_copy(grp, "drawMACZ", draw_mac_z);
1467 }
1468
1469 DRW_shgroup_call_procedural_lines(grp, ob, line_count);
1470 }
1471
1472 if (show_gridlines) {
1473 GPUShader *sh = OVERLAY_shader_volume_gridlines(color_with_flags, color_range);
1474 DRWShadingGroup *grp = DRW_shgroup_create(sh, data->psl->extra_ps[0]);
1475 DRW_shgroup_uniform_ivec3_copy(grp, "volumeSize", fds->res);
1476 DRW_shgroup_uniform_float_copy(grp, "slicePosition", fds->slice_depth);
1477 DRW_shgroup_uniform_vec3_copy(grp, "cellSize", fds->cell_size);
1478 DRW_shgroup_uniform_vec3_copy(grp, "domainOriginOffset", fds->p0);
1479 DRW_shgroup_uniform_ivec3_copy(grp, "adaptiveCellOffset", fds->res_min);
1480 DRW_shgroup_uniform_int_copy(grp, "sliceAxis", slice_axis);
1481
1482 if (color_with_flags || color_range) {
1483 DRW_fluid_ensure_flags(fmd);
1484 DRW_shgroup_uniform_texture(grp, "flagTexture", fds->tex_flags);
1485 }
1486
1487 if (color_range) {
1488 DRW_fluid_ensure_range_field(fmd);
1489 DRW_shgroup_uniform_texture(grp, "fieldTexture", fds->tex_range_field);
1490 DRW_shgroup_uniform_float_copy(grp, "lowerBound", fds->gridlines_lower_bound);
1491 DRW_shgroup_uniform_float_copy(grp, "upperBound", fds->gridlines_upper_bound);
1492 DRW_shgroup_uniform_vec4_copy(grp, "rangeColor", fds->gridlines_range_color);
1493 DRW_shgroup_uniform_int_copy(grp, "cellFilter", fds->gridlines_cell_filter);
1494 }
1495
1496 const int line_count = 4 * fds->res[0] * fds->res[1] * fds->res[2] / fds->res[slice_axis];
1497 DRW_shgroup_call_procedural_lines(grp, ob, line_count);
1498 }
1499
1500 if (draw_velocity || show_gridlines) {
1501 BLI_addtail(&data->stl->pd->smoke_domains, BLI_genericNodeN(fmd));
1502 }
1503 }
1504
OVERLAY_volume_free_smoke_textures(OVERLAY_Data * data)1505 static void OVERLAY_volume_free_smoke_textures(OVERLAY_Data *data)
1506 {
1507 /* Free Smoke Textures after rendering */
1508 /* XXX This is a waste of processing and GPU bandwidth if nothing
1509 * is updated. But the problem is since Textures are stored in the
1510 * modifier we don't want them to take precious VRAM if the
1511 * modifier is not used for display. We should share them for
1512 * all viewport in a redraw at least. */
1513 LinkData *link;
1514 while ((link = BLI_pophead(&data->stl->pd->smoke_domains))) {
1515 FluidModifierData *fmd = (FluidModifierData *)link->data;
1516 DRW_smoke_free_velocity(fmd);
1517 MEM_freeN(link);
1518 }
1519 }
1520
1521 /** \} */
1522
1523 /* -------------------------------------------------------------------- */
1524
OVERLAY_object_center(OVERLAY_ExtraCallBuffers * cb,Object * ob,OVERLAY_PrivateData * pd,ViewLayer * view_layer)1525 static void OVERLAY_object_center(OVERLAY_ExtraCallBuffers *cb,
1526 Object *ob,
1527 OVERLAY_PrivateData *pd,
1528 ViewLayer *view_layer)
1529 {
1530 const bool is_library = ID_REAL_USERS(&ob->id) > 1 || ID_IS_LINKED(ob);
1531
1532 if (ob == OBACT(view_layer)) {
1533 DRW_buffer_add_entry(cb->center_active, ob->obmat[3]);
1534 }
1535 else if (ob->base_flag & BASE_SELECTED) {
1536 DRWCallBuffer *cbuf = (is_library) ? cb->center_selected_lib : cb->center_selected;
1537 DRW_buffer_add_entry(cbuf, ob->obmat[3]);
1538 }
1539 else if (pd->v3d_flag & V3D_DRAW_CENTERS) {
1540 DRWCallBuffer *cbuf = (is_library) ? cb->center_deselected_lib : cb->center_deselected;
1541 DRW_buffer_add_entry(cbuf, ob->obmat[3]);
1542 }
1543 }
1544
OVERLAY_object_name(Object * ob,int theme_id)1545 static void OVERLAY_object_name(Object *ob, int theme_id)
1546 {
1547 struct DRWTextStore *dt = DRW_text_cache_ensure();
1548 uchar color[4];
1549 /* Color Management: Exception here as texts are drawn in sRGB space directly. */
1550 UI_GetThemeColor4ubv(theme_id, color);
1551
1552 DRW_text_cache_add(dt,
1553 ob->obmat[3],
1554 ob->id.name + 2,
1555 strlen(ob->id.name + 2),
1556 10,
1557 0,
1558 DRW_TEXT_CACHE_GLOBALSPACE | DRW_TEXT_CACHE_STRING_PTR,
1559 color);
1560 }
1561
OVERLAY_extra_cache_populate(OVERLAY_Data * vedata,Object * ob)1562 void OVERLAY_extra_cache_populate(OVERLAY_Data *vedata, Object *ob)
1563 {
1564 OVERLAY_ExtraCallBuffers *cb = OVERLAY_extra_call_buffer_get(vedata, ob);
1565 OVERLAY_PrivateData *pd = vedata->stl->pd;
1566 const DRWContextState *draw_ctx = DRW_context_state_get();
1567 ViewLayer *view_layer = draw_ctx->view_layer;
1568 Scene *scene = draw_ctx->scene;
1569 ModifierData *md = NULL;
1570
1571 const bool is_select_mode = DRW_state_is_select();
1572 const bool is_paint_mode = (draw_ctx->object_mode &
1573 (OB_MODE_ALL_PAINT | OB_MODE_ALL_PAINT_GPENCIL)) != 0;
1574 const bool from_dupli = (ob->base_flag & (BASE_FROM_SET | BASE_FROM_DUPLI)) != 0;
1575 const bool has_bounds = !ELEM(ob->type, OB_LAMP, OB_CAMERA, OB_EMPTY, OB_SPEAKER, OB_LIGHTPROBE);
1576 const bool has_texspace = has_bounds &&
1577 !ELEM(ob->type, OB_EMPTY, OB_LATTICE, OB_ARMATURE, OB_GPENCIL);
1578
1579 const bool draw_relations = ((pd->v3d_flag & V3D_HIDE_HELPLINES) == 0) && !is_select_mode;
1580 const bool draw_obcenters = !is_paint_mode &&
1581 (pd->overlay.flag & V3D_OVERLAY_HIDE_OBJECT_ORIGINS) == 0;
1582 const bool draw_texspace = (ob->dtx & OB_TEXSPACE) && has_texspace;
1583 const bool draw_obname = (ob->dtx & OB_DRAWNAME) && DRW_state_show_text();
1584 const bool draw_bounds = has_bounds && ((ob->dt == OB_BOUNDBOX) ||
1585 ((ob->dtx & OB_DRAWBOUNDOX) && !from_dupli));
1586 const bool draw_xform = draw_ctx->object_mode == OB_MODE_OBJECT &&
1587 (scene->toolsettings->transform_flag & SCE_XFORM_DATA_ORIGIN) &&
1588 (ob->base_flag & BASE_SELECTED) && !is_select_mode;
1589 /* Don't show fluid domain overlay extras outside of cache range. */
1590 const bool draw_volume = !from_dupli &&
1591 (md = BKE_modifiers_findby_type(ob, eModifierType_Fluid)) &&
1592 (BKE_modifier_is_enabled(scene, md, eModifierMode_Realtime)) &&
1593 (((FluidModifierData *)md)->domain != NULL) &&
1594 (CFRA >= (((FluidModifierData *)md)->domain->cache_frame_start)) &&
1595 (CFRA <= (((FluidModifierData *)md)->domain->cache_frame_end));
1596
1597 float *color;
1598 int theme_id = DRW_object_wire_theme_get(ob, view_layer, &color);
1599
1600 if (ob->pd && ob->pd->forcefield) {
1601 OVERLAY_forcefield(cb, ob, view_layer);
1602 }
1603
1604 if (draw_bounds) {
1605 OVERLAY_bounds(cb, ob, color, ob->boundtype, false);
1606 }
1607 /* Helpers for when we're transforming origins. */
1608 if (draw_xform) {
1609 const float color_xform[4] = {0.15f, 0.15f, 0.15f, 0.7f};
1610 DRW_buffer_add_entry(cb->origin_xform, color_xform, ob->obmat);
1611 }
1612 /* don't show object extras in set's */
1613 if (!from_dupli) {
1614 if (draw_obcenters) {
1615 OVERLAY_object_center(cb, ob, pd, view_layer);
1616 }
1617 if (draw_relations) {
1618 OVERLAY_relationship_lines(cb, draw_ctx->depsgraph, draw_ctx->scene, ob);
1619 }
1620 if (draw_obname) {
1621 OVERLAY_object_name(ob, theme_id);
1622 }
1623 if (draw_texspace) {
1624 OVERLAY_texture_space(cb, ob, color);
1625 }
1626 if (ob->rigidbody_object != NULL) {
1627 OVERLAY_collision(cb, ob, color);
1628 }
1629 if (ob->dtx & OB_AXIS) {
1630 DRW_buffer_add_entry(cb->empty_axes, color, ob->obmat);
1631 }
1632 if (draw_volume) {
1633 OVERLAY_volume_extra(cb, vedata, ob, md, scene, color);
1634 }
1635 }
1636 }
1637
OVERLAY_extra_blend_draw(OVERLAY_Data * vedata)1638 void OVERLAY_extra_blend_draw(OVERLAY_Data *vedata)
1639 {
1640 DRW_draw_pass(vedata->psl->extra_blend_ps);
1641 }
1642
OVERLAY_extra_draw(OVERLAY_Data * vedata)1643 void OVERLAY_extra_draw(OVERLAY_Data *vedata)
1644 {
1645 DRW_draw_pass(vedata->psl->extra_ps[0]);
1646 }
1647
OVERLAY_extra_in_front_draw(OVERLAY_Data * vedata)1648 void OVERLAY_extra_in_front_draw(OVERLAY_Data *vedata)
1649 {
1650 DRW_draw_pass(vedata->psl->extra_ps[1]);
1651
1652 OVERLAY_volume_free_smoke_textures(vedata);
1653 }
1654
OVERLAY_extra_centers_draw(OVERLAY_Data * vedata)1655 void OVERLAY_extra_centers_draw(OVERLAY_Data *vedata)
1656 {
1657 OVERLAY_PassList *psl = vedata->psl;
1658
1659 DRW_draw_pass(psl->extra_grid_ps);
1660 DRW_draw_pass(psl->extra_centers_ps);
1661 }
1662