70
73
static void drawObjectConstraint(TransInfo *t);
72
75
/* ************************** CONSTRAINTS ************************* */
73
void constraintAutoValues(TransInfo *t, float vec[3])
76
static void constraintAutoValues(TransInfo *t, float vec[3])
75
78
int mode = t->con.mode;
76
79
if (mode & CON_APPLY)
78
81
float nval = (t->flag & T_NULL_ONE)?1.0f:0.0f;
80
if ((mode & CON_AXIS0) == 0)
83
if ((mode & CON_AXIS0) == 0) {
84
if ((mode & CON_AXIS1) == 0)
86
if ((mode & CON_AXIS1) == 0) {
88
if ((mode & CON_AXIS2) == 0)
89
if ((mode & CON_AXIS2) == 0) {
157
158
if (hasNumInput(&t->num)) {
158
159
applyNumInput(&t->num, vec);
160
removeAspectRatio(t, vec);
159
161
constraintNumInput(t, vec);
162
164
/* autovalues is operator param, use that directly but not if snapping is forced */
163
if (t->flag & T_AUTOVALUES && (t->tsnap.status & SNAP_FORCED) == 0)
165
VECCOPY(vec, t->auto_values);
165
if (t->flag & T_AUTOVALUES && (t->tsnap.status & SNAP_FORCED) == 0) {
166
mul_v3_m3v3(vec, t->con.imtx, t->auto_values);
166
167
constraintAutoValues(t, vec);
168
/* inverse transformation at the end */
169
171
if (t->con.mode & CON_AXIS0) {
179
181
mul_m3_v3(t->con.mtx, vec);
182
static void axisProjection(TransInfo *t, float axis[3], float in[3], float out[3]) {
184
static void viewAxisCorrectCenter(TransInfo *t, float t_con_center[3])
186
if (t->spacetype == SPACE_VIEW3D) {
187
// View3D *v3d = t->sa->spacedata.first;
188
const float min_dist= 1.0f; // v3d->near;
192
sub_v3_v3v3(dir, t_con_center, t->viewinv[3]);
193
if (dot_v3v3(dir, t->viewinv[2]) < 0.0f) {
196
project_v3_v3v3(dir, dir, t->viewinv[2]);
202
normalize_v3_v3(diff, t->viewinv[2]);
203
mul_v3_fl(diff, min_dist - l);
205
sub_v3_v3(t_con_center, diff);
210
static void axisProjection(TransInfo *t, float axis[3], float in[3], float out[3])
183
212
float norm[3], vec[3], factor, angle;
213
float t_con_center[3];
185
if(in[0]==0.0f && in[1]==0.0f && in[2]==0.0f)
215
if (in[0]==0.0f && in[1]==0.0f && in[2]==0.0f)
188
angle = fabs(angle_v3v3(axis, t->viewinv[2]));
189
if (angle > M_PI / 2) {
190
angle = M_PI - angle;
218
copy_v3_v3(t_con_center, t->con.center);
220
/* checks for center being too close to the view center */
221
viewAxisCorrectCenter(t, t_con_center);
223
angle = fabsf(angle_v3v3(axis, t->viewinv[2]));
224
if (angle > (float)M_PI / 2.0f) {
225
angle = (float)M_PI - angle;
192
angle = 180.0f * angle / M_PI;
227
angle = RAD2DEGF(angle);
194
229
/* For when view is parallel to constraint... will cause NaNs otherwise
195
So we take vertical motion in 3D space and apply it to the
196
constraint axis. Nice for camera grab + MMB */
230
* So we take vertical motion in 3D space and apply it to the
231
* constraint axis. Nice for camera grab + MMB */
198
233
project_v3_v3v3(vec, in, t->viewinv[1]);
199
234
factor = dot_v3v3(t->viewinv[1], vec) * 2.0f;
200
235
/* since camera distance is quite relative, use quadratic relationship. holding shift can compensate */
201
if(factor<0.0f) factor*= -factor;
236
if (factor<0.0f) factor*= -factor;
202
237
else factor*= factor;
239
copy_v3_v3(out, axis);
205
240
normalize_v3(out);
206
241
mul_v3_fl(out, -factor); /* -factor makes move down going backwards */
211
246
float norm_center[3];
214
getViewVector(t, t->con.center, norm_center);
249
getViewVector(t, t_con_center, norm_center);
215
250
cross_v3_v3v3(plane, norm_center, axis);
217
252
project_v3_v3v3(vec, in, plane);
218
253
sub_v3_v3v3(vec, in, vec);
220
add_v3_v3v3(v, vec, t->con.center);
255
add_v3_v3v3(v, vec, t_con_center);
221
256
getViewVector(t, v, norm);
223
258
/* give arbitrary large value if projection is impossible */
224
259
factor = dot_v3v3(axis, norm);
225
if (1 - fabs(factor) < 0.0002f) {
260
if (1.0f - fabsf(factor) < 0.0002f) {
261
copy_v3_v3(out, axis);
227
262
if (factor > 0) {
228
mul_v3_fl(out, 1000000000);
230
mul_v3_fl(out, -1000000000);
233
add_v3_v3v3(v2, t->con.center, axis);
263
mul_v3_fl(out, 1000000000.0f);
266
mul_v3_fl(out, -1000000000.0f);
270
add_v3_v3v3(v2, t_con_center, axis);
234
271
add_v3_v3v3(v4, v, norm);
236
isect_line_line_v3(t->con.center, v2, v, v4, i1, i2);
273
isect_line_line_v3(t_con_center, v2, v, v4, i1, i2);
238
275
sub_v3_v3v3(v, i2, v);
240
sub_v3_v3v3(out, i1, t->con.center);
277
sub_v3_v3v3(out, i1, t_con_center);
279
/* possible some values become nan when
280
* viewpoint and object are both zero */
281
if (!finite(out[0])) out[0]= 0.0f;
282
if (!finite(out[1])) out[1]= 0.0f;
283
if (!finite(out[2])) out[2]= 0.0f;
245
static void planeProjection(TransInfo *t, float in[3], float out[3]) {
288
static void planeProjection(TransInfo *t, float in[3], float out[3])
246
290
float vec[3], factor, norm[3];
248
292
add_v3_v3v3(vec, in, t->con.center);
290
334
if (t->con.mode & CON_AXIS0) {
291
VECCOPY(c, t->con.mtx[0]);
335
copy_v3_v3(c, t->con.mtx[0]);
293
337
else if (t->con.mode & CON_AXIS1) {
294
VECCOPY(c, t->con.mtx[1]);
338
copy_v3_v3(c, t->con.mtx[1]);
296
340
else if (t->con.mode & CON_AXIS2) {
297
VECCOPY(c, t->con.mtx[2]);
341
copy_v3_v3(c, t->con.mtx[2]);
299
343
axisProjection(t, c, in, out);
331
375
if (t->con.mode & CON_AXIS0) {
332
VECCOPY(c, t->con.mtx[0]);
376
copy_v3_v3(c, t->con.mtx[0]);
334
378
else if (t->con.mode & CON_AXIS1) {
335
VECCOPY(c, t->con.mtx[1]);
379
copy_v3_v3(c, t->con.mtx[1]);
337
381
else if (t->con.mode & CON_AXIS2) {
338
VECCOPY(c, t->con.mtx[2]);
382
copy_v3_v3(c, t->con.mtx[2]);
340
384
axisProjection(t, c, in, out);
342
386
postConstraintChecks(t, out, pvec);
387
copy_v3_v3(out, pvec);
439
483
case (CON_AXIS1|CON_AXIS2):
440
VECCOPY(vec, t->con.mtx[0]);
484
copy_v3_v3(vec, t->con.mtx[0]);
443
487
case (CON_AXIS0|CON_AXIS2):
444
VECCOPY(vec, t->con.mtx[1]);
488
copy_v3_v3(vec, t->con.mtx[1]);
447
491
case (CON_AXIS0|CON_AXIS1):
448
VECCOPY(vec, t->con.mtx[2]);
492
copy_v3_v3(vec, t->con.mtx[2]);
451
495
/* don't flip axis if asked to or if num input */
486
530
case (CON_AXIS1|CON_AXIS2):
487
VECCOPY(vec, td->axismtx[0]);
531
copy_v3_v3(vec, td->axismtx[0]);
490
534
case (CON_AXIS0|CON_AXIS2):
491
VECCOPY(vec, td->axismtx[1]);
535
copy_v3_v3(vec, td->axismtx[1]);
494
538
case (CON_AXIS0|CON_AXIS1):
495
VECCOPY(vec, td->axismtx[2]);
539
copy_v3_v3(vec, td->axismtx[2]);
498
542
if (angle && (mode & CON_NOFLIP) == 0 && hasNumInput(&t->num) == 0) {
506
550
/*--------------------- INTERNAL SETUP CALLS ------------------*/
508
void setConstraint(TransInfo *t, float space[3][3], int mode, const char text[]) {
509
strncpy(t->con.text + 1, text, 48);
552
void setConstraint(TransInfo *t, float space[3][3], int mode, const char text[])
554
BLI_strncpy(t->con.text + 1, text, sizeof(t->con.text) - 1);
510
555
copy_m3_m3(t->con.mtx, space);
511
556
t->con.mode = mode;
512
557
getConstraintMatrix(t);
552
Set the constraint according to the user defined orientation
554
ftext is a format string passed to sprintf. It will add the name of
555
the orientation where %s is (logically).
557
void setUserConstraint(TransInfo *t, short orientation, int mode, const char ftext[]) {
598
* Set the constraint according to the user defined orientation
600
* ftext is a format string passed to BLI_snprintf. It will add the name of
601
* the orientation where %s is (logically).
603
void setUserConstraint(TransInfo *t, short orientation, int mode, const char ftext[])
560
607
switch(orientation) {
561
608
case V3D_MANIP_GLOBAL:
564
sprintf(text, ftext, "global");
610
float mtx[3][3]= MAT3_UNITY;
611
BLI_snprintf(text, sizeof(text), ftext, "global");
566
612
setConstraint(t, mtx, mode, text);
569
615
case V3D_MANIP_LOCAL:
570
sprintf(text, ftext, "local");
616
BLI_snprintf(text, sizeof(text), ftext, "local");
571
617
setLocalConstraint(t, mode, text);
573
619
case V3D_MANIP_NORMAL:
574
sprintf(text, ftext, "normal");
620
BLI_snprintf(text, sizeof(text), ftext, "normal");
575
621
setConstraint(t, t->spacemtx, mode, text);
577
623
case V3D_MANIP_VIEW:
578
sprintf(text, ftext, "view");
624
BLI_snprintf(text, sizeof(text), ftext, "view");
579
625
setConstraint(t, t->spacemtx, mode, text);
581
627
case V3D_MANIP_GIMBAL:
582
sprintf(text, ftext, "gimbal");
628
BLI_snprintf(text, sizeof(text), ftext, "gimbal");
583
629
setConstraint(t, t->spacemtx, mode, text);
585
631
default: /* V3D_MANIP_CUSTOM */
586
sprintf(text, ftext, t->spacename);
632
BLI_snprintf(text, sizeof(text), ftext, t->spacename);
587
633
setConstraint(t, t->spacemtx, mode, text);
622
668
char col2[3] = {255,255,255};
623
669
int depth_test_enabled;
625
convertViewVec(t, vec, (short)(t->mval[0] - t->con.imval[0]), (short)(t->mval[1] - t->con.imval[1]));
671
convertViewVec(t, vec, (t->mval[0] - t->con.imval[0]), (t->mval[1] - t->con.imval[1]));
626
672
add_v3_v3(vec, tc->center);
628
drawLine(t, tc->center, tc->mtx[0], 'x', 0);
629
drawLine(t, tc->center, tc->mtx[1], 'y', 0);
630
drawLine(t, tc->center, tc->mtx[2], 'z', 0);
674
drawLine(t, tc->center, tc->mtx[0], 'X', 0);
675
drawLine(t, tc->center, tc->mtx[1], 'Y', 0);
676
drawLine(t, tc->center, tc->mtx[2], 'Z', 0);
632
678
glColor3ubv((GLubyte *)col2);
634
680
depth_test_enabled = glIsEnabled(GL_DEPTH_TEST);
635
if(depth_test_enabled)
681
if (depth_test_enabled)
636
682
glDisable(GL_DEPTH_TEST);
645
if(depth_test_enabled)
691
if (depth_test_enabled)
646
692
glEnable(GL_DEPTH_TEST);
649
695
if (tc->mode & CON_AXIS0) {
650
drawLine(t, tc->center, tc->mtx[0], 'x', DRAWLIGHT);
696
drawLine(t, tc->center, tc->mtx[0], 'X', DRAWLIGHT);
652
698
if (tc->mode & CON_AXIS1) {
653
drawLine(t, tc->center, tc->mtx[1], 'y', DRAWLIGHT);
699
drawLine(t, tc->center, tc->mtx[1], 'Y', DRAWLIGHT);
655
701
if (tc->mode & CON_AXIS2) {
656
drawLine(t, tc->center, tc->mtx[2], 'z', DRAWLIGHT);
702
drawLine(t, tc->center, tc->mtx[2], 'Z', DRAWLIGHT);
669
715
UI_ThemeColor(TH_GRID);
671
if(t->spacetype == SPACE_VIEW3D && rv3d != NULL)
717
if (t->spacetype == SPACE_VIEW3D && rv3d != NULL) {
673
718
copy_m4_m4(tmat, rv3d->viewmat);
674
719
invert_m4_m4(imat, tmat);
684
VECCOPY(center, t->center);
728
copy_v3_v3(center, t->center);
686
if((t->spacetype == SPACE_VIEW3D) && t->obedit)
730
if ((t->spacetype == SPACE_VIEW3D) && t->obedit) {
688
731
mul_m4_v3(t->obedit->obmat, center); /* because t->center is in local space */
690
else if(t->spacetype == SPACE_IMAGE)
733
else if (t->spacetype == SPACE_IMAGE) {
692
734
float aspx, aspy;
694
736
ED_space_image_uv_aspect(t->sa->spacedata.first, &aspx, &aspy);
706
static void drawObjectConstraint(TransInfo *t) {
748
static void drawObjectConstraint(TransInfo *t)
708
751
TransData * td = t->data;
710
753
/* Draw the first one lighter because that's the one who controls the others.
711
Meaning the transformation is projected on that one and just copied on the others
713
In a nutshell, the object with light axis is controlled by the user and the others follow.
714
Without drawing the first light, users have little clue what they are doing.
754
* Meaning the transformation is projected on that one and just copied on the others
756
* In a nutshell, the object with light axis is controlled by the user and the others follow.
757
* Without drawing the first light, users have little clue what they are doing.
716
759
if (t->con.mode & CON_AXIS0) {
717
drawLine(t, td->ob->obmat[3], td->axismtx[0], 'x', DRAWLIGHT);
760
drawLine(t, td->ob->obmat[3], td->axismtx[0], 'X', DRAWLIGHT);
719
762
if (t->con.mode & CON_AXIS1) {
720
drawLine(t, td->ob->obmat[3], td->axismtx[1], 'y', DRAWLIGHT);
763
drawLine(t, td->ob->obmat[3], td->axismtx[1], 'Y', DRAWLIGHT);
722
765
if (t->con.mode & CON_AXIS2) {
723
drawLine(t, td->ob->obmat[3], td->axismtx[2], 'z', DRAWLIGHT);
766
drawLine(t, td->ob->obmat[3], td->axismtx[2], 'Z', DRAWLIGHT);
728
for(i=1;i<t->total;i++,td++) {
771
for (i=1;i<t->total;i++,td++) {
729
772
if (t->con.mode & CON_AXIS0) {
730
drawLine(t, td->ob->obmat[3], td->axismtx[0], 'x', 0);
773
drawLine(t, td->ob->obmat[3], td->axismtx[0], 'X', 0);
732
775
if (t->con.mode & CON_AXIS1) {
733
drawLine(t, td->ob->obmat[3], td->axismtx[1], 'y', 0);
776
drawLine(t, td->ob->obmat[3], td->axismtx[1], 'Y', 0);
735
778
if (t->con.mode & CON_AXIS2) {
736
drawLine(t, td->ob->obmat[3], td->axismtx[2], 'z', 0);
779
drawLine(t, td->ob->obmat[3], td->axismtx[2], 'Z', 0);
741
784
/*--------------------- START / STOP CONSTRAINTS ---------------------- */
743
void startConstraint(TransInfo *t) {
786
void startConstraint(TransInfo *t)
744
788
t->con.mode |= CON_APPLY;
745
789
*t->con.text = ' ';
746
790
t->num.idx_max = MIN2(getConstraintSpaceDimension(t) - 1, t->idx_max);
749
void stopConstraint(TransInfo *t) {
793
void stopConstraint(TransInfo *t)
750
795
t->con.mode &= ~(CON_APPLY|CON_SELECT);
751
796
*t->con.text = '\0';
752
797
t->num.idx_max = t->idx_max;
823
869
/* no correction needed... just use whichever one is lower */
824
870
if ( abs(t->mval[0]-t->con.imval[0]) < abs(t->mval[1]-t->con.imval[1]) ) {
825
871
t->con.mode |= CON_AXIS1;
826
sprintf(t->con.text, " along Y axis");
872
BLI_snprintf(t->con.text, sizeof(t->con.text), " along Y axis");
829
875
t->con.mode |= CON_AXIS0;
830
sprintf(t->con.text, " along X axis");
876
BLI_snprintf(t->con.text, sizeof(t->con.text), " along X axis");
846
892
/* we need to correct axis length for the current zoomlevel of view,
847
this to prevent projected values to be clipped behind the camera
848
and to overflow the short integers.
849
The formula used is a bit stupid, just a simplification of the substraction
850
of two 2D points 30 pixels apart (that's the last factor in the formula) after
851
projecting them with window_to_3d_delta and then get the length of that vector.
893
* this to prevent projected values to be clipped behind the camera
894
* and to overflow the short integers.
895
* The formula used is a bit stupid, just a simplification of the subtraction
896
* of two 2D points 30 pixels apart (that's the last factor in the formula) after
897
* projecting them with window_to_3d_delta and then get the length of that vector.
853
899
zfac= t->persmat[0][3]*t->center[0]+ t->persmat[1][3]*t->center[1]+ t->persmat[2][3]*t->center[2]+ t->persmat[3][3];
854
900
zfac = len_v3(t->persinv[0]) * 2.0f/t->ar->winx * zfac * 30.0f;
856
902
for (i = 0; i<3; i++) {
857
VECCOPY(axis, t->con.mtx[i]);
903
copy_v3_v3(axis, t->con.mtx[i]);
859
905
mul_v3_fl(axis, zfac);
860
906
/* now we can project to get window coordinate */
878
924
if (len[0] <= len[1] && len[0] <= len[2]) {
879
925
if (t->modifiers & MOD_CONSTRAINT_PLANE) {
880
926
t->con.mode |= (CON_AXIS1|CON_AXIS2);
881
sprintf(t->con.text, " locking %s X axis", t->spacename);
927
BLI_snprintf(t->con.text, sizeof(t->con.text), " locking %s X axis", t->spacename);
884
930
t->con.mode |= CON_AXIS0;
885
sprintf(t->con.text, " along %s X axis", t->spacename);
931
BLI_snprintf(t->con.text, sizeof(t->con.text), " along %s X axis", t->spacename);
888
934
else if (len[1] <= len[0] && len[1] <= len[2]) {
889
935
if (t->modifiers & MOD_CONSTRAINT_PLANE) {
890
936
t->con.mode |= (CON_AXIS0|CON_AXIS2);
891
sprintf(t->con.text, " locking %s Y axis", t->spacename);
937
BLI_snprintf(t->con.text, sizeof(t->con.text), " locking %s Y axis", t->spacename);
894
940
t->con.mode |= CON_AXIS1;
895
sprintf(t->con.text, " along %s Y axis", t->spacename);
941
BLI_snprintf(t->con.text, sizeof(t->con.text), " along %s Y axis", t->spacename);
898
944
else if (len[2] <= len[1] && len[2] <= len[0]) {
899
945
if (t->modifiers & MOD_CONSTRAINT_PLANE) {
900
946
t->con.mode |= (CON_AXIS0|CON_AXIS1);
901
sprintf(t->con.text, " locking %s Z axis", t->spacename);
947
BLI_snprintf(t->con.text, sizeof(t->con.text), " locking %s Z axis", t->spacename);
904
950
t->con.mode |= CON_AXIS2;
905
sprintf(t->con.text, " along %s Z axis", t->spacename);
951
BLI_snprintf(t->con.text, sizeof(t->con.text), " along %s Z axis", t->spacename);