Blender  V2.93
cage2d_gizmo.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2014 Blender Foundation.
17  * All rights reserved.
18  */
19 
31 #include "MEM_guardedalloc.h"
32 
33 #include "BLI_dial_2d.h"
34 #include "BLI_math.h"
35 #include "BLI_rect.h"
36 
37 #include "BKE_context.h"
38 
39 #include "GPU_immediate.h"
40 #include "GPU_immediate_util.h"
41 #include "GPU_matrix.h"
42 #include "GPU_select.h"
43 #include "GPU_shader.h"
44 #include "GPU_state.h"
45 
46 #include "RNA_access.h"
47 #include "RNA_define.h"
48 
49 #include "WM_api.h"
50 #include "WM_types.h"
51 
52 #include "ED_gizmo_library.h"
53 #include "ED_screen.h"
54 #include "ED_view3d.h"
55 
56 /* own includes */
57 #include "../gizmo_library_intern.h"
58 
59 #define GIZMO_MARGIN_OFFSET_SCALE 1.5f
60 
61 static bool gizmo_calc_rect_view_scale(const wmGizmo *gz, const float dims[2], float scale[2])
62 {
63  float matrix_final_no_offset[4][4];
64  float asp[2] = {1.0f, 1.0f};
65  if (dims[0] > dims[1]) {
66  asp[0] = dims[1] / dims[0];
67  }
68  else {
69  asp[1] = dims[0] / dims[1];
70  }
71  float x_axis[3], y_axis[3];
72  WM_gizmo_calc_matrix_final_no_offset(gz, matrix_final_no_offset);
73  mul_v3_mat3_m4v3(x_axis, matrix_final_no_offset, gz->matrix_offset[0]);
74  mul_v3_mat3_m4v3(y_axis, matrix_final_no_offset, gz->matrix_offset[1]);
75 
76  mul_v2_v2(x_axis, asp);
77  mul_v2_v2(y_axis, asp);
78 
79  float len_x_axis = len_v3(x_axis);
80  float len_y_axis = len_v3(y_axis);
81 
82  if (len_x_axis == 0.0f || len_y_axis == 0.0f) {
83  return false;
84  }
85 
86  scale[0] = 1.0f / len_x_axis;
87  scale[1] = 1.0f / len_y_axis;
88  return true;
89 }
90 
91 static bool gizmo_calc_rect_view_margin(const wmGizmo *gz, const float dims[2], float margin[2])
92 {
93  float handle_size;
94  handle_size = 0.15f;
95  handle_size *= gz->scale_final;
96  float scale_xy[2];
97  if (!gizmo_calc_rect_view_scale(gz, dims, scale_xy)) {
98  zero_v2(margin);
99  return false;
100  }
101  margin[0] = ((handle_size * scale_xy[0]));
102  margin[1] = ((handle_size * scale_xy[1]));
103  return true;
104 }
105 
106 /* -------------------------------------------------------------------- */
107 
108 static void gizmo_rect_pivot_from_scale_part(int part, float r_pt[2], bool r_constrain_axis[2])
109 {
110  bool x = true, y = true;
111  switch (part) {
113  ARRAY_SET_ITEMS(r_pt, 0.5, 0.0);
114  x = false;
115  break;
116  }
118  ARRAY_SET_ITEMS(r_pt, -0.5, 0.0);
119  x = false;
120  break;
121  }
123  ARRAY_SET_ITEMS(r_pt, 0.0, 0.5);
124  y = false;
125  break;
126  }
128  ARRAY_SET_ITEMS(r_pt, 0.0, -0.5);
129  y = false;
130  break;
131  }
133  ARRAY_SET_ITEMS(r_pt, 0.5, 0.5);
134  x = y = false;
135  break;
136  }
138  ARRAY_SET_ITEMS(r_pt, 0.5, -0.5);
139  x = y = false;
140  break;
141  }
143  ARRAY_SET_ITEMS(r_pt, -0.5, 0.5);
144  x = y = false;
145  break;
146  }
148  ARRAY_SET_ITEMS(r_pt, -0.5, -0.5);
149  x = y = false;
150  break;
151  }
152  default:
153  BLI_assert(0);
154  }
155  r_constrain_axis[0] = x;
156  r_constrain_axis[1] = y;
157 }
158 
159 /* -------------------------------------------------------------------- */
165 static void cage2d_draw_box_corners(const rctf *r,
166  const float margin[2],
167  const float color[3],
168  const float line_width)
169 {
171 
173  immUniformColor3fv(color);
174 
175  float viewport[4];
176  GPU_viewport_size_get_f(viewport);
177  immUniform2fv("viewportSize", &viewport[2]);
178 
179  immUniform1f("lineWidth", line_width * U.pixelsize);
180 
182 
183  immVertex2f(pos, r->xmin, r->ymin + margin[1]);
184  immVertex2f(pos, r->xmin, r->ymin);
185  immVertex2f(pos, r->xmin, r->ymin);
186  immVertex2f(pos, r->xmin + margin[0], r->ymin);
187 
188  immVertex2f(pos, r->xmax, r->ymin + margin[1]);
189  immVertex2f(pos, r->xmax, r->ymin);
190  immVertex2f(pos, r->xmax, r->ymin);
191  immVertex2f(pos, r->xmax - margin[0], r->ymin);
192 
193  immVertex2f(pos, r->xmax, r->ymax - margin[1]);
194  immVertex2f(pos, r->xmax, r->ymax);
195  immVertex2f(pos, r->xmax, r->ymax);
196  immVertex2f(pos, r->xmax - margin[0], r->ymax);
197 
198  immVertex2f(pos, r->xmin, r->ymax - margin[1]);
199  immVertex2f(pos, r->xmin, r->ymax);
200  immVertex2f(pos, r->xmin, r->ymax);
201  immVertex2f(pos, r->xmin + margin[0], r->ymax);
202 
203  immEnd();
204 
206 }
207 
208 static void cage2d_draw_box_interaction(const float color[4],
209  const int highlighted,
210  const float size[2],
211  const float margin[2],
212  const float line_width,
213  const bool is_solid,
214  const int draw_options)
215 {
216  /* 4 verts for translate, otherwise only 3 are used. */
217  float verts[4][2];
218  uint verts_len = 0;
219  GPUPrimType prim_type = GPU_PRIM_NONE;
220 
221  switch (highlighted) {
223  rctf r = {
224  .xmin = -size[0],
225  .xmax = -size[0] + margin[0],
226  .ymin = -size[1] + margin[1],
227  .ymax = size[1] - margin[1],
228  };
229  ARRAY_SET_ITEMS(verts[0], r.xmin, r.ymin);
230  ARRAY_SET_ITEMS(verts[1], r.xmin, r.ymax);
231  verts_len = 2;
232  if (is_solid) {
233  ARRAY_SET_ITEMS(verts[2], r.xmax, r.ymax);
234  ARRAY_SET_ITEMS(verts[3], r.xmax, r.ymin);
235  verts_len += 2;
236  prim_type = GPU_PRIM_TRI_FAN;
237  }
238  else {
239  prim_type = GPU_PRIM_LINE_STRIP;
240  }
241  break;
242  }
244  rctf r = {
245  .xmin = size[0] - margin[0],
246  .xmax = size[0],
247  .ymin = -size[1] + margin[1],
248  .ymax = size[1] - margin[1],
249  };
250  ARRAY_SET_ITEMS(verts[0], r.xmax, r.ymin);
251  ARRAY_SET_ITEMS(verts[1], r.xmax, r.ymax);
252  verts_len = 2;
253  if (is_solid) {
254  ARRAY_SET_ITEMS(verts[2], r.xmin, r.ymax);
255  ARRAY_SET_ITEMS(verts[3], r.xmin, r.ymin);
256  verts_len += 2;
257  prim_type = GPU_PRIM_TRI_FAN;
258  }
259  else {
260  prim_type = GPU_PRIM_LINE_STRIP;
261  }
262  break;
263  }
265  rctf r = {
266  .xmin = -size[0] + margin[0],
267  .xmax = size[0] - margin[0],
268  .ymin = -size[1],
269  .ymax = -size[1] + margin[1],
270  };
271  ARRAY_SET_ITEMS(verts[0], r.xmin, r.ymin);
272  ARRAY_SET_ITEMS(verts[1], r.xmax, r.ymin);
273  verts_len = 2;
274  if (is_solid) {
275  ARRAY_SET_ITEMS(verts[2], r.xmax, r.ymax);
276  ARRAY_SET_ITEMS(verts[3], r.xmin, r.ymax);
277  verts_len += 2;
278  prim_type = GPU_PRIM_TRI_FAN;
279  }
280  else {
281  prim_type = GPU_PRIM_LINE_STRIP;
282  }
283  break;
284  }
286  rctf r = {
287  .xmin = -size[0] + margin[0],
288  .xmax = size[0] - margin[0],
289  .ymin = size[1] - margin[1],
290  .ymax = size[1],
291  };
292  ARRAY_SET_ITEMS(verts[0], r.xmin, r.ymax);
293  ARRAY_SET_ITEMS(verts[1], r.xmax, r.ymax);
294  verts_len = 2;
295  if (is_solid) {
296  ARRAY_SET_ITEMS(verts[2], r.xmax, r.ymin);
297  ARRAY_SET_ITEMS(verts[3], r.xmin, r.ymin);
298  verts_len += 2;
299  prim_type = GPU_PRIM_TRI_FAN;
300  }
301  else {
302  prim_type = GPU_PRIM_LINE_STRIP;
303  }
304  break;
305  }
307  rctf r = {
308  .xmin = -size[0],
309  .xmax = -size[0] + margin[0],
310  .ymin = -size[1],
311  .ymax = -size[1] + margin[1],
312  };
313  ARRAY_SET_ITEMS(verts[0], r.xmax, r.ymin);
314  ARRAY_SET_ITEMS(verts[1], r.xmax, r.ymax);
315  ARRAY_SET_ITEMS(verts[2], r.xmin, r.ymax);
316  verts_len = 3;
317  if (is_solid) {
318  ARRAY_SET_ITEMS(verts[3], r.xmin, r.ymin);
319  verts_len += 1;
320  prim_type = GPU_PRIM_TRI_FAN;
321  }
322  else {
323  prim_type = GPU_PRIM_LINE_STRIP;
324  }
325  break;
326  }
328  rctf r = {
329  .xmin = -size[0],
330  .xmax = -size[0] + margin[0],
331  .ymin = size[1] - margin[1],
332  .ymax = size[1],
333  };
334  ARRAY_SET_ITEMS(verts[0], r.xmax, r.ymax);
335  ARRAY_SET_ITEMS(verts[1], r.xmax, r.ymin);
336  ARRAY_SET_ITEMS(verts[2], r.xmin, r.ymin);
337  verts_len = 3;
338  if (is_solid) {
339  ARRAY_SET_ITEMS(verts[3], r.xmin, r.ymax);
340  verts_len += 1;
341  prim_type = GPU_PRIM_TRI_FAN;
342  }
343  else {
344  prim_type = GPU_PRIM_LINE_STRIP;
345  }
346  break;
347  }
349  rctf r = {
350  .xmin = size[0] - margin[0],
351  .xmax = size[0],
352  .ymin = -size[1],
353  .ymax = -size[1] + margin[1],
354  };
355  ARRAY_SET_ITEMS(verts[0], r.xmin, r.ymin);
356  ARRAY_SET_ITEMS(verts[1], r.xmin, r.ymax);
357  ARRAY_SET_ITEMS(verts[2], r.xmax, r.ymax);
358  verts_len = 3;
359  if (is_solid) {
360  ARRAY_SET_ITEMS(verts[3], r.xmax, r.ymin);
361  verts_len += 1;
362  prim_type = GPU_PRIM_TRI_FAN;
363  }
364  else {
365  prim_type = GPU_PRIM_LINE_STRIP;
366  }
367  break;
368  }
370  rctf r = {
371  .xmin = size[0] - margin[0],
372  .xmax = size[0],
373  .ymin = size[1] - margin[1],
374  .ymax = size[1],
375  };
376  ARRAY_SET_ITEMS(verts[0], r.xmin, r.ymax);
377  ARRAY_SET_ITEMS(verts[1], r.xmin, r.ymin);
378  ARRAY_SET_ITEMS(verts[2], r.xmax, r.ymin);
379  verts_len = 3;
380  if (is_solid) {
381  ARRAY_SET_ITEMS(verts[3], r.xmax, r.ymax);
382  verts_len += 1;
383  prim_type = GPU_PRIM_TRI_FAN;
384  }
385  else {
386  prim_type = GPU_PRIM_LINE_STRIP;
387  }
388  break;
389  }
391  const float rotate_pt[2] = {0.0f, size[1] + margin[1]};
392  const rctf r_rotate = {
393  .xmin = rotate_pt[0] - margin[0] / 2.0f,
394  .xmax = rotate_pt[0] + margin[0] / 2.0f,
395  .ymin = rotate_pt[1] - margin[1] / 2.0f,
396  .ymax = rotate_pt[1] + margin[1] / 2.0f,
397  };
398 
399  ARRAY_SET_ITEMS(verts[0], r_rotate.xmin, r_rotate.ymin);
400  ARRAY_SET_ITEMS(verts[1], r_rotate.xmin, r_rotate.ymax);
401  ARRAY_SET_ITEMS(verts[2], r_rotate.xmax, r_rotate.ymax);
402  ARRAY_SET_ITEMS(verts[3], r_rotate.xmax, r_rotate.ymin);
403  verts_len = 4;
404  if (is_solid) {
405  prim_type = GPU_PRIM_TRI_FAN;
406  }
407  else {
408  prim_type = GPU_PRIM_LINE_STRIP;
409  }
410  break;
411  }
412 
415  ARRAY_SET_ITEMS(verts[0], -margin[0] / 2, -margin[1] / 2);
416  ARRAY_SET_ITEMS(verts[1], margin[0] / 2, margin[1] / 2);
417  ARRAY_SET_ITEMS(verts[2], -margin[0] / 2, margin[1] / 2);
418  ARRAY_SET_ITEMS(verts[3], margin[0] / 2, -margin[1] / 2);
419  verts_len = 4;
420  if (is_solid) {
421  prim_type = GPU_PRIM_TRI_FAN;
422  }
423  else {
424  prim_type = GPU_PRIM_LINES;
425  }
426  }
427  else {
428  /* Only used for 3D view selection, never displayed to the user. */
429  ARRAY_SET_ITEMS(verts[0], -size[0], -size[1]);
430  ARRAY_SET_ITEMS(verts[1], -size[0], size[1]);
431  ARRAY_SET_ITEMS(verts[2], size[0], size[1]);
432  ARRAY_SET_ITEMS(verts[3], size[0], -size[1]);
433  verts_len = 4;
434  if (is_solid) {
435  prim_type = GPU_PRIM_TRI_FAN;
436  }
437  else {
438  /* unreachable */
439  BLI_assert(0);
440  prim_type = GPU_PRIM_LINE_STRIP;
441  }
442  }
443  break;
444  default:
445  return;
446  }
447 
448  BLI_assert(prim_type != GPU_PRIM_NONE);
449 
451  struct {
452  uint pos, col;
453  } attr_id = {
456  };
458 
459  {
460  if (is_solid) {
461  BLI_assert(ELEM(prim_type, GPU_PRIM_TRI_FAN));
462  immBegin(prim_type, verts_len);
463  immAttr3f(attr_id.col, 0.0f, 0.0f, 0.0f);
464  for (uint i = 0; i < verts_len; i++) {
465  immVertex2fv(attr_id.pos, verts[i]);
466  }
467  immEnd();
468  }
469  else {
471 
472  float viewport[4];
473  GPU_viewport_size_get_f(viewport);
474  immUniform2fv("viewportSize", &viewport[2]);
475 
476  immUniform1f("lineWidth", (line_width * 3.0f) * U.pixelsize);
477 
478  immBegin(prim_type, verts_len);
479  immAttr3f(attr_id.col, 0.0f, 0.0f, 0.0f);
480  for (uint i = 0; i < verts_len; i++) {
481  immVertex2fv(attr_id.pos, verts[i]);
482  }
483  immEnd();
484 
485  immUniform1f("lineWidth", line_width * U.pixelsize);
486 
487  immBegin(prim_type, verts_len);
488  immAttr3fv(attr_id.col, color);
489  for (uint i = 0; i < verts_len; i++) {
490  immVertex2fv(attr_id.pos, verts[i]);
491  }
492  immEnd();
493  }
494  }
495 
497 }
498 
501 /* -------------------------------------------------------------------- */
508  uint pos, float x, float y, float rad_x, float rad_y, bool solid)
509 {
511  immVertex2f(pos, x - rad_x, y - rad_y);
512  immVertex2f(pos, x - rad_x, y + rad_y);
513  immVertex2f(pos, x + rad_x, y + rad_y);
514  immVertex2f(pos, x + rad_x, y - rad_y);
515  immEnd();
516 }
517 
518 static void cage2d_draw_circle_wire(const rctf *r,
519  const float margin[2],
520  const float color[3],
521  const int transform_flag,
522  const int draw_options,
523  const float line_width)
524 {
526 
528  immUniformColor3fv(color);
529 
530  float viewport[4];
531  GPU_viewport_size_get_f(viewport);
532  immUniform2fv("viewportSize", &viewport[2]);
533  immUniform1f("lineWidth", line_width * U.pixelsize);
534 
536  immVertex2f(pos, r->xmin, r->ymin);
537  immVertex2f(pos, r->xmax, r->ymin);
538  immVertex2f(pos, r->xmax, r->ymax);
539  immVertex2f(pos, r->xmin, r->ymax);
540  immEnd();
541 
542  if (transform_flag & ED_GIZMO_CAGE2D_XFORM_FLAG_ROTATE) {
544  immVertex2f(pos, BLI_rctf_cent_x(r), r->ymax);
545  immVertex2f(pos, BLI_rctf_cent_x(r), r->ymax + margin[1]);
546  immEnd();
547  }
548 
549  if (transform_flag & ED_GIZMO_CAGE2D_XFORM_FLAG_TRANSLATE) {
551  const float rad[2] = {margin[0] / 2, margin[1] / 2};
552  const float center[2] = {BLI_rctf_cent_x(r), BLI_rctf_cent_y(r)};
553 
555  immVertex2f(pos, center[0] - rad[0], center[1] - rad[1]);
556  immVertex2f(pos, center[0] + rad[0], center[1] + rad[1]);
557  immVertex2f(pos, center[0] + rad[0], center[1] - rad[1]);
558  immVertex2f(pos, center[0] - rad[0], center[1] + rad[1]);
559  immEnd();
560  }
561  }
562 
564 }
565 
566 static void cage2d_draw_circle_handles(const rctf *r,
567  const float margin[2],
568  const float color[3],
569  const int transform_flag,
570  bool solid)
571 {
573  void (*circle_fn)(uint, float, float, float, float, int) = (solid) ?
576  const int resolu = 12;
577  const float rad[2] = {margin[0] / 3, margin[1] / 3};
578 
580  immUniformColor3fv(color);
581 
582  /* should really divide by two, but looks too bulky. */
583  {
584  imm_draw_point_aspect_2d(pos, r->xmin, r->ymin, rad[0], rad[1], solid);
585  imm_draw_point_aspect_2d(pos, r->xmax, r->ymin, rad[0], rad[1], solid);
586  imm_draw_point_aspect_2d(pos, r->xmax, r->ymax, rad[0], rad[1], solid);
587  imm_draw_point_aspect_2d(pos, r->xmin, r->ymax, rad[0], rad[1], solid);
588  }
589 
590  if (transform_flag & ED_GIZMO_CAGE2D_XFORM_FLAG_ROTATE) {
591  const float handle[2] = {
593  r->ymax + (margin[1] * GIZMO_MARGIN_OFFSET_SCALE),
594  };
595  circle_fn(pos, handle[0], handle[1], rad[0], rad[1], resolu);
596  }
597 
599 }
600 
604  const bool select,
605  const bool highlight,
606  const int select_id)
607 {
608  // const bool use_clamp = (gz->parent_gzgroup->type->flag & WM_GIZMOGROUPTYPE_3D) == 0;
609  float dims[2];
610  RNA_float_get_array(gz->ptr, "dimensions", dims);
611  float matrix_final[4][4];
612 
613  const int transform_flag = RNA_enum_get(gz->ptr, "transform");
614  const int draw_style = RNA_enum_get(gz->ptr, "draw_style");
615  const int draw_options = RNA_enum_get(gz->ptr, "draw_options");
616 
617  const float size_real[2] = {dims[0] / 2.0f, dims[1] / 2.0f};
618 
619  WM_gizmo_calc_matrix_final(gz, matrix_final);
620 
621  GPU_matrix_push();
622  GPU_matrix_mul(matrix_final);
623 
624  float margin[2];
625  gizmo_calc_rect_view_margin(gz, dims, margin);
626 
627  /* Handy for quick testing draw (if it's outside bounds). */
628  if (false) {
632  immUniformColor4fv((const float[4]){1, 1, 1, 0.5f});
633  float s = 0.5f;
634  immRectf(pos, -s, -s, s, s);
637  }
638 
639  if (select) {
640  /* Expand for hot-spot. */
641  const float size[2] = {size_real[0] + margin[0] / 2, size_real[1] + margin[1] / 2};
642 
643  if (transform_flag & ED_GIZMO_CAGE2D_XFORM_FLAG_SCALE) {
644  int scale_parts[] = {
649 
654  };
655  for (int i = 0; i < ARRAY_SIZE(scale_parts); i++) {
656  GPU_select_load_id(select_id | scale_parts[i]);
658  gz->color, scale_parts[i], size, margin, gz->line_width, true, draw_options);
659  }
660  }
661  if (transform_flag & ED_GIZMO_CAGE2D_XFORM_FLAG_TRANSLATE) {
662  const int transform_part = ED_GIZMO_CAGE2D_PART_TRANSLATE;
663  GPU_select_load_id(select_id | transform_part);
665  gz->color, transform_part, size, margin, gz->line_width, true, draw_options);
666  }
667  if (transform_flag & ED_GIZMO_CAGE2D_XFORM_FLAG_ROTATE) {
670  size_real,
671  margin,
672  gz->line_width,
673  true,
674  draw_options);
675  }
676  }
677  else {
678  const rctf r = {
679  .xmin = -size_real[0],
680  .ymin = -size_real[1],
681  .xmax = size_real[0],
682  .ymax = size_real[1],
683  };
684  if (draw_style == ED_GIZMO_CAGE2D_STYLE_BOX) {
685  float color[4], black[3] = {0, 0, 0};
686  gizmo_color_get(gz, highlight, color);
687 
688  /* corner gizmos */
689  cage2d_draw_box_corners(&r, margin, black, gz->line_width + 3.0f);
690 
691  /* corner gizmos */
692  cage2d_draw_box_corners(&r, margin, color, gz->line_width);
693 
694  bool show = false;
696  /* Only show if we're drawing the center handle
697  * otherwise the entire rectangle is the hot-spot. */
699  show = true;
700  }
701  }
702  else {
703  show = true;
704  }
705 
706  if (show) {
708  gz->color, gz->highlight_part, size_real, margin, gz->line_width, false, draw_options);
709  }
710 
711  if (transform_flag & ED_GIZMO_CAGE2D_XFORM_FLAG_ROTATE) {
714  size_real,
715  margin,
716  gz->line_width,
717  false,
718  draw_options);
719  }
720  }
721  else if (draw_style == ED_GIZMO_CAGE2D_STYLE_CIRCLE) {
722  float color[4], black[3] = {0, 0, 0};
723  gizmo_color_get(gz, highlight, color);
724 
726 
727  float outline_line_width = gz->line_width + 3.0f;
728  cage2d_draw_circle_wire(&r, margin, black, transform_flag, draw_options, outline_line_width);
729  cage2d_draw_circle_wire(&r, margin, color, transform_flag, draw_options, gz->line_width);
730 
731  /* corner gizmos */
732  cage2d_draw_circle_handles(&r, margin, color, transform_flag, true);
733  cage2d_draw_circle_handles(&r, margin, (const float[3]){0, 0, 0}, transform_flag, false);
734 
736  }
737  else {
738  BLI_assert(0);
739  }
740  }
741 
742  GPU_matrix_pop();
743 }
744 
748 static void gizmo_cage2d_draw_select(const bContext *UNUSED(C), wmGizmo *gz, int select_id)
749 {
750  gizmo_cage2d_draw_intern(gz, true, false, select_id);
751 }
752 
753 static void gizmo_cage2d_draw(const bContext *UNUSED(C), wmGizmo *gz)
754 {
755  const bool is_highlight = (gz->state & WM_GIZMO_STATE_HIGHLIGHT) != 0;
756  gizmo_cage2d_draw_intern(gz, false, is_highlight, -1);
757 }
758 
760 {
761  int highlight_part = gz->highlight_part;
762 
764  return WM_CURSOR_NSEW_SCROLL;
765  }
766 
767  switch (highlight_part) {
769  return WM_CURSOR_NSEW_SCROLL;
772  return WM_CURSOR_X_MOVE;
775  return WM_CURSOR_Y_MOVE;
776 
777  /* TODO diagonal cursor */
780  return WM_CURSOR_NSEW_SCROLL;
783  return WM_CURSOR_NSEW_SCROLL;
785  return WM_CURSOR_CROSS;
786  default:
787  return WM_CURSOR_DEFAULT;
788  }
789 }
790 
791 static int gizmo_cage2d_test_select(bContext *C, wmGizmo *gz, const int mval[2])
792 {
793  float point_local[2];
794  float dims[2];
795  RNA_float_get_array(gz->ptr, "dimensions", dims);
796  const float size_real[2] = {dims[0] / 2.0f, dims[1] / 2.0f};
797 
798  if (gizmo_window_project_2d(C, gz, (const float[2]){UNPACK2(mval)}, 2, true, point_local) ==
799  false) {
800  return -1;
801  }
802 
803  float margin[2];
804  if (!gizmo_calc_rect_view_margin(gz, dims, margin)) {
805  return -1;
806  }
807 
808  /* Expand for hots-pot. */
809  const float size[2] = {size_real[0] + margin[0] / 2, size_real[1] + margin[1] / 2};
810 
811  const int transform_flag = RNA_enum_get(gz->ptr, "transform");
812  const int draw_options = RNA_enum_get(gz->ptr, "draw_options");
813 
814  if (transform_flag & ED_GIZMO_CAGE2D_XFORM_FLAG_TRANSLATE) {
815  rctf r;
817  r.xmin = -margin[0] / 2;
818  r.ymin = -margin[1] / 2;
819  r.xmax = margin[0] / 2;
820  r.ymax = margin[1] / 2;
821  }
822  else {
823  r.xmin = -size[0] + margin[0];
824  r.ymin = -size[1] + margin[1];
825  r.xmax = size[0] - margin[0];
826  r.ymax = size[1] - margin[1];
827  }
828  bool isect = BLI_rctf_isect_pt_v(&r, point_local);
829  if (isect) {
831  }
832  }
833 
834  /* if gizmo does not have a scale intersection, don't do it */
835  if (transform_flag &
837  const rctf r_xmin = {
838  .xmin = -size[0],
839  .ymin = -size[1],
840  .xmax = -size[0] + margin[0],
841  .ymax = size[1],
842  };
843  const rctf r_xmax = {
844  .xmin = size[0] - margin[0],
845  .ymin = -size[1],
846  .xmax = size[0],
847  .ymax = size[1],
848  };
849  const rctf r_ymin = {
850  .xmin = -size[0],
851  .ymin = -size[1],
852  .xmax = size[0],
853  .ymax = -size[1] + margin[1],
854  };
855  const rctf r_ymax = {
856  .xmin = -size[0],
857  .ymin = size[1] - margin[1],
858  .xmax = size[0],
859  .ymax = size[1],
860  };
861 
862  if (BLI_rctf_isect_pt_v(&r_xmin, point_local)) {
863  if (BLI_rctf_isect_pt_v(&r_ymin, point_local)) {
865  }
866  if (BLI_rctf_isect_pt_v(&r_ymax, point_local)) {
868  }
870  }
871  if (BLI_rctf_isect_pt_v(&r_xmax, point_local)) {
872  if (BLI_rctf_isect_pt_v(&r_ymin, point_local)) {
874  }
875  if (BLI_rctf_isect_pt_v(&r_ymax, point_local)) {
877  }
879  }
880  if (BLI_rctf_isect_pt_v(&r_ymin, point_local)) {
882  }
883  if (BLI_rctf_isect_pt_v(&r_ymax, point_local)) {
885  }
886  }
887 
888  if (transform_flag & ED_GIZMO_CAGE2D_XFORM_FLAG_ROTATE) {
889  /* Rotate:
890  * (*) <-- hot spot is here!
891  * +---+
892  * | |
893  * +---+ */
894  const float r_rotate_pt[2] = {0.0f, size_real[1] + (margin[1] * GIZMO_MARGIN_OFFSET_SCALE)};
895  const rctf r_rotate = {
896  .xmin = r_rotate_pt[0] - margin[0] / 2.0f,
897  .xmax = r_rotate_pt[0] + margin[0] / 2.0f,
898  .ymin = r_rotate_pt[1] - margin[1] / 2.0f,
899  .ymax = r_rotate_pt[1] + margin[1] / 2.0f,
900  };
901 
902  if (BLI_rctf_isect_pt_v(&r_rotate, point_local)) {
904  }
905  }
906 
907  return -1;
908 }
909 
910 typedef struct RectTransformInteraction {
911  float orig_mouse[2];
912  float orig_matrix_offset[4][4];
916 
917 static void gizmo_cage2d_setup(wmGizmo *gz)
918 {
920 }
921 
922 static int gizmo_cage2d_invoke(bContext *C, wmGizmo *gz, const wmEvent *event)
923 {
925  "cage_interaction");
926 
927  copy_m4_m4(data->orig_matrix_offset, gz->matrix_offset);
928  WM_gizmo_calc_matrix_final_no_offset(gz, data->orig_matrix_final_no_offset);
929 
931  C, gz, (const float[2]){UNPACK2(event->mval)}, 2, false, data->orig_mouse) == 0) {
932  zero_v2(data->orig_mouse);
933  }
934 
935  gz->interaction_data = data;
936 
937  return OPERATOR_RUNNING_MODAL;
938 }
939 
941  wmGizmo *gz,
942  const wmEvent *event,
943  eWM_GizmoFlagTweak UNUSED(tweak_flag))
944 {
945  if (event->type != MOUSEMOVE) {
946  return OPERATOR_RUNNING_MODAL;
947  }
948  /* For transform logic to be manageable we operate in -0.5..0.5 2D space,
949  * no matter the size of the rectangle, mouse coords are scaled to unit space.
950  * The mouse coords have been projected into the matrix
951  * so we don't need to worry about axis alignment.
952  *
953  * - The cursor offset are multiplied by 'dims'.
954  * - Matrix translation is also multiplied by 'dims'.
955  */
957  float point_local[2];
958 
959  float dims[2];
960  RNA_float_get_array(gz->ptr, "dimensions", dims);
961 
962  {
963  float matrix_back[4][4];
964  copy_m4_m4(matrix_back, gz->matrix_offset);
965  copy_m4_m4(gz->matrix_offset, data->orig_matrix_offset);
966 
967  bool ok = gizmo_window_project_2d(
968  C, gz, (const float[2]){UNPACK2(event->mval)}, 2, false, point_local);
969  copy_m4_m4(gz->matrix_offset, matrix_back);
970  if (!ok) {
971  return OPERATOR_RUNNING_MODAL;
972  }
973  }
974 
975  const int transform_flag = RNA_enum_get(gz->ptr, "transform");
976  wmGizmoProperty *gz_prop;
977 
978  gz_prop = WM_gizmo_target_property_find(gz, "matrix");
979  if (gz_prop->type != NULL) {
981  }
982 
984  /* do this to prevent clamping from changing size */
985  copy_m4_m4(gz->matrix_offset, data->orig_matrix_offset);
986  gz->matrix_offset[3][0] = data->orig_matrix_offset[3][0] +
987  (point_local[0] - data->orig_mouse[0]);
988  gz->matrix_offset[3][1] = data->orig_matrix_offset[3][1] +
989  (point_local[1] - data->orig_mouse[1]);
990  }
992 
993 #define MUL_V2_V3_M4_FINAL(test_co, mouse_co) \
994  mul_v3_m4v3( \
995  test_co, data->orig_matrix_final_no_offset, ((const float[3]){UNPACK2(mouse_co), 0.0}))
996 
997  float test_co[3];
998 
999  if (data->dial == NULL) {
1000  MUL_V2_V3_M4_FINAL(test_co, data->orig_matrix_offset[3]);
1001 
1002  data->dial = BLI_dial_init(test_co, FLT_EPSILON);
1003 
1004  MUL_V2_V3_M4_FINAL(test_co, data->orig_mouse);
1005  BLI_dial_angle(data->dial, test_co);
1006  }
1007 
1008  /* rotate */
1009  MUL_V2_V3_M4_FINAL(test_co, point_local);
1010  const float angle = BLI_dial_angle(data->dial, test_co);
1011 
1012  float matrix_space_inv[4][4];
1013  float matrix_rotate[4][4];
1014  float pivot[3];
1015 
1016  copy_v3_v3(pivot, data->orig_matrix_offset[3]);
1017 
1018  invert_m4_m4(matrix_space_inv, gz->matrix_space);
1019 
1020  unit_m4(matrix_rotate);
1021  mul_m4_m4m4(matrix_rotate, matrix_rotate, matrix_space_inv);
1022  rotate_m4(matrix_rotate, 'Z', -angle);
1023  mul_m4_m4m4(matrix_rotate, matrix_rotate, gz->matrix_space);
1024 
1025  zero_v3(matrix_rotate[3]);
1026  transform_pivot_set_m4(matrix_rotate, pivot);
1027 
1028  mul_m4_m4m4(gz->matrix_offset, matrix_rotate, data->orig_matrix_offset);
1029 
1030 #undef MUL_V2_V3_M4_FINAL
1031  }
1032  else {
1033  /* scale */
1034  copy_m4_m4(gz->matrix_offset, data->orig_matrix_offset);
1035  float pivot[2];
1036  bool constrain_axis[2] = {false};
1037 
1038  if (transform_flag & ED_GIZMO_CAGE2D_XFORM_FLAG_TRANSLATE) {
1039  gizmo_rect_pivot_from_scale_part(gz->highlight_part, pivot, constrain_axis);
1040  }
1041  else {
1042  zero_v2(pivot);
1043  }
1044 
1045  /* Cursor deltas scaled to (-0.5..0.5). */
1046  float delta_orig[2], delta_curr[2];
1047  for (int i = 0; i < 2; i++) {
1048  delta_orig[i] = ((data->orig_mouse[i] - data->orig_matrix_offset[3][i]) / dims[i]) -
1049  pivot[i];
1050  delta_curr[i] = ((point_local[i] - data->orig_matrix_offset[3][i]) / dims[i]) - pivot[i];
1051  }
1052 
1053  float scale[2] = {1.0f, 1.0f};
1054  for (int i = 0; i < 2; i++) {
1055  if (constrain_axis[i] == false) {
1056  if (delta_orig[i] < 0.0f) {
1057  delta_orig[i] *= -1.0f;
1058  delta_curr[i] *= -1.0f;
1059  }
1060  const int sign = signum_i(scale[i]);
1061 
1062  scale[i] = 1.0f + ((delta_curr[i] - delta_orig[i]) / len_v3(data->orig_matrix_offset[i]));
1063 
1064  if ((transform_flag & ED_GIZMO_CAGE2D_XFORM_FLAG_SCALE_SIGNED) == 0) {
1065  if (sign != signum_i(scale[i])) {
1066  scale[i] = 0.0f;
1067  }
1068  }
1069  }
1070  }
1071 
1072  if (transform_flag & ED_GIZMO_CAGE2D_XFORM_FLAG_SCALE_UNIFORM) {
1073  if (constrain_axis[0] == false && constrain_axis[1] == false) {
1074  scale[1] = scale[0] = (scale[1] + scale[0]) / 2.0f;
1075  }
1076  else if (constrain_axis[0] == false) {
1077  scale[1] = scale[0];
1078  }
1079  else if (constrain_axis[1] == false) {
1080  scale[0] = scale[1];
1081  }
1082  else {
1083  BLI_assert(0);
1084  }
1085  }
1086 
1087  /* scale around pivot */
1088  float matrix_scale[4][4];
1089  unit_m4(matrix_scale);
1090 
1091  mul_v3_fl(matrix_scale[0], scale[0]);
1092  mul_v3_fl(matrix_scale[1], scale[1]);
1093 
1094  transform_pivot_set_m4(matrix_scale,
1095  (const float[3]){pivot[0] * dims[0], pivot[1] * dims[1], 0.0f});
1096  mul_m4_m4m4(gz->matrix_offset, data->orig_matrix_offset, matrix_scale);
1097  }
1098 
1099  if (gz_prop->type != NULL) {
1100  WM_gizmo_target_property_float_set_array(C, gz, gz_prop, &gz->matrix_offset[0][0]);
1101  }
1102 
1103  /* tag the region for redraw */
1106 
1107  return OPERATOR_RUNNING_MODAL;
1108 }
1109 
1111 {
1112  if (STREQ(gz_prop->type->idname, "matrix")) {
1113  if (WM_gizmo_target_property_array_length(gz, gz_prop) == 16) {
1115  }
1116  else {
1117  BLI_assert(0);
1118  }
1119  }
1120  else {
1121  BLI_assert(0);
1122  }
1123 }
1124 
1125 static void gizmo_cage2d_exit(bContext *C, wmGizmo *gz, const bool cancel)
1126 {
1128 
1129  MEM_SAFE_FREE(data->dial);
1130 
1131  if (!cancel) {
1132  return;
1133  }
1134 
1135  wmGizmoProperty *gz_prop;
1136 
1137  /* reset properties */
1138  gz_prop = WM_gizmo_target_property_find(gz, "matrix");
1139  if (gz_prop->type != NULL) {
1140  WM_gizmo_target_property_float_set_array(C, gz, gz_prop, &data->orig_matrix_offset[0][0]);
1141  }
1142 
1143  copy_m4_m4(gz->matrix_offset, data->orig_matrix_offset);
1144 }
1145 
1146 /* -------------------------------------------------------------------- */
1151 {
1152  /* identifiers */
1153  gzt->idname = "GIZMO_GT_cage_2d";
1154 
1155  /* api callbacks */
1156  gzt->draw = gizmo_cage2d_draw;
1159  gzt->setup = gizmo_cage2d_setup;
1160  gzt->invoke = gizmo_cage2d_invoke;
1162  gzt->modal = gizmo_cage2d_modal;
1163  gzt->exit = gizmo_cage2d_exit;
1165 
1166  gzt->struct_size = sizeof(wmGizmo);
1167 
1168  /* rna */
1169  static EnumPropertyItem rna_enum_draw_style[] = {
1170  {ED_GIZMO_CAGE2D_STYLE_BOX, "BOX", 0, "Box", ""},
1171  {ED_GIZMO_CAGE2D_STYLE_CIRCLE, "CIRCLE", 0, "Circle", ""},
1172  {0, NULL, 0, NULL, NULL},
1173  };
1174  static EnumPropertyItem rna_enum_transform[] = {
1175  {ED_GIZMO_CAGE2D_XFORM_FLAG_TRANSLATE, "TRANSLATE", 0, "Move", ""},
1176  {ED_GIZMO_CAGE2D_XFORM_FLAG_ROTATE, "ROTATE", 0, "Rotate", ""},
1177  {ED_GIZMO_CAGE2D_XFORM_FLAG_SCALE, "SCALE", 0, "Scale", ""},
1178  {ED_GIZMO_CAGE2D_XFORM_FLAG_SCALE_UNIFORM, "SCALE_UNIFORM", 0, "Scale Uniform", ""},
1179  {0, NULL, 0, NULL, NULL},
1180  };
1181  static EnumPropertyItem rna_enum_draw_options[] = {
1183  "XFORM_CENTER_HANDLE",
1184  0,
1185  "Center Handle",
1186  ""},
1187  {0, NULL, 0, NULL, NULL},
1188  };
1189  static float unit_v2[2] = {1.0f, 1.0f};
1191  gzt->srna, "dimensions", 2, unit_v2, 0, FLT_MAX, "Dimensions", "", 0.0f, FLT_MAX);
1192  RNA_def_enum_flag(gzt->srna, "transform", rna_enum_transform, 0, "Transform Options", "");
1193  RNA_def_enum(gzt->srna,
1194  "draw_style",
1195  rna_enum_draw_style,
1197  "Draw Style",
1198  "");
1199  RNA_def_enum_flag(gzt->srna,
1200  "draw_options",
1201  rna_enum_draw_options,
1203  "Draw Options",
1204  "");
1205 
1206  WM_gizmotype_target_property_def(gzt, "matrix", PROP_FLOAT, 16);
1207 }
1208 
1210 {
1212 }
1213 
typedef float(TangentPoint)[2]
struct ARegion * CTX_wm_region(const bContext *C)
Definition: context.c:725
struct wmWindow * CTX_wm_window(const bContext *C)
Definition: context.c:699
#define BLI_assert(a)
Definition: BLI_assert.h:58
Dial * BLI_dial_init(const float start_position[2], float threshold)
Definition: BLI_dial_2d.c:48
float BLI_dial_angle(Dial *dial, const float current_position[2])
Definition: BLI_dial_2d.c:58
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:262
void unit_m4(float m[4][4])
Definition: rct.c:1140
bool invert_m4_m4(float R[4][4], const float A[4][4])
Definition: math_matrix.c:1278
void transform_pivot_set_m4(float mat[4][4], const float pivot[3])
Definition: math_matrix.c:2411
void copy_m4_m4(float m1[4][4], const float m2[4][4])
Definition: math_matrix.c:95
void mul_v3_mat3_m4v3(float r[3], const float M[4][4], const float v[3])
Definition: math_matrix.c:804
void rotate_m4(float mat[4][4], const char axis, const float angle)
Definition: math_matrix.c:2352
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:148
BLI_INLINE float BLI_rctf_cent_x(const struct rctf *rct)
Definition: BLI_rect.h:144
unsigned int uint
Definition: BLI_sys_types.h:83
#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:706
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 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 rad_x, float rad_y, int nsegments)
void imm_draw_circle_wire_aspect_2d(uint shdr_pos, float x, float y, float rad_x, float rad_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:142
#define GPU_matrix_mul(x)
Definition: GPU_matrix.h:223
void GPU_matrix_push(void)
Definition: gpu_matrix.cc:135
GPUPrimType
Definition: GPU_primitive.h:34
@ GPU_PRIM_TRI_FAN
Definition: GPU_primitive.h:41
@ GPU_PRIM_LINE_LOOP
Definition: GPU_primitive.h:39
@ GPU_PRIM_NONE
Definition: GPU_primitive.h:47
@ GPU_PRIM_LINES
Definition: GPU_primitive.h:36
@ GPU_PRIM_LINE_STRIP
Definition: GPU_primitive.h:38
bool GPU_select_load_id(unsigned int id)
Definition: gpu_select.c:108
@ GPU_SHADER_3D_POLYLINE_UNIFORM_COLOR
Definition: GPU_shader.h:223
@ GPU_SHADER_2D_UNIFORM_COLOR
Definition: GPU_shader.h:171
@ GPU_SHADER_3D_POLYLINE_FLAT_COLOR
Definition: GPU_shader.h:232
@ GPU_SHADER_2D_FLAT_COLOR
Definition: GPU_shader.h:178
@ GPU_BLEND_NONE
Definition: GPU_state.h:55
@ GPU_BLEND_ALPHA
Definition: GPU_state.h:57
void GPU_blend(eGPUBlend blend)
Definition: gpu_state.cc:55
void GPU_viewport_size_get_f(float coords[4])
Definition: gpu_state.cc:279
@ 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)
@ PROP_FLOAT
Definition: RNA_types.h:75
#define C
Definition: RandGen.cpp:39
struct wmGizmo wmGizmo
Definition: WM_api.h:74
eWM_GizmoFlagTweak
Gizmo tweak flag. Bitflag passed to gizmo while tweaking.
@ WM_GIZMO_DRAW_NO_SCALE
@ WM_GIZMO_DRAW_MODAL
@ WM_GIZMOGROUPTYPE_3D
@ WM_GIZMO_STATE_HIGHLIGHT
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:59
static bool gizmo_calc_rect_view_scale(const wmGizmo *gz, const float dims[2], float scale[2])
Definition: cage2d_gizmo.c:61
static int gizmo_cage2d_get_cursor(wmGizmo *gz)
Definition: cage2d_gizmo.c:759
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:208
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:165
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:518
static int gizmo_cage2d_modal(bContext *C, wmGizmo *gz, const wmEvent *event, eWM_GizmoFlagTweak UNUSED(tweak_flag))
Definition: cage2d_gizmo.c:940
static void gizmo_cage2d_draw(const bContext *UNUSED(C), wmGizmo *gz)
Definition: cage2d_gizmo.c:753
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:108
static int gizmo_cage2d_test_select(bContext *C, wmGizmo *gz, const int mval[2])
Definition: cage2d_gizmo.c:791
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:507
static int gizmo_cage2d_invoke(bContext *C, wmGizmo *gz, const wmEvent *event)
Definition: cage2d_gizmo.c:922
#define MUL_V2_V3_M4_FINAL(test_co, mouse_co)
static void gizmo_cage2d_setup(wmGizmo *gz)
Definition: cage2d_gizmo.c:917
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:748
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:603
static bool gizmo_calc_rect_view_margin(const wmGizmo *gz, const float dims[2], float margin[2])
Definition: cage2d_gizmo.c:91
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:566
static void gizmo_cage2d_property_update(wmGizmo *gz, wmGizmoProperty *gz_prop)
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, const bool highlight, float r_color[4])
uint pos
struct @612::@615 attr_id
uint col
format
Definition: logImageCore.h:47
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
double sign(double arg)
Definition: utility.h:250
void RNA_float_get_array(PointerRNA *ptr, const char *name, float *values)
Definition: rna_access.c:6378
int RNA_enum_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6402
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:3795
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:3851
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:3771
float orig_matrix_offset[4][4]
Definition: cage2d_gizmo.c:912
float orig_matrix_final_no_offset[4][4]
Definition: cage2d_gizmo.c:913
float xmax
Definition: DNA_vec_types.h:85
float xmin
Definition: DNA_vec_types.h:85
float ymax
Definition: DNA_vec_types.h:86
float ymin
Definition: DNA_vec_types.h:86
int mval[2]
Definition: WM_types.h:583
short type
Definition: WM_types.h:577
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
__forceinline const avxb select(const avxb &m, const avxb &t, const avxb &f)
Definition: util_avxb.h:167
@ WM_CURSOR_NSEW_SCROLL
Definition: wm_cursors.h:67
@ WM_CURSOR_CROSS
Definition: wm_cursors.h:42
@ WM_CURSOR_DEFAULT
Definition: wm_cursors.h:34
@ WM_CURSOR_Y_MOVE
Definition: wm_cursors.h:55
@ WM_CURSOR_X_MOVE
Definition: wm_cursors.h:54
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:601
void WM_gizmo_calc_matrix_final_no_offset(const wmGizmo *gz, float r_mat[4][4])
Definition: wm_gizmo.c:586
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 *))