Blender V5.0
dial3d_gizmo.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2014 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
19
20#include "MEM_guardedalloc.h"
21
22#include "BLI_math_geom.h"
23#include "BLI_math_matrix.h"
24#include "BLI_math_rotation.h"
25
26#include "BKE_context.hh"
27
28#include "GPU_immediate.hh"
29#include "GPU_immediate_util.hh"
30#include "GPU_matrix.hh"
31#include "GPU_select.hh"
32#include "GPU_state.hh"
33
34#include "RNA_access.hh"
35#include "RNA_define.hh"
36
37#include "WM_api.hh"
38#include "WM_types.hh"
39
40#include "ED_gizmo_library.hh"
41#include "ED_screen.hh"
42#include "ED_transform.hh"
43#include "ED_view3d.hh"
44
45/* own includes */
47
48// /** To use custom dials exported to `geom_dial_gizmo.cc`. */
49// #define USE_GIZMO_CUSTOM_DIAL
50
52 struct {
53 float mval[2];
54 /* Only for when using properties. */
57 struct {
58 /* Cache the last angle to detect rotations bigger than -/+ PI. */
60 float angle;
62
63 /* Number of full rotations. */
67
68 /* Final output values, used for drawing. */
69 struct {
70 float angle_ofs;
73};
74
75#define DIAL_WIDTH 1.0f
76
77/* Could make option, negative to clip more (don't show when view aligned). */
78#define DIAL_CLIP_BIAS 0.02
79
80/* -------------------------------------------------------------------- */
90static void dial_3d_draw_util(const float matrix_final[4][4],
91 const float line_width,
92 const float color[4],
93 const bool select,
95
96static void dial_geom_draw(const float color[4],
97 const float line_width,
98 const bool select,
99 const float clip_plane_mat[4][4],
100 const float clip_plane[4],
101 const float arc_partial_angle,
102 const float arc_inner_factor,
103 const int draw_options)
104{
105#ifdef USE_GIZMO_CUSTOM_DIAL
106 UNUSED_VARS(gz, axis_modal_mat, clip_plane);
108#else
109 const bool filled = (draw_options & (select ? (ED_GIZMO_DIAL_DRAW_FLAG_FILL |
112
114 /* NOTE(Metal): Prefer using 3D coordinates with 3D shader, even if rendering 2D gizmo's. */
115 uint pos = GPU_vertformat_attr_add(format, "pos", blender::gpu::VertAttrType::SFLOAT_32_32_32);
116
117 if (clip_plane) {
120 immUniform4fv("ClipPlane", clip_plane);
121 immUniformMatrix4fv("ModelMatrix", clip_plane_mat);
122 }
123 else {
126 }
127
128 immUniformColor4fv(color);
129
130 if (filled) {
131 if (arc_partial_angle == 0.0f) {
132 if (arc_inner_factor == 0.0f) {
133 imm_draw_circle_fill_3d(pos, 0.0f, 0.0f, 1.0f, DIAL_RESOLUTION);
134 }
135 else {
137 pos, 0.0f, 0.0f, 0.0f, arc_inner_factor, 1.0f, DIAL_RESOLUTION, 0, RAD2DEGF(M_PI * 2));
138 }
139 }
140 else {
141 float arc_partial_deg = RAD2DEGF((M_PI * 2) - arc_partial_angle);
143 0.0f,
144 0.0f,
145 0.0f,
146 arc_inner_factor,
147 1.0f,
149 -arc_partial_deg / 2,
150 arc_partial_deg);
151 }
152 }
153 else {
154 float viewport[4];
155 GPU_viewport_size_get_f(viewport);
156 immUniform2fv("viewportSize", &viewport[2]);
157 immUniform1f("lineWidth", line_width);
158
159 if (arc_partial_angle == 0.0f) {
160 imm_draw_circle_wire_3d(pos, 0.0f, 0.0f, 1.0f, DIAL_RESOLUTION);
161 if (arc_inner_factor != 0.0f) {
162 imm_draw_circle_wire_3d(pos, 0.0f, 0.0f, arc_inner_factor, DIAL_RESOLUTION);
163 }
164 }
165 else {
166 float arc_partial_deg = RAD2DEGF((M_PI * 2) - arc_partial_angle);
168 pos, 0.0f, 0.0f, 0.0f, 1.0f, DIAL_RESOLUTION, -arc_partial_deg / 2, arc_partial_deg);
169# if 0
170 if (arc_inner_factor != 0.0f) {
171 BLI_assert(0);
172 }
173# endif
174 }
175 }
176
178
180#endif
181}
182
186static void dial_ghostarc_draw_helpline(const float angle,
187 const float co_outer[3],
188 const float color[4],
189 const float line_width)
190{
192 GPU_matrix_rotate_3f(RAD2DEGF(angle), 0.0f, 0.0f, -1.0f);
193
195 immVertexFormat(), "pos", blender::gpu::VertAttrType::SFLOAT_32_32_32);
196
198
199 float viewport[4];
200 GPU_viewport_size_get_f(viewport);
201 immUniform2fv("viewportSize", &viewport[2]);
202 immUniform1f("lineWidth", line_width * U.pixelsize);
203
204 immUniformColor4fv(color);
205
207 immVertex3f(pos, 0.0f, 0.0f, 0.0f);
208 immVertex3fv(pos, co_outer);
209 immEnd();
210
212
214}
215
219static void dial_ghostarc_draw_incremental_angle(const float incremental_angle,
220 const float offset,
221 const float angle_delta)
222{
223
225 immVertexFormat(), "pos", blender::gpu::VertAttrType::SFLOAT_32_32_32);
227
228 immUniformColor3f(1.0f, 1.0f, 1.0f);
229
230 float viewport[4];
231 GPU_viewport_size_get_f(viewport);
232 immUniform2fv("viewportSize", &viewport[2]);
233 immUniform1f("lineWidth", U.pixelsize);
234
235 const int current_increment = roundf(angle_delta / incremental_angle);
236 const int total_increment = roundf((M_PI * 2.0f) / incremental_angle);
237
238 immBegin(GPU_PRIM_LINES, total_increment * 2);
239
240 /* Chop off excess full circles, draw an arc of ticks centered at current increment;
241 * if there's no even division of circle by increment,
242 * ends of the arc will move with the rotation. */
243 const float start_offset = fmodf(
244 offset + incremental_angle * (current_increment - total_increment / 2), M_PI * 2.0f);
245
246 float v[3] = {0};
247 for (int i = 0; i < total_increment; i++) {
248 v[0] = sinf(start_offset + incremental_angle * i);
249 v[1] = cosf(start_offset + incremental_angle * i);
250
251 mul_v2_fl(v, DIAL_WIDTH * 1.1f);
253
254 mul_v2_fl(v, 1.1f);
256 }
257
258 immEnd();
260}
261
262static void dial_ghostarc_draw(const float angle_ofs,
263 float angle_delta,
264 const float arc_inner_factor,
265 const float color[4])
266{
267 const float width_inner = DIAL_WIDTH;
269 uint pos = GPU_vertformat_attr_add(format, "pos", blender::gpu::VertAttrType::SFLOAT_32_32);
271
272 /* Avoid artifacts by drawing the main arc over the span of one rotation only. */
273 const float pi2 = float(M_PI * 2.0);
274 int rotation_count = int(floorf(fabsf(angle_delta) / pi2));
275 angle_delta = fmod(angle_delta, pi2);
276
277 /* Calculate the remaining angle that can be filled with the background color. */
278 const float angle_background = angle_delta >= 0 ? (pi2 - angle_delta) : -(pi2 + angle_delta);
279
280 float color_background[4] = {0};
281 if (arc_inner_factor != 0.0) {
282 color_background[3] = color[3] / 2.0f;
283 }
284
285 if (rotation_count != 0) {
286 /* Calculate the background color to visualize the rotation count. */
287 copy_v4_v4(color_background, color);
288 color_background[3] = color[3] * rotation_count;
289 }
290
291 immUniformColor4fv(color_background);
293 0,
294 0,
295 arc_inner_factor,
296 width_inner,
298 RAD2DEGF(angle_ofs + angle_delta),
299 RAD2DEGF(angle_background));
300
301 immUniformColor4f(UNPACK3(color), color[3] * (rotation_count + 1));
303 0,
304 0,
305 arc_inner_factor,
306 width_inner,
308 RAD2DEGF(angle_ofs),
309 RAD2DEGF(angle_delta));
311}
312
313static void dial_ghostarc_get_angles(const wmGizmo *gz,
314 const wmEvent *event,
315 const ARegion *region,
316 const float mat[4][4],
317 const float co_outer[3],
318 float *r_start,
319 float *r_delta)
320{
321 DialInteraction *inter = static_cast<DialInteraction *>(gz->interaction_data);
322 const RegionView3D *rv3d = static_cast<const RegionView3D *>(region->regiondata);
323 const float mval[2] = {float(event->xy[0] - region->winrct.xmin),
324 float(event->xy[1] - region->winrct.ymin)};
325
326 /* We might need to invert the direction of the angles. */
327 float view_vec[3], axis_vec[3];
328 ED_view3d_global_to_vector(rv3d, gz->matrix_basis[3], view_vec);
329 normalize_v3_v3(axis_vec, gz->matrix_basis[2]);
330
331 float proj_outer_rel[3];
332 mul_v3_project_m4_v3(proj_outer_rel, mat, co_outer);
333 sub_v3_v3(proj_outer_rel, gz->matrix_basis[3]);
334
335 float proj_mval_new_rel[3];
336 float proj_mval_init_rel[3];
337 float dial_plane[4];
338
339 plane_from_point_normal_v3(dial_plane, gz->matrix_basis[3], axis_vec);
340
341 const auto fail = [&]() {
342 /* If we can't project (unlikely). */
343 *r_start = 0.0;
344 *r_delta = 0.0;
345 };
346
348 region, dial_plane, inter->init.mval, false, proj_mval_init_rel))
349 {
350 fail();
351 return;
352 }
353 sub_v3_v3(proj_mval_init_rel, gz->matrix_basis[3]);
354
355 if (!ED_view3d_win_to_3d_on_plane(region, dial_plane, mval, false, proj_mval_new_rel)) {
356 fail();
357 return;
358 }
359 sub_v3_v3(proj_mval_new_rel, gz->matrix_basis[3]);
360
361 const int draw_options = RNA_enum_get(gz->ptr, "draw_options");
362
363 /* Start direction from mouse or set by user. */
364 const float *proj_init_rel = (draw_options & ED_GIZMO_DIAL_DRAW_FLAG_ANGLE_START_Y) ?
365 gz->matrix_basis[1] :
366 proj_mval_init_rel;
367
368 /* Return angles. */
369 const float start = angle_wrap_rad(
370 angle_signed_on_axis_v3v3_v3(proj_outer_rel, proj_init_rel, axis_vec));
371 const float delta = angle_wrap_rad(
372 angle_signed_on_axis_v3v3_v3(proj_mval_init_rel, proj_mval_new_rel, axis_vec));
373
374 /* Change of sign, we passed the 180 degree threshold. This means we need to add a turn
375 * to distinguish between transition from 0 to -1 and -PI to +PI, use comparison with PI/2.
376 * Logic taken from #BLI_dial_angle */
377 if ((delta * inter->prev.angle < 0.0f) && (fabsf(inter->prev.angle) > float(M_PI_2))) {
378 if (inter->prev.angle < 0.0f) {
379 inter->rotations--;
380 }
381 else {
382 inter->rotations++;
383 }
384 }
385 inter->prev.angle = delta;
386
387 const bool wrap_angle = RNA_boolean_get(gz->ptr, "wrap_angle");
388 const double delta_final = double(delta) + ((2 * M_PI) * double(inter->rotations));
389 *r_start = start;
390 *r_delta = float(wrap_angle ? fmod(delta_final, 2 * M_PI) : delta_final);
391}
392
393static void dial_ghostarc_draw_with_helplines(const float angle_ofs,
394 const float angle_delta,
395 const float arc_inner_factor,
396 const float color_helpline[4],
397 const int draw_options)
398{
399 /* Coordinate at which the arc drawing will be started. */
400 const float co_outer[4] = {0.0f, DIAL_WIDTH, 0.0f};
401 const float color_arc_inner[4] = {0.8f, 0.8f, 0.8f, 0.2f};
402 dial_ghostarc_draw(angle_ofs, angle_delta, arc_inner_factor, color_arc_inner);
403
404 float line_width = (draw_options & ED_GIZMO_DIAL_DRAW_FLAG_ANGLE_VALUE) ? 3.0f : 1.0f;
405 dial_ghostarc_draw_helpline(angle_ofs, co_outer, color_helpline, 1.0f);
406 dial_ghostarc_draw_helpline(angle_ofs + angle_delta, co_outer, color_helpline, line_width);
407}
408
409static void dial_draw_intern(const bContext *C,
410 wmGizmo *gz,
411 const bool select,
412 const bool highlight,
413 const bool use_clip_plane)
414{
415 float matrix_final[4][4];
416 float color[4];
417
418 (void)C;
419 BLI_assert(CTX_wm_area(C)->spacetype == SPACE_VIEW3D);
420
421 gizmo_color_get(gz, highlight, color);
422
423 WM_gizmo_calc_matrix_final(gz, matrix_final);
424
425 float clip_plane[4];
426 if (use_clip_plane) {
427 ARegion *region = CTX_wm_region(C);
428 RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
429
430 copy_v3_v3(clip_plane, rv3d->viewinv[2]);
431 clip_plane[3] = -dot_v3v3(rv3d->viewinv[2], gz->matrix_basis[3]);
432 /* NOTE: scaling by the pixel size has been needed since v3.4x,
433 * afterwards the behavior of the `ClipPlane` seems to have changed.
434 * While this works, it may be worth restoring the old behavior, see #111060. */
435 clip_plane[3] += (DIAL_CLIP_BIAS *
437 }
438
439 const float arc_partial_angle = RNA_float_get(gz->ptr, "arc_partial_angle");
440 const float arc_inner_factor = RNA_float_get(gz->ptr, "arc_inner_factor");
441 int draw_options = RNA_enum_get(gz->ptr, "draw_options");
442 float angle_ofs = 0.0f;
443 float angle_delta = 0.0f;
444 float angle_increment = 0.0f;
445
446 if (select) {
448 }
449
450 if (draw_options & ED_GIZMO_DIAL_DRAW_FLAG_ANGLE_VALUE && (gz->flag & WM_GIZMO_DRAW_VALUE)) {
451 DialInteraction *inter = static_cast<DialInteraction *>(gz->interaction_data);
452 if (inter) {
453 angle_ofs = inter->output.angle_ofs;
454 angle_delta = inter->output.angle_delta;
455 angle_increment = inter->angle_increment;
456 }
457 else {
458 wmGizmoProperty *gz_prop = WM_gizmo_target_property_find(gz, "offset");
460 angle_delta = WM_gizmo_target_property_float_get(gz, gz_prop);
461 }
462 if (gz->state & WM_GIZMO_STATE_MODAL) {
463 angle_increment = RNA_float_get(gz->ptr, "incremental_angle");
464 }
465 }
466 }
467
469 params.draw_options = draw_options;
470 params.angle_ofs = angle_ofs;
471 params.angle_delta = angle_delta;
472 params.angle_increment = angle_increment;
473 params.arc_partial_angle = arc_partial_angle;
474 params.arc_inner_factor = arc_inner_factor;
475 params.clip_plane = use_clip_plane ? clip_plane : nullptr;
476
477 const float line_width = (gz->line_width * U.pixelsize) + WM_gizmo_select_bias(select);
478 dial_3d_draw_util(matrix_final, line_width, color, select, &params);
479}
480
481static void gizmo_dial_draw_select(const bContext *C, wmGizmo *gz, int select_id)
482{
483 const int draw_options = RNA_enum_get(gz->ptr, "draw_options");
484 const bool use_clip_plane = (draw_options & ED_GIZMO_DIAL_DRAW_FLAG_CLIP);
485
486 GPU_select_load_id(select_id);
487 dial_draw_intern(C, gz, true, false, use_clip_plane);
488}
489
490static void gizmo_dial_draw(const bContext *C, wmGizmo *gz)
491{
492 const bool is_modal = gz->state & WM_GIZMO_STATE_MODAL;
493 const bool is_highlight = (gz->state & WM_GIZMO_STATE_HIGHLIGHT) != 0;
494 const int draw_options = RNA_enum_get(gz->ptr, "draw_options");
495 const bool use_clip_plane = !is_modal && (draw_options & ED_GIZMO_DIAL_DRAW_FLAG_CLIP);
496
498 dial_draw_intern(C, gz, false, is_highlight, use_clip_plane);
500}
501
503 wmGizmo *gz,
504 const wmEvent *event,
505 eWM_GizmoFlagTweak tweak_flag)
506{
507 DialInteraction *inter = static_cast<DialInteraction *>(gz->interaction_data);
508 if (!inter) {
509 return OPERATOR_CANCELLED;
510 }
511
512 if ((event->type != MOUSEMOVE) && (inter->prev.tweak_flag == tweak_flag)) {
514 }
515 /* Coordinate at which the arc drawing will be started. */
516 const float co_outer[4] = {0.0f, DIAL_WIDTH, 0.0f};
517 float angle_ofs, angle_delta, angle_increment = 0.0f;
518
520 gz, event, CTX_wm_region(C), gz->matrix_basis, co_outer, &angle_ofs, &angle_delta);
521
522 if (tweak_flag & WM_GIZMO_TWEAK_SNAP) {
523 angle_increment = RNA_float_get(gz->ptr, "incremental_angle");
524 angle_delta = roundf(double(angle_delta) / angle_increment) * angle_increment;
525 }
526 if (tweak_flag & WM_GIZMO_TWEAK_PRECISE) {
527 angle_increment *= 0.2f;
528 angle_delta *= 0.2f;
529 }
530 if (angle_delta != 0.0f) {
531 inter->has_drag = true;
532 }
533
534 inter->angle_increment = angle_increment;
535 inter->output.angle_delta = angle_delta;
536 inter->output.angle_ofs = angle_ofs;
537
538 /* Set the property for the operator and call its modal function. */
539 wmGizmoProperty *gz_prop = WM_gizmo_target_property_find(gz, "offset");
541 WM_gizmo_target_property_float_set(C, gz, gz_prop, inter->init.prop_angle + angle_delta);
542 }
543
544 inter->prev.tweak_flag = tweak_flag;
545
547}
548
549static void gizmo_dial_exit(bContext *C, wmGizmo *gz, const bool cancel)
550{
551 DialInteraction *inter = static_cast<DialInteraction *>(gz->interaction_data);
552 if (inter) {
553 bool use_reset_value = false;
554 float reset_value = 0.0f;
555
556 if (cancel) {
557 /* Set the property for the operator and call its modal function. */
558 wmGizmoProperty *gz_prop = WM_gizmo_target_property_find(gz, "offset");
560 use_reset_value = true;
561 reset_value = inter->init.prop_angle;
562 }
563 }
564 else {
565 if (inter->has_drag == false) {
566 PropertyRNA *prop = RNA_struct_find_property(gz->ptr, "click_value");
567 if (RNA_property_is_set(gz->ptr, prop)) {
568 use_reset_value = true;
569 reset_value = RNA_property_float_get(gz->ptr, prop);
570 }
571 }
572 }
573
574 if (use_reset_value) {
575 wmGizmoProperty *gz_prop = WM_gizmo_target_property_find(gz, "offset");
577 WM_gizmo_target_property_float_set(C, gz, gz_prop, reset_value);
578 }
579 }
580 }
581
582 if (!cancel) {
583 wmGizmoProperty *gz_prop = WM_gizmo_target_property_find(gz, "offset");
586 }
587 }
588}
589
590static void gizmo_dial_setup(wmGizmo *gz)
591{
592 const float dir_default[3] = {0.0f, 0.0f, 1.0f};
593
594 /* defaults */
595 copy_v3_v3(gz->matrix_basis[2], dir_default);
596}
597
599{
600 if (gz->custom_modal) {
601 /* #DialInteraction is only used for the inner modal. */
603 }
604
606
607 inter->init.mval[0] = event->mval[0];
608 inter->init.mval[1] = event->mval[1];
609
610 wmGizmoProperty *gz_prop = WM_gizmo_target_property_find(gz, "offset");
613 }
614
615 gz->interaction_data = inter;
616
618}
619
620/* -------------------------------------------------------------------- */
623
624static void dial_3d_draw_util(const float matrix_final[4][4],
625 const float line_width,
626 const float color[4],
627 const bool select,
629{
631 GPU_matrix_mul(matrix_final);
632
633 GPU_polygon_smooth(false);
634
635 if ((params->draw_options & ED_GIZMO_DIAL_DRAW_FLAG_ANGLE_VALUE) != 0) {
636 /* Draw rotation indicator arc first. */
638 params->angle_delta,
639 params->arc_inner_factor,
640 color,
641 params->draw_options);
642
643 if ((params->draw_options & ED_GIZMO_DIAL_DRAW_FLAG_ANGLE_MIRROR) != 0) {
645 params->angle_delta,
646 params->arc_inner_factor,
647 color,
648 params->draw_options);
649 }
650 }
651
652 if (params->angle_increment) {
654 params->angle_increment, params->angle_ofs, params->angle_delta);
655 }
656
657 /* Draw actual dial gizmo. */
658 dial_geom_draw(color,
659 line_width,
660 select,
661 matrix_final,
662 params->clip_plane,
663 params->arc_partial_angle,
664 params->arc_inner_factor,
665 params->draw_options);
666
668}
669
671{
672 /* identifiers */
673 gzt->idname = "GIZMO_GT_dial_3d";
674
675 /* API callbacks. */
676 gzt->draw = gizmo_dial_draw;
678 gzt->setup = gizmo_dial_setup;
680 gzt->modal = gizmo_dial_modal;
681 gzt->exit = gizmo_dial_exit;
682
683 gzt->struct_size = sizeof(wmGizmo);
684
685 /* rna */
686 static const EnumPropertyItem rna_enum_draw_options[] = {
687 {ED_GIZMO_DIAL_DRAW_FLAG_CLIP, "CLIP", 0, "Clipped", ""},
688 {ED_GIZMO_DIAL_DRAW_FLAG_FILL, "FILL", 0, "Filled", ""},
689 {ED_GIZMO_DIAL_DRAW_FLAG_FILL_SELECT, "FILL_SELECT", 0, "Use fill for selection test", ""},
690 {ED_GIZMO_DIAL_DRAW_FLAG_ANGLE_MIRROR, "ANGLE_MIRROR", 0, "Angle Mirror", ""},
691 {ED_GIZMO_DIAL_DRAW_FLAG_ANGLE_START_Y, "ANGLE_START_Y", 0, "Angle Start Y", ""},
692 {ED_GIZMO_DIAL_DRAW_FLAG_ANGLE_VALUE, "ANGLE_VALUE", 0, "Show Angle Value", ""},
693 {0, nullptr, 0, nullptr, nullptr},
694 };
695 RNA_def_enum_flag(gzt->srna, "draw_options", rna_enum_draw_options, 0, "Draw Options", "");
696 RNA_def_boolean(gzt->srna, "wrap_angle", true, "Wrap Angle", "");
698 gzt->srna, "arc_inner_factor", 0.0f, 0.0f, 1.0f, "Arc Inner Factor", "", 0.0f, 1.0f);
700 "arc_partial_angle",
701 0.0f,
702 0.0f,
703 M_PI * 2,
704 "Show Partial Dial",
705 "",
706 0.0f,
707 M_PI * 2);
709 "incremental_angle",
711 0.0f,
712 M_PI * 2,
713 "Incremental Angle",
714 "Angle to snap in steps",
715 0.0f,
716 M_PI * 2);
717 RNA_def_float(gzt->srna,
718 "click_value",
719 0.0f,
720 -FLT_MAX,
721 FLT_MAX,
722 "Click Value",
723 "Value to use for a single click action",
724 -FLT_MAX,
725 FLT_MAX);
726
728}
729
734
ScrArea * CTX_wm_area(const bContext *C)
ARegion * CTX_wm_region(const bContext *C)
#define BLI_assert(a)
Definition BLI_assert.h:46
#define M_PI_2
#define RAD2DEGF(_rad)
#define M_PI
void plane_from_point_normal_v3(float r_plane[4], const float plane_co[3], const float plane_no[3])
Definition math_geom.cc:217
void mul_v3_project_m4_v3(float r[3], const float mat[4][4], const float vec[3])
float angle_wrap_rad(float angle)
MINLINE void copy_v4_v4(float r[4], const float a[4])
MINLINE void sub_v3_v3(float r[3], const float a[3])
MINLINE void mul_v2_fl(float r[2], float f)
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE float dot_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
float angle_signed_on_axis_v3v3_v3(const float v1[3], const float v2[3], const float axis[3]) ATTR_WARN_UNUSED_RESULT
MINLINE float normalize_v3_v3(float r[3], const float a[3])
unsigned int uint
#define UNUSED_VARS(...)
#define UNPACK3(a)
@ SPACE_VIEW3D
@ OPERATOR_CANCELLED
@ OPERATOR_RUNNING_MODAL
@ ED_GIZMO_DIAL_DRAW_FLAG_ANGLE_MIRROR
@ ED_GIZMO_DIAL_DRAW_FLAG_FILL_SELECT
@ ED_GIZMO_DIAL_DRAW_FLAG_FILL
@ ED_GIZMO_DIAL_DRAW_FLAG_ANGLE_START_Y
@ ED_GIZMO_DIAL_DRAW_FLAG_ANGLE_VALUE
@ ED_GIZMO_DIAL_DRAW_FLAG_CLIP
#define SNAP_INCREMENTAL_ANGLE
void ED_view3d_global_to_vector(const RegionView3D *rv3d, const float coord[3], float r_out[3])
float ED_view3d_pixel_size_no_ui_scale(const RegionView3D *rv3d, const float co[3])
bool ED_view3d_win_to_3d_on_plane(const ARegion *region, const float plane[4], const float mval[2], bool do_clip, float r_out[3])
void immEnd()
void immUniform2fv(const char *name, const float data[2])
void immUnbindProgram()
void immBindBuiltinProgram(GPUBuiltinShader shader_id)
void immUniformMatrix4fv(const char *name, const float data[4][4])
void immUniformColor4f(float r, float g, float b, float a)
void immVertex3f(uint attr_id, float x, float y, float z)
void immUniform1f(const char *name, float x)
GPUVertFormat * immVertexFormat()
void immUniformColor4fv(const float rgba[4])
void immUniformColor3f(float r, float g, float b)
void immUniform4fv(const char *name, const float data[4])
void immVertex3fv(uint attr_id, const float data[3])
void immBegin(GPUPrimType, uint vertex_len)
void imm_draw_disk_partial_fill_3d(uint pos, float x, float y, float z, float rad_inner, float rad_outer, int nsegments, float start, float sweep)
void imm_draw_circle_partial_wire_3d(uint pos, float x, float y, float z, float radius, int nsegments, float start, float sweep)
void imm_draw_circle_wire_3d(uint pos, float x, float y, float radius, int nsegments)
void imm_draw_circle_fill_3d(uint pos, float x, float y, float radius, int nsegments)
void imm_draw_disk_partial_fill_2d(uint pos, float x, float y, float rad_inner, float rad_outer, int nsegments, float start, float sweep)
void GPU_matrix_push()
#define GPU_matrix_mul(x)
void GPU_matrix_rotate_3f(float deg, float x, float y, float z)
void GPU_matrix_pop()
@ GPU_PRIM_LINES
@ GPU_PRIM_LINE_STRIP
bool GPU_select_load_id(unsigned int id)
@ GPU_SHADER_3D_POLYLINE_UNIFORM_COLOR
@ GPU_SHADER_3D_CLIPPED_UNIFORM_COLOR
@ GPU_SHADER_3D_UNIFORM_COLOR
@ GPU_SHADER_3D_POLYLINE_CLIPPED_UNIFORM_COLOR
@ GPU_BLEND_NONE
Definition GPU_state.hh:85
@ GPU_BLEND_ALPHA
Definition GPU_state.hh:87
void GPU_blend(GPUBlend blend)
Definition gpu_state.cc:42
void GPU_viewport_size_get_f(float coords[4])
Definition gpu_state.cc:273
void GPU_polygon_smooth(bool enable)
Definition gpu_state.cc:83
uint GPU_vertformat_attr_add(GPUVertFormat *format, blender::StringRef name, blender::gpu::VertAttrType type)
static double angle(const Eigen::Vector3d &v1, const Eigen::Vector3d &v2)
Definition IK_Math.h:117
Read Guarded memory(de)allocation.
@ PROP_FLOAT
Definition RNA_types.hh:164
#define C
Definition RandGen.cpp:29
eWM_GizmoFlagTweak
Gizmo tweak flag. Bit-flag passed to gizmo while tweaking.
@ WM_GIZMO_TWEAK_PRECISE
@ WM_GIZMO_TWEAK_SNAP
@ WM_GIZMO_DRAW_VALUE
@ WM_GIZMO_STATE_HIGHLIGHT
@ WM_GIZMO_STATE_MODAL
#define U
ATTR_WARN_UNUSED_RESULT const BMVert * v
ccl_device_inline float wrap_angle(const float a)
nullptr float
#define fmodf(x, y)
#define roundf(x)
#define DIAL_CLIP_BIAS
static void dial_3d_draw_util(const float matrix_final[4][4], const float line_width, const float color[4], const bool select, Dial3dParams *params)
static void gizmo_dial_exit(bContext *C, wmGizmo *gz, const bool cancel)
static void dial_ghostarc_get_angles(const wmGizmo *gz, const wmEvent *event, const ARegion *region, const float mat[4][4], const float co_outer[3], float *r_start, float *r_delta)
static void gizmo_dial_setup(wmGizmo *gz)
static void dial_ghostarc_draw_with_helplines(const float angle_ofs, const float angle_delta, const float arc_inner_factor, const float color_helpline[4], const int draw_options)
static void gizmo_dial_draw(const bContext *C, wmGizmo *gz)
static void dial_geom_draw(const float color[4], const float line_width, const bool select, const float clip_plane_mat[4][4], const float clip_plane[4], const float arc_partial_angle, const float arc_inner_factor, const int draw_options)
static void gizmo_dial_draw_select(const bContext *C, wmGizmo *gz, int select_id)
static void dial_ghostarc_draw_incremental_angle(const float incremental_angle, const float offset, const float angle_delta)
#define DIAL_WIDTH
static wmOperatorStatus gizmo_dial_modal(bContext *C, wmGizmo *gz, const wmEvent *event, eWM_GizmoFlagTweak tweak_flag)
void ED_gizmotypes_dial_3d()
static wmOperatorStatus gizmo_dial_invoke(bContext *, wmGizmo *gz, const wmEvent *event)
static void dial_ghostarc_draw(const float angle_ofs, float angle_delta, const float arc_inner_factor, const float color[4])
static void GIZMO_GT_dial_3d(wmGizmoType *gzt)
static void dial_draw_intern(const bContext *C, wmGizmo *gz, const bool select, const bool highlight, const bool use_clip_plane)
static void dial_ghostarc_draw_helpline(const float angle, const float co_outer[3], const float color[4], const float line_width)
GizmoGeomInfo wm_gizmo_geom_data_dial
void wm_gizmo_geometryinfo_draw(const GizmoGeomInfo *info, const bool, const float color[4])
void gizmo_color_get(const wmGizmo *gz, bool highlight, float r_color[4])
#define DIAL_RESOLUTION
static float WM_gizmo_select_bias(bool select)
uint pos
#define output
#define select(A, B, C)
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
format
void * MEM_callocN(size_t len, const char *str)
Definition mallocn.cc:118
ccl_device_inline float2 fmod(const float2 a, const float b)
static void init(bNodeTree *, bNode *node)
#define floorf
#define fabsf
#define sinf
#define cosf
float RNA_property_float_get(PointerRNA *ptr, PropertyRNA *prop)
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
bool RNA_property_is_set(PointerRNA *ptr, PropertyRNA *prop)
float RNA_float_get(PointerRNA *ptr, const char *name)
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
int RNA_enum_get(PointerRNA *ptr, const char *name)
PropertyRNA * RNA_def_float_factor(StructOrFunctionRNA *cont_, const char *identifier, const float default_value, const float hardmin, const float hardmax, const char *ui_name, const char *ui_description, const float softmin, const float softmax)
PropertyRNA * RNA_def_float(StructOrFunctionRNA *cont_, const char *identifier, const float default_value, const float hardmin, const float hardmax, const char *ui_name, const char *ui_description, const float softmin, const float softmax)
PropertyRNA * RNA_def_enum_flag(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, const int default_value, const char *ui_name, const char *ui_description)
PropertyRNA * RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, const bool default_value, const char *ui_name, const char *ui_description)
#define FLT_MAX
Definition stdcycles.h:14
void * regiondata
float * clip_plane
float arc_inner_factor
float angle_increment
float arc_partial_angle
struct DialInteraction::@053032054333226076253353344046336043224331220103 output
struct DialInteraction::@107002320353104203017353232074171136375150346212 prev
struct DialInteraction::@013124152214112254267210060276365374126355161213 init
eWM_GizmoFlagTweak tweak_flag
float viewinv[4][4]
int ymin
int xmin
wmEventType type
Definition WM_types.hh:757
int xy[2]
Definition WM_types.hh:761
StructRNA * srna
wmGizmoFnDraw draw
wmGizmoFnModal modal
wmGizmoFnSetup setup
const char * idname
wmGizmoFnExit exit
wmGizmoFnInvoke invoke
wmGizmoFnDrawSelect draw_select
void * interaction_data
eWM_GizmoFlagState state
float matrix_basis[4][4]
PointerRNA * ptr
float line_width
eWM_GizmoFlag flag
wmGizmoFnModal custom_modal
i
Definition text_draw.cc:230
@ MOUSEMOVE
void WM_gizmo_calc_matrix_final(const wmGizmo *gz, float r_mat[4][4])
Definition wm_gizmo.cc:572
void WM_gizmo_target_property_float_set(bContext *C, const wmGizmo *gz, wmGizmoProperty *gz_prop, const float value)
void WM_gizmo_target_property_anim_autokey(bContext *C, const wmGizmo *, wmGizmoProperty *gz_prop)
bool WM_gizmo_target_property_is_valid(const wmGizmoProperty *gz_prop)
void WM_gizmotype_target_property_def(wmGizmoType *gzt, const char *idname, int data_type, int array_length)
float WM_gizmo_target_property_float_get(const wmGizmo *gz, wmGizmoProperty *gz_prop)
wmGizmoProperty * WM_gizmo_target_property_find(wmGizmo *gz, const char *idname)
void WM_gizmotype_append(void(*gtfunc)(wmGizmoType *))