Blender  V2.93
transform_constraints.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) 2001-2002 by NaN Holding BV.
17  * All rights reserved.
18  */
19 
24 #include <math.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 
29 #include "DNA_object_types.h"
30 #include "DNA_scene_types.h"
31 #include "DNA_screen_types.h"
32 #include "DNA_space_types.h"
33 #include "DNA_view3d_types.h"
34 
35 #include "GPU_immediate.h"
36 #include "GPU_matrix.h"
37 #include "GPU_state.h"
38 
39 #include "BLI_math.h"
40 #include "BLI_rect.h"
41 #include "BLI_string.h"
42 #include "BLI_utildefines.h"
43 
44 #include "BKE_context.h"
45 
46 #include "ED_view3d.h"
47 
48 #include "BLT_translation.h"
49 
50 #include "UI_resources.h"
51 
52 #include "transform.h"
53 #include "transform_orientations.h"
54 #include "transform_snap.h"
55 
56 /* Own include. */
57 #include "transform_constraints.h"
58 
59 static void drawObjectConstraint(TransInfo *t);
60 
61 /* -------------------------------------------------------------------- */
65 static void projection_matrix_calc(const TransInfo *t, float r_pmtx[3][3])
66 {
67  unit_m3(r_pmtx);
68 
69  if (!(t->con.mode & CON_AXIS0)) {
70  zero_v3(r_pmtx[0]);
71  }
72 
73  if (!(t->con.mode & CON_AXIS1)) {
74  zero_v3(r_pmtx[1]);
75  }
76 
77  if (!(t->con.mode & CON_AXIS2)) {
78  zero_v3(r_pmtx[2]);
79  }
80 
81  float mat[3][3];
82  mul_m3_m3m3(mat, r_pmtx, t->spacemtx_inv);
83  mul_m3_m3m3(r_pmtx, t->spacemtx, mat);
84 }
85 
86 static void view_vector_calc(const TransInfo *t, const float focus[3], float r_vec[3])
87 {
88  if (t->persp != RV3D_ORTHO) {
89  sub_v3_v3v3(r_vec, t->viewinv[3], focus);
90  }
91  else {
92  copy_v3_v3(r_vec, t->viewinv[2]);
93  }
94  normalize_v3(r_vec);
95 }
96 
97 /* ************************** CONSTRAINTS ************************* */
98 #define CONSTRAIN_EPSILON 0.0001f
99 
100 static void constraint_plane_calc(TransInfo *t, float r_plane[4])
101 {
102  const float *constraint_vector[2];
103  int n = 0;
104  for (int i = 0; i < 3; i++) {
105  if (t->con.mode & (CON_AXIS0 << i)) {
106  constraint_vector[n++] = t->spacemtx[i];
107  if (n == 2) {
108  break;
109  }
110  }
111  }
112  BLI_assert(n == 2);
113 
114  cross_v3_v3v3(r_plane, constraint_vector[0], constraint_vector[1]);
115  normalize_v3(r_plane);
116  r_plane[3] = -dot_v3v3(r_plane, t->center_global);
117 }
118 
119 void constraintNumInput(TransInfo *t, float vec[3])
120 {
121  int mode = t->con.mode;
122  if (mode & CON_APPLY) {
123  float nval = (t->flag & T_NULL_ONE) ? 1.0f : 0.0f;
124 
125  const int dims = getConstraintSpaceDimension(t);
126  if (dims == 2) {
127  int axis = mode & (CON_AXIS0 | CON_AXIS1 | CON_AXIS2);
128  if (axis == (CON_AXIS0 | CON_AXIS1)) {
129  /* vec[0] = vec[0]; */ /* same */
130  /* vec[1] = vec[1]; */ /* same */
131  vec[2] = nval;
132  }
133  else if (axis == (CON_AXIS1 | CON_AXIS2)) {
134  vec[2] = vec[1];
135  vec[1] = vec[0];
136  vec[0] = nval;
137  }
138  else if (axis == (CON_AXIS0 | CON_AXIS2)) {
139  /* vec[0] = vec[0]; */ /* same */
140  vec[2] = vec[1];
141  vec[1] = nval;
142  }
143  }
144  else if (dims == 1) {
145  if (mode & CON_AXIS0) {
146  /* vec[0] = vec[0]; */ /* same */
147  vec[1] = nval;
148  vec[2] = nval;
149  }
150  else if (mode & CON_AXIS1) {
151  vec[1] = vec[0];
152  vec[0] = nval;
153  vec[2] = nval;
154  }
155  else if (mode & CON_AXIS2) {
156  vec[2] = vec[0];
157  vec[0] = nval;
158  vec[1] = nval;
159  }
160  }
161  }
162 }
163 
164 static void viewAxisCorrectCenter(const TransInfo *t, float t_con_center[3])
165 {
166  if (t->spacetype == SPACE_VIEW3D) {
167  // View3D *v3d = t->area->spacedata.first;
168  const float min_dist = 1.0f; /* v3d->clip_start; */
169  float dir[3];
170  float l;
171 
172  sub_v3_v3v3(dir, t_con_center, t->viewinv[3]);
173  if (dot_v3v3(dir, t->viewinv[2]) < 0.0f) {
174  negate_v3(dir);
175  }
176  project_v3_v3v3(dir, dir, t->viewinv[2]);
177 
178  l = len_v3(dir);
179 
180  if (l < min_dist) {
181  float diff[3];
182  normalize_v3_v3_length(diff, t->viewinv[2], min_dist - l);
183  sub_v3_v3(t_con_center, diff);
184  }
185  }
186 }
187 
191 static void axisProjection(const TransInfo *t,
192  const float axis[3],
193  const float in[3],
194  float out[3])
195 {
196  float norm[3], vec[3], factor, angle;
197  float t_con_center[3];
198 
199  if (is_zero_v3(in)) {
200  return;
201  }
202 
203  copy_v3_v3(t_con_center, t->center_global);
204 
205  /* checks for center being too close to the view center */
206  viewAxisCorrectCenter(t, t_con_center);
207 
208  angle = fabsf(angle_v3v3(axis, t->viewinv[2]));
209  if (angle > (float)M_PI_2) {
210  angle = (float)M_PI - angle;
211  }
212 
213  /* For when view is parallel to constraint... will cause NaNs otherwise
214  * So we take vertical motion in 3D space and apply it to the
215  * constraint axis. Nice for camera grab + MMB */
216  if (angle < DEG2RADF(5.0f)) {
217  project_v3_v3v3(vec, in, t->viewinv[1]);
218  factor = dot_v3v3(t->viewinv[1], vec) * 2.0f;
219  /* Since camera distance is quite relative, use quadratic relationship.
220  * holding shift can compensate. */
221  if (factor < 0.0f) {
222  factor *= -factor;
223  }
224  else {
225  factor *= factor;
226  }
227 
228  /* -factor makes move down going backwards */
229  normalize_v3_v3_length(out, axis, -factor);
230  }
231  else {
232  float v[3];
233  float norm_center[3];
234  float plane[3];
235 
236  view_vector_calc(t, t_con_center, norm_center);
237  cross_v3_v3v3(plane, norm_center, axis);
238 
239  project_v3_v3v3(vec, in, plane);
240  sub_v3_v3v3(vec, in, vec);
241 
242  add_v3_v3v3(v, vec, t_con_center);
244 
245  /* give arbitrary large value if projection is impossible */
246  factor = dot_v3v3(axis, norm);
247  if (1.0f - fabsf(factor) < 0.0002f) {
248  copy_v3_v3(out, axis);
249  if (factor > 0) {
250  mul_v3_fl(out, 1000000000.0f);
251  }
252  else {
253  mul_v3_fl(out, -1000000000.0f);
254  }
255  }
256  else {
257  /* Use ray-ray intersection instead of line-line because this gave
258  * precision issues adding small values to large numbers. */
259  float mul;
260  if (isect_ray_ray_v3(t_con_center, axis, v, norm, &mul, NULL)) {
261  mul_v3_v3fl(out, axis, mul);
262  }
263  else {
264  /* In practice this should never fail. */
265  BLI_assert(0);
266  }
267 
268  /* possible some values become nan when
269  * viewpoint and object are both zero */
270  if (!isfinite(out[0])) {
271  out[0] = 0.0f;
272  }
273  if (!isfinite(out[1])) {
274  out[1] = 0.0f;
275  }
276  if (!isfinite(out[2])) {
277  out[2] = 0.0f;
278  }
279  }
280  }
281 }
282 
286 static void constraint_snap_plane_to_edge(const TransInfo *t, const float plane[4], float r_out[3])
287 {
288  float lambda;
289  const float *edge_snap_point = t->tsnap.snapPoint;
290  const float *edge_dir = t->tsnap.snapNormal;
291  bool is_aligned = fabsf(dot_v3v3(edge_dir, plane)) < CONSTRAIN_EPSILON;
292  if (!is_aligned && isect_ray_plane_v3(edge_snap_point, edge_dir, plane, &lambda, false)) {
293  madd_v3_v3v3fl(r_out, edge_snap_point, edge_dir, lambda);
294  sub_v3_v3(r_out, t->tsnap.snapTarget);
295  }
296 }
297 
302 static void UNUSED_FUNCTION(constraint_snap_plane_to_face(const TransInfo *t,
303  const float plane[4],
304  float r_out[3]))
305 {
306  float face_plane[4], isect_orig[3], isect_dir[3];
307  const float *face_snap_point = t->tsnap.snapPoint;
308  const float *face_normal = t->tsnap.snapNormal;
309  plane_from_point_normal_v3(face_plane, face_snap_point, face_normal);
310  bool is_aligned = fabsf(dot_v3v3(plane, face_plane)) > (1.0f - CONSTRAIN_EPSILON);
311  if (!is_aligned && isect_plane_plane_v3(plane, face_plane, isect_orig, isect_dir)) {
312  closest_to_ray_v3(r_out, face_snap_point, isect_orig, isect_dir);
313  sub_v3_v3(r_out, t->tsnap.snapTarget);
314  }
315 }
316 
321  const float axis[3],
322  float r_out[3])
323 {
324  float lambda;
325  const float *edge_snap_point = t->tsnap.snapPoint;
326  const float *edge_dir = t->tsnap.snapNormal;
327  bool is_aligned = fabsf(dot_v3v3(axis, edge_dir)) > (1.0f - CONSTRAIN_EPSILON);
328  if (!is_aligned &&
329  isect_ray_ray_v3(t->tsnap.snapTarget, axis, edge_snap_point, edge_dir, &lambda, NULL)) {
330  mul_v3_v3fl(r_out, axis, lambda);
331  }
332 }
333 
338  const float axis[3],
339  float r_out[3])
340 {
341  float lambda;
342  float face_plane[4];
343  const float *face_snap_point = t->tsnap.snapPoint;
344  const float *face_normal = t->tsnap.snapNormal;
345  plane_from_point_normal_v3(face_plane, face_snap_point, face_normal);
346  bool is_aligned = fabsf(dot_v3v3(axis, face_plane)) < CONSTRAIN_EPSILON;
347  if (!is_aligned && isect_ray_plane_v3(t->tsnap.snapTarget, axis, face_plane, &lambda, false)) {
348  mul_v3_v3fl(r_out, axis, lambda);
349  }
350 }
351 
356 static bool isPlaneProjectionViewAligned(const TransInfo *t, const float plane[4])
357 {
358  const float eps = 0.001f;
359  float view_to_plane[3];
360  view_vector_calc(t, t->center_global, view_to_plane);
361 
362  float factor = dot_v3v3(plane, view_to_plane);
363  return fabsf(factor) < eps;
364 }
365 
366 static void planeProjection(const TransInfo *t, const float in[3], float out[3])
367 {
368  float vec[3], factor, norm[3];
369 
370  add_v3_v3v3(vec, in, t->center_global);
371  view_vector_calc(t, vec, norm);
372 
373  sub_v3_v3v3(vec, out, in);
374 
375  factor = dot_v3v3(vec, norm);
376  if (factor == 0.0f) {
377  return; /* prevent divide by zero */
378  }
379  factor = dot_v3v3(vec, vec) / factor;
380 
381  copy_v3_v3(vec, norm);
382  mul_v3_fl(vec, factor);
383 
384  add_v3_v3v3(out, in, vec);
385 }
386 
395  TransInfo *t, TransDataContainer *UNUSED(tc), TransData *td, const float in[3], float out[3])
396 {
397  copy_v3_v3(out, in);
398  if (!td && t->con.mode & CON_APPLY) {
399  bool is_snap_to_point = false, is_snap_to_edge = false, is_snap_to_face = false;
400  mul_m3_v3(t->con.pmtx, out);
401 
402  if (activeSnap(t)) {
403  if (validSnap(t)) {
404  is_snap_to_edge = (t->tsnap.snapElem & SCE_SNAP_MODE_EDGE) != 0;
405  is_snap_to_face = (t->tsnap.snapElem & SCE_SNAP_MODE_FACE) != 0;
406  is_snap_to_point = !is_snap_to_edge && !is_snap_to_face;
407  }
408  else if (t->tsnap.snapElem & SCE_SNAP_MODE_GRID) {
409  is_snap_to_point = true;
410  }
411  }
412 
413  /* With snap points, a projection is alright, no adjustments needed. */
414  if (!is_snap_to_point || is_snap_to_edge || is_snap_to_face) {
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) {
422  constraint_snap_plane_to_edge(t, plane, out);
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 {
429  /* View alignment correction. */
430  if (!isPlaneProjectionViewAligned(t, plane)) {
431  planeProjection(t, in, out);
432  }
433  }
434  }
435  }
436  else if (dims == 1) {
437  float c[3];
438 
439  if (t->con.mode & CON_AXIS0) {
440  copy_v3_v3(c, t->spacemtx[0]);
441  }
442  else if (t->con.mode & CON_AXIS1) {
443  copy_v3_v3(c, t->spacemtx[1]);
444  }
445  else {
446  BLI_assert(t->con.mode & CON_AXIS2);
447  copy_v3_v3(c, t->spacemtx[2]);
448  }
449 
450  if (is_snap_to_edge) {
452  }
453  else if (is_snap_to_face) {
455  }
456  else {
457  /* View alignment correction. */
458  axisProjection(t, c, in, out);
459  }
460  }
461  }
462  }
463 }
464 
476  TransInfo *t, TransDataContainer *tc, TransData *td, const float in[3], float out[3])
477 {
478  if (!td) {
479  applyAxisConstraintVec(t, tc, td, in, out);
480  }
481  else {
482  /* Specific TransData's space. */
483  copy_v3_v3(out, in);
484  if (t->con.mode & CON_APPLY) {
485  mul_m3_v3(t->spacemtx_inv, out);
486  mul_m3_v3(td->axismtx, out);
487  if (t->flag & T_EDIT) {
488  mul_m3_v3(tc->mat3_unit, out);
489  }
490  }
491  }
492 }
493 
499  TransData *td,
500  float smat[3][3])
501 {
502  if (!td && t->con.mode & CON_APPLY) {
503  float tmat[3][3];
504 
505  if (!(t->con.mode & CON_AXIS0)) {
506  smat[0][0] = 1.0f;
507  }
508  if (!(t->con.mode & CON_AXIS1)) {
509  smat[1][1] = 1.0f;
510  }
511  if (!(t->con.mode & CON_AXIS2)) {
512  smat[2][2] = 1.0f;
513  }
514 
515  mul_m3_m3m3(tmat, smat, t->spacemtx_inv);
516  mul_m3_m3m3(smat, t->spacemtx, tmat);
517  }
518 }
519 
524  TransDataContainer *tc,
525  TransData *td,
526  float smat[3][3])
527 {
528  if (td && t->con.mode & CON_APPLY) {
529  float tmat[3][3];
530  float imat[3][3];
531 
532  invert_m3_m3(imat, td->axismtx);
533 
534  if (!(t->con.mode & CON_AXIS0)) {
535  smat[0][0] = 1.0f;
536  }
537  if (!(t->con.mode & CON_AXIS1)) {
538  smat[1][1] = 1.0f;
539  }
540  if (!(t->con.mode & CON_AXIS2)) {
541  smat[2][2] = 1.0f;
542  }
543 
544  mul_m3_m3m3(tmat, smat, imat);
545  if (t->flag & T_EDIT) {
546  mul_m3_m3m3(smat, tc->mat3_unit, smat);
547  }
548  mul_m3_m3m3(smat, td->axismtx, tmat);
549  }
550 }
551 
553  const float axismtx[3][3],
554  float r_vec[3],
555  float *r_angle)
556 {
557  BLI_assert(t->con.mode & CON_APPLY);
558  int mode = t->con.mode & (CON_AXIS0 | CON_AXIS1 | CON_AXIS2);
559 
560  switch (mode) {
561  case CON_AXIS0:
562  case (CON_AXIS1 | CON_AXIS2):
563  copy_v3_v3(r_vec, axismtx[0]);
564  break;
565  case CON_AXIS1:
566  case (CON_AXIS0 | CON_AXIS2):
567  copy_v3_v3(r_vec, axismtx[1]);
568  break;
569  case CON_AXIS2:
570  case (CON_AXIS0 | CON_AXIS1):
571  copy_v3_v3(r_vec, axismtx[2]);
572  break;
573  }
574  /* don't flip axis if asked to or if num input */
575  if (r_angle &&
576  !((mode & CON_NOFLIP) || hasNumInput(&t->num) || (t->flag & T_INPUT_IS_VALUES_FINAL))) {
577  float view_vector[3];
578  view_vector_calc(t, t->center_global, view_vector);
579  if (dot_v3v3(r_vec, view_vector) > 0.0f) {
580  *r_angle = -(*r_angle);
581  }
582  }
583 }
584 
599  TransInfo *t, TransDataContainer *UNUSED(tc), TransData *td, float vec[3], float *angle)
600 {
601  if (!td && t->con.mode & CON_APPLY) {
602  constraints_rotation_impl(t, t->spacemtx, vec, angle);
603  }
604 }
605 
620  TransInfo *t, TransDataContainer *tc, TransData *td, float vec[3], float *angle)
621 {
622  if (t->con.mode & CON_APPLY) {
623  float tmp_axismtx[3][3];
624  const float(*axismtx)[3];
625 
626  /* on setup call, use first object */
627  if (td == NULL) {
628  BLI_assert(tc == NULL);
630  td = tc->data;
631  }
632 
633  if (t->flag & T_EDIT) {
634  mul_m3_m3m3(tmp_axismtx, tc->mat3_unit, td->axismtx);
635  axismtx = tmp_axismtx;
636  }
637  else {
638  axismtx = td->axismtx;
639  }
640 
641  constraints_rotation_impl(t, axismtx, vec, angle);
642  }
643 }
644 
647 /* -------------------------------------------------------------------- */
651 void setConstraint(TransInfo *t, int mode, const char text[])
652 {
653  BLI_strncpy(t->con.text + 1, text, sizeof(t->con.text) - 1);
654  t->con.mode = mode;
655  projection_matrix_calc(t, t->con.pmtx);
656 
658 
659  t->con.drawExtra = NULL;
660  t->con.applyVec = applyAxisConstraintVec;
661  t->con.applySize = applyAxisConstraintSize;
662  t->con.applyRot = applyAxisConstraintRot;
663  t->redraw = TREDRAW_HARD;
664 }
665 
666 /* applies individual td->axismtx constraints */
667 void setAxisMatrixConstraint(TransInfo *t, int mode, const char text[])
668 {
669  BLI_strncpy(t->con.text + 1, text, sizeof(t->con.text) - 1);
670  t->con.mode = mode;
671  projection_matrix_calc(t, t->con.pmtx);
672 
674 
675  t->con.drawExtra = drawObjectConstraint;
676  t->con.applyVec = applyObjectConstraintVec;
677  t->con.applySize = applyObjectConstraintSize;
678  t->con.applyRot = applyObjectConstraintRot;
679  t->redraw = TREDRAW_HARD;
680 }
681 
682 void setLocalConstraint(TransInfo *t, int mode, const char text[])
683 {
684  if ((t->flag & T_EDIT) || t->data_len_all == 1) {
685  /* Although in edit-mode each object has its local space, use the
686  * orientation of the active object. */
687  setConstraint(t, mode, text);
688  }
689  else {
690  setAxisMatrixConstraint(t, mode, text);
691  }
692 }
693 
700 void setUserConstraint(TransInfo *t, int mode, const char ftext[])
701 {
702  char text[256];
703  short orientation = t->orient[t->orient_curr].type;
704  if (orientation == V3D_ORIENT_CUSTOM_MATRIX) {
705  /* Use the real value of the "orient_type". */
706  orientation = t->orient[0].type;
707  }
708 
709  const char *spacename = transform_orientations_spacename_get(t, orientation);
710  BLI_snprintf(text, sizeof(text), ftext, spacename);
711 
712  switch (orientation) {
713  case V3D_ORIENT_LOCAL:
714  setLocalConstraint(t, mode, text);
715  break;
716  case V3D_ORIENT_NORMAL:
717  if (checkUseAxisMatrix(t)) {
718  setAxisMatrixConstraint(t, mode, text);
719  break;
720  }
722  case V3D_ORIENT_GLOBAL:
723  case V3D_ORIENT_VIEW:
724  case V3D_ORIENT_CURSOR:
725  case V3D_ORIENT_GIMBAL:
727  case V3D_ORIENT_CUSTOM:
728  default: {
729  setConstraint(t, mode, text);
730  break;
731  }
732  }
733  t->con.mode |= CON_USER;
734 }
735 
738 /* -------------------------------------------------------------------- */
743 {
744  TransCon *tc = &(t->con);
745 
746  if (!ELEM(t->spacetype, SPACE_VIEW3D, SPACE_IMAGE, SPACE_NODE)) {
747  return;
748  }
749  if (!(tc->mode & CON_APPLY)) {
750  return;
751  }
752  if (t->flag & T_NO_CONSTRAINT) {
753  return;
754  }
755 
756  if (tc->drawExtra) {
757  tc->drawExtra(t);
758  }
759  else {
760  if (tc->mode & CON_SELECT) {
761  float vec[3];
762 
763  convertViewVec(t, vec, (t->mval[0] - t->con.imval[0]), (t->mval[1] - t->con.imval[1]));
764  add_v3_v3(vec, t->center_global);
765 
766  drawLine(t, t->center_global, t->spacemtx[0], 'X', 0);
767  drawLine(t, t->center_global, t->spacemtx[1], 'Y', 0);
768  drawLine(t, t->center_global, t->spacemtx[2], 'Z', 0);
769 
770  eGPUDepthTest depth_test_enabled = GPU_depth_test_get();
771  if (depth_test_enabled) {
773  }
774 
775  const uint shdr_pos = GPU_vertformat_attr_add(
777 
779 
780  float viewport_size[4];
781  GPU_viewport_size_get_f(viewport_size);
782  immUniform2f("viewport_size", viewport_size[2], viewport_size[3]);
783 
784  immUniform1i("colors_len", 0); /* "simple" mode */
785  immUniformColor4f(1.0f, 1.0f, 1.0f, 1.0f);
786  immUniform1f("dash_width", 2.0f);
787  immUniform1f("dash_factor", 0.5f);
788 
790  immVertex3fv(shdr_pos, t->center_global);
791  immVertex3fv(shdr_pos, vec);
792  immEnd();
793 
795 
796  if (depth_test_enabled) {
798  }
799  }
800 
801  if (tc->mode & CON_AXIS0) {
802  drawLine(t, t->center_global, t->spacemtx[0], 'X', DRAWLIGHT);
803  }
804  if (tc->mode & CON_AXIS1) {
805  drawLine(t, t->center_global, t->spacemtx[1], 'Y', DRAWLIGHT);
806  }
807  if (tc->mode & CON_AXIS2) {
808  drawLine(t, t->center_global, t->spacemtx[2], 'Z', DRAWLIGHT);
809  }
810  }
811 }
812 
813 /* called from drawview.c, as an extra per-window draw option */
814 void drawPropCircle(const struct bContext *C, TransInfo *t)
815 {
816  if (t->flag & T_PROP_EDIT) {
818  float tmat[4][4], imat[4][4];
819 
820  if (t->spacetype == SPACE_VIEW3D && rv3d != NULL) {
821  copy_m4_m4(tmat, rv3d->viewmat);
822  invert_m4_m4(imat, tmat);
823  }
824  else {
825  unit_m4(tmat);
826  unit_m4(imat);
827  }
828 
829  GPU_matrix_push();
830 
831  if (t->spacetype == SPACE_VIEW3D) {
832  /* pass */
833  }
834  else if (t->spacetype == SPACE_IMAGE) {
835  GPU_matrix_scale_2f(1.0f / t->aspect[0], 1.0f / t->aspect[1]);
836  }
837  else if (ELEM(t->spacetype, SPACE_GRAPH, SPACE_ACTION)) {
838  /* only scale y */
839  rcti *mask = &t->region->v2d.mask;
840  rctf *datamask = &t->region->v2d.cur;
841  float xsize = BLI_rctf_size_x(datamask);
842  float ysize = BLI_rctf_size_y(datamask);
843  float xmask = BLI_rcti_size_x(mask);
844  float ymask = BLI_rcti_size_y(mask);
845  GPU_matrix_scale_2f(1.0f, (ysize / xsize) * (xmask / ymask));
846  }
847 
848  eGPUDepthTest depth_test_enabled = GPU_depth_test_get();
849  if (depth_test_enabled) {
851  }
852 
854 
856 
857  float viewport[4];
858  GPU_viewport_size_get_f(viewport);
860 
861  immUniform2fv("viewportSize", &viewport[2]);
862  immUniform1f("lineWidth", 3.0f * U.pixelsize);
863 
865  imm_drawcircball(t->center_global, t->prop_size, imat, pos);
866 
867  immUniform1f("lineWidth", 1.0f * U.pixelsize);
869  imm_drawcircball(t->center_global, t->prop_size, imat, pos);
870 
872 
873  if (depth_test_enabled) {
875  }
876 
877  GPU_matrix_pop();
878  }
879 }
880 
882 {
883  /* Draw the first one lighter because that's the one who controls the others.
884  * Meaning the transformation is projected on that one and just copied on the others
885  * constraint space.
886  * In a nutshell, the object with light axis is controlled by the user and the others follow.
887  * Without drawing the first light, users have little clue what they are doing.
888  */
889  short options = DRAWLIGHT;
890  float tmp_axismtx[3][3];
891 
893  TransData *td = tc->data;
894  for (int i = 0; i < tc->data_len; i++, td++) {
895  float co[3];
896  float(*axismtx)[3];
897 
898  if (t->flag & T_PROP_EDIT) {
899  /* we're sorted, so skip the rest */
900  if (td->factor == 0.0f) {
901  break;
902  }
903  }
904 
905  if (t->options & CTX_GPENCIL_STROKES) {
906  /* only draw a constraint line for one point, otherwise we can't see anything */
907  if ((options & DRAWLIGHT) == 0) {
908  break;
909  }
910  }
911 
912  if (t->flag & T_EDIT) {
913  mul_v3_m4v3(co, tc->mat, td->center);
914 
915  mul_m3_m3m3(tmp_axismtx, tc->mat3_unit, td->axismtx);
916  axismtx = tmp_axismtx;
917  }
918  else if (t->options & CTX_POSE_BONE) {
919  mul_v3_m4v3(co, tc->mat, td->center);
920  axismtx = td->axismtx;
921  }
922  else {
923  copy_v3_v3(co, td->center);
924  axismtx = td->axismtx;
925  }
926 
927  if (t->con.mode & CON_AXIS0) {
928  drawLine(t, co, axismtx[0], 'X', options);
929  }
930  if (t->con.mode & CON_AXIS1) {
931  drawLine(t, co, axismtx[1], 'Y', options);
932  }
933  if (t->con.mode & CON_AXIS2) {
934  drawLine(t, co, axismtx[2], 'Z', options);
935  }
936  options &= ~DRAWLIGHT;
937  }
938  }
939 }
940 
943 /* -------------------------------------------------------------------- */
948 {
949  t->con.mode |= CON_APPLY;
950  *t->con.text = ' ';
951  t->num.idx_max = min_ii(getConstraintSpaceDimension(t) - 1, t->idx_max);
952 }
953 
955 {
956  if (t->orient_curr != O_DEFAULT) {
958  }
959 
960  t->con.mode &= ~(CON_APPLY | CON_SELECT);
961  *t->con.text = '\0';
962  t->num.idx_max = t->idx_max;
963 }
964 
967 /* -------------------------------------------------------------------- */
972 {
973  if (t->orient_curr == O_DEFAULT) {
975  }
976 
978 }
979 
981 {
982  if (t->con.mode & CON_SELECT) {
983  setNearestAxis(t);
985  }
986 }
987 
989 {
990  if (!(t->con.mode & CON_SELECT)) {
991  return;
992  }
993 
994  t->con.mode &= ~CON_AXIS0;
995  t->con.mode &= ~CON_AXIS1;
996  t->con.mode &= ~CON_AXIS2;
997  t->con.mode &= ~CON_SELECT;
998 
999  setNearestAxis(t);
1000 
1001  startConstraint(t);
1002  t->redraw = TREDRAW_HARD;
1003 }
1004 
1006 {
1007  /* no correction needed... just use whichever one is lower */
1008  if (abs(t->mval[0] - t->con.imval[0]) < abs(t->mval[1] - t->con.imval[1])) {
1009  t->con.mode |= CON_AXIS1;
1010  BLI_strncpy(t->con.text, TIP_(" along Y axis"), sizeof(t->con.text));
1011  }
1012  else {
1013  t->con.mode |= CON_AXIS0;
1014  BLI_strncpy(t->con.text, TIP_(" along X axis"), sizeof(t->con.text));
1015  }
1016 }
1017 
1019 {
1020  float zfac;
1021  float mvec[3], proj[3];
1022  float len[3];
1023  int i;
1024 
1025  /* calculate mouse movement */
1026  mvec[0] = (float)(t->mval[0] - t->con.imval[0]);
1027  mvec[1] = (float)(t->mval[1] - t->con.imval[1]);
1028  mvec[2] = 0.0f;
1029 
1030  /* We need to correct axis length for the current zoom-level of view,
1031  * this to prevent projected values to be clipped behind the camera
1032  * and to overflow the short integers.
1033  * The formula used is a bit stupid, just a simplification of the subtraction
1034  * of two 2D points 30 pixels apart (that's the last factor in the formula) after
1035  * projecting them with ED_view3d_win_to_delta and then get the length of that vector.
1036  */
1037  zfac = mul_project_m4_v3_zfac(t->persmat, t->center_global);
1038  zfac = len_v3(t->persinv[0]) * 2.0f / t->region->winx * zfac * 30.0f;
1039 
1040  for (i = 0; i < 3; i++) {
1041  float axis[3], axis_2d[2];
1042 
1043  copy_v3_v3(axis, t->spacemtx[i]);
1044 
1045  mul_v3_fl(axis, zfac);
1046  /* now we can project to get window coordinate */
1047  add_v3_v3(axis, t->center_global);
1048  projectFloatView(t, axis, axis_2d);
1049 
1050  sub_v2_v2v2(axis, axis_2d, t->center2d);
1051  axis[2] = 0.0f;
1052 
1053  if (normalize_v3(axis) > 1e-3f) {
1054  project_v3_v3v3(proj, mvec, axis);
1055  sub_v3_v3v3(axis, mvec, proj);
1056  len[i] = normalize_v3(axis);
1057  }
1058  else {
1059  len[i] = 1e10f;
1060  }
1061  }
1062 
1063  if (len[0] <= len[1] && len[0] <= len[2]) {
1064  if (t->modifiers & MOD_CONSTRAINT_SELECT_PLANE) {
1065  t->con.mode |= (CON_AXIS1 | CON_AXIS2);
1066  BLI_snprintf(t->con.text, sizeof(t->con.text), TIP_(" locking %s X axis"), t->spacename);
1067  }
1068  else {
1069  t->con.mode |= CON_AXIS0;
1070  BLI_snprintf(t->con.text, sizeof(t->con.text), TIP_(" along %s X axis"), t->spacename);
1071  }
1072  }
1073  else if (len[1] <= len[0] && len[1] <= len[2]) {
1074  if (t->modifiers & MOD_CONSTRAINT_SELECT_PLANE) {
1075  t->con.mode |= (CON_AXIS0 | CON_AXIS2);
1076  BLI_snprintf(t->con.text, sizeof(t->con.text), TIP_(" locking %s Y axis"), t->spacename);
1077  }
1078  else {
1079  t->con.mode |= CON_AXIS1;
1080  BLI_snprintf(t->con.text, sizeof(t->con.text), TIP_(" along %s Y axis"), t->spacename);
1081  }
1082  }
1083  else if (len[2] <= len[1] && len[2] <= len[0]) {
1084  if (t->modifiers & MOD_CONSTRAINT_SELECT_PLANE) {
1085  t->con.mode |= (CON_AXIS0 | CON_AXIS1);
1086  BLI_snprintf(t->con.text, sizeof(t->con.text), TIP_(" locking %s Z axis"), t->spacename);
1087  }
1088  else {
1089  t->con.mode |= CON_AXIS2;
1090  BLI_snprintf(t->con.text, sizeof(t->con.text), TIP_(" along %s Z axis"), t->spacename);
1091  }
1092  }
1093 }
1094 
1096 {
1097  /* clear any prior constraint flags */
1098  t->con.mode &= ~CON_AXIS0;
1099  t->con.mode &= ~CON_AXIS1;
1100  t->con.mode &= ~CON_AXIS2;
1101 
1102  /* constraint setting - depends on spacetype */
1103  if (t->spacetype == SPACE_VIEW3D) {
1104  /* 3d-view */
1106  }
1107  else {
1108  /* assume that this means a 2D-Editor */
1110  }
1111 
1112  projection_matrix_calc(t, t->con.pmtx);
1113 }
1114 
1117 /* -------------------------------------------------------------------- */
1122 {
1123  if ((t->con.mode & CON_APPLY) == 0) {
1124  return -1;
1125  }
1126  switch (t->con.mode & (CON_AXIS0 | CON_AXIS1 | CON_AXIS2)) {
1127  case (CON_AXIS0):
1128  case (CON_AXIS1 | CON_AXIS2):
1129  return 0;
1130  case (CON_AXIS1):
1131  case (CON_AXIS0 | CON_AXIS2):
1132  return 1;
1133  case (CON_AXIS2):
1134  case (CON_AXIS0 | CON_AXIS1):
1135  return 2;
1136  default:
1137  return -1;
1138  }
1139 }
1140 
1142 {
1143  int mode = t->con.mode;
1144 
1145  if ((mode & (CON_AXIS0 | CON_AXIS1)) == (CON_AXIS0 | CON_AXIS1)) {
1146  return true;
1147  }
1148 
1149  if ((mode & (CON_AXIS1 | CON_AXIS2)) == (CON_AXIS1 | CON_AXIS2)) {
1150  return true;
1151  }
1152 
1153  if ((mode & (CON_AXIS0 | CON_AXIS2)) == (CON_AXIS0 | CON_AXIS2)) {
1154  return true;
1155  }
1156 
1157  return false;
1158 }
1159 
1168 {
1169  int n = 0;
1170 
1171  if (t->con.mode & CON_AXIS0) {
1172  n++;
1173  }
1174 
1175  if (t->con.mode & CON_AXIS1) {
1176  n++;
1177  }
1178 
1179  if (t->con.mode & CON_AXIS2) {
1180  n++;
1181  }
1182 
1183  return n;
1184  /* Someone willing to do it cryptically could do the following instead:
1185  *
1186  * `return t->con & (CON_AXIS0|CON_AXIS1|CON_AXIS2);`
1187  *
1188  * Based on the assumptions that the axis flags are one after the other and start at 1
1189  */
1190 }
1191 
typedef float(TangentPoint)[2]
struct RegionView3D * CTX_wm_region_view3d(const bContext *C)
Definition: context.c:769
#define BLI_assert(a)
Definition: BLI_assert.h:58
#define ATTR_FALLTHROUGH
MINLINE int min_ii(int a, int b)
#define M_PI_2
Definition: BLI_math_base.h:41
#define M_PI
Definition: BLI_math_base.h:38
void plane_from_point_normal_v3(float r_plane[4], const float plane_co[3], const float plane_no[3])
Definition: math_geom.c:243
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:3210
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:3341
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:2265
bool isect_ray_plane_v3(const float ray_origin[3], const float ray_direction[3], const float plane[4], float *r_lambda, const bool clip)
Definition: math_geom.c:1808
void mul_m3_v3(const float M[3][3], float r[3])
Definition: math_matrix.c:930
void unit_m3(float m[3][3])
Definition: math_matrix.c:58
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
bool invert_m3_m3(float R[3][3], const float A[3][3])
Definition: math_matrix.c:1161
void copy_m4_m4(float m1[4][4], const float m2[4][4])
Definition: math_matrix.c:95
void mul_v3_m4v3(float r[3], const float M[4][4], const float v[3])
Definition: math_matrix.c:742
void mul_m3_m3m3(float R[3][3], const float A[3][3], const float B[3][3])
Definition: math_matrix.c:391
#define DEG2RADF(_deg)
float angle_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
Definition: math_vector.c:443
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:674
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 float normalize_v3_v3_length(float r[3], const float a[3], const float unit_scale)
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
BLI_INLINE int BLI_rcti_size_y(const struct rcti *rct)
Definition: BLI_rect.h:157
BLI_INLINE int BLI_rcti_size_x(const struct rcti *rct)
Definition: BLI_rect.h:153
BLI_INLINE float BLI_rctf_size_x(const struct rctf *rct)
Definition: BLI_rect.h:161
BLI_INLINE float BLI_rctf_size_y(const struct rctf *rct)
Definition: BLI_rect.h:165
size_t BLI_snprintf(char *__restrict dst, size_t maxncpy, const char *__restrict format,...) ATTR_NONNULL(1
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, const size_t maxncpy) ATTR_NONNULL()
Definition: string.c:108
unsigned int uint
Definition: BLI_sys_types.h:83
#define UNUSED(x)
#define ELEM(...)
#define TIP_(msgid)
Object is a sort of wrapper for general info.
#define SCE_SNAP_MODE_FACE
#define SCE_SNAP_MODE_GRID
#define SCE_SNAP_MODE_EDGE
@ SPACE_ACTION
@ SPACE_NODE
@ 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:185
void imm_drawcircball(const float cent[3], float rad, const float tmat[4][4], unsigned int pos)
Definition: drawobject.c:90
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)
_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:142
void GPU_matrix_scale_2f(float x, float y)
Definition: gpu_matrix.cc:232
void GPU_matrix_push(void)
Definition: gpu_matrix.cc:135
@ GPU_PRIM_LINES
Definition: GPU_primitive.h:36
@ GPU_SHADER_3D_LINE_DASHED_UNIFORM_COLOR
Definition: GPU_shader.h:366
@ GPU_SHADER_3D_POLYLINE_UNIFORM_COLOR
Definition: GPU_shader.h:223
@ GPU_BLEND_ALPHA
Definition: GPU_state.h:57
void GPU_blend(eGPUBlend blend)
Definition: gpu_state.cc:55
eGPUDepthTest
Definition: GPU_state.h:77
@ GPU_DEPTH_LESS_EQUAL
Definition: GPU_state.h:81
@ GPU_DEPTH_NONE
Definition: GPU_state.h:78
eGPUDepthTest GPU_depth_test_get(void)
Definition: gpu_state.cc:255
void GPU_depth_test(eGPUDepthTest test)
Definition: gpu_state.cc:75
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
#define C
Definition: RandGen.cpp:39
@ TH_GRID
Definition: UI_resources.h:84
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
uint pos
#define fabsf(x)
bool isfinite(uchar)
Definition: image.cpp:44
static unsigned c
Definition: RandGen.cpp:97
IMETHOD Vector diff(const Vector &a, const Vector &b, double dt=1)
static bool is_aligned(void *ptr, uint alignment)
const btScalar eps
Definition: poly34.cpp:11
float viewmat[4][4]
void(* drawExtra)(struct TransInfo *t)
Definition: transform.h:349
eTConstraint mode
Definition: transform.h:348
float mat3_unit[3][3]
Definition: transform.h:470
TransData * data
Definition: transform.h:448
float axismtx[3][3]
bool checkUseAxisMatrix(TransInfo *t)
Definition: transform.c:1965
void convertViewVec(TransInfo *t, float r_vec[3], double dx, double dy)
Definition: transform.c:180
void projectFloatView(TransInfo *t, const float vec[3], float adr[2])
Definition: transform.c:376
#define DRAWLIGHT
Definition: transform.h:773
@ CON_NOFLIP
Definition: transform.h:184
@ CON_APPLY
Definition: transform.h:177
@ CON_SELECT
Definition: transform.h:182
@ CON_AXIS1
Definition: transform.h:180
@ CON_USER
Definition: transform.h:185
@ CON_AXIS0
Definition: transform.h:179
@ CON_AXIS2
Definition: transform.h:181
@ CTX_POSE_BONE
Definition: transform.h:87
@ CTX_GPENCIL_STROKES
Definition: transform.h:82
@ MOD_CONSTRAINT_SELECT_PLANE
Definition: transform.h:161
#define TRANS_DATA_CONTAINER_FIRST_OK(t)
Definition: transform.h:808
@ TREDRAW_HARD
Definition: transform.h:199
@ T_PROP_EDIT
Definition: transform.h:111
@ T_INPUT_IS_VALUES_FINAL
Definition: transform.h:129
@ T_NO_CONSTRAINT
Definition: transform.h:106
@ T_NULL_ONE
Definition: transform.h:107
@ T_EDIT
Definition: transform.h:102
void drawLine(TransInfo *t, const float center[3], const float dir[3], char axis, short options)
#define FOREACH_TRANS_DATA_CONTAINER(t, th)
Definition: transform.h:813
static void constraints_rotation_impl(TransInfo *t, const float axismtx[3][3], float r_vec[3], float *r_angle)
static void applyObjectConstraintSize(TransInfo *t, TransDataContainer *tc, TransData *td, float smat[3][3])
static void drawObjectConstraint(TransInfo *t)
#define CONSTRAIN_EPSILON
void drawConstraint(TransInfo *t)
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)
int getConstraintSpaceDimension(TransInfo *t)
void transform_constraint_snap_axis_to_face(const TransInfo *t, const float axis[3], float r_out[3])
static void constraint_plane_calc(TransInfo *t, float r_plane[4])
static void setNearestAxis3d(TransInfo *t)
void postSelectConstraint(TransInfo *t)
void setUserConstraint(TransInfo *t, int mode, const char ftext[])
void stopConstraint(TransInfo *t)
static void planeProjection(const TransInfo *t, const float in[3], float out[3])
void constraintNumInput(TransInfo *t, float vec[3])
static void applyObjectConstraintVec(TransInfo *t, TransDataContainer *tc, TransData *td, const float in[3], float out[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])
void transform_constraint_snap_axis_to_edge(const TransInfo *t, const float axis[3], float r_out[3])
bool isLockConstraint(TransInfo *t)
static void applyAxisConstraintRot(TransInfo *t, TransDataContainer *UNUSED(tc), TransData *td, float vec[3], float *angle)
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 void applyAxisConstraintSize(TransInfo *t, TransDataContainer *UNUSED(tc), TransData *td, float smat[3][3])
static void applyAxisConstraintVec(TransInfo *t, TransDataContainer *UNUSED(tc), TransData *td, const float in[3], float out[3])
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 axisProjection(const TransInfo *t, const float axis[3], const float in[3], float out[3])
static void applyObjectConstraintRot(TransInfo *t, TransDataContainer *tc, TransData *td, float vec[3], float *angle)
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)
__forceinline const avxi abs(const avxi &a)
Definition: util_avxi.h:186
ccl_device_inline float4 mask(const int4 &mask, const float4 &a)
uint len