Blender  V3.3
cage2d_gizmo.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2014 Blender Foundation. All rights reserved. */
3 
15 #include "MEM_guardedalloc.h"
16 
17 #include "BLI_dial_2d.h"
18 #include "BLI_math.h"
19 #include "BLI_rect.h"
20 
21 #include "BKE_context.h"
22 
23 #include "GPU_immediate.h"
24 #include "GPU_immediate_util.h"
25 #include "GPU_matrix.h"
26 #include "GPU_select.h"
27 #include "GPU_shader.h"
28 #include "GPU_state.h"
29 
30 #include "RNA_access.h"
31 #include "RNA_define.h"
32 
33 #include "WM_api.h"
34 #include "WM_types.h"
35 
36 #include "ED_gizmo_library.h"
37 #include "ED_screen.h"
38 #include "ED_view3d.h"
39 
40 /* own includes */
41 #include "../gizmo_library_intern.h"
42 
43 #define GIZMO_MARGIN_OFFSET_SCALE 1.5f
44 
45 static bool gizmo_calc_rect_view_scale(const wmGizmo *gz, const float dims[2], float scale[2])
46 {
47  float matrix_final_no_offset[4][4];
48  float asp[2] = {1.0f, 1.0f};
49  if (dims[0] > dims[1]) {
50  asp[0] = dims[1] / dims[0];
51  }
52  else {
53  asp[1] = dims[0] / dims[1];
54  }
55  float x_axis[3], y_axis[3];
56  WM_gizmo_calc_matrix_final_no_offset(gz, matrix_final_no_offset);
57  mul_v3_mat3_m4v3(x_axis, matrix_final_no_offset, gz->matrix_offset[0]);
58  mul_v3_mat3_m4v3(y_axis, matrix_final_no_offset, gz->matrix_offset[1]);
59 
60  mul_v2_v2(x_axis, asp);
61  mul_v2_v2(y_axis, asp);
62 
63  float len_x_axis = len_v3(x_axis);
64  float len_y_axis = len_v3(y_axis);
65 
66  if (len_x_axis == 0.0f || len_y_axis == 0.0f) {
67  return false;
68  }
69 
70  scale[0] = 1.0f / len_x_axis;
71  scale[1] = 1.0f / len_y_axis;
72  return true;
73 }
74 
75 static bool gizmo_calc_rect_view_margin(const wmGizmo *gz, const float dims[2], float margin[2])
76 {
77  float handle_size;
78  handle_size = 0.15f;
79  handle_size *= gz->scale_final;
80  float scale_xy[2];
81  if (!gizmo_calc_rect_view_scale(gz, dims, scale_xy)) {
82  zero_v2(margin);
83  return false;
84  }
85 
86  margin[0] = ((handle_size * scale_xy[0]));
87  margin[1] = ((handle_size * scale_xy[1]));
88  return true;
89 }
90 
91 /* -------------------------------------------------------------------- */
97 static void cage2d_draw_box_corners(const rctf *r,
98  const float margin[2],
99  const float color[3],
100  const float line_width)
101 {
102  /* NOTE(Metal): Prefer using 3D coordinates with 3D shader, even if rendering 2D gizmo's. */
104 
107 
108  float viewport[4];
109  GPU_viewport_size_get_f(viewport);
110  immUniform2fv("viewportSize", &viewport[2]);
111 
112  immUniform1f("lineWidth", line_width * U.pixelsize);
113 
115 
116  immVertex3f(pos, r->xmin, r->ymin + margin[1], 0.0f);
117  immVertex3f(pos, r->xmin, r->ymin, 0.0f);
118  immVertex3f(pos, r->xmin, r->ymin, 0.0f);
119  immVertex3f(pos, r->xmin + margin[0], r->ymin, 0.0f);
120 
121  immVertex3f(pos, r->xmax, r->ymin + margin[1], 0.0f);
122  immVertex3f(pos, r->xmax, r->ymin, 0.0f);
123  immVertex3f(pos, r->xmax, r->ymin, 0.0f);
124  immVertex3f(pos, r->xmax - margin[0], r->ymin, 0.0f);
125 
126  immVertex3f(pos, r->xmax, r->ymax - margin[1], 0.0f);
127  immVertex3f(pos, r->xmax, r->ymax, 0.0f);
128  immVertex3f(pos, r->xmax, r->ymax, 0.0f);
129  immVertex3f(pos, r->xmax - margin[0], r->ymax, 0.0f);
130 
131  immVertex3f(pos, r->xmin, r->ymax - margin[1], 0.0f);
132  immVertex3f(pos, r->xmin, r->ymax, 0.0f);
133  immVertex3f(pos, r->xmin, r->ymax, 0.0f);
134  immVertex3f(pos, r->xmin + margin[0], r->ymax, 0.0f);
135 
136  immEnd();
137 
139 }
140 
141 static void cage2d_draw_box_interaction(const float color[4],
142  const int highlighted,
143  const float size[2],
144  const float margin[2],
145  const float line_width,
146  const bool is_solid,
147  const int draw_options)
148 {
149  /* 4 verts for translate, otherwise only 3 are used. */
150  float verts[4][2];
151  uint verts_len = 0;
152  GPUPrimType prim_type = GPU_PRIM_NONE;
153 
154  switch (highlighted) {
156  rctf r = {
157  .xmin = -size[0],
158  .xmax = -size[0] + margin[0],
159  .ymin = -size[1] + margin[1],
160  .ymax = size[1] - margin[1],
161  };
162  ARRAY_SET_ITEMS(verts[0], r.xmin, r.ymin);
163  ARRAY_SET_ITEMS(verts[1], r.xmin, r.ymax);
164  verts_len = 2;
165  if (is_solid) {
166  ARRAY_SET_ITEMS(verts[2], r.xmax, r.ymax);
167  ARRAY_SET_ITEMS(verts[3], r.xmax, r.ymin);
168  verts_len += 2;
169  prim_type = GPU_PRIM_TRI_FAN;
170  }
171  else {
172  prim_type = GPU_PRIM_LINE_STRIP;
173  }
174  break;
175  }
177  rctf r = {
178  .xmin = size[0] - margin[0],
179  .xmax = size[0],
180  .ymin = -size[1] + margin[1],
181  .ymax = size[1] - margin[1],
182  };
183  ARRAY_SET_ITEMS(verts[0], r.xmax, r.ymin);
184  ARRAY_SET_ITEMS(verts[1], r.xmax, r.ymax);
185  verts_len = 2;
186  if (is_solid) {
187  ARRAY_SET_ITEMS(verts[2], r.xmin, r.ymax);
188  ARRAY_SET_ITEMS(verts[3], r.xmin, r.ymin);
189  verts_len += 2;
190  prim_type = GPU_PRIM_TRI_FAN;
191  }
192  else {
193  prim_type = GPU_PRIM_LINE_STRIP;
194  }
195  break;
196  }
198  rctf r = {
199  .xmin = -size[0] + margin[0],
200  .xmax = size[0] - margin[0],
201  .ymin = -size[1],
202  .ymax = -size[1] + margin[1],
203  };
204  ARRAY_SET_ITEMS(verts[0], r.xmin, r.ymin);
205  ARRAY_SET_ITEMS(verts[1], r.xmax, r.ymin);
206  verts_len = 2;
207  if (is_solid) {
208  ARRAY_SET_ITEMS(verts[2], r.xmax, r.ymax);
209  ARRAY_SET_ITEMS(verts[3], r.xmin, r.ymax);
210  verts_len += 2;
211  prim_type = GPU_PRIM_TRI_FAN;
212  }
213  else {
214  prim_type = GPU_PRIM_LINE_STRIP;
215  }
216  break;
217  }
219  rctf r = {
220  .xmin = -size[0] + margin[0],
221  .xmax = size[0] - margin[0],
222  .ymin = size[1] - margin[1],
223  .ymax = size[1],
224  };
225  ARRAY_SET_ITEMS(verts[0], r.xmin, r.ymax);
226  ARRAY_SET_ITEMS(verts[1], r.xmax, r.ymax);
227  verts_len = 2;
228  if (is_solid) {
229  ARRAY_SET_ITEMS(verts[2], r.xmax, r.ymin);
230  ARRAY_SET_ITEMS(verts[3], r.xmin, r.ymin);
231  verts_len += 2;
232  prim_type = GPU_PRIM_TRI_FAN;
233  }
234  else {
235  prim_type = GPU_PRIM_LINE_STRIP;
236  }
237  break;
238  }
240  rctf r = {
241  .xmin = -size[0],
242  .xmax = -size[0] + margin[0],
243  .ymin = -size[1],
244  .ymax = -size[1] + margin[1],
245  };
246  ARRAY_SET_ITEMS(verts[0], r.xmax, r.ymin);
247  ARRAY_SET_ITEMS(verts[1], r.xmax, r.ymax);
248  ARRAY_SET_ITEMS(verts[2], r.xmin, r.ymax);
249  verts_len = 3;
250  if (is_solid) {
251  ARRAY_SET_ITEMS(verts[3], r.xmin, r.ymin);
252  verts_len += 1;
253  prim_type = GPU_PRIM_TRI_FAN;
254  }
255  else {
256  prim_type = GPU_PRIM_LINE_STRIP;
257  }
258  break;
259  }
261  rctf r = {
262  .xmin = -size[0],
263  .xmax = -size[0] + margin[0],
264  .ymin = size[1] - margin[1],
265  .ymax = size[1],
266  };
267  ARRAY_SET_ITEMS(verts[0], r.xmax, r.ymax);
268  ARRAY_SET_ITEMS(verts[1], r.xmax, r.ymin);
269  ARRAY_SET_ITEMS(verts[2], r.xmin, r.ymin);
270  verts_len = 3;
271  if (is_solid) {
272  ARRAY_SET_ITEMS(verts[3], r.xmin, r.ymax);
273  verts_len += 1;
274  prim_type = GPU_PRIM_TRI_FAN;
275  }
276  else {
277  prim_type = GPU_PRIM_LINE_STRIP;
278  }
279  break;
280  }
282  rctf r = {
283  .xmin = size[0] - margin[0],
284  .xmax = size[0],
285  .ymin = -size[1],
286  .ymax = -size[1] + margin[1],
287  };
288  ARRAY_SET_ITEMS(verts[0], r.xmin, r.ymin);
289  ARRAY_SET_ITEMS(verts[1], r.xmin, r.ymax);
290  ARRAY_SET_ITEMS(verts[2], r.xmax, r.ymax);
291  verts_len = 3;
292  if (is_solid) {
293  ARRAY_SET_ITEMS(verts[3], r.xmax, r.ymin);
294  verts_len += 1;
295  prim_type = GPU_PRIM_TRI_FAN;
296  }
297  else {
298  prim_type = GPU_PRIM_LINE_STRIP;
299  }
300  break;
301  }
303  rctf r = {
304  .xmin = size[0] - margin[0],
305  .xmax = size[0],
306  .ymin = size[1] - margin[1],
307  .ymax = size[1],
308  };
309  ARRAY_SET_ITEMS(verts[0], r.xmin, r.ymax);
310  ARRAY_SET_ITEMS(verts[1], r.xmin, r.ymin);
311  ARRAY_SET_ITEMS(verts[2], r.xmax, r.ymin);
312  verts_len = 3;
313  if (is_solid) {
314  ARRAY_SET_ITEMS(verts[3], r.xmax, r.ymax);
315  verts_len += 1;
316  prim_type = GPU_PRIM_TRI_FAN;
317  }
318  else {
319  prim_type = GPU_PRIM_LINE_STRIP;
320  }
321  break;
322  }
324  const float rotate_pt[2] = {0.0f, size[1] + margin[1]};
325  const rctf r_rotate = {
326  .xmin = rotate_pt[0] - margin[0] / 2.0f,
327  .xmax = rotate_pt[0] + margin[0] / 2.0f,
328  .ymin = rotate_pt[1] - margin[1] / 2.0f,
329  .ymax = rotate_pt[1] + margin[1] / 2.0f,
330  };
331 
332  ARRAY_SET_ITEMS(verts[0], r_rotate.xmin, r_rotate.ymin);
333  ARRAY_SET_ITEMS(verts[1], r_rotate.xmin, r_rotate.ymax);
334  ARRAY_SET_ITEMS(verts[2], r_rotate.xmax, r_rotate.ymax);
335  ARRAY_SET_ITEMS(verts[3], r_rotate.xmax, r_rotate.ymin);
336 
337  verts_len = 4;
338  if (is_solid) {
339  prim_type = GPU_PRIM_TRI_FAN;
340  }
341  else {
342  prim_type = GPU_PRIM_LINE_STRIP;
343  }
344  break;
345  }
346 
349  ARRAY_SET_ITEMS(verts[0], -margin[0] / 2, -margin[1] / 2);
350  ARRAY_SET_ITEMS(verts[1], margin[0] / 2, margin[1] / 2);
351  ARRAY_SET_ITEMS(verts[2], -margin[0] / 2, margin[1] / 2);
352  ARRAY_SET_ITEMS(verts[3], margin[0] / 2, -margin[1] / 2);
353  verts_len = 4;
354  if (is_solid) {
355  prim_type = GPU_PRIM_TRI_FAN;
356  }
357  else {
358  prim_type = GPU_PRIM_LINES;
359  }
360  }
361  else {
362  /* Only used for 3D view selection, never displayed to the user. */
363  ARRAY_SET_ITEMS(verts[0], -size[0], -size[1]);
364  ARRAY_SET_ITEMS(verts[1], -size[0], size[1]);
365  ARRAY_SET_ITEMS(verts[2], size[0], size[1]);
366  ARRAY_SET_ITEMS(verts[3], size[0], -size[1]);
367  verts_len = 4;
368  if (is_solid) {
369  prim_type = GPU_PRIM_TRI_FAN;
370  }
371  else {
372  /* unreachable */
373  BLI_assert(0);
374  prim_type = GPU_PRIM_LINE_STRIP;
375  }
376  }
377  break;
378  default:
379  return;
380  }
381 
382  BLI_assert(prim_type != GPU_PRIM_NONE);
383 
385  struct {
386  uint pos, col;
387  } attr_id = {
390  };
392 
393  {
394  if (is_solid) {
395  BLI_assert(ELEM(prim_type, GPU_PRIM_TRI_FAN));
396  immBegin(prim_type, verts_len);
397  immAttr3f(attr_id.col, 0.0f, 0.0f, 0.0f);
398  for (uint i = 0; i < verts_len; i++) {
399  immVertex2fv(attr_id.pos, verts[i]);
400  }
401  immEnd();
402  }
403  else {
405 
406  float viewport[4];
407  GPU_viewport_size_get_f(viewport);
408  immUniform2fv("viewportSize", &viewport[2]);
409 
410  immUniform1f("lineWidth", (line_width * 3.0f) * U.pixelsize);
411 
412  immBegin(prim_type, verts_len);
413  immAttr3f(attr_id.col, 0.0f, 0.0f, 0.0f);
414  for (uint i = 0; i < verts_len; i++) {
415  immVertex2fv(attr_id.pos, verts[i]);
416  }
417  immEnd();
418 
419  immUniform1f("lineWidth", line_width * U.pixelsize);
420 
421  immBegin(prim_type, verts_len);
422  immAttr3fv(attr_id.col, color);
423  for (uint i = 0; i < verts_len; i++) {
424  immVertex2fv(attr_id.pos, verts[i]);
425  }
426  immEnd();
427  }
428  }
429 
431 }
432 
435 /* -------------------------------------------------------------------- */
442  uint pos, float x, float y, float rad_x, float rad_y, bool solid)
443 {
444  if (solid) {
445  /* NOTE(Metal/AMD): Small Triangle-list primitives more optimal for GPU HW than Triangle-strip.
446  */
448  immVertex2f(pos, x - rad_x, y - rad_y);
449  immVertex2f(pos, x - rad_x, y + rad_y);
450  immVertex2f(pos, x + rad_x, y + rad_y);
451 
452  immVertex2f(pos, x - rad_x, y - rad_y);
453  immVertex2f(pos, x + rad_x, y + rad_y);
454  immVertex2f(pos, x + rad_x, y - rad_y);
455  immEnd();
456  }
457  else {
458  /* NOTE(Metal/AMD): Small Line-list primitives more optimal for GPU HW than Line-strip. */
460  immVertex2f(pos, x - rad_x, y - rad_y);
461  immVertex2f(pos, x - rad_x, y + rad_y);
462 
463  immVertex2f(pos, x - rad_x, y + rad_y);
464  immVertex2f(pos, x + rad_x, y + rad_y);
465 
466  immVertex2f(pos, x + rad_x, y + rad_y);
467  immVertex2f(pos, x + rad_x, y - rad_y);
468 
469  immVertex2f(pos, x + rad_x, y - rad_y);
470  immVertex2f(pos, x - rad_x, y - rad_y);
471  immEnd();
472  }
473 }
474 
475 static void cage2d_draw_circle_wire(const rctf *r,
476  const float margin[2],
477  const float color[3],
478  const int transform_flag,
479  const int draw_options,
480  const float line_width)
481 {
482  /* NOTE(Metal): Prefer using 3D coordinates with 3D shader input, even if rendering 2D gizmo's.
483  */
485 
488 
489  float viewport[4];
490  GPU_viewport_size_get_f(viewport);
491  immUniform2fv("viewportSize", &viewport[2]);
492  immUniform1f("lineWidth", line_width * U.pixelsize);
493 
494  /* Small 'lines' primitives more efficient for hardware processing than line-strip. */
496  immVertex3f(pos, r->xmin, r->ymin, 0.0f);
497  immVertex3f(pos, r->xmax, r->ymin, 0.0f);
498 
499  immVertex3f(pos, r->xmax, r->ymin, 0.0f);
500  immVertex3f(pos, r->xmax, r->ymax, 0.0f);
501 
502  immVertex3f(pos, r->xmax, r->ymax, 0.0f);
503  immVertex3f(pos, r->xmin, r->ymax, 0.0f);
504 
505  immVertex3f(pos, r->xmin, r->ymax, 0.0f);
506  immVertex3f(pos, r->xmin, r->ymin, 0.0f);
507  immEnd();
508 
509  if (transform_flag & ED_GIZMO_CAGE2D_XFORM_FLAG_ROTATE) {
511  immVertex3f(pos, BLI_rctf_cent_x(r), r->ymax, 0.0f);
512  immVertex3f(pos, BLI_rctf_cent_x(r), r->ymax + margin[1], 0.0f);
513 
514  immVertex3f(pos, BLI_rctf_cent_x(r), r->ymax + margin[1], 0.0f);
515  immVertex3f(pos, BLI_rctf_cent_x(r), r->ymax, 0.0f);
516  immEnd();
517  }
518 
519  if (transform_flag & ED_GIZMO_CAGE2D_XFORM_FLAG_TRANSLATE) {
521  const float rad[2] = {margin[0] / 2, margin[1] / 2};
522  const float center[2] = {BLI_rctf_cent_x(r), BLI_rctf_cent_y(r)};
523 
525  immVertex3f(pos, center[0] - rad[0], center[1] - rad[1], 0.0f);
526  immVertex3f(pos, center[0] + rad[0], center[1] + rad[1], 0.0f);
527  immVertex3f(pos, center[0] + rad[0], center[1] - rad[1], 0.0f);
528  immVertex3f(pos, center[0] - rad[0], center[1] + rad[1], 0.0f);
529  immEnd();
530  }
531  }
532 
534 }
535 
536 static void cage2d_draw_circle_handles(const rctf *r,
537  const float margin[2],
538  const float color[3],
539  const int transform_flag,
540  bool solid)
541 {
543  void (*circle_fn)(uint, float, float, float, float, int) = (solid) ?
546  const int resolu = 12;
547  const float rad[2] = {margin[0] / 3, margin[1] / 3};
548 
551 
552  /* should really divide by two, but looks too bulky. */
553  {
554  imm_draw_point_aspect_2d(pos, r->xmin, r->ymin, rad[0], rad[1], solid);
555  imm_draw_point_aspect_2d(pos, r->xmax, r->ymin, rad[0], rad[1], solid);
556  imm_draw_point_aspect_2d(pos, r->xmax, r->ymax, rad[0], rad[1], solid);
557  imm_draw_point_aspect_2d(pos, r->xmin, r->ymax, rad[0], rad[1], solid);
558  }
559 
560  if (transform_flag & ED_GIZMO_CAGE2D_XFORM_FLAG_ROTATE) {
561  const float handle[2] = {
563  r->ymax + (margin[1] * GIZMO_MARGIN_OFFSET_SCALE),
564  };
565  circle_fn(pos, handle[0], handle[1], rad[0], rad[1], resolu);
566  }
567 
569 }
570 
574  const bool select,
575  const bool highlight,
576  const int select_id)
577 {
578  // const bool use_clamp = (gz->parent_gzgroup->type->flag & WM_GIZMOGROUPTYPE_3D) == 0;
579  float dims[2];
580  RNA_float_get_array(gz->ptr, "dimensions", dims);
581  float matrix_final[4][4];
582 
583  const int transform_flag = RNA_enum_get(gz->ptr, "transform");
584  const int draw_style = RNA_enum_get(gz->ptr, "draw_style");
585  const int draw_options = RNA_enum_get(gz->ptr, "draw_options");
586 
587  const float size_real[2] = {dims[0] / 2.0f, dims[1] / 2.0f};
588 
589  WM_gizmo_calc_matrix_final(gz, matrix_final);
590 
591  GPU_matrix_push();
592  GPU_matrix_mul(matrix_final);
593 
594  float margin[2];
595  gizmo_calc_rect_view_margin(gz, dims, margin);
596 
597  /* Handy for quick testing draw (if it's outside bounds). */
598  if (false) {
602  immUniformColor4fv((const float[4]){1, 1, 1, 0.5f});
603  float s = 0.5f;
604  immRectf(pos, -s, -s, s, s);
607  }
608 
609  if (select) {
610  /* Expand for hot-spot. */
611  const float size[2] = {size_real[0] + margin[0] / 2, size_real[1] + margin[1] / 2};
612 
613  if (transform_flag & ED_GIZMO_CAGE2D_XFORM_FLAG_SCALE) {
614  int scale_parts[] = {
619 
624  };
625  for (int i = 0; i < ARRAY_SIZE(scale_parts); i++) {
626  GPU_select_load_id(select_id | scale_parts[i]);
628  gz->color, scale_parts[i], size, margin, gz->line_width, true, draw_options);
629  }
630  }
631  if (transform_flag & ED_GIZMO_CAGE2D_XFORM_FLAG_TRANSLATE) {
632  const int transform_part = ED_GIZMO_CAGE2D_PART_TRANSLATE;
633  GPU_select_load_id(select_id | transform_part);
635  gz->color, transform_part, size, margin, gz->line_width, true, draw_options);
636  }
637  if (transform_flag & ED_GIZMO_CAGE2D_XFORM_FLAG_ROTATE) {
640  size_real,
641  margin,
642  gz->line_width,
643  true,
644  draw_options);
645  }
646  }
647  else {
648  const rctf r = {
649  .xmin = -size_real[0],
650  .ymin = -size_real[1],
651  .xmax = size_real[0],
652  .ymax = size_real[1],
653  };
654  if (draw_style == ED_GIZMO_CAGE2D_STYLE_BOX) {
655  float color[4], black[3] = {0, 0, 0};
656  gizmo_color_get(gz, highlight, color);
657 
658  /* corner gizmos */
659  cage2d_draw_box_corners(&r, margin, black, gz->line_width + 3.0f);
660 
661  /* corner gizmos */
662  cage2d_draw_box_corners(&r, margin, color, gz->line_width);
663 
664  bool show = false;
666  /* Only show if we're drawing the center handle
667  * otherwise the entire rectangle is the hot-spot. */
669  show = true;
670  }
671  }
672  else {
673  show = true;
674  }
675 
676  if (show) {
678  gz->color, gz->highlight_part, size_real, margin, gz->line_width, false, draw_options);
679  }
680 
681  if (transform_flag & ED_GIZMO_CAGE2D_XFORM_FLAG_ROTATE) {
684  size_real,
685  margin,
686  gz->line_width,
687  false,
688  draw_options);
689  }
690  }
691  else if (draw_style == ED_GIZMO_CAGE2D_STYLE_CIRCLE) {
692  float color[4], black[3] = {0, 0, 0};
693  gizmo_color_get(gz, highlight, color);
694 
696 
697  float outline_line_width = gz->line_width + 3.0f;
698  cage2d_draw_circle_wire(&r, margin, black, transform_flag, draw_options, outline_line_width);
699  cage2d_draw_circle_wire(&r, margin, color, transform_flag, draw_options, gz->line_width);
700 
701  /* corner gizmos */
702  cage2d_draw_circle_handles(&r, margin, color, transform_flag, true);
703  cage2d_draw_circle_handles(&r, margin, (const float[3]){0, 0, 0}, transform_flag, false);
704 
706  }
707  else {
708  BLI_assert(0);
709  }
710  }
711 
712  GPU_matrix_pop();
713 }
714 
718 static void gizmo_cage2d_draw_select(const bContext *UNUSED(C), wmGizmo *gz, int select_id)
719 {
720  gizmo_cage2d_draw_intern(gz, true, false, select_id);
721 }
722 
723 static void gizmo_cage2d_draw(const bContext *UNUSED(C), wmGizmo *gz)
724 {
725  const bool is_highlight = (gz->state & WM_GIZMO_STATE_HIGHLIGHT) != 0;
726  gizmo_cage2d_draw_intern(gz, false, is_highlight, -1);
727 }
728 
730 {
731  int highlight_part = gz->highlight_part;
732 
734  return WM_CURSOR_NSEW_SCROLL;
735  }
736 
737  switch (highlight_part) {
739  return WM_CURSOR_NSEW_SCROLL;
742  return WM_CURSOR_NSEW_SCROLL;
745  return WM_CURSOR_NSEW_SCROLL;
746 
747  /* TODO: diagonal cursor. */
750  return WM_CURSOR_NSEW_SCROLL;
753  return WM_CURSOR_NSEW_SCROLL;
755  return WM_CURSOR_CROSS;
756  default:
757  return WM_CURSOR_DEFAULT;
758  }
759 }
760 
761 static int gizmo_cage2d_test_select(bContext *C, wmGizmo *gz, const int mval[2])
762 {
763  float point_local[2];
764  float dims[2];
765  RNA_float_get_array(gz->ptr, "dimensions", dims);
766  const float size_real[2] = {dims[0] / 2.0f, dims[1] / 2.0f};
767 
768  if (gizmo_window_project_2d(C, gz, (const float[2]){UNPACK2(mval)}, 2, true, point_local) ==
769  false) {
770  return -1;
771  }
772 
773  float margin[2];
774  if (!gizmo_calc_rect_view_margin(gz, dims, margin)) {
775  return -1;
776  }
777 
778  /* Expand for hots-pot. */
779  const float size[2] = {size_real[0] + margin[0] / 2, size_real[1] + margin[1] / 2};
780 
781  const int transform_flag = RNA_enum_get(gz->ptr, "transform");
782  const int draw_options = RNA_enum_get(gz->ptr, "draw_options");
783 
784  if (transform_flag & ED_GIZMO_CAGE2D_XFORM_FLAG_TRANSLATE) {
785  rctf r;
787  r.xmin = -margin[0] / 2;
788  r.ymin = -margin[1] / 2;
789  r.xmax = margin[0] / 2;
790  r.ymax = margin[1] / 2;
791  }
792  else {
793  r.xmin = -size[0] + margin[0];
794  r.ymin = -size[1] + margin[1];
795  r.xmax = size[0] - margin[0];
796  r.ymax = size[1] - margin[1];
797  }
798  bool isect = BLI_rctf_isect_pt_v(&r, point_local);
799  if (isect) {
801  }
802  }
803 
804  /* if gizmo does not have a scale intersection, don't do it */
805  if (transform_flag &
807  const rctf r_xmin = {
808  .xmin = -size[0],
809  .ymin = -size[1],
810  .xmax = -size[0] + margin[0],
811  .ymax = size[1],
812  };
813  const rctf r_xmax = {
814  .xmin = size[0] - margin[0],
815  .ymin = -size[1],
816  .xmax = size[0],
817  .ymax = size[1],
818  };
819  const rctf r_ymin = {
820  .xmin = -size[0],
821  .ymin = -size[1],
822  .xmax = size[0],
823  .ymax = -size[1] + margin[1],
824  };
825  const rctf r_ymax = {
826  .xmin = -size[0],
827  .ymin = size[1] - margin[1],
828  .xmax = size[0],
829  .ymax = size[1],
830  };
831 
832  if (BLI_rctf_isect_pt_v(&r_xmin, point_local)) {
833  if (BLI_rctf_isect_pt_v(&r_ymin, point_local)) {
835  }
836  if (BLI_rctf_isect_pt_v(&r_ymax, point_local)) {
838  }
840  }
841  if (BLI_rctf_isect_pt_v(&r_xmax, point_local)) {
842  if (BLI_rctf_isect_pt_v(&r_ymin, point_local)) {
844  }
845  if (BLI_rctf_isect_pt_v(&r_ymax, point_local)) {
847  }
849  }
850  if (BLI_rctf_isect_pt_v(&r_ymin, point_local)) {
852  }
853  if (BLI_rctf_isect_pt_v(&r_ymax, point_local)) {
855  }
856  }
857 
858  if (transform_flag & ED_GIZMO_CAGE2D_XFORM_FLAG_ROTATE) {
859  /* Rotate:
860  * (*) <-- hot spot is here!
861  * +---+
862  * | |
863  * +---+ */
864  const float r_rotate_pt[2] = {0.0f, size_real[1] + (margin[1] * GIZMO_MARGIN_OFFSET_SCALE)};
865  const rctf r_rotate = {
866  .xmin = r_rotate_pt[0] - margin[0] / 2.0f,
867  .xmax = r_rotate_pt[0] + margin[0] / 2.0f,
868  .ymin = r_rotate_pt[1] - margin[1] / 2.0f,
869  .ymax = r_rotate_pt[1] + margin[1] / 2.0f,
870  };
871 
872  if (BLI_rctf_isect_pt_v(&r_rotate, point_local)) {
874  }
875  }
876 
877  return -1;
878 }
879 
880 typedef struct RectTransformInteraction {
881  float orig_mouse[2];
882  float orig_matrix_offset[4][4];
886 
887 static void gizmo_cage2d_setup(wmGizmo *gz)
888 {
890 }
891 
892 static int gizmo_cage2d_invoke(bContext *C, wmGizmo *gz, const wmEvent *event)
893 {
895  "cage_interaction");
896 
897  copy_m4_m4(data->orig_matrix_offset, gz->matrix_offset);
898  WM_gizmo_calc_matrix_final_no_offset(gz, data->orig_matrix_final_no_offset);
899 
901  C, gz, (const float[2]){UNPACK2(event->mval)}, 2, false, data->orig_mouse) == 0) {
902  zero_v2(data->orig_mouse);
903  }
904 
905  gz->interaction_data = data;
906 
907  return OPERATOR_RUNNING_MODAL;
908 }
909 
910 static void gizmo_rect_pivot_from_scale_part(int part, float r_pt[2], bool r_constrain_axis[2])
911 {
912  bool x = true, y = true;
913  switch (part) {
915  ARRAY_SET_ITEMS(r_pt, 0.5, 0.0);
916  x = false;
917  break;
918  }
920  ARRAY_SET_ITEMS(r_pt, -0.5, 0.0);
921  x = false;
922  break;
923  }
925  ARRAY_SET_ITEMS(r_pt, 0.0, 0.5);
926  y = false;
927  break;
928  }
930  ARRAY_SET_ITEMS(r_pt, 0.0, -0.5);
931  y = false;
932  break;
933  }
935  ARRAY_SET_ITEMS(r_pt, 0.5, 0.5);
936  x = y = false;
937  break;
938  }
940  ARRAY_SET_ITEMS(r_pt, 0.5, -0.5);
941  x = y = false;
942  break;
943  }
945  ARRAY_SET_ITEMS(r_pt, -0.5, 0.5);
946  x = y = false;
947  break;
948  }
950  ARRAY_SET_ITEMS(r_pt, -0.5, -0.5);
951  x = y = false;
952  break;
953  }
954  default:
955  BLI_assert(0);
956  }
957  r_constrain_axis[0] = x;
958  r_constrain_axis[1] = y;
959 }
960 
962  wmGizmo *gz,
963  const wmEvent *event,
964  eWM_GizmoFlagTweak UNUSED(tweak_flag))
965 {
966  if (event->type != MOUSEMOVE) {
967  return OPERATOR_RUNNING_MODAL;
968  }
969  /* For transform logic to be manageable we operate in -0.5..0.5 2D space,
970  * no matter the size of the rectangle, mouse coords are scaled to unit space.
971  * The mouse coords have been projected into the matrix
972  * so we don't need to worry about axis alignment.
973  *
974  * - The cursor offset are multiplied by 'dims'.
975  * - Matrix translation is also multiplied by 'dims'.
976  */
978  float point_local[2];
979 
980  float dims[2];
981  RNA_float_get_array(gz->ptr, "dimensions", dims);
982 
983  {
984  float matrix_back[4][4];
985  copy_m4_m4(matrix_back, gz->matrix_offset);
986  copy_m4_m4(gz->matrix_offset, data->orig_matrix_offset);
987 
988  bool ok = gizmo_window_project_2d(
989  C, gz, (const float[2]){UNPACK2(event->mval)}, 2, false, point_local);
990  copy_m4_m4(gz->matrix_offset, matrix_back);
991  if (!ok) {
992  return OPERATOR_RUNNING_MODAL;
993  }
994  }
995 
996  const int transform_flag = RNA_enum_get(gz->ptr, "transform");
997  wmGizmoProperty *gz_prop;
998 
999  gz_prop = WM_gizmo_target_property_find(gz, "matrix");
1000  if (gz_prop->type != NULL) {
1002  }
1003 
1005  /* do this to prevent clamping from changing size */
1006  copy_m4_m4(gz->matrix_offset, data->orig_matrix_offset);
1007  gz->matrix_offset[3][0] = data->orig_matrix_offset[3][0] +
1008  (point_local[0] - data->orig_mouse[0]);
1009  gz->matrix_offset[3][1] = data->orig_matrix_offset[3][1] +
1010  (point_local[1] - data->orig_mouse[1]);
1011  }
1012  else if (gz->highlight_part == ED_GIZMO_CAGE2D_PART_ROTATE) {
1013 
1014 #define MUL_V2_V3_M4_FINAL(test_co, mouse_co) \
1015  mul_v3_m4v3( \
1016  test_co, data->orig_matrix_final_no_offset, ((const float[3]){UNPACK2(mouse_co), 0.0}))
1017 
1018  float test_co[3];
1019 
1020  if (data->dial == NULL) {
1021  MUL_V2_V3_M4_FINAL(test_co, data->orig_matrix_offset[3]);
1022 
1023  data->dial = BLI_dial_init(test_co, FLT_EPSILON);
1024 
1025  MUL_V2_V3_M4_FINAL(test_co, data->orig_mouse);
1026  BLI_dial_angle(data->dial, test_co);
1027  }
1028 
1029  /* rotate */
1030  MUL_V2_V3_M4_FINAL(test_co, point_local);
1031  const float angle = BLI_dial_angle(data->dial, test_co);
1032 
1033  float matrix_space_inv[4][4];
1034  float matrix_rotate[4][4];
1035  float pivot[3];
1036 
1037  copy_v3_v3(pivot, data->orig_matrix_offset[3]);
1038 
1039  invert_m4_m4(matrix_space_inv, gz->matrix_space);
1040 
1041  unit_m4(matrix_rotate);
1042  mul_m4_m4m4(matrix_rotate, matrix_rotate, matrix_space_inv);
1043  rotate_m4(matrix_rotate, 'Z', -angle);
1044  mul_m4_m4m4(matrix_rotate, matrix_rotate, gz->matrix_space);
1045 
1046  zero_v3(matrix_rotate[3]);
1047  transform_pivot_set_m4(matrix_rotate, pivot);
1048 
1049  mul_m4_m4m4(gz->matrix_offset, matrix_rotate, data->orig_matrix_offset);
1050 
1051 #undef MUL_V2_V3_M4_FINAL
1052  }
1053  else {
1054  /* scale */
1055  copy_m4_m4(gz->matrix_offset, data->orig_matrix_offset);
1056  float pivot[2];
1057  bool constrain_axis[2] = {false};
1058 
1059  if (transform_flag & ED_GIZMO_CAGE2D_XFORM_FLAG_TRANSLATE) {
1060  gizmo_rect_pivot_from_scale_part(gz->highlight_part, pivot, constrain_axis);
1061  }
1062  else {
1063  zero_v2(pivot);
1064  }
1065 
1066  /* Cursor deltas scaled to (-0.5..0.5). */
1067  float delta_orig[2], delta_curr[2];
1068  for (int i = 0; i < 2; i++) {
1069  delta_orig[i] = ((data->orig_mouse[i] - data->orig_matrix_offset[3][i]) / dims[i]) -
1070  pivot[i];
1071  delta_curr[i] = ((point_local[i] - data->orig_matrix_offset[3][i]) / dims[i]) - pivot[i];
1072  }
1073 
1074  float scale[2] = {1.0f, 1.0f};
1075  for (int i = 0; i < 2; i++) {
1076  if (constrain_axis[i] == false) {
1077  if (delta_orig[i] < 0.0f) {
1078  delta_orig[i] *= -1.0f;
1079  delta_curr[i] *= -1.0f;
1080  }
1081  const int sign = signum_i(scale[i]);
1082 
1083  scale[i] = 1.0f + ((delta_curr[i] - delta_orig[i]) / len_v3(data->orig_matrix_offset[i]));
1084 
1085  if ((transform_flag & ED_GIZMO_CAGE2D_XFORM_FLAG_SCALE_SIGNED) == 0) {
1086  if (sign != signum_i(scale[i])) {
1087  scale[i] = 0.0f;
1088  }
1089  }
1090  }
1091  }
1092 
1093  if (transform_flag & ED_GIZMO_CAGE2D_XFORM_FLAG_SCALE_UNIFORM) {
1094  if (constrain_axis[0] == false && constrain_axis[1] == false) {
1095  scale[1] = scale[0] = (scale[1] + scale[0]) / 2.0f;
1096  }
1097  else if (constrain_axis[0] == false) {
1098  scale[1] = scale[0];
1099  }
1100  else if (constrain_axis[1] == false) {
1101  scale[0] = scale[1];
1102  }
1103  else {
1104  BLI_assert(0);
1105  }
1106  }
1107 
1108  /* scale around pivot */
1109  float matrix_scale[4][4];
1110  unit_m4(matrix_scale);
1111 
1112  mul_v3_fl(matrix_scale[0], scale[0]);
1113  mul_v3_fl(matrix_scale[1], scale[1]);
1114 
1115  transform_pivot_set_m4(matrix_scale,
1116  (const float[3]){pivot[0] * dims[0], pivot[1] * dims[1], 0.0f});
1117  mul_m4_m4m4(gz->matrix_offset, data->orig_matrix_offset, matrix_scale);
1118  }
1119 
1120  if (gz_prop->type != NULL) {
1121  WM_gizmo_target_property_float_set_array(C, gz, gz_prop, &gz->matrix_offset[0][0]);
1122  }
1123 
1124  /* tag the region for redraw */
1127 
1128  return OPERATOR_RUNNING_MODAL;
1129 }
1130 
1132 {
1133  if (STREQ(gz_prop->type->idname, "matrix")) {
1134  if (WM_gizmo_target_property_array_length(gz, gz_prop) == 16) {
1136  }
1137  else {
1138  BLI_assert(0);
1139  }
1140  }
1141  else {
1142  BLI_assert(0);
1143  }
1144 }
1145 
1146 static void gizmo_cage2d_exit(bContext *C, wmGizmo *gz, const bool cancel)
1147 {
1149 
1150  MEM_SAFE_FREE(data->dial);
1151 
1152  if (!cancel) {
1153  return;
1154  }
1155 
1156  wmGizmoProperty *gz_prop;
1157 
1158  /* reset properties */
1159  gz_prop = WM_gizmo_target_property_find(gz, "matrix");
1160  if (gz_prop->type != NULL) {
1161  WM_gizmo_target_property_float_set_array(C, gz, gz_prop, &data->orig_matrix_offset[0][0]);
1162  }
1163 
1164  copy_m4_m4(gz->matrix_offset, data->orig_matrix_offset);
1165 }
1166 
1167 /* -------------------------------------------------------------------- */
1172 {
1173  /* identifiers */
1174  gzt->idname = "GIZMO_GT_cage_2d";
1175 
1176  /* api callbacks */
1177  gzt->draw = gizmo_cage2d_draw;
1180  gzt->setup = gizmo_cage2d_setup;
1181  gzt->invoke = gizmo_cage2d_invoke;
1183  gzt->modal = gizmo_cage2d_modal;
1184  gzt->exit = gizmo_cage2d_exit;
1186 
1187  gzt->struct_size = sizeof(wmGizmo);
1188 
1189  /* rna */
1190  static EnumPropertyItem rna_enum_draw_style[] = {
1191  {ED_GIZMO_CAGE2D_STYLE_BOX, "BOX", 0, "Box", ""},
1192  {ED_GIZMO_CAGE2D_STYLE_CIRCLE, "CIRCLE", 0, "Circle", ""},
1193  {0, NULL, 0, NULL, NULL},
1194  };
1195  static EnumPropertyItem rna_enum_transform[] = {
1196  {ED_GIZMO_CAGE2D_XFORM_FLAG_TRANSLATE, "TRANSLATE", 0, "Move", ""},
1197  {ED_GIZMO_CAGE2D_XFORM_FLAG_ROTATE, "ROTATE", 0, "Rotate", ""},
1198  {ED_GIZMO_CAGE2D_XFORM_FLAG_SCALE, "SCALE", 0, "Scale", ""},
1199  {ED_GIZMO_CAGE2D_XFORM_FLAG_SCALE_UNIFORM, "SCALE_UNIFORM", 0, "Scale Uniform", ""},
1200  {0, NULL, 0, NULL, NULL},
1201  };
1202  static EnumPropertyItem rna_enum_draw_options[] = {
1204  "XFORM_CENTER_HANDLE",
1205  0,
1206  "Center Handle",
1207  ""},
1208  {0, NULL, 0, NULL, NULL},
1209  };
1210  static float unit_v2[2] = {1.0f, 1.0f};
1212  gzt->srna, "dimensions", 2, unit_v2, 0, FLT_MAX, "Dimensions", "", 0.0f, FLT_MAX);
1213  RNA_def_enum_flag(gzt->srna, "transform", rna_enum_transform, 0, "Transform Options", "");
1214  RNA_def_enum(gzt->srna,
1215  "draw_style",
1216  rna_enum_draw_style,
1218  "Draw Style",
1219  "");
1220  RNA_def_enum_flag(gzt->srna,
1221  "draw_options",
1222  rna_enum_draw_options,
1224  "Draw Options",
1225  "");
1226 
1227  WM_gizmotype_target_property_def(gzt, "matrix", PROP_FLOAT, 16);
1228 }
1229 
1231 {
1233 }
1234 
typedef float(TangentPoint)[2]
struct ARegion * CTX_wm_region(const bContext *C)
Definition: context.c:749
struct wmWindow * CTX_wm_window(const bContext *C)
Definition: context.c:723
#define BLI_assert(a)
Definition: BLI_assert.h:46
Dial * BLI_dial_init(const float start_position[2], float threshold)
Definition: BLI_dial_2d.c:34
float BLI_dial_angle(Dial *dial, const float current_position[2])
Definition: BLI_dial_2d.c:44
MINLINE int signum_i(float a)
void mul_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4])
Definition: math_matrix.c:259
void unit_m4(float m[4][4])
Definition: rct.c:1090
bool invert_m4_m4(float R[4][4], const float A[4][4])
Definition: math_matrix.c:1287
void transform_pivot_set_m4(float mat[4][4], const float pivot[3])
Definition: math_matrix.c:2369
void copy_m4_m4(float m1[4][4], const float m2[4][4])
Definition: math_matrix.c:77
void rotate_m4(float mat[4][4], char axis, float angle)
Definition: math_matrix.c:2325
void mul_v3_mat3_m4v3(float r[3], const float M[4][4], const float v[3])
Definition: math_matrix.c:800
MINLINE void mul_v2_v2(float r[2], const float a[2])
MINLINE void mul_v3_fl(float r[3], float f)
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void zero_v2(float r[2])
MINLINE void zero_v3(float r[3])
MINLINE float len_v3(const float a[3]) ATTR_WARN_UNUSED_RESULT
bool BLI_rctf_isect_pt_v(const struct rctf *rect, const float xy[2])
BLI_INLINE float BLI_rctf_cent_y(const struct rctf *rct)
Definition: BLI_rect.h:181
BLI_INLINE float BLI_rctf_cent_x(const struct rctf *rct)
Definition: BLI_rect.h:177
unsigned int uint
Definition: BLI_sys_types.h:67
#define UNPACK2(a)
#define ARRAY_SIZE(arr)
#define ARRAY_SET_ITEMS(...)
#define UNUSED(x)
#define ELEM(...)
#define STREQ(a, b)
@ OPERATOR_RUNNING_MODAL
@ ED_GIZMO_CAGE2D_PART_SCALE_MIN_X_MAX_Y
@ ED_GIZMO_CAGE2D_PART_TRANSLATE
@ ED_GIZMO_CAGE2D_PART_ROTATE
@ ED_GIZMO_CAGE2D_PART_SCALE_MAX_Y
@ ED_GIZMO_CAGE2D_PART_SCALE_MAX_X_MAX_Y
@ ED_GIZMO_CAGE2D_PART_SCALE_MIN_X
@ ED_GIZMO_CAGE2D_PART_SCALE_MAX_X_MIN_Y
@ ED_GIZMO_CAGE2D_PART_SCALE_MAX_X
@ ED_GIZMO_CAGE2D_PART_SCALE_MIN_X_MIN_Y
@ ED_GIZMO_CAGE2D_PART_SCALE_MIN_Y
@ ED_GIZMO_CAGE2D_STYLE_BOX
@ ED_GIZMO_CAGE2D_STYLE_CIRCLE
@ ED_GIZMO_CAGE2D_DRAW_FLAG_XFORM_CENTER_HANDLE
@ ED_GIZMO_CAGE2D_XFORM_FLAG_TRANSLATE
@ ED_GIZMO_CAGE2D_XFORM_FLAG_SCALE_SIGNED
@ ED_GIZMO_CAGE2D_XFORM_FLAG_SCALE
@ ED_GIZMO_CAGE2D_XFORM_FLAG_ROTATE
@ ED_GIZMO_CAGE2D_XFORM_FLAG_SCALE_UNIFORM
void ED_region_tag_redraw_editor_overlays(struct ARegion *region)
Definition: area.c:690
NSNotificationCenter * center
void immUniform2fv(const char *name, const float data[2])
void immUnbindProgram(void)
void immVertex2f(uint attr_id, float x, float y)
void immBindBuiltinProgram(eGPUBuiltinShader shader_id)
void immVertex3f(uint attr_id, float x, float y, float z)
void immVertex2fv(uint attr_id, const float data[2])
void immUniform1f(const char *name, float x)
void immUniformColor4fv(const float rgba[4])
GPUVertFormat * immVertexFormat(void)
void immAttr3fv(uint attr_id, const float data[3])
void immBegin(GPUPrimType, uint vertex_len)
void immAttr3f(uint attr_id, float x, float y, float z)
void immEnd(void)
void immUniformColor3fv(const float rgb[3])
void imm_draw_circle_fill_aspect_2d(uint shdr_pos, float x, float y, float radius_x, float radius_y, int nsegments)
void imm_draw_circle_wire_aspect_2d(uint shdr_pos, float x, float y, float radius_x, float radius_y, int nsegments)
void immRectf(uint pos, float x1, float y1, float x2, float y2)
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble GLdouble r _GL_VOID_RET _GL_VOID GLfloat GLfloat r _GL_VOID_RET _GL_VOID GLint GLint r _GL_VOID_RET _GL_VOID GLshort GLshort r _GL_VOID_RET _GL_VOID GLdouble GLdouble r
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint y
void GPU_matrix_pop(void)
Definition: gpu_matrix.cc:126
#define GPU_matrix_mul(x)
Definition: GPU_matrix.h:224
void GPU_matrix_push(void)
Definition: gpu_matrix.cc:119
GPUPrimType
Definition: GPU_primitive.h:18
@ GPU_PRIM_TRI_FAN
Definition: GPU_primitive.h:25
@ GPU_PRIM_NONE
Definition: GPU_primitive.h:33
@ GPU_PRIM_LINES
Definition: GPU_primitive.h:20
@ GPU_PRIM_LINE_STRIP
Definition: GPU_primitive.h:22
@ GPU_PRIM_TRIS
Definition: GPU_primitive.h:21
bool GPU_select_load_id(unsigned int id)
Definition: gpu_select.c:117
@ GPU_SHADER_3D_POLYLINE_UNIFORM_COLOR
Definition: GPU_shader.h:253
@ GPU_SHADER_2D_UNIFORM_COLOR
Definition: GPU_shader.h:201
@ GPU_SHADER_3D_POLYLINE_FLAT_COLOR
Definition: GPU_shader.h:262
@ GPU_SHADER_2D_FLAT_COLOR
Definition: GPU_shader.h:208
@ GPU_BLEND_NONE
Definition: GPU_state.h:60
@ GPU_BLEND_ALPHA
Definition: GPU_state.h:62
void GPU_blend(eGPUBlend blend)
Definition: gpu_state.cc:39
void GPU_viewport_size_get_f(float coords[4])
Definition: gpu_state.cc:259
@ 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.
#define MEM_SAFE_FREE(v)
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Bright Control the brightness and contrast of the input color Vector Map an input vectors to used to fine tune the interpolation of the input Camera Retrieve information about the camera and how it relates to the current shading point s position Clamp a value between a minimum and a maximum Vector Perform vector math operation Invert a color
@ PROP_FLOAT
Definition: RNA_types.h:61
#define C
Definition: RandGen.cpp:25
struct wmGizmo wmGizmo
Definition: WM_api.h:68
eWM_GizmoFlagTweak
Gizmo tweak flag. Bit-flag passed to gizmo while tweaking.
@ WM_GIZMO_DRAW_NO_SCALE
@ WM_GIZMO_DRAW_MODAL
@ WM_GIZMOGROUPTYPE_3D
@ WM_GIZMO_STATE_HIGHLIGHT
__forceinline const avxb select(const avxb &m, const avxb &t, const avxb &f)
Definition: avxb.h:154
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
unsigned int U
Definition: btGjkEpa3.h:78
SIMD_FORCE_INLINE btScalar angle(const btVector3 &v) const
Return the angle between this and another vector.
Definition: btVector3.h:356
static void GIZMO_GT_cage_2d(wmGizmoType *gzt)
#define GIZMO_MARGIN_OFFSET_SCALE
Definition: cage2d_gizmo.c:43
static bool gizmo_calc_rect_view_scale(const wmGizmo *gz, const float dims[2], float scale[2])
Definition: cage2d_gizmo.c:45
static int gizmo_cage2d_get_cursor(wmGizmo *gz)
Definition: cage2d_gizmo.c:729
static void cage2d_draw_box_interaction(const float color[4], const int highlighted, const float size[2], const float margin[2], const float line_width, const bool is_solid, const int draw_options)
Definition: cage2d_gizmo.c:141
static void cage2d_draw_box_corners(const rctf *r, const float margin[2], const float color[3], const float line_width)
Definition: cage2d_gizmo.c:97
static void cage2d_draw_circle_wire(const rctf *r, const float margin[2], const float color[3], const int transform_flag, const int draw_options, const float line_width)
Definition: cage2d_gizmo.c:475
static int gizmo_cage2d_modal(bContext *C, wmGizmo *gz, const wmEvent *event, eWM_GizmoFlagTweak UNUSED(tweak_flag))
Definition: cage2d_gizmo.c:961
static void gizmo_cage2d_draw(const bContext *UNUSED(C), wmGizmo *gz)
Definition: cage2d_gizmo.c:723
struct RectTransformInteraction RectTransformInteraction
static void gizmo_rect_pivot_from_scale_part(int part, float r_pt[2], bool r_constrain_axis[2])
Definition: cage2d_gizmo.c:910
static int gizmo_cage2d_test_select(bContext *C, wmGizmo *gz, const int mval[2])
Definition: cage2d_gizmo.c:761
static void imm_draw_point_aspect_2d(uint pos, float x, float y, float rad_x, float rad_y, bool solid)
Definition: cage2d_gizmo.c:441
static int gizmo_cage2d_invoke(bContext *C, wmGizmo *gz, const wmEvent *event)
Definition: cage2d_gizmo.c:892
#define MUL_V2_V3_M4_FINAL(test_co, mouse_co)
static void gizmo_cage2d_setup(wmGizmo *gz)
Definition: cage2d_gizmo.c:887
static void gizmo_cage2d_exit(bContext *C, wmGizmo *gz, const bool cancel)
static void gizmo_cage2d_draw_select(const bContext *UNUSED(C), wmGizmo *gz, int select_id)
Definition: cage2d_gizmo.c:718
void ED_gizmotypes_cage_2d(void)
static void gizmo_cage2d_draw_intern(wmGizmo *gz, const bool select, const bool highlight, const int select_id)
Definition: cage2d_gizmo.c:573
static bool gizmo_calc_rect_view_margin(const wmGizmo *gz, const float dims[2], float margin[2])
Definition: cage2d_gizmo.c:75
static void cage2d_draw_circle_handles(const rctf *r, const float margin[2], const float color[3], const int transform_flag, bool solid)
Definition: cage2d_gizmo.c:536
static void gizmo_cage2d_property_update(wmGizmo *gz, wmGizmoProperty *gz_prop)
SyclQueue void void size_t num_bytes void
static float verts[][3]
bool gizmo_window_project_2d(bContext *C, const struct wmGizmo *gz, const float mval[2], int axis, bool use_offset, float r_co[2])
void gizmo_color_get(const struct wmGizmo *gz, bool highlight, float r_color[4])
uint pos
struct @653::@656 attr_id
uint col
format
Definition: logImageCore.h:38
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:31
double sign(double arg)
Definition: utility.h:250
void RNA_float_get_array(PointerRNA *ptr, const char *name, float *values)
Definition: rna_access.c:4980
int RNA_enum_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:5004
PropertyRNA * RNA_def_enum_flag(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, int default_value, const char *ui_name, const char *ui_description)
Definition: rna_define.c:3806
PropertyRNA * RNA_def_float_vector(StructOrFunctionRNA *cont_, const char *identifier, int len, const float *default_value, float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax)
Definition: rna_define.c:3862
PropertyRNA * RNA_def_enum(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, int default_value, const char *ui_name, const char *ui_description)
Definition: rna_define.c:3783
float orig_matrix_offset[4][4]
Definition: cage2d_gizmo.c:882
float orig_matrix_final_no_offset[4][4]
Definition: cage2d_gizmo.c:883
float xmax
Definition: DNA_vec_types.h:69
float xmin
Definition: DNA_vec_types.h:69
float ymax
Definition: DNA_vec_types.h:70
float ymin
Definition: DNA_vec_types.h:70
int mval[2]
Definition: WM_types.h:684
short type
Definition: WM_types.h:678
eWM_GizmoFlagGroupTypeFlag flag
struct wmGizmoGroupType * type
const struct wmGizmoPropertyType * type
wmGizmoFnDraw draw
wmGizmoFnModal modal
wmGizmoFnSetup setup
const char * idname
wmGizmoFnTestSelect test_select
wmGizmoFnExit exit
wmGizmoFnCursorGet cursor_get
struct StructRNA * srna
wmGizmoFnInvoke invoke
wmGizmoFnDrawSelect draw_select
wmGizmoFnPropertyUpdate property_update
void * interaction_data
eWM_GizmoFlagState state
struct wmGizmoGroup * parent_gzgroup
int highlight_part
float matrix_offset[4][4]
float scale_final
float color[4]
struct PointerRNA * ptr
float matrix_space[4][4]
float line_width
eWM_GizmoFlag flag
@ WM_CURSOR_NSEW_SCROLL
Definition: wm_cursors.h:51
@ WM_CURSOR_CROSS
Definition: wm_cursors.h:26
@ WM_CURSOR_DEFAULT
Definition: wm_cursors.h:18
void WM_event_add_mousemove(wmWindow *win)
@ MOUSEMOVE
void WM_gizmo_calc_matrix_final(const wmGizmo *gz, float r_mat[4][4])
Definition: wm_gizmo.c:554
void WM_gizmo_calc_matrix_final_no_offset(const wmGizmo *gz, float r_mat[4][4])
Definition: wm_gizmo.c:539
wmGizmoProperty * WM_gizmo_target_property_find(wmGizmo *gz, const char *idname)
void WM_gizmo_target_property_float_get_array(const wmGizmo *gz, wmGizmoProperty *gz_prop, float *value)
void WM_gizmotype_target_property_def(wmGizmoType *gzt, const char *idname, int data_type, int array_length)
void WM_gizmo_target_property_float_set_array(bContext *C, const wmGizmo *gz, wmGizmoProperty *gz_prop, const float *value)
int WM_gizmo_target_property_array_length(const wmGizmo *UNUSED(gz), wmGizmoProperty *gz_prop)
void WM_gizmotype_append(void(*gtfunc)(struct wmGizmoType *))
Definition: wm_gizmo_type.c:93