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