Blender V4.3
overlay_next_armature.hh
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
9#pragma once
10
11#include "ED_view3d.hh"
12
15
16namespace blender::draw::overlay {
17using namespace blender;
18
24
25class Armatures {
31
32 private:
33 const SelectionType selection_type_;
34
35 PassSimple armature_ps_ = {"Armature"};
36
37 /* Force transparent drawing in X-ray mode. */
38 bool draw_transparent = false;
39 /* Force disable drawing relation is relations are off in viewport. */
40 bool show_relations = false;
41 /* Show selection state. */
42 bool show_outline = false;
43
44 struct BoneBuffers {
45 const SelectionType selection_type_;
46
47 /* Bone end points (joints). */
48 PassSimple::Sub *sphere_fill = nullptr;
49 PassSimple::Sub *sphere_outline = nullptr;
50 /* Bone shapes. */
51 PassSimple::Sub *shape_fill = nullptr;
52 PassSimple::Sub *shape_outline = nullptr;
53 /* Custom bone wire-frame. */
54 PassSimple::Sub *shape_wire = nullptr;
55 /* Envelopes. */
56 PassSimple::Sub *envelope_fill = nullptr;
57 PassSimple::Sub *envelope_outline = nullptr;
58 PassSimple::Sub *envelope_distance = nullptr;
59 /* Stick bones. */
60 PassSimple::Sub *stick = nullptr;
61 /* Wire bones. */
62 PassSimple::Sub *wire = nullptr;
63
64 /* Bone axes. */
65 PassSimple::Sub *arrows = nullptr;
66 /* Degrees of freedom. */
67 PassSimple::Sub *degrees_of_freedom_fill = nullptr;
68 PassSimple::Sub *degrees_of_freedom_wire = nullptr;
69 /* Relations. */
70 PassSimple::Sub *relations = nullptr;
71
72 BoneInstanceBuf bbones_fill_buf = {selection_type_, "bbones_fill_buf"};
73 BoneInstanceBuf bbones_outline_buf = {selection_type_, "bbones_outline_buf"};
74
75 BoneInstanceBuf octahedral_fill_buf = {selection_type_, "octahedral_fill_buf"};
76 BoneInstanceBuf octahedral_outline_buf = {selection_type_, "octahedral_outline_buf"};
77
78 BoneInstanceBuf sphere_fill_buf = {selection_type_, "sphere_fill_buf"};
79 BoneInstanceBuf sphere_outline_buf = {selection_type_, "sphere_outline_buf"};
80
81 BoneEnvelopeBuf envelope_fill_buf = {selection_type_, "envelope_fill_buf"};
82 BoneEnvelopeBuf envelope_outline_buf = {selection_type_, "envelope_outline_buf"};
83 BoneEnvelopeBuf envelope_distance_buf = {selection_type_, "envelope_distance_buf"};
84
85 BoneStickBuf stick_buf = {selection_type_, "stick_buf"};
86
87 LinePrimitiveBuf wire_buf = {selection_type_, "wire_buf"};
88
89 EmptyInstanceBuf arrows_buf = {selection_type_, "arrows_buf"};
90
91 DegreesOfFreedomBuf degrees_of_freedom_fill_buf = {SelectionType::DISABLED,
92 "degrees_of_freedom_buf"};
93 DegreesOfFreedomBuf degrees_of_freedom_wire_buf = {SelectionType::DISABLED,
94 "degrees_of_freedom_buf"};
95
96 LinePrimitiveBuf relations_buf = {SelectionType::DISABLED, "relations_buf"};
97
101
102 BoneInstanceBuf &custom_shape_fill_get_buffer(gpu::Batch *geom)
103 {
104 return *custom_shape_fill.lookup_or_add_cb(geom, [this]() {
105 return std::make_unique<BoneInstanceBuf>(this->selection_type_, "CustomBoneSolid");
106 });
107 }
108
109 BoneInstanceBuf &custom_shape_outline_get_buffer(gpu::Batch *geom)
110 {
111 return *custom_shape_outline.lookup_or_add_cb(geom, [this]() {
112 return std::make_unique<BoneInstanceBuf>(this->selection_type_, "CustomBoneOutline");
113 });
114 }
115
116 BoneInstanceBuf &custom_shape_wire_get_buffer(gpu::Batch *geom)
117 {
118 return *custom_shape_wire.lookup_or_add_cb(geom, [this]() {
119 return std::make_unique<BoneInstanceBuf>(this->selection_type_, "CustomBoneWire");
120 });
121 }
122
123 BoneBuffers(const SelectionType selection_type) : selection_type_(selection_type){};
124 };
125
126 BoneBuffers opaque_ = {selection_type_};
127 BoneBuffers transparent_ = {selection_type_};
128
129 bool enabled_ = false;
130
131 public:
132 Armatures(const SelectionType selection_type) : selection_type_(selection_type){};
133
134 void begin_sync(Resources &res, const State &state)
135 {
136 enabled_ = state.v3d && !(state.overlay.flag & V3D_OVERLAY_HIDE_BONES);
137
138 if (!enabled_) {
139 return;
140 }
141
142 const bool is_select_mode = (selection_type_ != SelectionType::DISABLED);
143
144 draw_transparent = (state.v3d->shading.type == OB_WIRE) || XRAY_FLAG_ENABLED(state.v3d);
145 show_relations = !((state.v3d->flag & V3D_HIDE_HELPLINES) || is_select_mode);
146 show_outline = (state.v3d->flag & V3D_SELECT_OUTLINE);
147
148 const bool do_smooth_wire = U.gpu_flag & USER_GPU_FLAG_OVERLAY_SMOOTH_WIRE;
149 const float wire_alpha = state.overlay.bone_wire_alpha;
150 /* Draw bone outlines and custom shape wire with a specific alpha. */
151 const bool use_wire_alpha = (wire_alpha < 1.0f);
152
153 GPUTexture **depth_tex = (state.xray_enabled) ? &res.depth_tx : &res.dummy_depth_tx;
154
155 armature_ps_.init();
156 res.select_bind(armature_ps_);
157
158 /* Envelope distances and degrees of freedom need to be drawn first as they use additive
159 * transparent blending. */
160 {
163 {
164 auto &sub = armature_ps_.sub("opaque.envelope_distance");
165 sub.state_set(transparent_state | DRW_STATE_CULL_FRONT, state.clipping_plane_count);
166 sub.shader_set(res.shaders.armature_envelope_fill.get());
167 sub.push_constant("alpha", 1.0f);
168 sub.push_constant("isDistance", true);
169 opaque_.envelope_distance = &sub;
170 }
171 if (use_wire_alpha) {
172 auto &sub = armature_ps_.sub("transparent.envelope_distance");
173 sub.state_set(transparent_state | DRW_STATE_CULL_FRONT, state.clipping_plane_count);
174 sub.shader_set(res.shaders.armature_envelope_fill.get());
175 sub.push_constant("alpha", wire_alpha);
176 sub.push_constant("isDistance", true);
177 transparent_.envelope_distance = &sub;
178 }
179 else {
180 transparent_.envelope_distance = opaque_.envelope_distance;
181 }
182
183 {
184 auto &sub = armature_ps_.sub("opaque.degrees_of_freedom_fill");
185 sub.state_set(transparent_state, state.clipping_plane_count);
186 sub.shader_set(res.shaders.armature_degrees_of_freedom.get());
187 sub.push_constant("alpha", 1.0f);
188 sub.bind_ubo("globalsBlock", &res.globals_buf);
189 opaque_.degrees_of_freedom_fill = &sub;
190 }
191 if (use_wire_alpha) {
192 auto &sub = armature_ps_.sub("transparent.degrees_of_freedom_fill");
193 sub.state_set(transparent_state, state.clipping_plane_count);
194 sub.shader_set(res.shaders.armature_degrees_of_freedom.get());
195 sub.push_constant("alpha", wire_alpha);
196 sub.bind_ubo("globalsBlock", &res.globals_buf);
197 transparent_.degrees_of_freedom_fill = &sub;
198 }
199 else {
200 transparent_.degrees_of_freedom_fill = opaque_.degrees_of_freedom_fill;
201 }
202 }
203
206
207 /* Bone Shapes (Octahedral, Box, Custom Shapes, Spheres). */
208 {
209 {
210 auto &sub = armature_ps_.sub("opaque.sphere_fill");
211 sub.state_set(default_state, state.clipping_plane_count);
212 sub.shader_set(res.shaders.armature_sphere_fill.get());
213 sub.push_constant("alpha", 1.0f);
214 opaque_.sphere_fill = &sub;
215 }
216 {
217 auto &sub = armature_ps_.sub("transparent.sphere_fill");
219 state.clipping_plane_count);
220 sub.shader_set(res.shaders.armature_sphere_fill.get());
221 sub.push_constant("alpha", wire_alpha * 0.4f);
222 transparent_.sphere_fill = &sub;
223 }
224
225 {
226 auto &sub = armature_ps_.sub("opaque.shape_fill");
227 sub.state_set(default_state, state.clipping_plane_count);
228 sub.shader_set(res.shaders.armature_shape_fill.get());
229 sub.push_constant("alpha", 1.0f);
230 opaque_.shape_fill = &sub;
231 }
232 {
233 auto &sub = armature_ps_.sub("transparent.shape_fill");
235 state.clipping_plane_count);
236 sub.shader_set(res.shaders.armature_shape_fill.get());
237 sub.push_constant("alpha", wire_alpha * 0.6f);
238 transparent_.shape_fill = &sub;
239 }
240
241 {
242 auto &sub = armature_ps_.sub("opaque.sphere_outline");
243 sub.state_set(default_state, state.clipping_plane_count);
244 sub.shader_set(res.shaders.armature_sphere_outline.get());
245 sub.bind_ubo("globalsBlock", &res.globals_buf);
246 sub.push_constant("alpha", 1.0f);
247 opaque_.sphere_outline = &sub;
248 }
249 if (use_wire_alpha) {
250 auto &sub = armature_ps_.sub("transparent.sphere_outline");
251 sub.state_set(default_state | DRW_STATE_BLEND_ALPHA, state.clipping_plane_count);
252 sub.shader_set(res.shaders.armature_sphere_outline.get());
253 sub.bind_ubo("globalsBlock", &res.globals_buf);
254 sub.push_constant("alpha", wire_alpha);
255 transparent_.sphere_outline = &sub;
256 }
257 else {
258 transparent_.sphere_outline = opaque_.sphere_outline;
259 }
260
261 {
262 auto &sub = armature_ps_.sub("opaque.shape_outline");
263 sub.state_set(default_state, state.clipping_plane_count);
264 sub.shader_set(res.shaders.armature_shape_outline.get());
265 sub.bind_ubo("globalsBlock", &res.globals_buf);
266 sub.push_constant("alpha", 1.0f);
267 opaque_.shape_outline = &sub;
268 }
269 if (use_wire_alpha) {
270 auto &sub = armature_ps_.sub("transparent.shape_outline");
271 sub.state_set(default_state | DRW_STATE_BLEND_ALPHA, state.clipping_plane_count);
272 sub.shader_set(res.shaders.armature_shape_outline.get());
273 sub.bind_ubo("globalsBlock", &res.globals_buf);
274 sub.bind_texture("depthTex", depth_tex);
275 sub.push_constant("alpha", wire_alpha * 0.6f);
276 sub.push_constant("do_smooth_wire", do_smooth_wire);
277 transparent_.shape_outline = &sub;
278 }
279 else {
280 transparent_.shape_outline = opaque_.shape_outline;
281 }
282
283 {
284 auto &sub = armature_ps_.sub("opaque.shape_wire");
285 sub.state_set(default_state, state.clipping_plane_count);
286 sub.shader_set(res.shaders.armature_shape_wire.get());
287 sub.bind_ubo("globalsBlock", &res.globals_buf);
288 sub.push_constant("alpha", 1.0f);
289 opaque_.shape_wire = &sub;
290 }
291 if (use_wire_alpha) {
292 auto &sub = armature_ps_.sub("transparent.shape_wire");
293 sub.state_set(default_state | DRW_STATE_BLEND_ALPHA, state.clipping_plane_count);
294 sub.shader_set(res.shaders.armature_shape_wire.get());
295 sub.bind_ubo("globalsBlock", &res.globals_buf);
296 sub.bind_texture("depthTex", depth_tex);
297 sub.push_constant("alpha", wire_alpha * 0.6f);
298 sub.push_constant("do_smooth_wire", do_smooth_wire);
299 transparent_.shape_wire = &sub;
300 }
301 else {
302 transparent_.shape_wire = opaque_.shape_wire;
303 }
304 }
305 /* Degrees of freedom. */
306 {
307 {
308 auto &sub = armature_ps_.sub("opaque.degrees_of_freedom_wire");
310 sub.push_constant("alpha", 1.0f);
311 sub.bind_ubo("globalsBlock", &res.globals_buf);
312 opaque_.degrees_of_freedom_wire = &sub;
313 }
314 if (use_wire_alpha) {
315 auto &sub = armature_ps_.sub("transparent.degrees_of_freedom_wire");
317 sub.push_constant("alpha", wire_alpha);
318 sub.bind_ubo("globalsBlock", &res.globals_buf);
319 transparent_.degrees_of_freedom_wire = &sub;
320 }
321 else {
322 transparent_.degrees_of_freedom_wire = opaque_.degrees_of_freedom_wire;
323 }
324 }
325 /* Stick bones. */
326 {
327 {
328 auto &sub = armature_ps_.sub("opaque.stick");
329 sub.shader_set(res.shaders.armature_stick.get());
330 sub.bind_ubo("globalsBlock", &res.globals_buf);
331 sub.push_constant("alpha", 1.0f);
332 opaque_.stick = &sub;
333 }
334 if (use_wire_alpha) {
335 auto &sub = armature_ps_.sub("transparent.stick");
336 sub.state_set(default_state | DRW_STATE_BLEND_ALPHA, state.clipping_plane_count);
337 sub.shader_set(res.shaders.armature_stick.get());
338 sub.bind_ubo("globalsBlock", &res.globals_buf);
339 sub.push_constant("alpha", wire_alpha);
340 transparent_.stick = &sub;
341 }
342 else {
343 transparent_.stick = opaque_.stick;
344 }
345 }
346 /* Envelopes. */
347 {
348 {
349 auto &sub = armature_ps_.sub("opaque.envelope_fill");
350 sub.state_set(default_state | DRW_STATE_CULL_BACK, state.clipping_plane_count);
351 sub.shader_set(res.shaders.armature_envelope_fill.get());
352 sub.push_constant("isDistance", false);
353 sub.push_constant("alpha", 1.0f);
354 opaque_.envelope_fill = &sub;
355 }
356 {
357 auto &sub = armature_ps_.sub("transparent.envelope_fill");
358 sub.state_set((default_state & ~DRW_STATE_WRITE_DEPTH) |
360 state.clipping_plane_count);
361 sub.shader_set(res.shaders.armature_envelope_fill.get());
362 sub.push_constant("alpha", wire_alpha * 0.6f);
363 transparent_.envelope_fill = &sub;
364 }
365
366 {
367 auto &sub = armature_ps_.sub("opaque.envelope_outline");
368 sub.state_set(default_state | DRW_STATE_CULL_BACK, state.clipping_plane_count);
369 sub.shader_set(res.shaders.armature_envelope_outline.get());
370 sub.bind_ubo("globalsBlock", &res.globals_buf);
371 sub.push_constant("alpha", 1.0f);
372 opaque_.envelope_outline = &sub;
373 }
374 if (use_wire_alpha) {
375 auto &sub = armature_ps_.sub("transparent.envelope_outline");
376 sub.state_set((default_state & ~DRW_STATE_WRITE_DEPTH) |
378 state.clipping_plane_count);
379 sub.shader_set(res.shaders.armature_envelope_outline.get());
380 sub.bind_ubo("globalsBlock", &res.globals_buf);
381 sub.push_constant("alpha", wire_alpha);
382 transparent_.envelope_outline = &sub;
383 }
384 else {
385 transparent_.envelope_outline = opaque_.envelope_outline;
386 }
387 }
388 {
389 {
390 auto &sub = armature_ps_.sub("opaque.wire");
391 sub.shader_set(res.shaders.armature_wire.get());
392 sub.bind_ubo("globalsBlock", &res.globals_buf);
393 sub.push_constant("alpha", 1.0f);
394 opaque_.wire = &sub;
395 }
396 if (use_wire_alpha) {
397 auto &sub = armature_ps_.sub("transparent.wire");
398 sub.state_set(default_state | DRW_STATE_BLEND_ALPHA, state.clipping_plane_count);
399 sub.shader_set(res.shaders.armature_wire.get());
400 sub.bind_ubo("globalsBlock", &res.globals_buf);
401 sub.push_constant("alpha", wire_alpha);
402 transparent_.wire = &sub;
403 }
404 else {
405 transparent_.wire = opaque_.wire;
406 }
407 }
408
409 {
410 auto &sub = armature_ps_.sub("opaque.arrow");
411 sub.shader_set(res.shaders.extra_shape.get());
412 sub.bind_ubo("globalsBlock", &res.globals_buf);
413 opaque_.arrows = &sub;
414 transparent_.arrows = opaque_.arrows;
415 }
416
417 {
418 auto &sub = armature_ps_.sub("opaque.relations");
419 sub.shader_set(res.shaders.extra_wire.get());
420 sub.bind_ubo("globalsBlock", &res.globals_buf);
421 opaque_.relations = &sub;
422 transparent_.relations = opaque_.relations;
423 }
424
425 auto shape_instance_bufs_begin_sync = [](BoneBuffers &bb) {
426 bb.envelope_fill_buf.clear();
427 bb.envelope_outline_buf.clear();
428 bb.envelope_distance_buf.clear();
429 bb.bbones_fill_buf.clear();
430 bb.bbones_outline_buf.clear();
431 bb.octahedral_fill_buf.clear();
432 bb.octahedral_outline_buf.clear();
433 bb.sphere_fill_buf.clear();
434 bb.sphere_outline_buf.clear();
435 bb.stick_buf.clear();
436 bb.wire_buf.clear();
437 bb.arrows_buf.clear();
438 bb.degrees_of_freedom_fill_buf.clear();
439 bb.degrees_of_freedom_wire_buf.clear();
440 bb.relations_buf.clear();
441 /* TODO(fclem): Potentially expensive operation recreating a lot of gpu buffers.
442 * Prefer a pruning strategy. */
443 bb.custom_shape_fill.clear();
444 bb.custom_shape_outline.clear();
445 bb.custom_shape_wire.clear();
446 };
447
448 shape_instance_bufs_begin_sync(transparent_);
449 shape_instance_bufs_begin_sync(opaque_);
450 }
451
452 struct DrawContext {
453 /* Current armature object */
454 Object *ob = nullptr;
455 const ObjectRef *ob_ref = nullptr;
456
457 /* Note: can be mutated inside `draw_armature_pose()`. */
460
461 Armatures::BoneBuffers *bone_buf = nullptr;
462 Resources *res = nullptr;
463 const ShapeCache *shapes = nullptr;
464
465 /* TODO: Legacy structures to be removed after overlay next is shipped. */
468 DRWCallBuffer *wire = nullptr;
482
483 /* Not a theme, this is an override. */
484 const float *const_color = nullptr;
485 /* Wire thickness. */
486 float const_wire = 0.0f;
487
488 bool do_relations = false;
489 bool transparent = false;
490 bool show_relations = false;
493 /* Draw the inner part of the bones, otherwise render just outlines. */
494 bool is_filled = false;
495
496 const ThemeWireColor *bcolor = nullptr; /* pchan color */
497
498 DrawContext() = default;
499
500 /* Runtime switch between legacy and new overlay code-base.
501 * Should be removed once the legacy code is removed. */
502 bool is_overlay_next() const
503 {
504 return this->bone_buf != nullptr;
505 }
506 };
507
509 Resources &res,
510 const ShapeCache &shapes,
511 const State &state,
512 eArmatureDrawMode draw_mode)
513 {
514 bArmature *arm = static_cast<bArmature *>(ob_ref.object->data);
515
516 DrawContext ctx;
517 ctx.ob = ob_ref.object;
518 ctx.ob_ref = &ob_ref;
519 ctx.res = &res;
520 ctx.shapes = &shapes;
521 ctx.draw_mode = draw_mode;
523
524 const bool is_edit_or_pose_mode = draw_mode != ARM_DRAW_MODE_OBJECT;
525 const bool draw_as_wire = (ctx.ob->dt < OB_SOLID);
526 const bool is_transparent = draw_transparent || (draw_as_wire && is_edit_or_pose_mode);
527
528 ctx.bone_buf = is_transparent ? &transparent_ : &opaque_;
529
530 ctx.is_filled = (!draw_transparent && !draw_as_wire) || is_edit_or_pose_mode;
531 ctx.show_relations = show_relations;
532 ctx.do_relations = show_relations && is_edit_or_pose_mode;
533 ctx.draw_envelope_distance = is_edit_or_pose_mode;
535 ctx.const_color = is_edit_or_pose_mode ? nullptr : &res.object_wire_color(ob_ref, state)[0];
536 ctx.const_wire = (!ctx.is_filled || is_transparent) ? 1.0f : 0.0f;
537 if ((ctx.ob->base_flag & BASE_SELECTED) && show_outline) {
538 ctx.const_wire = 1.5f;
539 }
540 return ctx;
541 }
542
543 void edit_object_sync(const ObjectRef &ob_ref,
544 Resources &res,
545 ShapeCache &shapes,
546 const State &state)
547 {
548 if (!enabled_) {
549 return;
550 }
551
552 DrawContext ctx = create_draw_context(ob_ref, res, shapes, state, ARM_DRAW_MODE_EDIT);
553 draw_armature_edit(&ctx);
554 }
555
556 void object_sync(const ObjectRef &ob_ref,
557 Resources &res,
558 const ShapeCache &shapes,
559 const State &state)
560 {
561 if (!enabled_ || ob_ref.object->dt == OB_BOUNDBOX) {
562 return;
563 }
564
567
568 DrawContext ctx = create_draw_context(ob_ref, res, shapes, state, draw_mode);
569 draw_armature_pose(&ctx);
570 }
571
572 void end_sync(Resources & /*res*/, const ShapeCache &shapes, const State & /*state*/)
573 {
574 if (!enabled_) {
575 return;
576 }
577
578 auto end_sync = [&](BoneBuffers &bb) {
579 bb.sphere_fill_buf.end_sync(*bb.sphere_fill, shapes.bone_sphere.get());
580 bb.sphere_outline_buf.end_sync(*bb.sphere_outline, shapes.bone_sphere_wire.get());
581
582 bb.octahedral_fill_buf.end_sync(*bb.shape_fill, shapes.bone_octahedron.get());
583 bb.octahedral_outline_buf.end_sync(
584 *bb.shape_outline, shapes.bone_octahedron_wire.get(), GPU_PRIM_LINES, 1);
585
586 bb.bbones_fill_buf.end_sync(*bb.shape_fill, shapes.bone_box.get());
587 bb.bbones_outline_buf.end_sync(
588 *bb.shape_outline, shapes.bone_box_wire.get(), GPU_PRIM_LINES, 1);
589
590 bb.envelope_fill_buf.end_sync(*bb.envelope_fill, shapes.bone_envelope.get());
591 bb.envelope_outline_buf.end_sync(*bb.envelope_outline, shapes.bone_envelope_wire.get());
592 bb.envelope_distance_buf.end_sync(*bb.envelope_distance, shapes.bone_envelope.get());
593
594 bb.stick_buf.end_sync(*bb.stick, shapes.bone_stick.get());
595
596 bb.wire_buf.end_sync(*bb.wire);
597
598 bb.arrows_buf.end_sync(*bb.arrows, shapes.arrows.get());
599
600 bb.degrees_of_freedom_fill_buf.end_sync(*bb.degrees_of_freedom_fill,
601 shapes.bone_degrees_of_freedom.get());
602 bb.degrees_of_freedom_wire_buf.end_sync(*bb.degrees_of_freedom_wire,
603 shapes.bone_degrees_of_freedom_wire.get());
604
605 bb.relations_buf.end_sync(*bb.relations);
606
608
609 for (CustomShapeBuf item : bb.custom_shape_fill.items()) {
610 item.value->end_sync(*bb.shape_fill, item.key);
611 }
612 for (CustomShapeBuf item : bb.custom_shape_outline.items()) {
613 item.value->end_sync(*bb.shape_outline, item.key, GPU_PRIM_LINES, 1);
614 }
615 for (CustomShapeBuf item : bb.custom_shape_wire.items()) {
616 item.value->end_sync(*bb.shape_wire, item.key, GPU_PRIM_TRIS, 2);
617 }
618 };
619
620 end_sync(transparent_);
621 end_sync(opaque_);
622 }
623
624 void draw(Framebuffer &framebuffer, Manager &manager, View &view)
625 {
626 if (!enabled_) {
627 return;
628 }
629
630 GPU_framebuffer_bind(framebuffer);
631 manager.submit(armature_ps_, view);
632 }
633
634 /* Public for the time of the Overlay Next port to avoid duplicated logic. */
635 public:
638
639 static bool is_pose_mode(const Object *armature_ob, const State &state)
640 {
641 Object *active_ob = state.active_base->object;
642
643 /* Armature is in pose mode. */
644 if (((armature_ob == active_ob) || (armature_ob->mode & OB_MODE_POSE)) &&
645 ((state.object_mode & OB_MODE_POSE) != 0))
646 {
647 return true;
648 }
649
650 /* Active object is in weight paint and the associated armature is in pose mode. */
651 if ((active_ob != nullptr) && (state.object_mode & OB_MODE_ALL_WEIGHT_PAINT)) {
652 if (armature_ob == BKE_object_pose_armature_get(active_ob)) {
653 return true;
654 }
655 }
656
657 return false;
658 }
659};
660
661} // namespace blender::draw::overlay
Object * BKE_object_pose_armature_get(Object *ob)
@ ARM_DRAW_RELATION_FROM_HEAD
eArmature_Drawtype
@ OB_WIRE
@ OB_BOUNDBOX
@ OB_SOLID
#define OB_MODE_ALL_WEIGHT_PAINT
@ OB_MODE_POSE
#define BASE_SELECTED(v3d, base)
@ USER_GPU_FLAG_OVERLAY_SMOOTH_WIRE
@ V3D_OVERLAY_HIDE_BONES
@ V3D_SELECT_OUTLINE
@ V3D_HIDE_HELPLINES
#define XRAY_FLAG_ENABLED(v3d)
void GPU_framebuffer_bind(GPUFrameBuffer *framebuffer)
@ GPU_PRIM_LINES
@ GPU_PRIM_TRIS
unsigned int U
Definition btGjkEpa3.h:78
Value & lookup_or_add_cb(const Key &key, const CreateValueF &create_value)
Definition BLI_map.hh:582
void submit(PassSimple &pass, View &view)
PassBase< DrawCommandBufType > & sub(const char *name)
Definition draw_pass.hh:616
void state_set(DRWState state, int clip_plane_count=0)
Definition draw_pass.hh:954
void clear(eGPUFrameBufferBits planes, float4 color, float depth, uint8_t stencil)
Definition draw_pass.hh:584
void shader_set(GPUShader *shader)
Definition draw_pass.hh:971
static bool is_pose_mode(const Object *armature_ob, const State &state)
DrawContext create_draw_context(const ObjectRef &ob_ref, Resources &res, const ShapeCache &shapes, const State &state, eArmatureDrawMode draw_mode)
static void draw_armature_pose(Armatures::DrawContext *ctx)
Armatures(const SelectionType selection_type)
void begin_sync(Resources &res, const State &state)
void edit_object_sync(const ObjectRef &ob_ref, Resources &res, ShapeCache &shapes, const State &state)
void draw(Framebuffer &framebuffer, Manager &manager, View &view)
void object_sync(const ObjectRef &ob_ref, Resources &res, const ShapeCache &shapes, const State &state)
void end_sync(Resources &, const ShapeCache &shapes, const State &)
static void draw_armature_edit(Armatures::DrawContext *ctx)
DRWState
Definition draw_state.hh:25
@ DRW_STATE_BLEND_ALPHA
Definition draw_state.hh:55
@ DRW_STATE_BLEND_ADD
Definition draw_state.hh:51
@ DRW_STATE_CULL_FRONT
Definition draw_state.hh:44
@ DRW_STATE_WRITE_DEPTH
Definition draw_state.hh:29
@ DRW_STATE_WRITE_COLOR
Definition draw_state.hh:30
@ DRW_STATE_DEPTH_LESS_EQUAL
Definition draw_state.hh:38
@ DRW_STATE_CULL_BACK
Definition draw_state.hh:43
static ulong state[N]
short base_flag
const float4 & object_wire_color(const ObjectRef &ob_ref, ThemeColorID theme_id) const
void select_bind(PassSimple &pass)