#endif
}
-
-
-/* ************************** INPUT FROM MOUSE *************************** */
-
-float InputScaleRatio(TransInfo *t, short mval[2]) {
- float ratio, dx, dy;
- if(t->flag & T_SHIFT_MOD) {
- /* calculate ratio for shiftkey pos, and for total, and blend these for precision */
- dx = (float)(t->center2d[0] - t->shiftmval[0]);
- dy = (float)(t->center2d[1] - t->shiftmval[1]);
- ratio = (float)sqrt( dx*dx + dy*dy)/t->fac;
-
- dx= (float)(t->center2d[0] - mval[0]);
- dy= (float)(t->center2d[1] - mval[1]);
- ratio+= 0.1f*(float)(sqrt( dx*dx + dy*dy)/t->fac -ratio);
- }
- else {
- dx = (float)(t->center2d[0] - mval[0]);
- dy = (float)(t->center2d[1] - mval[1]);
- ratio = (float)sqrt( dx*dx + dy*dy)/t->fac;
- }
- return ratio;
-}
-
-float InputHorizontalRatio(TransInfo *t, short mval[2]) {
- float x, pad;
-
- pad = t->ar->winx / 10;
-
- if (t->flag & T_SHIFT_MOD) {
- /* deal with Shift key by adding motion / 10 to motion before shift press */
- x = t->shiftmval[0] + (float)(mval[0] - t->shiftmval[0]) / 10.0f;
- }
- else {
- x = mval[0];
- }
- return (x - pad) / (t->ar->winx - 2 * pad);
-}
-
-float InputHorizontalAbsolute(TransInfo *t, short mval[2]) {
- float vec[3];
- if(t->flag & T_SHIFT_MOD) {
- float dvec[3];
- /* calculate the main translation and the precise one separate */
- convertViewVec(t, dvec, (short)(mval[0] - t->shiftmval[0]), (short)(mval[1] - t->shiftmval[1]));
- VecMulf(dvec, 0.1f);
- convertViewVec(t, t->vec, (short)(t->shiftmval[0] - t->imval[0]), (short)(t->shiftmval[1] - t->imval[1]));
- VecAddf(t->vec, t->vec, dvec);
- }
- else {
- convertViewVec(t, t->vec, (short)(mval[0] - t->imval[0]), (short)(mval[1] - t->imval[1]));
- }
- Projf(vec, t->vec, t->viewinv[0]);
- return Inpf(t->viewinv[0], vec) * 2.0f;
-}
-
-float InputVerticalRatio(TransInfo *t, short mval[2]) {
- float y, pad;
-
- pad = t->ar->winy / 10;
-
- if (t->flag & T_SHIFT_MOD) {
- /* deal with Shift key by adding motion / 10 to motion before shift press */
- y = t->shiftmval[1] + (float)(mval[1] - t->shiftmval[1]) / 10.0f;
- }
- else {
- y = mval[0];
- }
- return (y - pad) / (t->ar->winy - 2 * pad);
-}
-
-float InputVerticalAbsolute(TransInfo *t, short mval[2]) {
- float vec[3];
- if(t->flag & T_SHIFT_MOD) {
- float dvec[3];
- /* calculate the main translation and the precise one separate */
- convertViewVec(t, dvec, (short)(mval[0] - t->shiftmval[0]), (short)(mval[1] - t->shiftmval[1]));
- VecMulf(dvec, 0.1f);
- convertViewVec(t, t->vec, (short)(t->shiftmval[0] - t->imval[0]), (short)(t->shiftmval[1] - t->imval[1]));
- VecAddf(t->vec, t->vec, dvec);
- }
- else {
- convertViewVec(t, t->vec, (short)(mval[0] - t->imval[0]), (short)(mval[1] - t->imval[1]));
- }
- Projf(vec, t->vec, t->viewinv[1]);
- return Inpf(t->viewinv[1], vec) * 2.0f;
-}
-
-float InputDeltaAngle(TransInfo *t, short mval[2])
-{
- double dx2 = mval[0] - t->center2d[0];
- double dy2 = mval[1] - t->center2d[1];
- double B = sqrt(dx2*dx2+dy2*dy2);
-
- double dx1 = t->imval[0] - t->center2d[0];
- double dy1 = t->imval[1] - t->center2d[1];
- double A = sqrt(dx1*dx1+dy1*dy1);
-
- double dx3 = mval[0] - t->imval[0];
- double dy3 = mval[1] - t->imval[1];
-
- /* use doubles here, to make sure a "1.0" (no rotation) doesnt become 9.999999e-01, which gives 0.02 for acos */
- double deler = ((dx1*dx1+dy1*dy1)+(dx2*dx2+dy2*dy2)-(dx3*dx3+dy3*dy3))
- / (2.0 * (A*B?A*B:1.0));
- /* (A*B?A*B:1.0f) this takes care of potential divide by zero errors */
-
- float dphi;
-
- dphi = saacos((float)deler);
- if( (dx1*dy2-dx2*dy1)>0.0 ) dphi= -dphi;
-
- /* If the angle is zero, because of lack of precision close to the 1.0 value in acos
- * approximate the angle with the oposite side of the normalized triangle
- * This is a good approximation here since the smallest acos value seems to be around
- * 0.02 degree and lower values don't even have a 0.01% error compared to the approximation
- * */
- if (dphi == 0)
- {
- double dx, dy;
-
- dx2 /= A;
- dy2 /= A;
-
- dx1 /= B;
- dy1 /= B;
-
- dx = dx1 - dx2;
- dy = dy1 - dy2;
-
- dphi = sqrt(dx*dx + dy*dy);
- if( (dx1*dy2-dx2*dy1)>0.0 ) dphi= -dphi;
- }
-
- if(t->flag & T_SHIFT_MOD) dphi = dphi/30.0f;
-
- /* if no delta angle, don't update initial position */
- if (dphi != 0)
- {
- t->imval[0] = mval[0];
- t->imval[1] = mval[1];
- }
-
- return dphi;
-}
-
/* ************************** SPACE DEPENDANT CODE **************************** */
void setTransformViewMatrices(TransInfo *t)
void convertVecToDisplayNum(float *vec, float *num)
{
- // TRANSFORM_FIX_ME
- TransInfo *t = NULL; //BIF_GetTransInfo();
-
VECCOPY(num, vec);
#if 0 // TRANSFORM_FIX_ME
+ TransInfo *t = BIF_GetTransInfo();
+
if ((t->spacetype==SPACE_IMAGE) && (t->mode==TFM_TRANSLATION)) {
float aspx, aspy;
void convertDisplayNumToVec(float *num, float *vec)
{
- // TRANSFORM_FIX_ME
- TransInfo *t = NULL; //BIF_GetTransInfo();
-
VECCOPY(vec, num);
#if 0 // TRANSFORM_FIX_ME
+ TransInfo *t = BIF_GetTransInfo();
+
if ((t->spacetype==SPACE_IMAGE) && (t->mode==TFM_TRANSLATION)) {
float aspx, aspy;
t->event = event;
+ t->redraw |= handleMouseInput(t, &t->mouse, event);
+
if (event->type == MOUSEMOVE)
{
t->mval[0] = event->x - t->ar->winrct.xmin;
t->mval[1] = event->y - t->ar->winrct.ymin;
+
+ applyMouseInput(t, &t->mouse, t->mval, t->values);
}
-
+
if (event->val) {
switch (event->type){
/* enforce redraw of transform when modifiers are used */
case RIGHTCTRLKEY:
t->redraw = 1;
break;
- case LEFTSHIFTKEY:
- case RIGHTSHIFTKEY:
- /* shift is modifier for higher resolution transform, works nice to store this mouse position */
- t->shiftmval[0] = event->x - t->ar->winrct.xmin;
- t->shiftmval[1] = event->y - t->ar->winrct.ymin;
- t->flag |= T_SHIFT_MOD;
- t->redraw = 1;
- break;
case SPACEKEY:
if ((t->spacetype==SPACE_VIEW3D) && event->alt) {
if (t->options & CTX_TWEAK)
t->state = TRANS_CONFIRM;
break;
- case LEFTSHIFTKEY:
- case RIGHTSHIFTKEY:
- /* shift is modifier for higher resolution transform */
- t->flag &= ~T_SHIFT_MOD;
- break;
}
}
calculatePropRatio(t);
calculateCenter(t);
+
+ initMouseInput(t, &t->mouse, t->center2d, t->imval);
switch (mode) {
case TFM_TRANSLATION:
t->transform = Warp;
t->handleEvent = handleEventWarp;
+ initMouseInputMode(t, &t->mouse, INPUT_HORIZONTAL_RATIO);
+
t->idx_max = 0;
t->num.idx_max = 0;
t->snap[0] = 0.0f;
t->flag |= T_NO_CONSTRAINT;
-/* warp is done fully in view space */
- calculateCenterCursor(t);
- t->fac = (float)(t->center2d[0] - t->imval[0]);
-
/* we need min/max in view space */
for(i = 0; i < t->total; i++) {
float center[3];
VecSubf(cursor, cursor, t->viewmat[3]);
/* amount of degrees for warp */
- circumfac= 360.0f * InputHorizontalRatio(t, mval);
+ circumfac = 360.0f * t->values[0];
if (t->customData) /* non-null value indicates reversed input */
{
t->transform = Shear;
t->handleEvent = handleEventShear;
+ initMouseInputMode(t, &t->mouse, INPUT_HORIZONTAL_ABSOLUTE);
+
t->idx_max = 0;
t->num.idx_max = 0;
t->snap[0] = 0.0f;
{
// Use customData pointer to signal Shear direction
if (t->customData == 0)
+ {
+ initMouseInputMode(t, &t->mouse, INPUT_VERTICAL_ABSOLUTE);
t->customData = (void*)1;
+ }
else
+ {
+ initMouseInputMode(t, &t->mouse, INPUT_HORIZONTAL_ABSOLUTE);
t->customData = 0;
+ }
status = 1;
}
Mat3CpyMat4(persmat, t->viewmat);
Mat3Inv(persinv, persmat);
- // Custom data signals shear direction
- if (t->customData == 0)
- value = 0.05f * InputHorizontalAbsolute(t, mval);
- else
- value = 0.05f * InputVerticalAbsolute(t, mval);
+ value = 0.05f * t->values[0];
snapGrid(t, &value);
t->mode = TFM_RESIZE;
t->transform = Resize;
+ initMouseInputMode(t, &t->mouse, INPUT_SPRING_FLIP);
+
t->flag |= T_NULL_ONE;
t->num.flag |= NUM_NULL_ONE;
t->num.flag |= NUM_AFFECT_ALL;
t->snap[0] = 0.0f;
t->snap[1] = 0.1f;
t->snap[2] = t->snap[1] * 0.1f;
-
- t->fac = (float)sqrt(
- (
- ((float)(t->center2d[1] - t->imval[1]))*((float)(t->center2d[1] - t->imval[1]))
- +
- ((float)(t->center2d[0] - t->imval[0]))*((float)(t->center2d[0] - t->imval[0]))
- ) );
-
- if(t->fac==0.0f) t->fac= 1.0f; // prevent Inf
}
static void headerResize(TransInfo *t, float vec[3], char *str) {
char str[200];
/* for manipulator, center handle, the scaling can't be done relative to center */
- if( (t->flag & T_USES_MANIPULATOR) && t->con.mode==0) {
+ if( (t->flag & T_USES_MANIPULATOR) && t->con.mode==0)
+ {
ratio = 1.0f - ((t->imval[0] - mval[0]) + (t->imval[1] - mval[1]))/100.0f;
}
- else {
- ratio = InputScaleRatio(t, mval);
-
- /* flip scale, but not for manipulator center handle */
- if ((t->center2d[0] - mval[0]) * (t->center2d[0] - t->imval[0]) +
- (t->center2d[1] - mval[1]) * (t->center2d[1] - t->imval[1]) < 0)
- ratio *= -1.0f;
+ else
+ {
+ ratio = t->values[0];
}
size[0] = size[1] = size[2] = ratio;
t->mode = TFM_TOSPHERE;
t->transform = ToSphere;
+
+ initMouseInputMode(t, &t->mouse, INPUT_HORIZONTAL_RATIO);
t->idx_max = 0;
t->num.idx_max = 0;
char str[64];
TransData *td = t->data;
- ratio = InputHorizontalRatio(t, mval);
+ ratio = t->values[0];
snapGrid(t, &ratio);
t->mode = TFM_ROTATION;
t->transform = Rotation;
+ initMouseInputMode(t, &t->mouse, INPUT_ANGLE);
+
t->ndof.axis = 16;
/* Scale down and flip input for rotation */
t->ndof.factor[0] = -0.2f;
t->snap[0] = 0.0f;
t->snap[1] = (float)((5.0/180)*M_PI);
t->snap[2] = t->snap[1] * 0.2f;
- t->fac = 0;
if (t->flag & T_2D_EDIT)
t->flag |= T_NO_CONSTRAINT;
VecMulf(axis, -1.0f);
Normalize(axis);
- t->fac += InputDeltaAngle(t, mval);
-
- final = t->fac;
+ final = t->values[0];
applyNDofInput(&t->ndof, &final);
VecRotToMat3(axis, final, mat);
- t->val = final; // used in manipulator
- Mat3CpyMat3(t->mat, mat); // used in manipulator
+ // TRANSFORM_FIX_ME
+// t->values[0] = final; // used in manipulator
+// Mat3CpyMat3(t->mat, mat); // used in manipulator
applyRotation(t, final, axis);
t->mode = TFM_TRACKBALL;
t->transform = Trackball;
+ initMouseInputMode(t, &t->mouse, INPUT_TRACKBALL);
+
t->ndof.axis = 40;
/* Scale down input for rotation */
t->ndof.factor[0] = 0.2f;
t->snap[0] = 0.0f;
t->snap[1] = (float)((5.0/180)*M_PI);
t->snap[2] = t->snap[1] * 0.2f;
- t->fac = 0;
t->flag |= T_NO_CONSTRAINT;
}
Normalize(axis1);
Normalize(axis2);
- /* factore has to become setting or so */
- phi[0]= 0.01f*(float)( t->imval[1] - mval[1] );
- phi[1]= 0.01f*(float)( mval[0] - t->imval[0] );
+ phi[0] = t->values[0];
+ phi[1] = t->values[1];
applyNDofInput(&t->ndof, phi);
}
else {
sprintf(str, "Trackball: %.2f %.2f %s", 180.0*phi[0]/M_PI, 180.0*phi[1]/M_PI, t->proptext);
-
- if(t->flag & T_SHIFT_MOD) {
- if(phi[0] != 0.0) phi[0]/= 5.0f;
- if(phi[1] != 0.0) phi[1]/= 5.0f;
- }
}
VecRotToMat3(axis1, phi[0], smat);
Mat3MulMat3(mat, smat, totmat);
- Mat3CpyMat3(t->mat, mat); // used in manipulator
+ // TRANSFORM_FIX_ME
+ //Mat3CpyMat3(t->mat, mat); // used in manipulator
applyTrackball(t, axis1, axis2, phi);
{
t->mode = TFM_TRANSLATION;
t->transform = Translation;
+
+ initMouseInputMode(t, &t->mouse, INPUT_VECTOR);
t->idx_max = (t->flag & T_2D_EDIT)? 1: 2;
t->num.flag = 0;
t->num.idx_max = t->idx_max;
- t->ndof.axis = 7;
+ t->ndof.axis = 1|2|4;
if(t->spacetype == SPACE_VIEW3D) {
View3D *v3d = t->view;
-
- /* initgrabz() defines a factor for perspective depth correction, used in window_to_3d() */
- if(t->flag & (T_EDIT|T_POSE)) {
- Object *ob= G.obedit?G.obedit:t->poseobj;
- float vec[3];
-
- VECCOPY(vec, t->center);
- Mat4MulVecfl(ob->obmat, vec);
- initgrabz(v3d, vec[0], vec[1], vec[2]);
- }
- else {
- initgrabz(v3d, t->center[0], t->center[1], t->center[2]);
- }
t->snap[0] = 0.0f;
t->snap[1] = v3d->gridview * 1.0f;
float tvec[3];
char str[250];
- if(t->flag & T_SHIFT_MOD) {
- float dvec[3];
- /* calculate the main translation and the precise one separate */
- convertViewVec(t, dvec, (short)(mval[0] - t->shiftmval[0]), (short)(mval[1] - t->shiftmval[1]));
- VecMulf(dvec, 0.1f);
- convertViewVec(t, t->vec, (short)(t->shiftmval[0] - t->imval[0]), (short)(t->shiftmval[1] - t->imval[1]));
- VecAddf(t->vec, t->vec, dvec);
- }
- else convertViewVec(t, t->vec, (short)(mval[0] - t->imval[0]), (short)(mval[1] - t->imval[1]));
-
if (t->con.mode & CON_APPLY) {
float pvec[3] = {0.0f, 0.0f, 0.0f};
- applySnapping(t, t->vec);
- t->con.applyVec(t, NULL, t->vec, tvec, pvec);
- VECCOPY(t->vec, tvec);
+ applySnapping(t, t->values);
+ t->con.applyVec(t, NULL, t->values, tvec, pvec);
+ VECCOPY(t->values, tvec);
headerTranslation(t, pvec, str);
}
else {
- applyNDofInput(&t->ndof, t->vec);
- snapGrid(t, t->vec);
- applyNumInput(&t->num, t->vec);
- applySnapping(t, t->vec);
- headerTranslation(t, t->vec, str);
+ applyNDofInput(&t->ndof, t->values);
+ snapGrid(t, t->values);
+ applyNumInput(&t->num, t->values);
+ applySnapping(t, t->values);
+ headerTranslation(t, t->values, str);
}
- applyTranslation(t, t->vec);
+ applyTranslation(t, t->values);
/* evil hack - redo translation if cliiping needeed */
- if (t->flag & T_CLIP_UV && clipUVTransform(t, t->vec, 0))
- applyTranslation(t, t->vec);
+ if (t->flag & T_CLIP_UV && clipUVTransform(t, t->values, 0))
+ applyTranslation(t, t->values);
recalcData(t);
else {
t->mode = TFM_SHRINKFATTEN;
t->transform = ShrinkFatten;
+
+ initMouseInputMode(t, &t->mouse, INPUT_VERTICAL_ABSOLUTE);
t->idx_max = 0;
t->num.idx_max = 0;
char str[64];
TransData *td = t->data;
- distance = -InputVerticalAbsolute(t, mval);
+ distance = -t->values[0];
snapGrid(t, &distance);
{
t->mode = TFM_TILT;
t->transform = Tilt;
+
+ initMouseInputMode(t, &t->mouse, INPUT_ANGLE);
t->ndof.axis = 16;
/* Scale down and flip input for rotation */
t->snap[0] = 0.0f;
t->snap[1] = (float)((5.0/180)*M_PI);
t->snap[2] = t->snap[1] * 0.2f;
- t->fac = 0;
t->flag |= T_NO_CONSTRAINT;
}
float final;
- t->fac += InputDeltaAngle(t, mval);
-
- final = t->fac;
+ final = t->values[0];
applyNDofInput(&t->ndof, &final);
/* ******************** Curve Shrink/Fatten *************** */
+void initCurveShrinkFatten(TransInfo *t)
+{
+ t->mode = TFM_CURVE_SHRINKFATTEN;
+ t->transform = CurveShrinkFatten;
+
+ initMouseInputMode(t, &t->mouse, INPUT_SPRING);
+
+ t->idx_max = 0;
+ t->num.idx_max = 0;
+ t->snap[0] = 0.0f;
+ t->snap[1] = 0.1f;
+ t->snap[2] = t->snap[1] * 0.1f;
+
+ t->flag |= T_NO_CONSTRAINT;
+}
+
int CurveShrinkFatten(TransInfo *t, short mval[2])
{
TransData *td = t->data;
int i;
char str[50];
- if(t->flag & T_SHIFT_MOD) {
- /* calculate ratio for shiftkey pos, and for total, and blend these for precision */
- float dx= (float)(t->center2d[0] - t->shiftmval[0]);
- float dy= (float)(t->center2d[1] - t->shiftmval[1]);
- ratio = (float)sqrt( dx*dx + dy*dy)/t->fac;
-
- dx= (float)(t->center2d[0] - mval[0]);
- dy= (float)(t->center2d[1] - mval[1]);
- ratio+= 0.1f*(float)(sqrt( dx*dx + dy*dy)/t->fac -ratio);
-
- }
- else {
- float dx= (float)(t->center2d[0] - mval[0]);
- float dy= (float)(t->center2d[1] - mval[1]);
- ratio = (float)sqrt( dx*dx + dy*dy)/t->fac;
- }
+ ratio = t->values[0];
snapGrid(t, &ratio);
return 1;
}
-void initCurveShrinkFatten(TransInfo *t)
-{
- t->mode = TFM_CURVE_SHRINKFATTEN;
- t->transform = CurveShrinkFatten;
-
- t->idx_max = 0;
- t->num.idx_max = 0;
- t->snap[0] = 0.0f;
- t->snap[1] = 0.1f;
- t->snap[2] = t->snap[1] * 0.1f;
-
- t->flag |= T_NO_CONSTRAINT;
-
- t->fac = (float)sqrt( (
- ((float)(t->center2d[1] - t->imval[1]))*((float)(t->center2d[1] - t->imval[1]))
- +
- ((float)(t->center2d[0] - t->imval[0]))*((float)(t->center2d[0] - t->imval[0]))
- ) );
-}
-
/* ************************** PUSH/PULL *************************** */
void initPushPull(TransInfo *t)
t->mode = TFM_PUSHPULL;
t->transform = PushPull;
+ initMouseInputMode(t, &t->mouse, INPUT_VERTICAL_ABSOLUTE);
+
t->ndof.axis = 4;
/* Flip direction */
t->ndof.factor[0] = -1.0f;
char str[128];
TransData *td = t->data;
- distance = InputVerticalAbsolute(t, mval);
+ distance = t->values[0];
applyNDofInput(&t->ndof, &distance);
void initBevel(TransInfo *t)
{
+ t->transform = Bevel;
+ t->handleEvent = handleEventBevel;
+
+ initMouseInputMode(t, &t->mouse, INPUT_HORIZONTAL_ABSOLUTE);
+
t->mode = TFM_BEVEL;
t->flag |= T_NO_CONSTRAINT;
t->num.flag |= NUM_NO_NEGATIVE;
- t->transform = Bevel;
- t->handleEvent = handleEventBevel;
t->idx_max = 0;
t->num.idx_max = 0;
TransData *td = t->data;
mode = (G.editBMesh->options & BME_BEVEL_VERT) ? "verts only" : "normal";
- distance = InputHorizontalAbsolute(t, mval)/4; /* 4 just seemed a nice value to me, nothing special */
+ distance = t->values[0] / 4; /* 4 just seemed a nice value to me, nothing special */
distance = fabs(distance);
t->mode = TFM_BWEIGHT;
t->transform = BevelWeight;
+ initMouseInputMode(t, &t->mouse, INPUT_SPRING);
+
t->idx_max = 0;
t->num.idx_max = 0;
t->snap[0] = 0.0f;
t->snap[2] = t->snap[1] * 0.1f;
t->flag |= T_NO_CONSTRAINT;
-
- t->fac = (float)sqrt(
- (
- ((float)(t->center2d[1] - t->imval[1]))*((float)(t->center2d[1] - t->imval[1]))
- +
- ((float)(t->center2d[0] - t->imval[0]))*((float)(t->center2d[0] - t->imval[0]))
- ) );
-
- if(t->fac==0.0f) t->fac= 1.0f; // prevent Inf
}
int BevelWeight(TransInfo *t, short mval[2])
int i;
char str[50];
-
- if(t->flag & T_SHIFT_MOD) {
- /* calculate ratio for shiftkey pos, and for total, and blend these for precision */
- float dx= (float)(t->center2d[0] - t->shiftmval[0]);
- float dy= (float)(t->center2d[1] - t->shiftmval[1]);
- weight = (float)sqrt( dx*dx + dy*dy)/t->fac;
-
- dx= (float)(t->center2d[0] - mval[0]);
- dy= (float)(t->center2d[1] - mval[1]);
- weight+= 0.1f*(float)(sqrt( dx*dx + dy*dy)/t->fac -weight);
-
- }
- else {
- float dx= (float)(t->center2d[0] - mval[0]);
- float dy= (float)(t->center2d[1] - mval[1]);
- weight = (float)sqrt( dx*dx + dy*dy)/t->fac;
- }
+ weight = t->values[0];
weight -= 1.0f;
if (weight > 1.0f) weight = 1.0f;
t->mode = TFM_CREASE;
t->transform = Crease;
+ initMouseInputMode(t, &t->mouse, INPUT_SPRING);
+
t->idx_max = 0;
t->num.idx_max = 0;
t->snap[0] = 0.0f;
t->snap[2] = t->snap[1] * 0.1f;
t->flag |= T_NO_CONSTRAINT;
-
- t->fac = (float)sqrt(
- (
- ((float)(t->center2d[1] - t->imval[1]))*((float)(t->center2d[1] - t->imval[1]))
- +
- ((float)(t->center2d[0] - t->imval[0]))*((float)(t->center2d[0] - t->imval[0]))
- ) );
-
- if(t->fac==0.0f) t->fac= 1.0f; // prevent Inf
}
int Crease(TransInfo *t, short mval[2])
int i;
char str[50];
-
- if(t->flag & T_SHIFT_MOD) {
- /* calculate ratio for shiftkey pos, and for total, and blend these for precision */
- float dx= (float)(t->center2d[0] - t->shiftmval[0]);
- float dy= (float)(t->center2d[1] - t->shiftmval[1]);
- crease = (float)sqrt( dx*dx + dy*dy)/t->fac;
-
- dx= (float)(t->center2d[0] - mval[0]);
- dy= (float)(t->center2d[1] - mval[1]);
- crease+= 0.1f*(float)(sqrt( dx*dx + dy*dy)/t->fac -crease);
-
- }
- else {
- float dx= (float)(t->center2d[0] - mval[0]);
- float dy= (float)(t->center2d[1] - mval[1]);
- crease = (float)sqrt( dx*dx + dy*dy)/t->fac;
- }
+ crease = t->values[0];
crease -= 1.0f;
if (crease > 1.0f) crease = 1.0f;
t->mode = TFM_BONESIZE;
t->transform = BoneSize;
+ initMouseInputMode(t, &t->mouse, INPUT_SPRING_FLIP);
+
t->idx_max = 2;
t->num.idx_max = 2;
t->num.flag |= NUM_NULL_ONE;
t->snap[0] = 0.0f;
t->snap[1] = 0.1f;
t->snap[2] = t->snap[1] * 0.1f;
-
- t->fac = (float)sqrt( (
- ((float)(t->center2d[1] - t->imval[1]))*((float)(t->center2d[1] - t->imval[1]))
- +
- ((float)(t->center2d[0] - t->imval[0]))*((float)(t->center2d[0] - t->imval[0]))
- ) );
-
- if(t->fac==0.0f) t->fac= 1.0f; // prevent Inf
}
static void headerBoneSize(TransInfo *t, float vec[3], char *str) {
int i;
char str[60];
+ // TRANSFORM_FIX_ME MOVE TO MOUSE INPUT
/* for manipulator, center handle, the scaling can't be done relative to center */
- if( (t->flag & T_USES_MANIPULATOR) && t->con.mode==0) {
+ if( (t->flag & T_USES_MANIPULATOR) && t->con.mode==0)
+ {
ratio = 1.0f - ((t->imval[0] - mval[0]) + (t->imval[1] - mval[1]))/100.0f;
}
- else {
-
- if(t->flag & T_SHIFT_MOD) {
- /* calculate ratio for shiftkey pos, and for total, and blend these for precision */
- float dx= (float)(t->center2d[0] - t->shiftmval[0]);
- float dy= (float)(t->center2d[1] - t->shiftmval[1]);
- ratio = (float)sqrt( dx*dx + dy*dy)/t->fac;
-
- dx= (float)(t->center2d[0] - mval[0]);
- dy= (float)(t->center2d[1] - mval[1]);
- ratio+= 0.1f*(float)(sqrt( dx*dx + dy*dy)/t->fac -ratio);
-
- }
- else {
- float dx= (float)(t->center2d[0] - mval[0]);
- float dy= (float)(t->center2d[1] - mval[1]);
- ratio = (float)sqrt( dx*dx + dy*dy)/t->fac;
- }
-
- /* flip scale, but not for manipulator center handle */
- if ((t->center2d[0] - mval[0]) * (t->center2d[0] - t->imval[0]) +
- (t->center2d[1] - mval[1]) * (t->center2d[1] - t->imval[1]) < 0)
- ratio *= -1.0f;
+ else
+ {
+ ratio = t->values[0];
}
size[0] = size[1] = size[2] = ratio;
t->mode = TFM_BONE_ENVELOPE;
t->transform = BoneEnvelope;
+ initMouseInputMode(t, &t->mouse, INPUT_SPRING);
+
t->idx_max = 0;
t->num.idx_max = 0;
t->snap[0] = 0.0f;
t->snap[2] = t->snap[1] * 0.1f;
t->flag |= T_NO_CONSTRAINT;
-
- t->fac = (float)sqrt( (
- ((float)(t->center2d[1] - t->imval[1]))*((float)(t->center2d[1] - t->imval[1]))
- +
- ((float)(t->center2d[0] - t->imval[0]))*((float)(t->center2d[0] - t->imval[0]))
- ) );
-
- if(t->fac==0.0f) t->fac= 1.0f; // prevent Inf
}
int BoneEnvelope(TransInfo *t, short mval[2])
int i;
char str[50];
- if(t->flag & T_SHIFT_MOD) {
- /* calculate ratio for shiftkey pos, and for total, and blend these for precision */
- float dx= (float)(t->center2d[0] - t->shiftmval[0]);
- float dy= (float)(t->center2d[1] - t->shiftmval[1]);
- ratio = (float)sqrt( dx*dx + dy*dy)/t->fac;
-
- dx= (float)(t->center2d[0] - mval[0]);
- dy= (float)(t->center2d[1] - mval[1]);
- ratio+= 0.1f*(float)(sqrt( dx*dx + dy*dy)/t->fac -ratio);
-
- }
- else {
- float dx= (float)(t->center2d[0] - mval[0]);
- float dy= (float)(t->center2d[1] - mval[1]);
- ratio = (float)sqrt( dx*dx + dy*dy)/t->fac;
- }
+ ratio = t->values[0];
snapGrid(t, &ratio);
{
t->mode = TFM_BONE_ROLL;
t->transform = BoneRoll;
+
+ initMouseInputMode(t, &t->mouse, INPUT_ANGLE);
t->idx_max = 0;
t->num.idx_max = 0;
t->snap[1] = (float)((5.0/180)*M_PI);
t->snap[2] = t->snap[1] * 0.2f;
- t->fac = 0.0f;
-
t->flag |= T_NO_CONSTRAINT;
}
float final;
- t->fac += InputDeltaAngle(t, mval);
-
- final = t->fac;
+ final = t->values[0];
snapGrid(t, &final);
void initBakeTime(TransInfo *t)
{
+ t->transform = BakeTime;
+ initMouseInputMode(t, &t->mouse, INPUT_NONE);
+
t->idx_max = 0;
t->num.idx_max = 0;
t->snap[0] = 0.0f;
t->snap[1] = 1.0f;
t->snap[2] = t->snap[1] * 0.1f;
- t->transform = BakeTime;
- t->fac = 0.1f;
}
int BakeTime(TransInfo *t, short mval[2])
float time;
int i;
char str[50];
-
+
+ float fac = 0.1f;
- if(t->flag & T_SHIFT_MOD) {
+ if(t->mouse.precision) {
/* calculate ratio for shiftkey pos, and for total, and blend these for precision */
- time= (float)(t->center2d[0] - t->shiftmval[0])*t->fac;
- time+= 0.1f*((float)(t->center2d[0]*t->fac - mval[0]) -time);
+ time= (float)(t->center2d[0] - t->mouse.precision_mval[0]) * fac;
+ time+= 0.1f*((float)(t->center2d[0]*fac - mval[0]) -time);
}
else {
- time = (float)(t->center2d[0] - mval[0])*t->fac;
+ time = (float)(t->center2d[0] - mval[0])*fac;
}
snapGrid(t, &time);
void initMirror(TransInfo *t)
{
+ t->transform = Mirror;
+ initMouseInputMode(t, &t->mouse, INPUT_NONE);
+
t->flag |= T_NULL_ONE;
if (!G.obedit) {
t->flag |= T_NO_ZERO;
}
-
- t->transform = Mirror;
}
int Mirror(TransInfo *t, short mval[2])
t->flag |= T_NO_CONSTRAINT;
t->transform = Align;
+
+ initMouseInputMode(t, &t->mouse, INPUT_NONE);
}
int Align(TransInfo *t, short mval[2])
{
t->mode = TFM_TIME_TRANSLATE;
t->transform = TimeTranslate;
+
+ initMouseInputMode(t, &t->mouse, INPUT_NONE);
/* num-input has max of (n-1) */
t->idx_max = 0;
const short autosnap= getAnimEdit_SnapMode(t);
const short doTime = getAnimEdit_DrawTime(t);
const double secf= FPS;
- float val= t->fac;
+ float val = t->values[0];
/* apply snapping + frame->seconds conversions */
if (autosnap == SACTSNAP_STEP) {
/* check if any need to apply nla-scaling */
if (ob) {
- deltax = t->fac;
+ deltax = t->values[0];
if (autosnap == SACTSNAP_STEP) {
if (doTime)
*(td->val) = get_action_frame(ob, val);
}
else {
- deltax = val = t->fac;
+ deltax = val = t->values[0];
if (autosnap == SACTSNAP_STEP) {
if (doTime)
UI_view2d_region_to_view(v2d, t->imval[0], t->imval[0], &sval[0], &sval[1]);
/* we only need to calculate effect for time (applyTimeTranslate only needs that) */
- t->fac= cval[0] - sval[0];
+ t->values[0] = cval[0] - sval[0];
/* handle numeric-input stuff */
- t->vec[0] = t->fac;
+ t->vec[0] = t->values[0];
applyNumInput(&t->num, &t->vec[0]);
- t->fac = t->vec[0];
+ t->values[0] = t->vec[0];
headerTimeTranslate(t, str);
applyTimeTranslate(t, sval[0]);
t->mode = TFM_TIME_SLIDE;
t->transform = TimeSlide;
t->flag |= T_FREE_CUSTOMDATA;
+
+ initMouseInputMode(t, &t->mouse, INPUT_NONE);
/* num-input has max of (n-1) */
t->idx_max = 0;
else {
float minx= *((float *)(t->customData));
float maxx= *((float *)(t->customData) + 1);
- float cval= t->fac;
+ float cval= t->values[0];
float val;
val= 2.0f*(cval-sval) / (maxx-minx);
/* set value for drawing black line */
if (t->spacetype == SPACE_ACTION) {
SpaceAction *saction= (SpaceAction *)t->sa->spacedata.first;
- float cvalf = t->fac;
+ float cvalf = t->values[0];
saction->timeslide= cvalf;
}
* whose active action is where this keyframe comes from
*/
Object *ob= td->ob;
- float cval = t->fac;
+ float cval = t->values[0];
/* apply scaling to necessary values */
if (ob)
UI_view2d_region_to_view(v2d, mval[0], mval[0], &cval[0], &cval[1]);
UI_view2d_region_to_view(v2d, t->imval[0], t->imval[0], &sval[0], &sval[1]);
- /* t->fac stores cval[0], which is the current mouse-pointer location (in frames) */
- t->fac= cval[0];
+ /* t->values[0] stores cval[0], which is the current mouse-pointer location (in frames) */
+ t->values[0] = cval[0];
/* handle numeric-input stuff */
t->vec[0] = 2.0f*(cval[0]-sval[0]) / (maxx-minx);
applyNumInput(&t->num, &t->vec[0]);
- t->fac = (maxx-minx) * t->vec[0] / 2.0 + sval[0];
+ t->values[0] = (maxx-minx) * t->vec[0] / 2.0 + sval[0];
headerTimeSlide(t, sval[0], str);
applyTimeSlide(t, sval[0]);
{
t->mode = TFM_TIME_SCALE;
t->transform = TimeScale;
+
+ initMouseInputMode(t, &t->mouse, INPUT_NONE);
t->flag |= T_NULL_ONE;
t->num.flag |= NUM_NULL_ONE;
if (hasNumInput(&t->num))
outputNumInput(&(t->num), tvec);
else
- sprintf(&tvec[0], "%.4f", t->fac);
+ sprintf(&tvec[0], "%.4f", t->values[0]);
sprintf(str, "ScaleX: %s", &tvec[0]);
}
*/
Object *ob= td->ob;
float startx= CFRA;
- float fac= t->fac;
+ float fac= t->values[0];
if (autosnap == SACTSNAP_STEP) {
if (doTime)
/* calculate scaling factor */
startx= sval-(width/2+(t->ar->winx)/2);
deltax= cval-(width/2+(t->ar->winx)/2);
- t->fac = deltax / startx;
+ t->values[0] = deltax / startx;
/* handle numeric-input stuff */
- t->vec[0] = t->fac;
+ t->vec[0] = t->values[0];
applyNumInput(&t->num, &t->vec[0]);
- t->fac = t->vec[0];
+ t->values[0] = t->vec[0];
headerTimeScale(t, str);
applyTimeScale(t);
--- /dev/null
+/**
+ * $Id: transform_input.c 18142 2008-12-29 07:19:16Z aligorith $
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include <stdlib.h>
+#include <math.h>
+
+#include "DNA_screen_types.h"
+
+#include "BLI_arithb.h"
+
+#include "WM_types.h"
+
+#include "transform.h"
+
+
+
+/* ************************** INPUT FROM MOUSE *************************** */
+
+void InputVector(TransInfo *t, MouseInput *mi, short mval[2], float output[3])
+{
+ float vec[3], dvec[3];
+ if(mi->precision)
+ {
+ /* calculate the main translation and the precise one separate */
+ convertViewVec(t, dvec, (short)(mval[0] - mi->precision_mval[0]), (short)(mval[1] - mi->precision_mval[1]));
+ VecMulf(dvec, 0.1f);
+ convertViewVec(t, vec, (short)(mi->precision_mval[0] - t->imval[0]), (short)(mi->precision_mval[1] - t->imval[1]));
+ VecAddf(output, vec, dvec);
+ }
+ else
+ {
+ convertViewVec(t, output, (short)(mval[0] - t->imval[0]), (short)(mval[1] - t->imval[1]));
+ }
+
+}
+
+void InputSpring(TransInfo *t, MouseInput *mi, short mval[2], float output[3])
+{
+ float ratio, precise_ratio, dx, dy;
+ if(mi->precision)
+ {
+ /* calculate ratio for shiftkey pos, and for total, and blend these for precision */
+ dx = (float)(mi->center[0] - mi->precision_mval[0]);
+ dy = (float)(mi->center[1] - mi->precision_mval[1]);
+ ratio = (float)sqrt( dx*dx + dy*dy);
+
+ dx= (float)(mi->center[0] - mval[0]);
+ dy= (float)(mi->center[1] - mval[1]);
+ precise_ratio = (float)sqrt( dx*dx + dy*dy);
+
+ ratio = (ratio + (precise_ratio - ratio) / 10.0f) / mi->factor;
+ }
+ else
+ {
+ dx = (float)(mi->center[0] - mval[0]);
+ dy = (float)(mi->center[1] - mval[1]);
+ ratio = (float)sqrt( dx*dx + dy*dy) / mi->factor;
+ }
+
+ output[0] = ratio;
+}
+
+void InputSpringFlip(TransInfo *t, MouseInput *mi, short mval[2], float output[3])
+{
+ InputSpring(t, mi, mval, output);
+
+ /* flip scale */
+ if ((mi->center[0] - mval[0]) * (mi->center[0] - mi->imval[0]) +
+ (mi->center[1] - mval[1]) * (mi->center[1] - mi->imval[1]) < 0)
+ {
+ output[0] *= -1.0f;
+ }
+}
+
+void InputTrackBall(TransInfo *t, MouseInput *mi, short mval[2], float output[3])
+{
+
+ if(mi->precision)
+ {
+ output[0] = ( mi->imval[1] - mi->precision_mval[1] ) + ( mi->precision_mval[1] - mval[1] ) * 0.1f;
+ output[1] = ( mi->precision_mval[0] - mi->imval[0] ) + ( mval[0] - mi->precision_mval[0] ) * 0.1f;
+ }
+ else
+ {
+ output[0] = (float)( mi->imval[1] - mval[1] );
+ output[1] = (float)( mval[0] - mi->imval[0] );
+ }
+
+ output[0] *= mi->factor;
+ output[1] *= mi->factor;
+}
+
+void InputHorizontalRatio(TransInfo *t, MouseInput *mi, short mval[2], float output[3]) {
+ float x, pad;
+
+ pad = t->ar->winx / 10;
+
+ if (mi->precision)
+ {
+ /* deal with Shift key by adding motion / 10 to motion before shift press */
+ x = mi->precision_mval[0] + (float)(mval[0] - mi->precision_mval[0]) / 10.0f;
+ }
+ else {
+ x = mval[0];
+ }
+
+ output[0] = (x - pad) / (t->ar->winx - 2 * pad);
+}
+
+void InputHorizontalAbsolute(TransInfo *t, MouseInput *mi, short mval[2], float output[3]) {
+ float vec[3];
+
+ InputVector(t, mi, mval, vec);
+ Projf(vec, vec, t->viewinv[0]);
+
+ output[0] = Inpf(t->viewinv[0], vec) * 2.0f;
+}
+
+void InputVerticalRatio(TransInfo *t, MouseInput *mi, short mval[2], float output[3]) {
+ float y, pad;
+
+ pad = t->ar->winy / 10;
+
+ if (mi->precision) {
+ /* deal with Shift key by adding motion / 10 to motion before shift press */
+ y = mi->precision_mval[1] + (float)(mval[1] - mi->precision_mval[1]) / 10.0f;
+ }
+ else {
+ y = mval[0];
+ }
+
+ output[0] = (y - pad) / (t->ar->winy - 2 * pad);
+}
+
+void InputVerticalAbsolute(TransInfo *t, MouseInput *mi, short mval[2], float output[3]) {
+ float vec[3];
+
+ InputVector(t, mi, mval, vec);
+ Projf(vec, vec, t->viewinv[1]);
+
+ output[0] = Inpf(t->viewinv[1], vec) * 2.0f;
+}
+
+void InputAngle(TransInfo *t, MouseInput *mi, short mval[2], float output[3])
+{
+ double dx2 = mval[0] - mi->center[0];
+ double dy2 = mval[1] - mi->center[1];
+ double B = sqrt(dx2*dx2+dy2*dy2);
+
+ double dx1 = mi->imval[0] - mi->center[0];
+ double dy1 = mi->imval[1] - mi->center[1];
+ double A = sqrt(dx1*dx1+dy1*dy1);
+
+ double dx3 = mval[0] - mi->imval[0];
+ double dy3 = mval[1] - mi->imval[1];
+
+ /* use doubles here, to make sure a "1.0" (no rotation) doesnt become 9.999999e-01, which gives 0.02 for acos */
+ double deler = ((dx1*dx1+dy1*dy1)+(dx2*dx2+dy2*dy2)-(dx3*dx3+dy3*dy3))
+ / (2.0 * (A*B?A*B:1.0));
+ /* (A*B?A*B:1.0f) this takes care of potential divide by zero errors */
+
+ float dphi;
+
+ dphi = saacos((float)deler);
+ if( (dx1*dy2-dx2*dy1)>0.0 ) dphi= -dphi;
+
+ /* If the angle is zero, because of lack of precision close to the 1.0 value in acos
+ * approximate the angle with the oposite side of the normalized triangle
+ * This is a good approximation here since the smallest acos value seems to be around
+ * 0.02 degree and lower values don't even have a 0.01% error compared to the approximation
+ * */
+ if (dphi == 0)
+ {
+ double dx, dy;
+
+ dx2 /= A;
+ dy2 /= A;
+
+ dx1 /= B;
+ dy1 /= B;
+
+ dx = dx1 - dx2;
+ dy = dy1 - dy2;
+
+ dphi = sqrt(dx*dx + dy*dy);
+ if( (dx1*dy2-dx2*dy1)>0.0 ) dphi= -dphi;
+ }
+
+ if(mi->precision) dphi = dphi/30.0f;
+
+ /* if no delta angle, don't update initial position */
+ if (dphi != 0)
+ {
+ mi->imval[0] = mval[0];
+ mi->imval[1] = mval[1];
+ }
+
+ output[0] += dphi;
+}
+
+void initMouseInput(TransInfo *t, MouseInput *mi, int center[2], short mval[2])
+{
+ mi->factor = 0;
+ mi->precision = 0;
+
+ mi->center[0] = center[0];
+ mi->center[1] = center[1];
+
+ mi->imval[0] = mval[0];
+ mi->imval[1] = mval[1];
+}
+
+static void calcSpringFactor(MouseInput *mi)
+{
+ mi->factor = (float)sqrt(
+ (
+ ((float)(mi->center[1] - mi->imval[1]))*((float)(mi->center[1] - mi->imval[1]))
+ +
+ ((float)(mi->center[0] - mi->imval[0]))*((float)(mi->center[0] - mi->imval[0]))
+ ) );
+
+ if (mi->factor==0.0f)
+ mi->factor= 1.0f; /* prevent Inf */
+}
+
+void initMouseInputMode(TransInfo *t, MouseInput *mi, MouseInputMode mode)
+{
+
+ switch(mode)
+ {
+ case INPUT_VECTOR:
+ mi->apply = InputVector;
+ break;
+ case INPUT_SPRING:
+ calcSpringFactor(mi);
+ mi->apply = InputSpring;
+ break;
+ case INPUT_SPRING_FLIP:
+ calcSpringFactor(mi);
+ mi->apply = InputSpringFlip;
+ break;
+ case INPUT_ANGLE:
+ mi->apply = InputAngle;
+ break;
+ case INPUT_TRACKBALL:
+ /* factor has to become setting or so */
+ mi->factor = 0.1f;
+ mi->apply = InputTrackBall;
+ break;
+ case INPUT_HORIZONTAL_RATIO:
+ mi->factor = (float)(mi->center[0] - mi->imval[0]);
+ mi->apply = InputHorizontalRatio;
+ break;
+ case INPUT_HORIZONTAL_ABSOLUTE:
+ mi->apply = InputHorizontalAbsolute;
+ break;
+ case INPUT_VERTICAL_RATIO:
+ mi->apply = InputVerticalRatio;
+ break;
+ case INPUT_VERTICAL_ABSOLUTE:
+ mi->apply = InputVerticalAbsolute;
+ break;
+ case INPUT_NONE:
+ default:
+ mi->apply = NULL;
+ break;
+ }
+
+ /* bootstrap mouse input with initial values */
+ applyMouseInput(t, mi, mi->imval, t->values);
+}
+
+void applyMouseInput(TransInfo *t, MouseInput *mi, short mval[2], float output[3])
+{
+ if (mi->apply != NULL)
+ {
+ mi->apply(t, mi, mval, output);
+ }
+}
+
+int handleMouseInput(TransInfo *t, MouseInput *mi, wmEvent *event)
+{
+ int redraw = 0;
+
+ switch (event->type)
+ {
+ case LEFTSHIFTKEY:
+ case RIGHTSHIFTKEY:
+ if (event->val)
+ {
+ /* shift is modifier for higher precision transform
+ * store the mouse position where the normal movement ended */
+ mi->precision_mval[0] = event->x - t->ar->winrct.xmin;
+ mi->precision_mval[1] = event->y - t->ar->winrct.ymin;
+ mi->precision = 1;
+ }
+ else
+ {
+ mi->precision = 0;
+ }
+ redraw = 1;
+ break;
+ }
+
+ return redraw;
+}