Blender  V3.3
transform_constraints.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2001-2002 NaN Holding BV. All rights reserved. */
3 
8 #include <math.h>
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 
13 #include "DNA_object_types.h"
14 #include "DNA_scene_types.h"
15 #include "DNA_screen_types.h"
16 #include "DNA_space_types.h"
17 #include "DNA_view3d_types.h"
18 
19 #include "GPU_immediate.h"
20 #include "GPU_matrix.h"
21 #include "GPU_state.h"
22 
23 #include "BLI_math.h"
24 #include "BLI_rect.h"
25 #include "BLI_string.h"
26 #include "BLI_utildefines.h"
27 
28 #include "BKE_context.h"
29 
30 #include "ED_view3d.h"
31 
32 #include "BLT_translation.h"
33 
34 #include "UI_resources.h"
35 #include "UI_view2d.h"
36 
37 #include "transform.h"
38 #include "transform_orientations.h"
39 #include "transform_snap.h"
40 
41 /* Own include. */
42 #include "transform_constraints.h"
43 
44 static void drawObjectConstraint(TransInfo *t);
45 
46 /* -------------------------------------------------------------------- */
50 static void projection_matrix_calc(const TransInfo *t, float r_pmtx[3][3])
51 {
52  unit_m3(r_pmtx);
53 
54  if (!(t->con.mode & CON_AXIS0)) {
55  zero_v3(r_pmtx[0]);
56  }
57 
58  if (!(t->con.mode & CON_AXIS1)) {
59  zero_v3(r_pmtx[1]);
60  }
61 
62  if (!(t->con.mode & CON_AXIS2)) {
63  zero_v3(r_pmtx[2]);
64  }
65 
66  float mat[3][3];
67  mul_m3_m3m3(mat, r_pmtx, t->spacemtx_inv);
68  mul_m3_m3m3(r_pmtx, t->spacemtx, mat);
69 }
70 
71 static void view_vector_calc(const TransInfo *t, const float focus[3], float r_vec[3])
72 {
73  if (t->persp != RV3D_ORTHO) {
74  sub_v3_v3v3(r_vec, t->viewinv[3], focus);
75  }
76  else {
77  copy_v3_v3(r_vec, t->viewinv[2]);
78  }
79  normalize_v3(r_vec);
80 }
81 
82 /* ************************** CONSTRAINTS ************************* */
83 #define CONSTRAIN_EPSILON 0.0001f
84 
85 static void constraint_plane_calc(const TransInfo *t, float r_plane[4])
86 {
87  const float *constraint_vector[2];
88  int n = 0;
89  for (int i = 0; i < 3; i++) {
90  if (t->con.mode & (CON_AXIS0 << i)) {
91  constraint_vector[n++] = t->spacemtx[i];
92  if (n == 2) {
93  break;
94  }
95  }
96  }
97  BLI_assert(n == 2);
98 
99  cross_v3_v3v3(r_plane, constraint_vector[0], constraint_vector[1]);
100  normalize_v3(r_plane);
101  r_plane[3] = -dot_v3v3(r_plane, t->center_global);
102 }
103 
104 void constraintNumInput(TransInfo *t, float vec[3])
105 {
106  int mode = t->con.mode;
107  if (mode & CON_APPLY) {
108  float nval = (t->flag & T_NULL_ONE) ? 1.0f : 0.0f;
109 
110  const int dims = getConstraintSpaceDimension(t);
111  if (dims == 2) {
112  int axis = mode & (CON_AXIS0 | CON_AXIS1 | CON_AXIS2);
113  if (axis == (CON_AXIS0 | CON_AXIS1)) {
114  /* vec[0] = vec[0]; */ /* same */
115  /* vec[1] = vec[1]; */ /* same */
116  vec[2] = nval;
117  }
118  else if (axis == (CON_AXIS1 | CON_AXIS2)) {
119  vec[2] = vec[1];
120  vec[1] = vec[0];
121  vec[0] = nval;
122  }
123  else if (axis == (CON_AXIS0 | CON_AXIS2)) {
124  /* vec[0] = vec[0]; */ /* same */
125  vec[2] = vec[1];
126  vec[1] = nval;
127  }
128  }
129  else if (dims == 1) {
130  if (mode & CON_AXIS0) {
131  /* vec[0] = vec[0]; */ /* same */
132  vec[1] = nval;
133  vec[2] = nval;
134  }
135  else if (mode & CON_AXIS1) {
136  vec[1] = vec[0];
137  vec[0] = nval;
138  vec[2] = nval;
139  }
140  else if (mode & CON_AXIS2) {
141  vec[2] = vec[0];
142  vec[0] = nval;
143  vec[1] = nval;
144  }
145  }
146  }
147 }
148 
149 static void viewAxisCorrectCenter(const TransInfo *t, float t_con_center[3])
150 {
151  if (t->spacetype == SPACE_VIEW3D) {
152  // View3D *v3d = t->area->spacedata.first;
153  const float min_dist = 1.0f; /* v3d->clip_start; */
154  float dir[3];
155  float l;
156 
157  sub_v3_v3v3(dir, t_con_center, t->viewinv[3]);
158  if (dot_v3v3(dir, t->viewinv[2]) < 0.0f) {
159  negate_v3(dir);
160  }
161  project_v3_v3v3(dir, dir, t->viewinv[2]);
162 
163  l = len_v3(dir);
164 
165  if (l < min_dist) {
166  float diff[3];
167  normalize_v3_v3_length(diff, t->viewinv[2], min_dist - l);
168  sub_v3_v3(t_con_center, diff);
169  }
170  }
171 }
172 
176 static void axisProjection(const TransInfo *t,
177  const float axis[3],
178  const float in[3],
179  float out[3])
180 {
181  float norm[3], vec[3], factor, angle;
182  float t_con_center[3];
183 
184  if (is_zero_v3(in)) {
185  return;
186  }
187 
188  copy_v3_v3(t_con_center, t->center_global);
189 
190  /* checks for center being too close to the view center */
191  viewAxisCorrectCenter(t, t_con_center);
192 
193  angle = fabsf(angle_v3v3(axis, t->viewinv[2]));
194  if (angle > (float)M_PI_2) {
195  angle = (float)M_PI - angle;
196  }
197 
198  /* For when view is parallel to constraint... will cause NaNs otherwise
199  * So we take vertical motion in 3D space and apply it to the
200  * constraint axis. Nice for camera grab + MMB */
201  if (angle < DEG2RADF(5.0f)) {
202  project_v3_v3v3(vec, in, t->viewinv[1]);
203  factor = dot_v3v3(t->viewinv[1], vec) * 2.0f;
204  /* Since camera distance is quite relative, use quadratic relationship.
205  * holding shift can compensate. */
206  if (factor < 0.0f) {
207  factor *= -factor;
208  }
209  else {
210  factor *= factor;
211  }
212 
213  /* -factor makes move down going backwards */
214  normalize_v3_v3_length(out, axis, -factor);
215  }
216  else {
217  float v[3];
218  float norm_center[3];
219  float plane[3];
220 
221  view_vector_calc(t, t_con_center, norm_center);
222  cross_v3_v3v3(plane, norm_center, axis);
223 
224  project_v3_v3v3(vec, in, plane);
225  sub_v3_v3v3(vec, in, vec);
226 
227  add_v3_v3v3(v, vec, t_con_center);
229 
230  /* give arbitrary large value if projection is impossible */
231  factor = dot_v3v3(axis, norm);
232  if (1.0f - fabsf(factor) < 0.0002f) {
233  copy_v3_v3(out, axis);
234  if (factor > 0) {
235  mul_v3_fl(out, 1000000000.0f);
236  }
237  else {
238  mul_v3_fl(out, -1000000000.0f);
239  }
240  }
241  else {
242  /* Use ray-ray intersection instead of line-line because this gave
243  * precision issues adding small values to large numbers. */
244  float mul;
245  if (isect_ray_ray_v3(t_con_center, axis, v, norm, &mul, NULL)) {
246  mul_v3_v3fl(out, axis, mul);
247  }
248  else {
249  /* In practice this should never fail. */
250  BLI_assert(0);
251  }
252 
253  /* possible some values become nan when
254  * viewpoint and object are both zero */
255  if (!isfinite(out[0])) {
256  out[0] = 0.0f;
257  }
258  if (!isfinite(out[1])) {
259  out[1] = 0.0f;
260  }
261  if (!isfinite(out[2])) {
262  out[2] = 0.0f;
263  }
264  }
265  }
266 }
267 
271 static void constraint_snap_plane_to_edge(const TransInfo *t, const float plane[4], float r_out[3])
272 {
273  float lambda;
274  const float *edge_snap_point = t->tsnap.snapPoint;
275  const float *edge_dir = t->tsnap.snapNormal;
276  bool is_aligned = fabsf(dot_v3v3(edge_dir, plane)) < CONSTRAIN_EPSILON;
277  if (!is_aligned && isect_ray_plane_v3(edge_snap_point, edge_dir, plane, &lambda, false)) {
278  madd_v3_v3v3fl(r_out, edge_snap_point, edge_dir, lambda);
279  sub_v3_v3(r_out, t->tsnap.snapTarget);
280  }
281 }
282 
283 static void UNUSED_FUNCTION(constraint_snap_plane_to_face(const TransInfo *t,
284  const float plane[4],
285  float r_out[3]))
286 {
287  float face_plane[4], isect_orig[3], isect_dir[3];
288  const float *face_snap_point = t->tsnap.snapPoint;
289  const float *face_normal = t->tsnap.snapNormal;
290  plane_from_point_normal_v3(face_plane, face_snap_point, face_normal);
291  bool is_aligned = fabsf(dot_v3v3(plane, face_plane)) > (1.0f - CONSTRAIN_EPSILON);
292  if (!is_aligned && isect_plane_plane_v3(plane, face_plane, isect_orig, isect_dir)) {
293  closest_to_ray_v3(r_out, face_snap_point, isect_orig, isect_dir);
294  sub_v3_v3(r_out, t->tsnap.snapTarget);
295  }
296 }
297 
299  const float axis[3],
300  float r_out[3])
301 {
302  float lambda;
303  const float *edge_snap_point = t->tsnap.snapPoint;
304  const float *edge_dir = t->tsnap.snapNormal;
305  bool is_aligned = fabsf(dot_v3v3(axis, edge_dir)) > (1.0f - CONSTRAIN_EPSILON);
306  if (!is_aligned &&
307  isect_ray_ray_v3(t->tsnap.snapTarget, axis, edge_snap_point, edge_dir, &lambda, NULL)) {
308  mul_v3_v3fl(r_out, axis, lambda);
309  }
310 }
311 
313  const float axis[3],
314  float r_out[3])
315 {
316  float lambda;
317  float face_plane[4];
318  const float *face_snap_point = t->tsnap.snapPoint;
319  const float *face_normal = t->tsnap.snapNormal;
320  plane_from_point_normal_v3(face_plane, face_snap_point, face_normal);
321  bool is_aligned = fabsf(dot_v3v3(axis, face_plane)) < CONSTRAIN_EPSILON;
322  if (!is_aligned && isect_ray_plane_v3(t->tsnap.snapTarget, axis, face_plane, &lambda, false)) {
323  mul_v3_v3fl(r_out, axis, lambda);
324  }
325 }
326 
331 static bool isPlaneProjectionViewAligned(const TransInfo *t, const float plane[4])
332 {
333  const float eps = 0.001f;
334  float view_to_plane[3];
335  view_vector_calc(t, t->center_global, view_to_plane);
336 
337  float factor = dot_v3v3(plane, view_to_plane);
338  return fabsf(factor) < eps;
339 }
340 
341 static void planeProjection(const TransInfo *t,
342  const float plane[3],
343  const float in[3],
344  float out[3])
345 {
346 
347  float pos[3], view_vec[3], factor;
348 
349  add_v3_v3v3(pos, in, t->center_global);
350  view_vector_calc(t, pos, view_vec);
351 
352  if (isect_ray_plane_v3(pos, view_vec, plane, &factor, false)) {
353  madd_v3_v3v3fl(out, in, view_vec, factor);
354  }
355 }
356 
358 {
359  short orientation = t->orient[t->orient_curr].type;
360  if (orientation == V3D_ORIENT_CUSTOM_MATRIX) {
361  /* Use the real value of the "orient_type". */
362  orientation = t->orient[O_DEFAULT].type;
363  }
364  return orientation;
365 }
366 
368  const TransDataContainer *UNUSED(tc),
369  const TransData *td))[3]
370 {
372  BLI_assert(t->orient_type_mask & (1 << V3D_ORIENT_GIMBAL));
373  if (t->options & (CTX_POSE_BONE | CTX_OBJECT)) {
374  return td->ext->axismtx_gimbal;
375  }
376  }
377  return td->axismtx;
378 }
379 
387 static void applyAxisConstraintVec(const TransInfo *t,
388  const TransDataContainer *UNUSED(tc),
389  const TransData *td,
390  const float in[3],
391  float out[3])
392 {
393  copy_v3_v3(out, in);
394  if (!td && t->con.mode & CON_APPLY) {
395  bool is_snap_to_point = false, is_snap_to_edge = false, is_snap_to_face = false;
396 
397  if (activeSnap(t)) {
398  if (validSnap(t)) {
399  is_snap_to_edge = (t->tsnap.snapElem & SCE_SNAP_MODE_EDGE) != 0;
400  is_snap_to_face = (t->tsnap.snapElem & SCE_SNAP_MODE_FACE_RAYCAST) != 0;
401  is_snap_to_point = !is_snap_to_edge && !is_snap_to_face;
402  }
403  else if (t->tsnap.snapElem & SCE_SNAP_MODE_GRID) {
404  is_snap_to_point = true;
405  }
406  }
407 
408  /* Fallback for when axes are aligned. */
409  mul_m3_v3(t->con.pmtx, out);
410 
411  if (is_snap_to_point) {
412  /* Pass. With snap points, a projection is alright, no adjustments needed. */
413  }
414  else {
415  const int dims = getConstraintSpaceDimension(t);
416  if (dims == 2) {
417  if (!is_zero_v3(out)) {
418  float plane[4];
419  constraint_plane_calc(t, plane);
420 
421  if (is_snap_to_edge) {
423  }
424  else if (is_snap_to_face) {
425  /* Disabled, as it has not proven to be really useful. (See T82386). */
426  // constraint_snap_plane_to_face(t, plane, out);
427  }
428  else if (!isPlaneProjectionViewAligned(t, plane)) {
429  /* View alignment correction. */
430  planeProjection(t, plane, in, out);
431  }
432  }
433  }
434  else if (dims == 1) {
435  float c[3];
436 
437  if (t->con.mode & CON_AXIS0) {
438  copy_v3_v3(c, t->spacemtx[0]);
439  }
440  else if (t->con.mode & CON_AXIS1) {
441  copy_v3_v3(c, t->spacemtx[1]);
442  }
443  else {
444  BLI_assert(t->con.mode & CON_AXIS2);
445  copy_v3_v3(c, t->spacemtx[2]);
446  }
447 
448  if (is_snap_to_edge) {
450  }
451  else if (is_snap_to_face) {
453  }
454  else {
455  /* View alignment correction. */
456  axisProjection(t, c, in, out);
457  }
458  }
459  }
460  }
461 }
462 
474  const TransDataContainer *tc,
475  const TransData *td,
476  const float in[3],
477  float out[3])
478 {
479  if (!td) {
480  applyAxisConstraintVec(t, tc, td, in, out);
481  }
482  else {
483  /* Specific TransData's space. */
484  copy_v3_v3(out, in);
485  if (t->con.mode & CON_APPLY) {
486  mul_m3_v3(t->spacemtx_inv, out);
487  const float(*axismtx)[3] = transform_object_axismtx_get(t, tc, td);
488  mul_m3_v3(axismtx, out);
489  if (t->flag & T_EDIT) {
490  mul_m3_v3(tc->mat3_unit, out);
491  }
492  }
493  }
494 }
495 
500  const TransDataContainer *UNUSED(tc),
501  const TransData *td,
502  float r_smat[3][3])
503 {
504  if (!td && t->con.mode & CON_APPLY) {
505  float tmat[3][3];
506 
507  if (!(t->con.mode & CON_AXIS0)) {
508  r_smat[0][0] = 1.0f;
509  }
510  if (!(t->con.mode & CON_AXIS1)) {
511  r_smat[1][1] = 1.0f;
512  }
513  if (!(t->con.mode & CON_AXIS2)) {
514  r_smat[2][2] = 1.0f;
515  }
516 
517  mul_m3_m3m3(tmat, r_smat, t->spacemtx_inv);
518  mul_m3_m3m3(r_smat, t->spacemtx, tmat);
519  }
520 }
521 
526  const TransDataContainer *tc,
527  const TransData *td,
528  float r_smat[3][3])
529 {
530  if (td && t->con.mode & CON_APPLY) {
531  float tmat[3][3];
532  float imat[3][3];
533 
534  const float(*axismtx)[3] = transform_object_axismtx_get(t, tc, td);
535  invert_m3_m3(imat, axismtx);
536 
537  if (!(t->con.mode & CON_AXIS0)) {
538  r_smat[0][0] = 1.0f;
539  }
540  if (!(t->con.mode & CON_AXIS1)) {
541  r_smat[1][1] = 1.0f;
542  }
543  if (!(t->con.mode & CON_AXIS2)) {
544  r_smat[2][2] = 1.0f;
545  }
546 
547  mul_m3_m3m3(tmat, r_smat, imat);
548  if (t->flag & T_EDIT) {
549  mul_m3_m3m3(r_smat, tc->mat3_unit, r_smat);
550  }
551  mul_m3_m3m3(r_smat, axismtx, tmat);
552  }
553 }
554 
556  const float axismtx[3][3],
557  float r_axis[3],
558  float *r_angle)
559 {
560  BLI_assert(t->con.mode & CON_APPLY);
561  int mode = t->con.mode & (CON_AXIS0 | CON_AXIS1 | CON_AXIS2);
562 
563  switch (mode) {
564  case CON_AXIS0:
565  case (CON_AXIS1 | CON_AXIS2):
566  copy_v3_v3(r_axis, axismtx[0]);
567  break;
568  case CON_AXIS1:
569  case (CON_AXIS0 | CON_AXIS2):
570  copy_v3_v3(r_axis, axismtx[1]);
571  break;
572  case CON_AXIS2:
573  case (CON_AXIS0 | CON_AXIS1):
574  copy_v3_v3(r_axis, axismtx[2]);
575  break;
576  }
577  /* don't flip axis if asked to or if num input */
578  if (r_angle &&
579  !((mode & CON_NOFLIP) || hasNumInput(&t->num) || (t->flag & T_INPUT_IS_VALUES_FINAL))) {
580  float view_vector[3];
581  view_vector_calc(t, t->center_global, view_vector);
582  if (dot_v3v3(r_axis, view_vector) > 0.0f) {
583  *r_angle = -(*r_angle);
584  }
585  }
586 }
587 
601 static void applyAxisConstraintRot(const TransInfo *t,
602  const TransDataContainer *UNUSED(tc),
603  const TransData *td,
604  float r_axis[3],
605  float *r_angle)
606 {
607  if (!td && t->con.mode & CON_APPLY) {
608  constraints_rotation_impl(t, t->spacemtx, r_axis, r_angle);
609  }
610 }
611 
626  const TransDataContainer *tc,
627  const TransData *td,
628  float r_axis[3],
629  float *r_angle)
630 {
631  if (t->con.mode & CON_APPLY) {
632  float tmp_axismtx[3][3];
633  const float(*axismtx)[3];
634 
635  /* on setup call, use first object */
636  if (td == NULL) {
637  BLI_assert(tc == NULL);
639  td = tc->data;
640  }
641 
642  if (t->flag & T_EDIT) {
643  mul_m3_m3m3(tmp_axismtx, tc->mat3_unit, td->axismtx);
644  axismtx = tmp_axismtx;
645  }
646  else {
647  axismtx = transform_object_axismtx_get(t, tc, td);
648  }
649 
650  constraints_rotation_impl(t, axismtx, r_axis, r_angle);
651  }
652 }
653 
656 /* -------------------------------------------------------------------- */
660 void setConstraint(TransInfo *t, int mode, const char text[])
661 {
662  BLI_strncpy(t->con.text + 1, text, sizeof(t->con.text) - 1);
663  t->con.mode = mode;
664  projection_matrix_calc(t, t->con.pmtx);
665 
667 
668  t->con.drawExtra = NULL;
669  t->con.applyVec = applyAxisConstraintVec;
670  t->con.applySize = applyAxisConstraintSize;
671  t->con.applyRot = applyAxisConstraintRot;
672  t->redraw = TREDRAW_HARD;
673 }
674 
675 void setAxisMatrixConstraint(TransInfo *t, int mode, const char text[])
676 {
677  BLI_strncpy(t->con.text + 1, text, sizeof(t->con.text) - 1);
678  t->con.mode = mode;
679  projection_matrix_calc(t, t->con.pmtx);
680 
682 
683  t->con.drawExtra = drawObjectConstraint;
684  t->con.applyVec = applyObjectConstraintVec;
685  t->con.applySize = applyObjectConstraintSize;
686  t->con.applyRot = applyObjectConstraintRot;
687  t->redraw = TREDRAW_HARD;
688 }
689 
690 void setLocalConstraint(TransInfo *t, int mode, const char text[])
691 {
692  if ((t->flag & T_EDIT) || t->data_len_all == 1) {
693  /* Although in edit-mode each object has its local space, use the
694  * orientation of the active object. */
695  setConstraint(t, mode, text);
696  }
697  else {
698  setAxisMatrixConstraint(t, mode, text);
699  }
700 }
701 
702 void setUserConstraint(TransInfo *t, int mode, const char ftext[])
703 {
704  char text[256];
705  const short orientation = transform_orientation_or_default(t);
706  const char *spacename = transform_orientations_spacename_get(t, orientation);
707  BLI_snprintf(text, sizeof(text), ftext, spacename);
708 
709  switch (orientation) {
710  case V3D_ORIENT_LOCAL:
711  case V3D_ORIENT_GIMBAL:
712  setLocalConstraint(t, mode, text);
713  break;
714  case V3D_ORIENT_NORMAL:
715  if (checkUseAxisMatrix(t)) {
716  setAxisMatrixConstraint(t, mode, text);
717  break;
718  }
720  case V3D_ORIENT_GLOBAL:
721  case V3D_ORIENT_VIEW:
722  case V3D_ORIENT_CURSOR:
724  case V3D_ORIENT_CUSTOM:
725  default: {
726  setConstraint(t, mode, text);
727  break;
728  }
729  }
730  t->con.mode |= CON_USER;
731 }
732 
735 /* -------------------------------------------------------------------- */
740 {
741  TransCon *tc = &(t->con);
742 
743  if (!ELEM(t->spacetype, SPACE_VIEW3D, SPACE_IMAGE, SPACE_NODE, SPACE_SEQ)) {
744  return;
745  }
746  if (!(tc->mode & CON_APPLY)) {
747  return;
748  }
749  if (t->flag & T_NO_CONSTRAINT) {
750  return;
751  }
752 
753  if (tc->drawExtra) {
754  tc->drawExtra(t);
755  }
756  else {
757  if (tc->mode & CON_SELECT) {
758  float vec[3];
759 
760  convertViewVec(t, vec, (t->mval[0] - t->con.imval[0]), (t->mval[1] - t->con.imval[1]));
761  add_v3_v3(vec, t->center_global);
762 
763  drawLine(t, t->center_global, t->spacemtx[0], 'X', 0);
764  drawLine(t, t->center_global, t->spacemtx[1], 'Y', 0);
765  drawLine(t, t->center_global, t->spacemtx[2], 'Z', 0);
766 
767  eGPUDepthTest depth_test_enabled = GPU_depth_test_get();
768  if (depth_test_enabled) {
770  }
771 
772  const uint shdr_pos = GPU_vertformat_attr_add(
774 
776 
777  float viewport_size[4];
778  GPU_viewport_size_get_f(viewport_size);
779  immUniform2f("viewport_size", viewport_size[2], viewport_size[3]);
780 
781  immUniform1i("colors_len", 0); /* "simple" mode */
782  immUniformColor4f(1.0f, 1.0f, 1.0f, 1.0f);
783  immUniform1f("dash_width", 2.0f);
784  immUniform1f("dash_factor", 0.5f);
785 
787  immVertex3fv(shdr_pos, t->center_global);
788  immVertex3fv(shdr_pos, vec);
789  immEnd();
790 
792 
793  if (depth_test_enabled) {
795  }
796  }
797 
798  if (tc->mode & CON_AXIS0) {
799  drawLine(t, t->center_global, t->spacemtx[0], 'X', DRAWLIGHT);
800  }
801  if (tc->mode & CON_AXIS1) {
802  drawLine(t, t->center_global, t->spacemtx[1], 'Y', DRAWLIGHT);
803  }
804  if (tc->mode & CON_AXIS2) {
805  drawLine(t, t->center_global, t->spacemtx[2], 'Z', DRAWLIGHT);
806  }
807  }
808 }
809 
810 void drawPropCircle(const struct bContext *C, TransInfo *t)
811 {
812  if (t->flag & T_PROP_EDIT) {
814  float tmat[4][4], imat[4][4];
815 
816  if (t->spacetype == SPACE_VIEW3D && rv3d != NULL) {
817  copy_m4_m4(tmat, rv3d->viewmat);
818  invert_m4_m4(imat, tmat);
819  }
820  else {
821  unit_m4(tmat);
822  unit_m4(imat);
823  }
824 
825  GPU_matrix_push();
826 
827  if (t->spacetype == SPACE_VIEW3D) {
828  /* pass */
829  }
830  else if (t->spacetype == SPACE_IMAGE) {
831  GPU_matrix_scale_2f(1.0f / t->aspect[0], 1.0f / t->aspect[1]);
832  }
833  else if (ELEM(t->spacetype, SPACE_GRAPH, SPACE_ACTION)) {
834  /* only scale y */
835  float xscale, yscale;
836  UI_view2d_scale_get(&t->region->v2d, &xscale, &yscale);
837 
838  const float fac_scale = xscale / yscale;
839  GPU_matrix_scale_2f(1.0f, fac_scale);
840  GPU_matrix_translate_2f(0.0f, (t->center_global[1] / fac_scale) - t->center_global[1]);
841  }
842 
843  eGPUDepthTest depth_test_enabled = GPU_depth_test_get();
844  if (depth_test_enabled) {
846  }
847 
849 
851 
852  float viewport[4];
853  GPU_viewport_size_get_f(viewport);
855 
856  immUniform2fv("viewportSize", &viewport[2]);
857  immUniform1f("lineWidth", 3.0f * U.pixelsize);
858 
860  imm_drawcircball(t->center_global, t->prop_size, imat, pos);
861 
862  immUniform1f("lineWidth", 1.0f * U.pixelsize);
864  imm_drawcircball(t->center_global, t->prop_size, imat, pos);
865 
867 
868  if (depth_test_enabled) {
870  }
871 
872  GPU_matrix_pop();
873  }
874 }
875 
877 {
878  /* Draw the first one lighter because that's the one who controls the others.
879  * Meaning the transformation is projected on that one and just copied on the others
880  * constraint space.
881  * In a nutshell, the object with light axis is controlled by the user and the others follow.
882  * Without drawing the first light, users have little clue what they are doing.
883  */
884  short options = DRAWLIGHT;
885  float tmp_axismtx[3][3];
886 
888  TransData *td = tc->data;
889  for (int i = 0; i < tc->data_len; i++, td++) {
890  float co[3];
891  const float(*axismtx)[3];
892 
893  if (t->flag & T_PROP_EDIT) {
894  /* we're sorted, so skip the rest */
895  if (td->factor == 0.0f) {
896  break;
897  }
898  }
899 
900  if (t->options & CTX_GPENCIL_STROKES) {
901  /* only draw a constraint line for one point, otherwise we can't see anything */
902  if ((options & DRAWLIGHT) == 0) {
903  break;
904  }
905  }
906 
907  if (t->options & CTX_SEQUENCER_IMAGE) {
908  /* Because we construct an "L" shape to deform the sequence, we should skip
909  * all points except the first vertex. Otherwise we will draw the same axis constraint line
910  * 3 times for each strip.
911  */
912  if (i % 3 != 0) {
913  continue;
914  }
915  }
916 
917  if (t->flag & T_EDIT) {
918  mul_v3_m4v3(co, tc->mat, td->center);
919 
920  mul_m3_m3m3(tmp_axismtx, tc->mat3_unit, td->axismtx);
921  axismtx = tmp_axismtx;
922  }
923  else {
924  if (t->options & CTX_POSE_BONE) {
925  mul_v3_m4v3(co, tc->mat, td->center);
926  }
927  else {
928  copy_v3_v3(co, td->center);
929  }
930  axismtx = transform_object_axismtx_get(t, tc, td);
931  }
932 
933  if (t->con.mode & CON_AXIS0) {
934  drawLine(t, co, axismtx[0], 'X', options);
935  }
936  if (t->con.mode & CON_AXIS1) {
937  drawLine(t, co, axismtx[1], 'Y', options);
938  }
939  if (t->con.mode & CON_AXIS2) {
940  drawLine(t, co, axismtx[2], 'Z', options);
941  }
942  options &= ~DRAWLIGHT;
943  }
944  }
945 }
946 
949 /* -------------------------------------------------------------------- */
954 {
955  t->con.mode |= CON_APPLY;
956  *t->con.text = ' ';
957  t->num.idx_max = min_ii(getConstraintSpaceDimension(t) - 1, t->idx_max);
958 }
959 
961 {
962  if (t->orient_curr != O_DEFAULT) {
964  }
965 
966  t->con.mode &= ~(CON_APPLY | CON_SELECT);
967  *t->con.text = '\0';
968  t->num.idx_max = t->idx_max;
969 }
970 
973 /* -------------------------------------------------------------------- */
978 {
979  if (t->orient_curr == O_DEFAULT) {
981  }
982 
984 }
985 
987 {
988  if (t->con.mode & CON_SELECT) {
989  setNearestAxis(t);
991  }
992 }
993 
995 {
996  t->con.mode &= ~CON_SELECT;
997  if (!(t->con.mode & (CON_AXIS0 | CON_AXIS1 | CON_AXIS2))) {
998  t->con.mode &= ~CON_APPLY;
999  }
1000 }
1001 
1003 {
1004  /* no correction needed... just use whichever one is lower */
1005  if (abs(t->mval[0] - t->con.imval[0]) < abs(t->mval[1] - t->con.imval[1])) {
1006  t->con.mode |= CON_AXIS1;
1007  BLI_strncpy(t->con.text, TIP_(" along Y axis"), sizeof(t->con.text));
1008  }
1009  else {
1010  t->con.mode |= CON_AXIS0;
1011  BLI_strncpy(t->con.text, TIP_(" along X axis"), sizeof(t->con.text));
1012  }
1013 }
1014 
1016 {
1017  float zfac;
1018  float mvec[3], proj[3];
1019  float len[3];
1020  int i;
1021 
1022  /* calculate mouse movement */
1023  mvec[0] = (float)(t->mval[0] - t->con.imval[0]);
1024  mvec[1] = (float)(t->mval[1] - t->con.imval[1]);
1025  mvec[2] = 0.0f;
1026 
1027  /* We need to correct axis length for the current zoom-level of view,
1028  * this to prevent projected values to be clipped behind the camera
1029  * and to overflow the short integers.
1030  * The formula used is a bit stupid, just a simplification of the subtraction
1031  * of two 2D points 30 pixels apart (that's the last factor in the formula) after
1032  * projecting them with #ED_view3d_win_to_delta and then get the length of that vector. */
1033  zfac = mul_project_m4_v3_zfac(t->persmat, t->center_global);
1034  zfac = len_v3(t->persinv[0]) * 2.0f / t->region->winx * zfac * 30.0f;
1035 
1036  for (i = 0; i < 3; i++) {
1037  float axis[3], axis_2d[2];
1038 
1039  copy_v3_v3(axis, t->spacemtx[i]);
1040 
1041  mul_v3_fl(axis, zfac);
1042  /* now we can project to get window coordinate */
1043  add_v3_v3(axis, t->center_global);
1044  projectFloatView(t, axis, axis_2d);
1045 
1046  sub_v2_v2v2(axis, axis_2d, t->center2d);
1047  axis[2] = 0.0f;
1048 
1049  if (normalize_v3(axis) > 1e-3f) {
1050  project_v3_v3v3(proj, mvec, axis);
1051  sub_v3_v3v3(axis, mvec, proj);
1052  len[i] = normalize_v3(axis);
1053  }
1054  else {
1055  len[i] = 1e10f;
1056  }
1057  }
1058 
1059  if (len[0] <= len[1] && len[0] <= len[2]) {
1060  if (t->modifiers & MOD_CONSTRAINT_SELECT_PLANE) {
1061  t->con.mode |= (CON_AXIS1 | CON_AXIS2);
1062  BLI_snprintf(t->con.text, sizeof(t->con.text), TIP_(" locking %s X axis"), t->spacename);
1063  }
1064  else {
1065  t->con.mode |= CON_AXIS0;
1066  BLI_snprintf(t->con.text, sizeof(t->con.text), TIP_(" along %s X axis"), t->spacename);
1067  }
1068  }
1069  else if (len[1] <= len[0] && len[1] <= len[2]) {
1070  if (t->modifiers & MOD_CONSTRAINT_SELECT_PLANE) {
1071  t->con.mode |= (CON_AXIS0 | CON_AXIS2);
1072  BLI_snprintf(t->con.text, sizeof(t->con.text), TIP_(" locking %s Y axis"), t->spacename);
1073  }
1074  else {
1075  t->con.mode |= CON_AXIS1;
1076  BLI_snprintf(t->con.text, sizeof(t->con.text), TIP_(" along %s Y axis"), t->spacename);
1077  }
1078  }
1079  else if (len[2] <= len[1] && len[2] <= len[0]) {
1080  if (t->modifiers & MOD_CONSTRAINT_SELECT_PLANE) {
1081  t->con.mode |= (CON_AXIS0 | CON_AXIS1);
1082  BLI_snprintf(t->con.text, sizeof(t->con.text), TIP_(" locking %s Z axis"), t->spacename);
1083  }
1084  else {
1085  t->con.mode |= CON_AXIS2;
1086  BLI_snprintf(t->con.text, sizeof(t->con.text), TIP_(" along %s Z axis"), t->spacename);
1087  }
1088  }
1089 }
1090 
1092 {
1093  /* clear any prior constraint flags */
1094  t->con.mode &= ~CON_AXIS0;
1095  t->con.mode &= ~CON_AXIS1;
1096  t->con.mode &= ~CON_AXIS2;
1097 
1098  /* constraint setting - depends on spacetype */
1099  if (t->spacetype == SPACE_VIEW3D) {
1100  /* 3d-view */
1102  }
1103  else {
1104  /* assume that this means a 2D-Editor */
1106  }
1107 
1108  projection_matrix_calc(t, t->con.pmtx);
1109 }
1110 
1113 /* -------------------------------------------------------------------- */
1118 {
1119  if ((t->con.mode & CON_APPLY) == 0) {
1120  return -1;
1121  }
1122  switch (t->con.mode & (CON_AXIS0 | CON_AXIS1 | CON_AXIS2)) {
1123  case (CON_AXIS0):
1124  case (CON_AXIS1 | CON_AXIS2):
1125  return 0;
1126  case (CON_AXIS1):
1127  case (CON_AXIS0 | CON_AXIS2):
1128  return 1;
1129  case (CON_AXIS2):
1130  case (CON_AXIS0 | CON_AXIS1):
1131  return 2;
1132  default:
1133  return -1;
1134  }
1135 }
1136 
1138 {
1139  int mode = t->con.mode;
1140 
1141  if ((mode & (CON_AXIS0 | CON_AXIS1)) == (CON_AXIS0 | CON_AXIS1)) {
1142  return true;
1143  }
1144 
1145  if ((mode & (CON_AXIS1 | CON_AXIS2)) == (CON_AXIS1 | CON_AXIS2)) {
1146  return true;
1147  }
1148 
1149  if ((mode & (CON_AXIS0 | CON_AXIS2)) == (CON_AXIS0 | CON_AXIS2)) {
1150  return true;
1151  }
1152 
1153  return false;
1154 }
1155 
1157 {
1158  int n = 0;
1159 
1160  if (t->con.mode & CON_AXIS0) {
1161  n++;
1162  }
1163 
1164  if (t->con.mode & CON_AXIS1) {
1165  n++;
1166  }
1167 
1168  if (t->con.mode & CON_AXIS2) {
1169  n++;
1170  }
1171 
1172  return n;
1173  /* Someone willing to do it cryptically could do the following instead:
1174  *
1175  * `return t->con & (CON_AXIS0|CON_AXIS1|CON_AXIS2);`
1176  *
1177  * Based on the assumptions that the axis flags are one after the other and start at 1
1178  */
1179 }
1180 
typedef float(TangentPoint)[2]
struct RegionView3D * CTX_wm_region_view3d(const bContext *C)
Definition: context.c:793
#define BLI_assert(a)
Definition: BLI_assert.h:46
#define ATTR_FALLTHROUGH
MINLINE int min_ii(int a, int b)
#define M_PI_2
Definition: BLI_math_base.h:23
#define M_PI
Definition: BLI_math_base.h:20
void plane_from_point_normal_v3(float r_plane[4], const float plane_co[3], const float plane_no[3])
Definition: math_geom.c:209
bool isect_ray_ray_v3(const float ray_origin_a[3], const float ray_direction_a[3], const float ray_origin_b[3], const float ray_direction_b[3], float *r_lambda_a, float *r_lambda_b)
Definition: math_geom.c:3032
float closest_to_ray_v3(float r_close[3], const float p[3], const float ray_orig[3], const float ray_dir[3])
Definition: math_geom.c:3157
bool isect_ray_plane_v3(const float ray_origin[3], const float ray_direction[3], const float plane[4], float *r_lambda, bool clip)
Definition: math_geom.c:1713
bool isect_plane_plane_v3(const float plane_a[4], const float plane_b[4], float r_isect_co[3], float r_isect_no[3]) ATTR_WARN_UNUSED_RESULT
Definition: math_geom.c:2134
void mul_m3_v3(const float M[3][3], float r[3])
Definition: math_matrix.c:926
void unit_m3(float m[3][3])
Definition: math_matrix.c:40
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
bool invert_m3_m3(float R[3][3], const float A[3][3])
Definition: math_matrix.c:1180
void copy_m4_m4(float m1[4][4], const float m2[4][4])
Definition: math_matrix.c:77
void mul_v3_m4v3(float r[3], const float M[4][4], const float v[3])
Definition: math_matrix.c:739
void mul_m3_m3m3(float R[3][3], const float A[3][3], const float B[3][3])
Definition: math_matrix.c:388
#define DEG2RADF(_deg)
MINLINE float normalize_v3_v3_length(float r[3], const float a[3], float unit_scale)
float angle_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
Definition: math_vector.c:385
MINLINE float normalize_v3(float r[3])
MINLINE void sub_v3_v3(float r[3], const float a[3])
MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void mul_v3_fl(float r[3], float f)
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE bool is_zero_v3(const float a[3]) ATTR_WARN_UNUSED_RESULT
void project_v3_v3v3(float out[3], const float p[3], const float v_proj[3])
Definition: math_vector.c:600
MINLINE float dot_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void add_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void cross_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void negate_v3(float r[3])
MINLINE void sub_v2_v2v2(float r[2], const float a[2], const float b[2])
MINLINE float mul_project_m4_v3_zfac(const float mat[4][4], const float co[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void madd_v3_v3v3fl(float r[3], const float a[3], const float b[3], float f)
MINLINE void zero_v3(float r[3])
MINLINE void mul_v3_v3fl(float r[3], const float a[3], float f)
MINLINE void add_v3_v3(float r[3], const float a[3])
MINLINE float len_v3(const float a[3]) ATTR_WARN_UNUSED_RESULT
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t maxncpy) ATTR_NONNULL()
Definition: string.c:64
size_t BLI_snprintf(char *__restrict dst, size_t maxncpy, const char *__restrict format,...) ATTR_NONNULL(1
unsigned int uint
Definition: BLI_sys_types.h:67
#define UNUSED(x)
#define ELEM(...)
#define TIP_(msgid)
Object is a sort of wrapper for general info.
@ SCE_SNAP_MODE_EDGE
@ SCE_SNAP_MODE_FACE_RAYCAST
@ SCE_SNAP_MODE_GRID
@ SPACE_ACTION
@ SPACE_NODE
@ SPACE_SEQ
@ SPACE_IMAGE
@ SPACE_GRAPH
@ SPACE_VIEW3D
@ V3D_ORIENT_NORMAL
@ V3D_ORIENT_CUSTOM
@ V3D_ORIENT_GLOBAL
@ V3D_ORIENT_CUSTOM_MATRIX
@ V3D_ORIENT_LOCAL
@ V3D_ORIENT_VIEW
@ V3D_ORIENT_CURSOR
@ V3D_ORIENT_GIMBAL
#define RV3D_ORTHO
bool hasNumInput(const NumInput *n)
Definition: numinput.c:170
void immUniform2fv(const char *name, const float data[2])
void immUniform2f(const char *name, float x, float y)
void immUniformThemeColorShadeAlpha(int color_id, int color_offset, int alpha_offset)
void immUniformColor4f(float r, float g, float b, float a)
void immUnbindProgram(void)
void immBindBuiltinProgram(eGPUBuiltinShader shader_id)
void immUniform1i(const char *name, int x)
void immUniform1f(const char *name, float x)
GPUVertFormat * immVertexFormat(void)
void immVertex3fv(uint attr_id, const float data[3])
void immBegin(GPUPrimType, uint vertex_len)
void immEnd(void)
void imm_drawcircball(const float cent[3], float radius, const float tmat[4][4], uint pos)
_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 t
void GPU_matrix_pop(void)
Definition: gpu_matrix.cc:126
void GPU_matrix_scale_2f(float x, float y)
Definition: gpu_matrix.cc:216
void GPU_matrix_push(void)
Definition: gpu_matrix.cc:119
void GPU_matrix_translate_2f(float x, float y)
Definition: gpu_matrix.cc:174
@ GPU_PRIM_LINES
Definition: GPU_primitive.h:20
@ GPU_SHADER_3D_LINE_DASHED_UNIFORM_COLOR
Definition: GPU_shader.h:350
@ GPU_SHADER_3D_POLYLINE_UNIFORM_COLOR
Definition: GPU_shader.h:253
@ GPU_BLEND_ALPHA
Definition: GPU_state.h:62
void GPU_blend(eGPUBlend blend)
Definition: gpu_state.cc:39
eGPUDepthTest
Definition: GPU_state.h:82
@ GPU_DEPTH_LESS_EQUAL
Definition: GPU_state.h:86
@ GPU_DEPTH_NONE
Definition: GPU_state.h:83
eGPUDepthTest GPU_depth_test_get(void)
Definition: gpu_state.cc:236
void GPU_depth_test(eGPUDepthTest test)
Definition: gpu_state.cc:65
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
#define C
Definition: RandGen.cpp:25
@ TH_GRID
Definition: UI_resources.h:68
void UI_view2d_scale_get(const struct View2D *v2d, float *r_x, float *r_y)
ATTR_WARN_UNUSED_RESULT const BMLoop * l
ATTR_WARN_UNUSED_RESULT const BMVert * v
unsigned int U
Definition: btGjkEpa3.h:78
static void mul(btAlignedObjectArray< T > &items, const Q &value)
SIMD_FORCE_INLINE btScalar norm() const
Return the norm (length) of the vector.
Definition: btVector3.h:263
SIMD_FORCE_INLINE btScalar angle(const btVector3 &v) const
Return the angle between this and another vector.
Definition: btVector3.h:356
CCL_NAMESPACE_BEGIN struct Options options
int len
Definition: draw_manager.c:108
uint pos
#define fabsf(x)
Definition: metal/compat.h:219
bool isfinite(uchar)
Definition: scene/image.cpp:31
static unsigned c
Definition: RandGen.cpp:83
IMETHOD Vector diff(const Vector &a, const Vector &b, double dt=1)
T abs(const T &a)
static bool is_aligned(void *ptr, uint alignment)
static const pxr::TfToken out("out", pxr::TfToken::Immortal)
const btScalar eps
Definition: poly34.cpp:11
#define TRANS_DATA_CONTAINER_FIRST_OK(t)
void drawLine(TransInfo *t, const float center[3], const float dir[3], char axis, short options)
#define FOREACH_TRANS_DATA_CONTAINER(t, th)
float viewmat[4][4]
void(* drawExtra)(struct TransInfo *t)
float axismtx[3][3]
bool checkUseAxisMatrix(TransInfo *t)
Definition: transform.c:2062
void convertViewVec(TransInfo *t, float r_vec[3], double dx, double dy)
Definition: transform.c:170
void projectFloatView(TransInfo *t, const float vec[3], float adr[2])
Definition: transform.c:366
static void drawObjectConstraint(TransInfo *t)
static void constraints_rotation_impl(const TransInfo *t, const float axismtx[3][3], float r_axis[3], float *r_angle)
bool isLockConstraint(const TransInfo *t)
#define CONSTRAIN_EPSILON
void drawConstraint(TransInfo *t)
static void applyAxisConstraintRot(const TransInfo *t, const TransDataContainer *UNUSED(tc), const TransData *td, float r_axis[3], float *r_angle)
static void applyAxisConstraintVec(const TransInfo *t, const TransDataContainer *UNUSED(tc), const TransData *td, const float in[3], float out[3])
void drawPropCircle(const struct bContext *C, TransInfo *t)
void startConstraint(TransInfo *t)
static void projection_matrix_calc(const TransInfo *t, float r_pmtx[3][3])
void setConstraint(TransInfo *t, int mode, const char text[])
static void viewAxisCorrectCenter(const TransInfo *t, float t_con_center[3])
int constraintModeToIndex(const TransInfo *t)
void setAxisMatrixConstraint(TransInfo *t, int mode, const char text[])
void setNearestAxis(TransInfo *t)
void transform_constraint_snap_axis_to_face(const TransInfo *t, const float axis[3], float r_out[3])
static void setNearestAxis3d(TransInfo *t)
void postSelectConstraint(TransInfo *t)
void setUserConstraint(TransInfo *t, int mode, const char ftext[])
void stopConstraint(TransInfo *t)
void constraintNumInput(TransInfo *t, float vec[3])
void setLocalConstraint(TransInfo *t, int mode, const char text[])
static void constraint_snap_plane_to_edge(const TransInfo *t, const float plane[4], float r_out[3])
static void applyAxisConstraintSize(const TransInfo *t, const TransDataContainer *UNUSED(tc), const TransData *td, float r_smat[3][3])
void transform_constraint_snap_axis_to_edge(const TransInfo *t, const float axis[3], float r_out[3])
static const float(* transform_object_axismtx_get(const TransInfo *t, const TransDataContainer *UNUSED(tc), const TransData *td))[3]
static void applyObjectConstraintRot(const TransInfo *t, const TransDataContainer *tc, const TransData *td, float r_axis[3], float *r_angle)
int getConstraintSpaceDimension(const TransInfo *t)
static void applyObjectConstraintSize(const TransInfo *t, const TransDataContainer *tc, const TransData *td, float r_smat[3][3])
static void planeProjection(const TransInfo *t, const float plane[3], const float in[3], float out[3])
static void UNUSED_FUNCTION(constraint_snap_plane_to_face(const TransInfo *t, const float plane[4], float r_out[3]))
void initSelectConstraint(TransInfo *t)
static void setNearestAxis2d(TransInfo *t)
static short transform_orientation_or_default(const TransInfo *t)
void selectConstraint(TransInfo *t)
static void view_vector_calc(const TransInfo *t, const float focus[3], float r_vec[3])
static bool isPlaneProjectionViewAligned(const TransInfo *t, const float plane[4])
static void applyObjectConstraintVec(const TransInfo *t, const TransDataContainer *tc, const TransData *td, const float in[3], float out[3])
static void constraint_plane_calc(const TransInfo *t, float r_plane[4])
static void axisProjection(const TransInfo *t, const float axis[3], const float in[3], float out[3])
const char * transform_orientations_spacename_get(TransInfo *t, const short orient_type)
void transform_orientations_current_set(TransInfo *t, const short orient_index)
bool validSnap(const TransInfo *t)
bool activeSnap(const TransInfo *t)