Blender V4.3
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
20#include "MEM_guardedalloc.h"
21
22#include "BLI_math_matrix.h"
23#include "BLI_math_rotation.h"
24
25#include "BKE_context.hh"
26
27#include "GPU_immediate.hh"
28#include "GPU_immediate_util.hh"
29#include "GPU_matrix.hh"
30#include "GPU_select.hh"
31#include "GPU_state.hh"
32
33#include "RNA_access.hh"
34#include "RNA_define.hh"
35
36#include "WM_api.hh"
37#include "WM_types.hh"
38
39#include "ED_gizmo_library.hh"
40#include "ED_screen.hh"
41#include "ED_transform.hh"
42#include "ED_view3d.hh"
43
44/* own includes */
46
47// /** To use custom dials exported to `geom_dial_gizmo.cc`. */
48// #define USE_GIZMO_CUSTOM_DIAL
49
51 struct {
52 float mval[2];
53 /* Only for when using properties. */
56 struct {
57 /* Cache the last angle to detect rotations bigger than -/+ PI. */
59 float angle;
61
62 /* Number of full rotations. */
66
67 /* Final output values, used for drawing. */
68 struct {
69 float angle_ofs;
72};
73
74#define DIAL_WIDTH 1.0f
75
76/* Could make option, negative to clip more (don't show when view aligned). */
77#define DIAL_CLIP_BIAS 0.02
78
79/* -------------------------------------------------------------------- */
89static void dial_3d_draw_util(const float matrix_final[4][4],
90 const float line_width,
91 const float color[4],
92 const bool select,
94
95static void dial_geom_draw(const float color[4],
96 const float line_width,
97 const bool select,
98 const float clip_plane_mat[4][4],
99 const float clip_plane[4],
100 const float arc_partial_angle,
101 const float arc_inner_factor,
102 const int draw_options)
103{
104#ifdef USE_GIZMO_CUSTOM_DIAL
105 UNUSED_VARS(gz, axis_modal_mat, clip_plane);
107#else
108 const bool filled = (draw_options & (select ? (ED_GIZMO_DIAL_DRAW_FLAG_FILL |
111
113 /* NOTE(Metal): Prefer using 3D coordinates with 3D shader, even if rendering 2D gizmo's. */
115
116 if (clip_plane) {
119 immUniform4fv("ClipPlane", clip_plane);
120 immUniformMatrix4fv("ModelMatrix", clip_plane_mat);
121 }
122 else {
125 }
126
127 immUniformColor4fv(color);
128
129 if (filled) {
130 if (arc_partial_angle == 0.0f) {
131 if (arc_inner_factor == 0.0f) {
132 imm_draw_circle_fill_3d(pos, 0.0f, 0.0f, 1.0f, DIAL_RESOLUTION);
133 }
134 else {
136 pos, 0.0f, 0.0f, 0.0f, arc_inner_factor, 1.0f, DIAL_RESOLUTION, 0, RAD2DEGF(M_PI * 2));
137 }
138 }
139 else {
140 float arc_partial_deg = RAD2DEGF((M_PI * 2) - arc_partial_angle);
142 0.0f,
143 0.0f,
144 0.0f,
145 arc_inner_factor,
146 1.0f,
148 -arc_partial_deg / 2,
149 arc_partial_deg);
150 }
151 }
152 else {
153 float viewport[4];
154 GPU_viewport_size_get_f(viewport);
155 immUniform2fv("viewportSize", &viewport[2]);
156 immUniform1f("lineWidth", line_width * U.pixelsize);
157
158 if (arc_partial_angle == 0.0f) {
159 imm_draw_circle_wire_3d(pos, 0.0f, 0.0f, 1.0f, DIAL_RESOLUTION);
160 if (arc_inner_factor != 0.0f) {
161 imm_draw_circle_wire_3d(pos, 0.0f, 0.0f, arc_inner_factor, DIAL_RESOLUTION);
162 }
163 }
164 else {
165 float arc_partial_deg = RAD2DEGF((M_PI * 2) - arc_partial_angle);
167 pos, 0.0f, 0.0f, 0.0f, 1.0f, DIAL_RESOLUTION, -arc_partial_deg / 2, arc_partial_deg);
168# if 0
169 if (arc_inner_factor != 0.0f) {
170 BLI_assert(0);
171 }
172# endif
173 }
174 }
175
177
179#endif
180}
181
185static void dial_ghostarc_draw_helpline(const float angle,
186 const float co_outer[3],
187 const float color[4],
188 const float line_width)
189{
191 GPU_matrix_rotate_3f(RAD2DEGF(angle), 0.0f, 0.0f, -1.0f);
192
194
196
197 float viewport[4];
198 GPU_viewport_size_get_f(viewport);
199 immUniform2fv("viewportSize", &viewport[2]);
200 immUniform1f("lineWidth", line_width * U.pixelsize);
201
202 immUniformColor4fv(color);
203
205 immVertex3f(pos, 0.0f, 0.0f, 0.0f);
206 immVertex3fv(pos, co_outer);
207 immEnd();
208
210
212}
213
217static void dial_ghostarc_draw_incremental_angle(const float incremental_angle,
218 const float offset,
219 const float angle_delta)
220{
221
224
225 immUniformColor3f(1.0f, 1.0f, 1.0f);
226
227 float viewport[4];
228 GPU_viewport_size_get_f(viewport);
229 immUniform2fv("viewportSize", &viewport[2]);
230 immUniform1f("lineWidth", U.pixelsize);
231
232 const int current_increment = roundf(angle_delta / incremental_angle);
233 const int total_increment = roundf((M_PI * 2.0f) / incremental_angle);
234
235 immBegin(GPU_PRIM_LINES, total_increment * 2);
236
237 /* Chop off excess full circles, draw an arc of ticks centered at current increment;
238 * if there's no even division of circle by increment,
239 * ends of the arc will move with the rotation. */
240 const float start_offset = fmodf(
241 offset + incremental_angle * (current_increment - total_increment / 2), M_PI * 2.0f);
242
243 float v[3] = {0};
244 for (int i = 0; i < total_increment; i++) {
245 v[0] = sinf(start_offset + incremental_angle * i);
246 v[1] = cosf(start_offset + incremental_angle * i);
247
248 mul_v2_fl(v, DIAL_WIDTH * 1.1f);
250
251 mul_v2_fl(v, 1.1f);
253 }
254
255 immEnd();
257}
258
259static void dial_ghostarc_draw(const float angle_ofs,
260 float angle_delta,
261 const float arc_inner_factor,
262 const float color[4])
263{
264 const float width_inner = DIAL_WIDTH;
268
269 /* Avoid artifacts by drawing the main arc over the span of one rotation only. */
270 const float pi2 = float(M_PI * 2.0);
271 int rotation_count = int(floorf(fabsf(angle_delta) / pi2));
272 angle_delta = fmod(angle_delta, pi2);
273
274 /* Calculate the remaining angle that can be filled with the background color. */
275 const float angle_background = angle_delta >= 0 ? (pi2 - angle_delta) : -(pi2 + angle_delta);
276
277 float color_background[4] = {0};
278 if (arc_inner_factor != 0.0) {
279 color_background[3] = color[3] / 2.0f;
280 }
281
282 if (rotation_count != 0) {
283 /* Calculate the background color to visualize the rotation count. */
284 copy_v4_v4(color_background, color);
285 color_background[3] = color[3] * rotation_count;
286 }
287
288 immUniformColor4fv(color_background);
290 0,
291 0,
292 arc_inner_factor,
293 width_inner,
295 RAD2DEGF(angle_ofs + angle_delta),
296 RAD2DEGF(angle_background));
297
298 immUniformColor4f(UNPACK3(color), color[3] * (rotation_count + 1));
300 0,
301 0,
302 arc_inner_factor,
303 width_inner,
305 RAD2DEGF(angle_ofs),
306 RAD2DEGF(angle_delta));
308}
309
310static void dial_ghostarc_get_angles(const wmGizmo *gz,
311 const wmEvent *event,
312 const ARegion *region,
313 const float mat[4][4],
314 const float co_outer[3],
315 float *r_start,
316 float *r_delta)
317{
318 DialInteraction *inter = static_cast<DialInteraction *>(gz->interaction_data);
319 const RegionView3D *rv3d = static_cast<const RegionView3D *>(region->regiondata);
320 const float mval[2] = {float(event->xy[0] - region->winrct.xmin),
321 float(event->xy[1] - region->winrct.ymin)};
322
323 /* We might need to invert the direction of the angles. */
324 float view_vec[3], axis_vec[3];
325 ED_view3d_global_to_vector(rv3d, gz->matrix_basis[3], view_vec);
326 normalize_v3_v3(axis_vec, gz->matrix_basis[2]);
327
328 float proj_outer_rel[3];
329 mul_v3_project_m4_v3(proj_outer_rel, mat, co_outer);
330 sub_v3_v3(proj_outer_rel, gz->matrix_basis[3]);
331
332 float proj_mval_new_rel[3];
333 float proj_mval_init_rel[3];
334 float dial_plane[4];
335
336 plane_from_point_normal_v3(dial_plane, gz->matrix_basis[3], axis_vec);
337
338 const auto fail = [&]() {
339 /* If we can't project (unlikely). */
340 *r_start = 0.0;
341 *r_delta = 0.0;
342 };
343
345 region, dial_plane, inter->init.mval, false, proj_mval_init_rel))
346 {
347 return fail();
348 }
349 sub_v3_v3(proj_mval_init_rel, gz->matrix_basis[3]);
350
351 if (!ED_view3d_win_to_3d_on_plane(region, dial_plane, mval, false, proj_mval_new_rel)) {
352 return fail();
353 }
354 sub_v3_v3(proj_mval_new_rel, gz->matrix_basis[3]);
355
356 const int draw_options = RNA_enum_get(gz->ptr, "draw_options");
357
358 /* Start direction from mouse or set by user. */
359 const float *proj_init_rel = (draw_options & ED_GIZMO_DIAL_DRAW_FLAG_ANGLE_START_Y) ?
360 gz->matrix_basis[1] :
361 proj_mval_init_rel;
362
363 /* Return angles. */
364 const float start = angle_wrap_rad(
365 angle_signed_on_axis_v3v3_v3(proj_outer_rel, proj_init_rel, axis_vec));
366 const float delta = angle_wrap_rad(
367 angle_signed_on_axis_v3v3_v3(proj_mval_init_rel, proj_mval_new_rel, axis_vec));
368
369 /* Change of sign, we passed the 180 degree threshold. This means we need to add a turn
370 * to distinguish between transition from 0 to -1 and -PI to +PI, use comparison with PI/2.
371 * Logic taken from #BLI_dial_angle */
372 if ((delta * inter->prev.angle < 0.0f) && (fabsf(inter->prev.angle) > float(M_PI_2))) {
373 if (inter->prev.angle < 0.0f) {
374 inter->rotations--;
375 }
376 else {
377 inter->rotations++;
378 }
379 }
380 inter->prev.angle = delta;
381
382 const bool wrap_angle = RNA_boolean_get(gz->ptr, "wrap_angle");
383 const double delta_final = double(delta) + ((2 * M_PI) * double(inter->rotations));
384 *r_start = start;
385 *r_delta = float(wrap_angle ? fmod(delta_final, 2 * M_PI) : delta_final);
386}
387
388static void dial_ghostarc_draw_with_helplines(const float angle_ofs,
389 const float angle_delta,
390 const float arc_inner_factor,
391 const float color_helpline[4],
392 const int draw_options)
393{
394 /* Coordinate at which the arc drawing will be started. */
395 const float co_outer[4] = {0.0f, DIAL_WIDTH, 0.0f};
396 const float color_arc_inner[4] = {0.8f, 0.8f, 0.8f, 0.2f};
397 dial_ghostarc_draw(angle_ofs, angle_delta, arc_inner_factor, color_arc_inner);
398
399 float line_width = (draw_options & ED_GIZMO_DIAL_DRAW_FLAG_ANGLE_VALUE) ? 3.0f : 1.0f;
400 dial_ghostarc_draw_helpline(angle_ofs, co_outer, color_helpline, 1.0f);
401 dial_ghostarc_draw_helpline(angle_ofs + angle_delta, co_outer, color_helpline, line_width);
402}
403
405 const bContext *C, wmGizmo *gz, const bool select, const bool highlight, float clip_plane[4])
406{
407 float matrix_final[4][4];
408 float color[4];
409
410 (void)C;
411 BLI_assert(CTX_wm_area(C)->spacetype == SPACE_VIEW3D);
412
413 gizmo_color_get(gz, highlight, color);
414
415 WM_gizmo_calc_matrix_final(gz, matrix_final);
416
417 const float arc_partial_angle = RNA_float_get(gz->ptr, "arc_partial_angle");
418 const float arc_inner_factor = RNA_float_get(gz->ptr, "arc_inner_factor");
419 int draw_options = RNA_enum_get(gz->ptr, "draw_options");
420 float angle_ofs = 0.0f;
421 float angle_delta = 0.0f;
422 float angle_increment = 0.0f;
423
424 if (select) {
425 draw_options &= ~ED_GIZMO_DIAL_DRAW_FLAG_ANGLE_VALUE;
426 }
427
428 if (draw_options & ED_GIZMO_DIAL_DRAW_FLAG_ANGLE_VALUE && (gz->flag & WM_GIZMO_DRAW_VALUE)) {
429 DialInteraction *inter = static_cast<DialInteraction *>(gz->interaction_data);
430 if (inter) {
431 angle_ofs = inter->output.angle_ofs;
432 angle_delta = inter->output.angle_delta;
433 angle_increment = inter->angle_increment;
434 }
435 else {
436 wmGizmoProperty *gz_prop = WM_gizmo_target_property_find(gz, "offset");
438 angle_delta = WM_gizmo_target_property_float_get(gz, gz_prop);
439 }
440 if (gz->state & WM_GIZMO_STATE_MODAL) {
441 angle_increment = RNA_float_get(gz->ptr, "incremental_angle");
442 }
443 }
444 }
445
447 params.draw_options = draw_options;
448 params.angle_ofs = angle_ofs;
449 params.angle_delta = angle_delta;
450 params.angle_increment = angle_increment;
451 params.arc_partial_angle = arc_partial_angle;
452 params.arc_inner_factor = arc_inner_factor;
453 params.clip_plane = clip_plane;
454 dial_3d_draw_util(matrix_final, gz->line_width, color, select, &params);
455}
456
457static void gizmo_dial_draw_select(const bContext *C, wmGizmo *gz, int select_id)
458{
459 float clip_plane_buf[4];
460 const int draw_options = RNA_enum_get(gz->ptr, "draw_options");
461 float *clip_plane = (draw_options & ED_GIZMO_DIAL_DRAW_FLAG_CLIP) ? clip_plane_buf : nullptr;
462
463 if (clip_plane) {
464 ARegion *region = CTX_wm_region(C);
465 RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
466
467 copy_v3_v3(clip_plane, rv3d->viewinv[2]);
468 clip_plane[3] = -dot_v3v3(rv3d->viewinv[2], gz->matrix_basis[3]);
469 clip_plane[3] += DIAL_CLIP_BIAS;
470 }
471
472 GPU_select_load_id(select_id);
473 dial_draw_intern(C, gz, true, false, clip_plane);
474}
475
476static void gizmo_dial_draw(const bContext *C, wmGizmo *gz)
477{
478 const bool is_modal = gz->state & WM_GIZMO_STATE_MODAL;
479 const bool is_highlight = (gz->state & WM_GIZMO_STATE_HIGHLIGHT) != 0;
480 float clip_plane_buf[4];
481 const int draw_options = RNA_enum_get(gz->ptr, "draw_options");
482 float *clip_plane = (!is_modal && (draw_options & ED_GIZMO_DIAL_DRAW_FLAG_CLIP)) ?
483 clip_plane_buf :
484 nullptr;
485
486 if (clip_plane) {
487 ARegion *region = CTX_wm_region(C);
488 RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
489
490 copy_v3_v3(clip_plane, rv3d->viewinv[2]);
491 clip_plane[3] = -dot_v3v3(rv3d->viewinv[2], gz->matrix_basis[3]);
492 clip_plane[3] += DIAL_CLIP_BIAS;
493 }
494
496 dial_draw_intern(C, gz, false, is_highlight, clip_plane);
498}
499
501 wmGizmo *gz,
502 const wmEvent *event,
503 eWM_GizmoFlagTweak tweak_flag)
504{
505 DialInteraction *inter = static_cast<DialInteraction *>(gz->interaction_data);
506 if (!inter) {
507 return OPERATOR_CANCELLED;
508 }
509
510 if ((event->type != MOUSEMOVE) && (inter->prev.tweak_flag == tweak_flag)) {
512 }
513 /* Coordinate at which the arc drawing will be started. */
514 const float co_outer[4] = {0.0f, DIAL_WIDTH, 0.0f};
515 float angle_ofs, angle_delta, angle_increment = 0.0f;
516
518 gz, event, CTX_wm_region(C), gz->matrix_basis, co_outer, &angle_ofs, &angle_delta);
519
520 if (tweak_flag & WM_GIZMO_TWEAK_SNAP) {
521 angle_increment = RNA_float_get(gz->ptr, "incremental_angle");
522 angle_delta = float(roundf(double(angle_delta) / angle_increment)) * angle_increment;
523 }
524 if (tweak_flag & WM_GIZMO_TWEAK_PRECISE) {
525 angle_increment *= 0.2f;
526 angle_delta *= 0.2f;
527 }
528 if (angle_delta != 0.0f) {
529 inter->has_drag = true;
530 }
531
532 inter->angle_increment = angle_increment;
533 inter->output.angle_delta = angle_delta;
534 inter->output.angle_ofs = angle_ofs;
535
536 /* Set the property for the operator and call its modal function. */
537 wmGizmoProperty *gz_prop = WM_gizmo_target_property_find(gz, "offset");
539 WM_gizmo_target_property_float_set(C, gz, gz_prop, inter->init.prop_angle + angle_delta);
540 }
541
542 inter->prev.tweak_flag = tweak_flag;
543
545}
546
547static void gizmo_dial_exit(bContext *C, wmGizmo *gz, const bool cancel)
548{
549 DialInteraction *inter = static_cast<DialInteraction *>(gz->interaction_data);
550 if (inter) {
551 bool use_reset_value = false;
552 float reset_value = 0.0f;
553
554 if (cancel) {
555 /* Set the property for the operator and call its modal function. */
556 wmGizmoProperty *gz_prop = WM_gizmo_target_property_find(gz, "offset");
558 use_reset_value = true;
559 reset_value = inter->init.prop_angle;
560 }
561 }
562 else {
563 if (inter->has_drag == false) {
564 PropertyRNA *prop = RNA_struct_find_property(gz->ptr, "click_value");
565 if (RNA_property_is_set(gz->ptr, prop)) {
566 use_reset_value = true;
567 reset_value = RNA_property_float_get(gz->ptr, prop);
568 }
569 }
570 }
571
572 if (use_reset_value) {
573 wmGizmoProperty *gz_prop = WM_gizmo_target_property_find(gz, "offset");
575 WM_gizmo_target_property_float_set(C, gz, gz_prop, reset_value);
576 }
577 }
578 }
579
580 if (!cancel) {
581 wmGizmoProperty *gz_prop = WM_gizmo_target_property_find(gz, "offset");
584 }
585 }
586}
587
588static void gizmo_dial_setup(wmGizmo *gz)
589{
590 const float dir_default[3] = {0.0f, 0.0f, 1.0f};
591
592 /* defaults */
593 copy_v3_v3(gz->matrix_basis[2], dir_default);
594}
595
596static int gizmo_dial_invoke(bContext * /*C*/, wmGizmo *gz, const wmEvent *event)
597{
598 if (gz->custom_modal) {
599 /* #DialInteraction is only used for the inner modal. */
601 }
602
603 DialInteraction *inter = static_cast<DialInteraction *>(
604 MEM_callocN(sizeof(DialInteraction), __func__));
605
606 inter->init.mval[0] = event->mval[0];
607 inter->init.mval[1] = event->mval[1];
608
609 wmGizmoProperty *gz_prop = WM_gizmo_target_property_find(gz, "offset");
612 }
613
614 gz->interaction_data = inter;
615
617}
618
619/* -------------------------------------------------------------------- */
623static void dial_3d_draw_util(const float matrix_final[4][4],
624 const float line_width,
625 const float color[4],
626 const bool select,
628{
630 GPU_matrix_mul(matrix_final);
631
632 GPU_polygon_smooth(false);
633
634 if ((params->draw_options & ED_GIZMO_DIAL_DRAW_FLAG_ANGLE_VALUE) != 0) {
635 /* Draw rotation indicator arc first. */
637 params->angle_delta,
638 params->arc_inner_factor,
639 color,
640 params->draw_options);
641
642 if ((params->draw_options & ED_GIZMO_DIAL_DRAW_FLAG_ANGLE_MIRROR) != 0) {
644 params->angle_delta,
645 params->arc_inner_factor,
646 color,
647 params->draw_options);
648 }
649 }
650
651 if (params->angle_increment) {
653 params->angle_increment, params->angle_ofs, params->angle_delta);
654 }
655
656 /* Draw actual dial gizmo. */
657 dial_geom_draw(color,
658 line_width,
659 select,
660 matrix_final,
661 params->clip_plane,
662 params->arc_partial_angle,
663 params->arc_inner_factor,
664 params->draw_options);
665
667}
668
670{
671 /* identifiers */
672 gzt->idname = "GIZMO_GT_dial_3d";
673
674 /* api callbacks */
675 gzt->draw = gizmo_dial_draw;
677 gzt->setup = gizmo_dial_setup;
679 gzt->modal = gizmo_dial_modal;
680 gzt->exit = gizmo_dial_exit;
681
682 gzt->struct_size = sizeof(wmGizmo);
683
684 /* rna */
685 static const EnumPropertyItem rna_enum_draw_options[] = {
686 {ED_GIZMO_DIAL_DRAW_FLAG_CLIP, "CLIP", 0, "Clipped", ""},
687 {ED_GIZMO_DIAL_DRAW_FLAG_FILL, "FILL", 0, "Filled", ""},
688 {ED_GIZMO_DIAL_DRAW_FLAG_FILL_SELECT, "FILL_SELECT", 0, "Use fill for selection test", ""},
689 {ED_GIZMO_DIAL_DRAW_FLAG_ANGLE_MIRROR, "ANGLE_MIRROR", 0, "Angle Mirror", ""},
690 {ED_GIZMO_DIAL_DRAW_FLAG_ANGLE_START_Y, "ANGLE_START_Y", 0, "Angle Start Y", ""},
691 {ED_GIZMO_DIAL_DRAW_FLAG_ANGLE_VALUE, "ANGLE_VALUE", 0, "Show Angle Value", ""},
692 {0, nullptr, 0, nullptr, nullptr},
693 };
694 RNA_def_enum_flag(gzt->srna, "draw_options", rna_enum_draw_options, 0, "Draw Options", "");
695 RNA_def_boolean(gzt->srna, "wrap_angle", true, "Wrap Angle", "");
697 gzt->srna, "arc_inner_factor", 0.0f, 0.0f, 1.0f, "Arc Inner Factor", "", 0.0f, 1.0f);
699 "arc_partial_angle",
700 0.0f,
701 0.0f,
702 M_PI * 2,
703 "Show Partial Dial",
704 "",
705 0.0f,
706 M_PI * 2);
708 "incremental_angle",
710 0.0f,
711 M_PI * 2,
712 "Incremental Angle",
713 "Angle to snap in steps",
714 0.0f,
715 M_PI * 2);
716 RNA_def_float(gzt->srna,
717 "click_value",
718 0.0f,
719 -FLT_MAX,
720 FLT_MAX,
721 "Click Value",
722 "Value to use for a single click action",
723 -FLT_MAX,
724 FLT_MAX);
725
727}
728
733
ScrArea * CTX_wm_area(const bContext *C)
ARegion * CTX_wm_region(const bContext *C)
#define BLI_assert(a)
Definition BLI_assert.h:50
#define M_PI_2
#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:215
void mul_v3_project_m4_v3(float r[3], const float mat[4][4], const float vec[3])
#define RAD2DEGF(_rad)
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)
typedef double(DMatrix)[4][4]
@ SPACE_VIEW3D
@ 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])
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 immUniformMatrix4fv(const char *name, const float data[4][4])
void immUniformColor4f(float r, float g, float b, float a)
void immBindBuiltinProgram(eGPUBuiltinShader shader_id)
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(eGPUBlend blend)
Definition gpu_state.cc:42
void GPU_viewport_size_get_f(float coords[4])
Definition gpu_state.cc:262
void GPU_polygon_smooth(bool enable)
Definition gpu_state.cc:83
@ GPU_FETCH_FLOAT
uint GPU_vertformat_attr_add(GPUVertFormat *, const char *name, GPUVertCompType, uint comp_len, GPUVertFetchMode)
@ GPU_COMP_F32
Read Guarded memory(de)allocation.
@ PROP_FLOAT
Definition RNA_types.hh:67
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
ATTR_WARN_UNUSED_RESULT const BMVert * v
ccl_device_inline float wrap_angle(float a)
unsigned int U
Definition btGjkEpa3.h:78
#define sinf(x)
#define cosf(x)
#define fmodf(x, y)
#define floorf(x)
#define fabsf(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 int gizmo_dial_modal(bContext *C, wmGizmo *gz, const wmEvent *event, eWM_GizmoFlagTweak tweak_flag)
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 void dial_draw_intern(const bContext *C, wmGizmo *gz, const bool select, const bool highlight, float clip_plane[4])
void ED_gizmotypes_dial_3d()
static void dial_ghostarc_draw(const float angle_ofs, float angle_delta, const float arc_inner_factor, const float color[4])
static int gizmo_dial_invoke(bContext *, wmGizmo *gz, const wmEvent *event)
static void GIZMO_GT_dial_3d(wmGizmoType *gzt)
static void dial_ghostarc_draw_helpline(const float angle, const float co_outer[3], const float color[4], const float line_width)
draw_view in_light_buf[] float
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
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
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
format
void *(* MEM_callocN)(size_t len, const char *str)
Definition mallocn.cc:42
ccl_device_inline float2 fmod(const float2 a, const float b)
ccl_device_inline float4 select(const int4 mask, const float4 a, const float4 b)
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
float * clip_plane
float arc_inner_factor
float angle_increment
float arc_partial_angle
struct DialInteraction::@326 output
struct DialInteraction::@324 init
struct DialInteraction::@325 prev
eWM_GizmoFlagTweak tweak_flag
float viewinv[4][4]
int xy[2]
Definition WM_types.hh:726
short type
Definition WM_types.hh:722
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
@ MOUSEMOVE
void WM_gizmo_calc_matrix_final(const wmGizmo *gz, float r_mat[4][4])
Definition wm_gizmo.cc:569
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 *))