Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2015-10-30 09:31:07 +0300
committerCampbell Barton <ideasman42@gmail.com>2015-10-30 10:24:02 +0300
commite6abc3ad5751a272930841757e588bc25ce0bde7 (patch)
tree307cfecbbe3604050b65dbd5ff0e4ace345672eb
parentd2af1401510200bcc5d1841d5ef186e7cb545133 (diff)
Transform: Support storing virtual cursor location
Grabbing now doesn't 'jump' when shift is released (matching rotation modes). This simplifies most logic for transform input, where mouse input callbacks can choose to use the 'virtual' cursor, which accounts for precision when shift is held.
-rw-r--r--source/blender/editors/transform/transform.c9
-rw-r--r--source/blender/editors/transform/transform.h20
-rw-r--r--source/blender/editors/transform/transform_input.c179
3 files changed, 95 insertions, 113 deletions
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index 6d0e8593e79..86d97e9cac1 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -313,7 +313,7 @@ static void convertViewVec2D_mask(View2D *v2d, float r_vec[3], int dx, int dy)
r_vec[2] = 0.0f;
}
-void convertViewVec(TransInfo *t, float r_vec[3], int dx, int dy)
+void convertViewVec(TransInfo *t, float r_vec[3], double dx, double dy)
{
if ((t->spacetype == SPACE_VIEW3D) && (t->ar->regiontype == RGN_TYPE_WINDOW)) {
if (t->options & CTX_PAINT_CURVE) {
@@ -7605,12 +7605,17 @@ static void applyBakeTime(TransInfo *t, const int mval[2])
float fac = 0.1f;
+ /* XXX, disable precission for now,
+ * this isn't even accessible by the user */
+#if 0
if (t->mouse.precision) {
/* calculate ratio for shiftkey pos, and for total, and blend these for precision */
time = (float)(t->center2d[0] - t->mouse.precision_mval[0]) * fac;
time += 0.1f * ((float)(t->center2d[0] * fac - mval[0]) - time);
}
- else {
+ else
+#endif
+ {
time = (float)(t->center2d[0] - mval[0]) * fac;
}
diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h
index d4e1b3fc71c..bd5d043e3bb 100644
--- a/source/blender/editors/transform/transform.h
+++ b/source/blender/editors/transform/transform.h
@@ -326,15 +326,29 @@ typedef struct TransData {
} TransData;
typedef struct MouseInput {
- void (*apply)(struct TransInfo *t, struct MouseInput *mi, const int mval[2], float output[3]);
+ void (*apply)(struct TransInfo *t, struct MouseInput *mi, const double mval[2], float output[3]);
void (*post)(struct TransInfo *t, float values[3]);
int imval[2]; /* initial mouse position */
bool precision;
- int precision_mval[2]; /* mouse position when precision key was pressed */
+ float precision_factor;
float center[2];
float factor;
void *data; /* additional data, if needed by the particular function */
+
+ /**
+ * Use virtual cursor, which takes precission into account
+ * keeping track of the cursors 'virtual' location,
+ * to avoid jumping values when its toggled.
+ *
+ * This works well for scaling drag motion,
+ * but not for rotating around a point (rotaton needs its own custom accumulator)
+ */
+ bool use_virtual_mval;
+ struct {
+ double prev[2];
+ double accum[2];
+ } virtual_mval;
} MouseInput;
typedef struct TransInfo {
@@ -549,7 +563,7 @@ int transformEnd(struct bContext *C, TransInfo *t);
void setTransformViewMatrices(TransInfo *t);
void setTransformViewAspect(TransInfo *t, float r_aspect[3]);
-void convertViewVec(TransInfo *t, float r_vec[3], int dx, int dy);
+void convertViewVec(TransInfo *t, float r_vec[3], double dx, double dy);
void projectIntViewEx(TransInfo *t, const float vec[3], int adr[2], const eV3DProjTest flag);
void projectIntView(TransInfo *t, const float vec[3], int adr[2]);
void projectFloatViewEx(TransInfo *t, const float vec[3], float adr[2], const eV3DProjTest flag);
diff --git a/source/blender/editors/transform/transform_input.c b/source/blender/editors/transform/transform_input.c
index a18be8fb5fa..16ce0cde72f 100644
--- a/source/blender/editors/transform/transform_input.c
+++ b/source/blender/editors/transform/transform_input.c
@@ -39,54 +39,26 @@
#include "MEM_guardedalloc.h"
-struct InputTrackBall_Data {
- float value_accum[2];
- float value_prev[2];
-};
-
/* ************************** INPUT FROM MOUSE *************************** */
-static void InputVector(TransInfo *t, MouseInput *mi, const int mval[2], float output[3])
+static void InputVector(TransInfo *t, MouseInput *mi, const double 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, (mval[0] - mi->precision_mval[0]), (mval[1] - mi->precision_mval[1]));
- mul_v3_fl(dvec, 0.1f);
- convertViewVec(t, vec, (mi->precision_mval[0] - t->mouse.imval[0]), (mi->precision_mval[1] - t->mouse.imval[1]));
- add_v3_v3v3(output, vec, dvec);
- }
- else {
- convertViewVec(t, output, (mval[0] - t->mouse.imval[0]), (mval[1] - t->mouse.imval[1]));
- }
-
+ convertViewVec(t, output, mval[0] - mi->imval[0], mval[1] - mi->imval[1]);
}
-static void InputSpring(TransInfo *UNUSED(t), MouseInput *mi, const int mval[2], float output[3])
+static void InputSpring(TransInfo *UNUSED(t), MouseInput *mi, const double 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 = hypotf(dx, dy);
-
- dx = (float)(mi->center[0] - mval[0]);
- dy = (float)(mi->center[1] - mval[1]);
- precise_ratio = hypotf(dx, dy);
+ double dx, dy;
+ float ratio;
- 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 = hypotf(dx, dy) / mi->factor;
- }
+ dx = (mi->center[0] - mval[0]);
+ dy = (mi->center[1] - mval[1]);
+ ratio = hypot(dx, dy) / mi->factor;
output[0] = ratio;
}
-static void InputSpringFlip(TransInfo *t, MouseInput *mi, const int mval[2], float output[3])
+static void InputSpringFlip(TransInfo *t, MouseInput *mi, const double mval[2], float output[3])
{
InputSpring(t, mi, mval, output);
@@ -99,51 +71,29 @@ static void InputSpringFlip(TransInfo *t, MouseInput *mi, const int mval[2], flo
}
}
-static void InputSpringDelta(TransInfo *t, MouseInput *mi, const int mval[2], float output[3])
+static void InputSpringDelta(TransInfo *t, MouseInput *mi, const double mval[2], float output[3])
{
InputSpring(t, mi, mval, output);
output[0] -= 1.0f;
}
-static void InputTrackBall(TransInfo *UNUSED(t), MouseInput *mi, const int mval[2], float output[3])
+static void InputTrackBall(TransInfo *UNUSED(t), MouseInput *mi, const double mval[2], float output[3])
{
- struct InputTrackBall_Data *data = mi->data;
- float dxy[2];
- float dxy_accum[2];
+ output[0] = (float)(mi->imval[1] - mval[1]);
+ output[1] = (float)(mval[0] - mi->imval[0]);
- dxy[0] = (mi->imval[1] - mval[1]);
- dxy[1] = (mval[0] - mi->imval[0]);
-
- sub_v2_v2v2(dxy_accum, dxy, data->value_prev);
-
- add_v2_v2(data->value_prev, dxy_accum);
-
- if (mi->precision) {
- mul_v2_fl(dxy_accum, 1.0f / 30.0f);
- }
-
- add_v2_v2(data->value_accum, dxy_accum);
- mul_v2_v2fl(output, data->value_accum, mi->factor);
+ output[0] *= mi->factor;
+ output[1] *= mi->factor;
}
-static void InputHorizontalRatio(TransInfo *t, MouseInput *mi, const int mval[2], float output[3])
+static void InputHorizontalRatio(TransInfo *t, MouseInput *UNUSED(mi), const double 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];
- }
+ const float pad = t->ar->winx / 10;
- output[0] = (x - pad) / (t->ar->winx - 2 * pad);
+ output[0] = (mval[0] - pad) / (t->ar->winx - 2 * pad);
}
-static void InputHorizontalAbsolute(TransInfo *t, MouseInput *mi, const int mval[2], float output[3])
+static void InputHorizontalAbsolute(TransInfo *t, MouseInput *mi, const double mval[2], float output[3])
{
float vec[3];
@@ -153,24 +103,14 @@ static void InputHorizontalAbsolute(TransInfo *t, MouseInput *mi, const int mval
output[0] = dot_v3v3(t->viewinv[0], vec) * 2.0f;
}
-static void InputVerticalRatio(TransInfo *t, MouseInput *mi, const int mval[2], float output[3])
+static void InputVerticalRatio(TransInfo *t, MouseInput *UNUSED(mi), const double mval[2], float output[3])
{
- float y, pad;
+ const float pad = t->ar->winy / 10;
- 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);
+ output[0] = (mval[1] - pad) / (t->ar->winy - 2 * pad);
}
-static void InputVerticalAbsolute(TransInfo *t, MouseInput *mi, const int mval[2], float output[3])
+static void InputVerticalAbsolute(TransInfo *t, MouseInput *mi, const double mval[2], float output[3])
{
float vec[3];
@@ -194,7 +134,7 @@ void setCustomPoints(TransInfo *UNUSED(t), MouseInput *mi, const int mval_start[
data[3] = mval_end[1];
}
-static void InputCustomRatioFlip(TransInfo *UNUSED(t), MouseInput *mi, const int mval[2], float output[3])
+static void InputCustomRatioFlip(TransInfo *UNUSED(t), MouseInput *mi, const double mval[2], float output[3])
{
double length;
double distance;
@@ -202,38 +142,28 @@ static void InputCustomRatioFlip(TransInfo *UNUSED(t), MouseInput *mi, const int
const int *data = mi->data;
if (data) {
+ int mdx, mdy;
dx = data[2] - data[0];
dy = data[3] - data[1];
-
+
length = hypot(dx, dy);
-
- if (mi->precision) {
- /* deal with Shift key by adding motion / 10 to motion before shift press */
- int mdx, mdy;
- mdx = (mi->precision_mval[0] + (float)(mval[0] - mi->precision_mval[0]) / 10.0f) - data[2];
- mdy = (mi->precision_mval[1] + (float)(mval[1] - mi->precision_mval[1]) / 10.0f) - data[3];
- distance = (length != 0.0) ? (mdx * dx + mdy * dy) / length : 0.0;
- }
- else {
- int mdx, mdy;
- mdx = mval[0] - data[2];
- mdy = mval[1] - data[3];
+ mdx = mval[0] - data[2];
+ mdy = mval[1] - data[3];
- distance = (length != 0.0) ? (mdx * dx + mdy * dy) / length : 0.0;
- }
+ distance = (length != 0.0) ? (mdx * dx + mdy * dy) / length : 0.0;
output[0] = (length != 0.0) ? (double)(distance / length) : 0.0;
}
}
-static void InputCustomRatio(TransInfo *t, MouseInput *mi, const int mval[2], float output[3])
+static void InputCustomRatio(TransInfo *t, MouseInput *mi, const double mval[2], float output[3])
{
InputCustomRatioFlip(t, mi, mval, output);
output[0] = -output[0];
}
-static void InputAngle(TransInfo *UNUSED(t), MouseInput *mi, const int mval[2], float output[3])
+static void InputAngle(TransInfo *UNUSED(t), MouseInput *mi, const double mval[2], float output[3])
{
double dx2 = mval[0] - mi->center[0];
double dy2 = mval[1] - mi->center[1];
@@ -281,7 +211,7 @@ static void InputAngle(TransInfo *UNUSED(t), MouseInput *mi, const int mval[2],
}
if (mi->precision) {
- dphi = dphi / 30.0f;
+ dphi = dphi * mi->precision_factor;
}
/* if no delta angle, don't update initial position */
@@ -295,7 +225,7 @@ static void InputAngle(TransInfo *UNUSED(t), MouseInput *mi, const int mval[2],
output[0] = *angle;
}
-static void InputAngleSpring(TransInfo *t, MouseInput *mi, const int mval[2], float output[3])
+static void InputAngleSpring(TransInfo *t, MouseInput *mi, const double mval[2], float output[3])
{
float toutput[3];
@@ -334,6 +264,9 @@ void initMouseInputMode(TransInfo *t, MouseInput *mi, MouseInputMode mode)
/* incase we allocate a new value */
void *mi_data_prev = mi->data;
+ mi->use_virtual_mval = true;
+ mi->precision_factor = 1.0f / 10.0f;
+
switch (mode) {
case INPUT_VECTOR:
mi->apply = InputVector;
@@ -355,20 +288,23 @@ void initMouseInputMode(TransInfo *t, MouseInput *mi, MouseInputMode mode)
t->helpline = HLP_SPRING;
break;
case INPUT_ANGLE:
+ mi->use_virtual_mval = false;
+ mi->precision_factor = 1.0f / 30.0f;
mi->data = MEM_callocN(sizeof(double), "angle accumulator");
mi->apply = InputAngle;
t->helpline = HLP_ANGLE;
break;
case INPUT_ANGLE_SPRING:
+ mi->use_virtual_mval = false;
calcSpringFactor(mi);
mi->data = MEM_callocN(sizeof(double), "angle accumulator");
mi->apply = InputAngleSpring;
t->helpline = HLP_ANGLE;
break;
case INPUT_TRACKBALL:
+ mi->precision_factor = 1.0f / 30.0f;
/* factor has to become setting or so */
mi->factor = 0.01f;
- mi->data = MEM_callocN(sizeof(struct InputTrackBall_Data), "angle accumulator");
mi->apply = InputTrackBall;
t->helpline = HLP_TRACKBALL;
break;
@@ -420,8 +356,37 @@ void setInputPostFct(MouseInput *mi, void (*post)(struct TransInfo *t, float val
void applyMouseInput(TransInfo *t, MouseInput *mi, const int mval[2], float output[3])
{
+ double mval_db[2];
+
+ if (mi->use_virtual_mval) {
+ /* update accumulator */
+ double mval_delta[2];
+
+ mval_delta[0] = (mval[0] - mi->imval[0]) - mi->virtual_mval.prev[0];
+ mval_delta[1] = (mval[1] - mi->imval[1]) - mi->virtual_mval.prev[1];
+
+ mi->virtual_mval.prev[0] += mval_delta[0];
+ mi->virtual_mval.prev[1] += mval_delta[1];
+
+ if (mi->precision) {
+ mval_delta[0] *= mi->precision_factor;
+ mval_delta[1] *= mi->precision_factor;
+ }
+
+ mi->virtual_mval.accum[0] += mval_delta[0];
+ mi->virtual_mval.accum[1] += mval_delta[1];
+
+ mval_db[0] = mi->imval[0] + mi->virtual_mval.accum[0];
+ mval_db[1] = mi->imval[1] + mi->virtual_mval.accum[1];
+ }
+ else {
+ mval_db[0] = mval[0];
+ mval_db[1] = mval[1];
+ }
+
+
if (mi->apply != NULL) {
- mi->apply(t, mi, mval, output);
+ mi->apply(t, mi, mval_db, output);
}
if (mi->post) {
@@ -438,9 +403,7 @@ eRedrawFlag handleMouseInput(TransInfo *t, MouseInput *mi, const wmEvent *event)
case RIGHTSHIFTKEY:
if (event->val == KM_PRESS) {
t->modifiers |= MOD_PRECISION;
- /* shift is modifier for higher precision transform
- * store the mouse position where the normal movement ended */
- copy_v2_v2_int(mi->precision_mval, event->mval);
+ /* shift is modifier for higher precision transforn */
mi->precision = 1;
redraw = TREDRAW_HARD;
}