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>2017-08-30 18:38:51 +0300
committerCampbell Barton <ideasman42@gmail.com>2017-08-30 19:00:16 +0300
commit00ba48a6997d5421a899101b696e5f86c0bdef0a (patch)
tree8f54f9cd478f88134bea37bb2143e73f83d9a19a /source/blender
parentb448b025c70ab4e6966d3469dc71a5318d3ef731 (diff)
Manipulator: replace old cage2d manipulator
Mostly internal changes, keeping both manipulators could have worked but there was no point long term. There are still some glitches to resolve, will work on those next.
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/editors/include/ED_manipulator_library.h1
-rw-r--r--source/blender/editors/manipulator_library/CMakeLists.txt1
-rw-r--r--source/blender/editors/manipulator_library/manipulator_types/cage2d_manipulator.c607
-rw-r--r--source/blender/editors/manipulator_library/manipulator_types/cage2d_rotate_manipulator.c617
-rw-r--r--source/blender/editors/space_api/spacetypes.c1
-rw-r--r--source/blender/editors/space_node/node_manipulators.c113
-rw-r--r--source/blender/editors/space_view3d/view3d_manipulator_camera.c67
-rw-r--r--source/blender/editors/space_view3d/view3d_manipulator_empty.c63
-rw-r--r--source/blender/editors/space_view3d/view3d_manipulator_lamp.c45
-rw-r--r--source/blender/editors/transform/transform_manipulator2d.c9
-rw-r--r--source/blender/makesrna/intern/rna_wm_manipulator.c22
-rw-r--r--source/blender/windowmanager/manipulators/WM_manipulator_types.h5
-rw-r--r--source/blender/windowmanager/manipulators/intern/wm_manipulator.c13
13 files changed, 442 insertions, 1122 deletions
diff --git a/source/blender/editors/include/ED_manipulator_library.h b/source/blender/editors/include/ED_manipulator_library.h
index f283973a144..bde2a165ee6 100644
--- a/source/blender/editors/include/ED_manipulator_library.h
+++ b/source/blender/editors/include/ED_manipulator_library.h
@@ -34,7 +34,6 @@
void ED_manipulatortypes_arrow_2d(void);
void ED_manipulatortypes_arrow_3d(void);
void ED_manipulatortypes_cage_2d(void);
-void ED_manipulatortypes_cage_2d_rotate(void);
void ED_manipulatortypes_dial_3d(void);
void ED_manipulatortypes_grab_3d(void);
void ED_manipulatortypes_facemap_3d(void);
diff --git a/source/blender/editors/manipulator_library/CMakeLists.txt b/source/blender/editors/manipulator_library/CMakeLists.txt
index 43783eb3e4a..0604946dc24 100644
--- a/source/blender/editors/manipulator_library/CMakeLists.txt
+++ b/source/blender/editors/manipulator_library/CMakeLists.txt
@@ -47,7 +47,6 @@ set(SRC
geometry/geom_dial_manipulator.c
manipulator_types/arrow2d_manipulator.c
manipulator_types/arrow3d_manipulator.c
- manipulator_types/cage2d_rotate_manipulator.c
manipulator_types/cage2d_manipulator.c
manipulator_types/dial3d_manipulator.c
manipulator_types/grab3d_manipulator.c
diff --git a/source/blender/editors/manipulator_library/manipulator_types/cage2d_manipulator.c b/source/blender/editors/manipulator_library/manipulator_types/cage2d_manipulator.c
index 1b7b4ffda1f..7187e3ff62e 100644
--- a/source/blender/editors/manipulator_library/manipulator_types/cage2d_manipulator.c
+++ b/source/blender/editors/manipulator_library/manipulator_types/cage2d_manipulator.c
@@ -61,11 +61,28 @@
/* own includes */
#include "../manipulator_library_intern.h"
-#define MANIPULATOR_RECT_MIN_WIDTH 15.0f
#define MANIPULATOR_RESIZER_WIDTH 20.0f
/* -------------------------------------------------------------------- */
+static void manipulator_rect_pivot_from_scale_part(int part, float r_pt[2], bool r_constrain_axis[2])
+{
+ bool x = true, y = true;
+ switch (part) {
+ case ED_MANIPULATOR_CAGE2D_PART_SCALE_MIN_X: { ARRAY_SET_ITEMS(r_pt, 0.5, 0.0); x = false; break; }
+ case ED_MANIPULATOR_CAGE2D_PART_SCALE_MAX_X: { ARRAY_SET_ITEMS(r_pt, -0.5, 0.0); x = false; break; }
+ case ED_MANIPULATOR_CAGE2D_PART_SCALE_MIN_Y: { ARRAY_SET_ITEMS(r_pt, 0.0, 0.5); y = false; break; }
+ case ED_MANIPULATOR_CAGE2D_PART_SCALE_MAX_Y: { ARRAY_SET_ITEMS(r_pt, 0.0, -0.5); y = false; break; }
+ case ED_MANIPULATOR_CAGE2D_PART_SCALE_MIN_X_MIN_Y: { ARRAY_SET_ITEMS(r_pt, 0.5, 0.5); x = y = false; break; }
+ case ED_MANIPULATOR_CAGE2D_PART_SCALE_MIN_X_MAX_Y: { ARRAY_SET_ITEMS(r_pt, 0.5, -0.5); x = y = false; break; }
+ case ED_MANIPULATOR_CAGE2D_PART_SCALE_MAX_X_MIN_Y: { ARRAY_SET_ITEMS(r_pt, -0.5, 0.5); x = y = false; break; }
+ case ED_MANIPULATOR_CAGE2D_PART_SCALE_MAX_X_MAX_Y: { ARRAY_SET_ITEMS(r_pt, -0.5, -0.5); x = y = false; break; }
+ default: BLI_assert(0);
+ }
+ r_constrain_axis[0] = x;
+ r_constrain_axis[1] = y;
+}
+
static void rect_transform_draw_corners(
const rctf *r, const float offsetx, const float offsety, const float color[3])
{
@@ -103,72 +120,90 @@ static void rect_transform_draw_corners(
static void rect_transform_draw_interaction(
const float color[4], const int highlighted,
- const float half_w, const float half_h,
- const float w, const float h, const float line_width)
+ const float size[2], const float margin[2],
+ const float line_width)
{
- /* Why generate coordinates for 4 vertices, when we only use three? */
+ /* 4 verts for translate, otherwise only 3 are used. */
float verts[4][2];
+ uint verts_len = 0;
switch (highlighted) {
case ED_MANIPULATOR_CAGE2D_PART_SCALE_MIN_X:
- verts[0][0] = -half_w + w;
- verts[0][1] = -half_h;
- verts[1][0] = -half_w;
- verts[1][1] = -half_h;
- verts[2][0] = -half_w;
- verts[2][1] = half_h;
- verts[3][0] = -half_w + w;
- verts[3][1] = half_h;
+ ARRAY_SET_ITEMS(verts[0], -size[0] + margin[0], -size[1]);
+ ARRAY_SET_ITEMS(verts[1], -size[0], -size[1]);
+ ARRAY_SET_ITEMS(verts[2], -size[0], size[1]);
+ verts_len = 3;
break;
-
case ED_MANIPULATOR_CAGE2D_PART_SCALE_MAX_X:
- verts[0][0] = half_w - w;
- verts[0][1] = -half_h;
- verts[1][0] = half_w;
- verts[1][1] = -half_h;
- verts[2][0] = half_w;
- verts[2][1] = half_h;
- verts[3][0] = half_w - w;
- verts[3][1] = half_h;
+ ARRAY_SET_ITEMS(verts[0], size[0] - margin[0], -size[1]);
+ ARRAY_SET_ITEMS(verts[1], size[0], -size[1]);
+ ARRAY_SET_ITEMS(verts[2], size[0], size[1]);
+ verts_len = 3;
break;
-
case ED_MANIPULATOR_CAGE2D_PART_SCALE_MIN_Y:
- verts[0][0] = -half_w;
- verts[0][1] = -half_h + h;
- verts[1][0] = -half_w;
- verts[1][1] = -half_h;
- verts[2][0] = half_w;
- verts[2][1] = -half_h;
- verts[3][0] = half_w;
- verts[3][1] = -half_h + h;
+ ARRAY_SET_ITEMS(verts[0], -size[0], -size[1] + margin[1]);
+ ARRAY_SET_ITEMS(verts[1], -size[0], -size[1]);
+ ARRAY_SET_ITEMS(verts[2], size[0], -size[1]);
+ verts_len = 3;
break;
-
case ED_MANIPULATOR_CAGE2D_PART_SCALE_MAX_Y:
- verts[0][0] = -half_w;
- verts[0][1] = half_h - h;
- verts[1][0] = -half_w;
- verts[1][1] = half_h;
- verts[2][0] = half_w;
- verts[2][1] = half_h;
- verts[3][0] = half_w;
- verts[3][1] = half_h - h;
+ ARRAY_SET_ITEMS(verts[0], -size[0], size[1] - margin[1]);
+ ARRAY_SET_ITEMS(verts[1], -size[0], size[1]);
+ ARRAY_SET_ITEMS(verts[2], size[0], size[1]);
+ verts_len = 3;
break;
- /* Only used for 3D view selection, never displayed to the user. */
- case ED_MANIPULATOR_CAGE2D_PART_TRANSLATE:
- verts[0][0] = -half_w;
- verts[0][1] = -half_h;
-
- verts[1][0] = -half_w;
- verts[1][1] = half_h;
+ case ED_MANIPULATOR_CAGE2D_PART_SCALE_MIN_X_MIN_Y:
+ ARRAY_SET_ITEMS(verts[0], -size[0] + margin[0], -size[1]);
+ ARRAY_SET_ITEMS(verts[1], -size[0] + margin[0], -size[1] + margin[1]);
+ ARRAY_SET_ITEMS(verts[2], -size[0], -size[1] + margin[1]);
+ verts_len = 3;
+ break;
+ case ED_MANIPULATOR_CAGE2D_PART_SCALE_MIN_X_MAX_Y:
+ ARRAY_SET_ITEMS(verts[0], -size[0] + margin[0], size[1]);
+ ARRAY_SET_ITEMS(verts[1], -size[0] + margin[0], size[1] - margin[1]);
+ ARRAY_SET_ITEMS(verts[2], -size[0], size[1] - margin[1]);
+ verts_len = 3;
+ break;
+ case ED_MANIPULATOR_CAGE2D_PART_SCALE_MAX_X_MIN_Y:
+ ARRAY_SET_ITEMS(verts[0], size[0] - margin[0], -size[1]);
+ ARRAY_SET_ITEMS(verts[1], size[0] - margin[0], -size[1] + margin[1]);
+ ARRAY_SET_ITEMS(verts[2], size[0], -size[1] + margin[1]);
+ verts_len = 3;
+ break;
+ case ED_MANIPULATOR_CAGE2D_PART_SCALE_MAX_X_MAX_Y:
+ ARRAY_SET_ITEMS(verts[0], size[0] - margin[0], size[1]);
+ ARRAY_SET_ITEMS(verts[1], size[0] - margin[0], size[1] - margin[1]);
+ ARRAY_SET_ITEMS(verts[2], size[0], size[1] - margin[1]);
+ verts_len = 3;
+ break;
- verts[2][0] = half_w;
- verts[2][1] = half_h;
+ case ED_MANIPULATOR_CAGE2D_PART_ROTATE:
+ {
+ const float rotate_pt[2] = {0.0f, size[1] + margin[1]};
+ const rctf r_rotate = {
+ .xmin = rotate_pt[0] - margin[0] / 2.0f,
+ .xmax = rotate_pt[0] + margin[0] / 2.0f,
+ .ymin = rotate_pt[1] - margin[1] / 2.0f,
+ .ymax = rotate_pt[1] + margin[1] / 2.0f,
+ };
- verts[3][0] = half_w;
- verts[3][1] = -half_h;
+ ARRAY_SET_ITEMS(verts[0], r_rotate.xmin, r_rotate.ymin);
+ ARRAY_SET_ITEMS(verts[1], r_rotate.xmin, r_rotate.ymax);
+ ARRAY_SET_ITEMS(verts[2], r_rotate.xmax, r_rotate.ymax);
+ ARRAY_SET_ITEMS(verts[3], r_rotate.xmax, r_rotate.ymin);
+ verts_len = 4;
break;
+ }
+ /* Only used for 3D view selection, never displayed to the user. */
+ case ED_MANIPULATOR_CAGE2D_PART_TRANSLATE:
+ ARRAY_SET_ITEMS(verts[0], -size[0], -size[1]);
+ ARRAY_SET_ITEMS(verts[1], -size[0], size[1]);
+ ARRAY_SET_ITEMS(verts[2], size[0], size[1]);
+ ARRAY_SET_ITEMS(verts[3], size[0], -size[1]);
+ verts_len = 4;
+ break;
default:
return;
}
@@ -185,29 +220,28 @@ static void rect_transform_draw_interaction(
if (highlighted == ED_MANIPULATOR_CAGE2D_PART_TRANSLATE) {
immBegin(GWN_PRIM_TRI_FAN, 4);
immAttrib3f(attr_id.col, 0.0f, 0.0f, 0.0f);
- immVertex2fv(attr_id.pos, verts[0]);
- immVertex2fv(attr_id.pos, verts[1]);
- immVertex2fv(attr_id.pos, verts[2]);
- immVertex2fv(attr_id.pos, verts[3]);
+ for (uint i = 0; i < verts_len; i++) {
+ immVertex2fv(attr_id.pos, verts[i]);
+ }
immEnd();
}
else {
glLineWidth(line_width + 3.0f);
- immBegin(GWN_PRIM_LINE_STRIP, 3);
+ immBegin(GWN_PRIM_LINE_STRIP, verts_len);
immAttrib3f(attr_id.col, 0.0f, 0.0f, 0.0f);
- immVertex2fv(attr_id.pos, verts[0]);
- immVertex2fv(attr_id.pos, verts[1]);
- immVertex2fv(attr_id.pos, verts[2]);
+ for (uint i = 0; i < verts_len; i++) {
+ immVertex2fv(attr_id.pos, verts[i]);
+ }
immEnd();
glLineWidth(line_width);
- immBegin(GWN_PRIM_LINE_STRIP, 3);
+ immBegin(GWN_PRIM_LINE_STRIP, verts_len);
immAttrib3fv(attr_id.col, color);
- immVertex2fv(attr_id.pos, verts[0]);
- immVertex2fv(attr_id.pos, verts[1]);
- immVertex2fv(attr_id.pos, verts[2]);
+ for (uint i = 0; i < verts_len; i++) {
+ immVertex2fv(attr_id.pos, verts[i]);
+ }
immEnd();
}
@@ -218,28 +252,28 @@ static void rect_transform_draw_interaction(
static void manipulator_rect_transform_draw_intern(
wmManipulator *mpr, const bool select, const bool highlight, const int select_id)
{
- const bool use_clamp = (mpr->parent_mgroup->type->flag & WM_MANIPULATORGROUPTYPE_3D) == 0;
+ // const bool use_clamp = (mpr->parent_mgroup->type->flag & WM_MANIPULATORGROUPTYPE_3D) == 0;
float dims[2];
RNA_float_get_array(mpr->ptr, "dimensions", dims);
- float w = dims[0];
- float h = dims[1];
+ const float w = dims[0];
+ const float h = dims[1];
+ float matrix_final[4][4];
const int transform_flag = RNA_enum_get(mpr->ptr, "transform");
float aspx = 1.0f, aspy = 1.0f;
- const float half_w = w / 2.0f;
- const float half_h = h / 2.0f;
+ const float size[2] = {w / 2.0f, h / 2.0f};
const rctf r = {
- .xmin = -half_w,
- .ymin = -half_h,
- .xmax = half_w,
- .ymax = half_h,
+ .xmin = -size[0],
+ .ymin = -size[1],
+ .xmax = size[0],
+ .ymax = size[1],
};
+ WM_manipulator_calc_matrix_final(mpr, matrix_final);
+
gpuPushMatrix();
- gpuMultMatrix(mpr->matrix_space);
- gpuMultMatrix(mpr->matrix_basis);
- gpuMultMatrix(mpr->matrix_offset);
+ gpuMultMatrix(matrix_final);
if (w > h) {
aspx = h / w;
@@ -248,26 +282,33 @@ static void manipulator_rect_transform_draw_intern(
aspy = w / h;
}
- if (use_clamp) {
- w = min_ff(aspx * w / MANIPULATOR_RESIZER_WIDTH, MANIPULATOR_RESIZER_WIDTH);
- h = min_ff(aspy * h / MANIPULATOR_RESIZER_WIDTH, MANIPULATOR_RESIZER_WIDTH);
- }
- else {
- /* Corner size. */
- w = h = min_ff(w * aspx, h * aspy) / 10.0f;
- }
+ const float margin[2] = {
+ aspx * w / MANIPULATOR_RESIZER_WIDTH,
+ aspy * h / MANIPULATOR_RESIZER_WIDTH,
+ };
/* corner manipulators */
glLineWidth(mpr->line_width + 3.0f);
+ rect_transform_draw_corners(&r, margin[0], margin[1], (const float[3]){0, 0, 0});
- rect_transform_draw_corners(&r, w, h, (const float[3]){0, 0, 0});
+ /* Handy for quick testing draw (if it's outside bounds). */
+ if (false) {
+ glEnable(GL_BLEND);
+ uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformColor4fv((const float[4]){1, 1, 1, 0.5f});
+ float s = 0.5f;
+ immRectf(pos, -s, -s, s, s);
+ immUnbindProgram();
+ glDisable(GL_BLEND);
+ }
/* corner manipulators */
{
float color[4];
manipulator_color_get(mpr, highlight, color);
glLineWidth(mpr->line_width);
- rect_transform_draw_corners(&r, w, h, color);
+ rect_transform_draw_corners(&r, margin[0], margin[1], color);
}
if (select) {
@@ -275,30 +316,37 @@ static void manipulator_rect_transform_draw_intern(
int scale_parts[] = {
ED_MANIPULATOR_CAGE2D_PART_SCALE_MIN_X,
ED_MANIPULATOR_CAGE2D_PART_SCALE_MAX_X,
- ED_MANIPULATOR_CAGE2D_PART_SCALE_MIN_Y,
+ ED_MANIPULATOR_CAGE2D_PART_SCALE_MIN_Y,
ED_MANIPULATOR_CAGE2D_PART_SCALE_MAX_Y,
+
+ ED_MANIPULATOR_CAGE2D_PART_SCALE_MIN_X_MIN_Y,
+ ED_MANIPULATOR_CAGE2D_PART_SCALE_MIN_X_MAX_Y,
+ ED_MANIPULATOR_CAGE2D_PART_SCALE_MAX_X_MIN_Y,
+ ED_MANIPULATOR_CAGE2D_PART_SCALE_MAX_X_MAX_Y,
};
for (int i = 0; i < ARRAY_SIZE(scale_parts); i++) {
GPU_select_load_id(select_id | scale_parts[i]);
- rect_transform_draw_interaction(
- mpr->color, scale_parts[i], half_w, half_h,
- w, h, mpr->line_width);
+ rect_transform_draw_interaction(mpr->color, scale_parts[i], size, margin, mpr->line_width);
}
}
if (transform_flag & ED_MANIPULATOR_CAGE2D_XFORM_FLAG_TRANSLATE) {
const int transform_part = ED_MANIPULATOR_CAGE2D_PART_TRANSLATE;
GPU_select_load_id(select_id | transform_part);
+ rect_transform_draw_interaction(mpr->color, transform_part, size, margin, mpr->line_width);
+ }
+ if (transform_flag & ED_MANIPULATOR_CAGE2D_XFORM_FLAG_ROTATE) {
rect_transform_draw_interaction(
- mpr->color, transform_part, half_w, half_h,
- w, h, mpr->line_width);
+ mpr->color, ED_MANIPULATOR_CAGE2D_PART_ROTATE, size, margin, mpr->line_width);
}
}
else {
/* Don't draw translate (only for selection). */
if (mpr->highlight_part != ED_MANIPULATOR_CAGE2D_PART_TRANSLATE) {
+ rect_transform_draw_interaction(mpr->color, mpr->highlight_part, size, margin, mpr->line_width);
+ }
+ if (transform_flag & ED_MANIPULATOR_CAGE2D_XFORM_FLAG_ROTATE) {
rect_transform_draw_interaction(
- mpr->color, mpr->highlight_part, half_w, half_h,
- w, h, mpr->line_width);
+ mpr->color, ED_MANIPULATOR_CAGE2D_PART_ROTATE, size, margin, mpr->line_width);
}
}
@@ -337,6 +385,16 @@ static int manipulator_rect_transform_get_cursor(wmManipulator *mpr)
case ED_MANIPULATOR_CAGE2D_PART_SCALE_MIN_Y:
case ED_MANIPULATOR_CAGE2D_PART_SCALE_MAX_Y:
return CURSOR_Y_MOVE;
+
+ /* TODO diagonal cursor */
+ case ED_MANIPULATOR_CAGE2D_PART_SCALE_MIN_X_MIN_Y:
+ case ED_MANIPULATOR_CAGE2D_PART_SCALE_MAX_X_MIN_Y:
+ return BC_NSEW_SCROLLCURSOR;
+ case ED_MANIPULATOR_CAGE2D_PART_SCALE_MIN_X_MAX_Y:
+ case ED_MANIPULATOR_CAGE2D_PART_SCALE_MAX_X_MAX_Y:
+ return BC_NSEW_SCROLLCURSOR;
+ case ED_MANIPULATOR_CAGE2D_PART_ROTATE:
+ return BC_CROSSCURSOR;
default:
return CURSOR_STD;
}
@@ -345,14 +403,12 @@ static int manipulator_rect_transform_get_cursor(wmManipulator *mpr)
static int manipulator_rect_transform_test_select(
bContext *C, wmManipulator *mpr, const wmEvent *event)
{
- //float matrot[2][2];
float point_local[2];
float dims[2];
RNA_float_get_array(mpr->ptr, "dimensions", dims);
- float w = dims[0];
- float h = dims[1];
- float half_w = w / 2.0f;
- float half_h = h / 2.0f;
+ const float w = dims[0];
+ const float h = dims[1];
+ const float size[2] = {w / 2.0f, h / 2.0f};
float aspx = 1.0f, aspy = 1.0f;
if (manipulator_window_project_2d(
@@ -368,65 +424,75 @@ static int manipulator_rect_transform_test_select(
else {
aspy = w / h;
}
- w = min_ff(aspx * w / MANIPULATOR_RESIZER_WIDTH, MANIPULATOR_RESIZER_WIDTH);
- h = min_ff(aspy * h / MANIPULATOR_RESIZER_WIDTH, MANIPULATOR_RESIZER_WIDTH);
-
-
- rctf r;
- r.xmin = -half_w + w;
- r.ymin = -half_h + h;
- r.xmax = half_w - w;
- r.ymax = half_h - h;
-
- bool isect = BLI_rctf_isect_pt_v(&r, point_local);
+ const float margin[2] = {
+ aspx * w / MANIPULATOR_RESIZER_WIDTH,
+ aspy * h / MANIPULATOR_RESIZER_WIDTH,
+ };
- if (isect)
- return ED_MANIPULATOR_CAGE2D_PART_TRANSLATE;
+ if (transform_flag & ED_MANIPULATOR_CAGE2D_XFORM_FLAG_TRANSLATE) {
+ const rctf r = {
+ .xmin = -size[0] + margin[0],
+ .ymin = -size[1] + margin[1],
+ .xmax = size[0] - margin[0],
+ .ymax = size[1] - margin[1],
+ };
+ bool isect = BLI_rctf_isect_pt_v(&r, point_local);
+ if (isect) {
+ return ED_MANIPULATOR_CAGE2D_PART_TRANSLATE;
+ }
+ }
/* if manipulator does not have a scale intersection, don't do it */
- if (transform_flag &
- (ED_MANIPULATOR_CAGE2D_XFORM_FLAG_SCALE | ED_MANIPULATOR_CAGE2D_XFORM_FLAG_SCALE_UNIFORM))
- {
- r.xmin = -half_w;
- r.ymin = -half_h;
- r.xmax = -half_w + w;
- r.ymax = half_h;
-
- isect = BLI_rctf_isect_pt_v(&r, point_local);
-
- if (isect)
+ if (transform_flag & (ED_MANIPULATOR_CAGE2D_XFORM_FLAG_SCALE | ED_MANIPULATOR_CAGE2D_XFORM_FLAG_SCALE_UNIFORM)) {
+ const rctf r_xmin = {.xmin = -size[0], .ymin = -size[1], .xmax = -size[0] + margin[0], .ymax = size[1]};
+ const rctf r_xmax = {.xmin = size[0] - margin[0], .ymin = -size[1], .xmax = size[0], .ymax = size[1]};
+ const rctf r_ymin = {.xmin = -size[0], .ymin = -size[1], .xmax = size[0], .ymax = -size[1] + margin[1]};
+ const rctf r_ymax = {.xmin = -size[0], .ymin = size[1] - margin[1], .xmax = size[0], .ymax = size[1]};
+
+ if (BLI_rctf_isect_pt_v(&r_xmin, point_local)) {
+ if (BLI_rctf_isect_pt_v(&r_ymin, point_local)) {
+ return ED_MANIPULATOR_CAGE2D_PART_SCALE_MIN_X_MIN_Y;
+ }
+ if (BLI_rctf_isect_pt_v(&r_ymax, point_local)) {
+ return ED_MANIPULATOR_CAGE2D_PART_SCALE_MIN_X_MAX_Y;
+ }
return ED_MANIPULATOR_CAGE2D_PART_SCALE_MIN_X;
-
- r.xmin = half_w - w;
- r.ymin = -half_h;
- r.xmax = half_w;
- r.ymax = half_h;
-
- isect = BLI_rctf_isect_pt_v(&r, point_local);
-
- if (isect)
+ }
+ if (BLI_rctf_isect_pt_v(&r_xmax, point_local)) {
+ if (BLI_rctf_isect_pt_v(&r_ymin, point_local)) {
+ return ED_MANIPULATOR_CAGE2D_PART_SCALE_MAX_X_MIN_Y;
+ }
+ if (BLI_rctf_isect_pt_v(&r_ymax, point_local)) {
+ return ED_MANIPULATOR_CAGE2D_PART_SCALE_MAX_X_MAX_Y;
+ }
return ED_MANIPULATOR_CAGE2D_PART_SCALE_MAX_X;
-
- r.xmin = -half_w;
- r.ymin = -half_h;
- r.xmax = half_w;
- r.ymax = -half_h + h;
-
- isect = BLI_rctf_isect_pt_v(&r, point_local);
-
- if (isect)
+ }
+ if (BLI_rctf_isect_pt_v(&r_ymin, point_local)) {
return ED_MANIPULATOR_CAGE2D_PART_SCALE_MIN_Y;
-
- r.xmin = -half_w;
- r.ymin = half_h - h;
- r.xmax = half_w;
- r.ymax = half_h;
-
- isect = BLI_rctf_isect_pt_v(&r, point_local);
-
- if (isect)
+ }
+ if (BLI_rctf_isect_pt_v(&r_ymax, point_local)) {
return ED_MANIPULATOR_CAGE2D_PART_SCALE_MAX_Y;
+ }
+ }
+
+ if (transform_flag & ED_MANIPULATOR_CAGE2D_XFORM_FLAG_ROTATE) {
+ /* Rotate:
+ * (*) <-- hot spot is here!
+ * +---+
+ * | |
+ * +---+ */
+ const float r_rotate_pt[2] = {0.0f, size[1] + margin[1]};
+ const rctf r_rotate = {
+ .xmin = r_rotate_pt[0] - margin[0] / 2.0f,
+ .xmax = r_rotate_pt[0] + margin[0] / 2.0f,
+ .ymin = r_rotate_pt[1] - margin[1] / 2.0f,
+ .ymax = r_rotate_pt[1] + margin[1] / 2.0f,
+ };
+
+ if (BLI_rctf_isect_pt_v(&r_rotate, point_local)) {
+ return ED_MANIPULATOR_CAGE2D_PART_ROTATE;
+ }
}
return -1;
@@ -437,37 +503,9 @@ typedef struct RectTransformInteraction {
float orig_matrix_offset[4][4];
} RectTransformInteraction;
-static bool manipulator_rect_transform_get_prop_value(
- wmManipulator *mpr, wmManipulatorProperty *mpr_prop, float *value)
-{
- if (STREQ(mpr_prop->type->idname, "offset")) {
- WM_manipulator_target_property_value_get_array(mpr, mpr_prop, value);
- }
- else if (STREQ(mpr_prop->type->idname, "scale")) {
- const int transform_flag = RNA_enum_get(mpr->ptr, "transform");
- if (transform_flag & ED_MANIPULATOR_CAGE2D_XFORM_FLAG_SCALE_UNIFORM) {
- if (WM_manipulator_target_property_array_length(mpr, mpr_prop) == 2) {
- WM_manipulator_target_property_value_get_array(mpr, mpr_prop, value);
- }
- else {
- *value = WM_manipulator_target_property_value_get(mpr, mpr_prop);
- value[1] = value[0];
- }
- }
- else {
- WM_manipulator_target_property_value_get_array(mpr, mpr_prop, value);
- }
- }
- else {
- BLI_assert(0);
- }
-
- return true;
-}
-
static void manipulator_rect_transform_setup(wmManipulator *mpr)
{
- mpr->flag |= WM_MANIPULATOR_DRAW_MODAL;
+ mpr->flag |= WM_MANIPULATOR_DRAW_MODAL | WM_MANIPULATOR_DRAW_NO_SCALE;
}
static int manipulator_rect_transform_invoke(
@@ -492,157 +530,124 @@ static int manipulator_rect_transform_modal(
bContext *C, wmManipulator *mpr, const wmEvent *event,
eWM_ManipulatorTweak UNUSED(tweak_flag))
{
- const int transform_flag = RNA_enum_get(mpr->ptr, "transform");
- const bool pivot_center = (transform_flag & ED_MANIPULATOR_CAGE2D_XFORM_FLAG_TRANSLATE) == 0;
RectTransformInteraction *data = mpr->interaction_data;
-#if 0
- /* needed here as well in case clamping occurs */
- const bool use_clamp = (mpr->parent_mgroup->type->flag & WM_MANIPULATORGROUPTYPE_3D) == 0;
- const float orig_ofx = mpr->matrix_offset[3][0];
- const float orig_ofy = mpr->matrix_offset[3][1];
-#endif
-
float point_local[2];
- if (manipulator_window_project_2d(
- C, mpr, (const float[2]){UNPACK2(event->mval)}, 2, false, point_local) == false)
+ float dims[2];
+ RNA_float_get_array(mpr->ptr, "dimensions", dims);
+
{
- return OPERATOR_RUNNING_MODAL;
+ float matrix_back[4][4];
+ copy_m4_m4(matrix_back, mpr->matrix_offset);
+ copy_m4_m4(mpr->matrix_offset, data->orig_matrix_offset);
+
+ bool ok = manipulator_window_project_2d(
+ C, mpr, (const float[2]){UNPACK2(event->mval)}, 2, false, point_local);
+ copy_m4_m4(mpr->matrix_offset, matrix_back);
+ if (!ok) {
+ return OPERATOR_RUNNING_MODAL;
+ }
}
- float value_x = (point_local[0] - data->orig_mouse[0]);
- float value_y = (point_local[1] - data->orig_mouse[1]);
+ const int transform_flag = RNA_enum_get(mpr->ptr, "transform");
- float dims[2];
- RNA_float_get_array(mpr->ptr, "dimensions", dims);
+ const float value_xy[2] = {
+ (point_local[0] - data->orig_mouse[0]),
+ (point_local[1] - data->orig_mouse[1]),
+ };
- const float orig_scale[2] = {data->orig_matrix_offset[0][0], data->orig_matrix_offset[1][1]};
- const float *orig_offset = data->orig_matrix_offset[3];
+ wmManipulatorProperty *mpr_prop;
- float scale[2] = {mpr->matrix_offset[0][0], mpr->matrix_offset[1][1]};
- float *offset = mpr->matrix_offset[3];
+ mpr_prop = WM_manipulator_target_property_find(mpr, "matrix");
+ if (mpr_prop->type != NULL) {
+ WM_manipulator_target_property_value_get_array(mpr, mpr_prop, &mpr->matrix_offset[0][0]);
+ }
if (mpr->highlight_part == ED_MANIPULATOR_CAGE2D_PART_TRANSLATE) {
- offset[0] = orig_offset[0] + value_x;
- offset[1] = orig_offset[1] + value_y;
- }
- else if (mpr->highlight_part == ED_MANIPULATOR_CAGE2D_PART_SCALE_MIN_X) {
- value_x = min_ff(value_x, (dims[0] * orig_scale[0]) * (pivot_center ? 2 : 1));
- if (pivot_center == false) {
- offset[0] = orig_offset[0] + value_x / 2.0f;
- }
- scale[0] = (dims[0] * orig_scale[0] - value_x) / dims[0];
- }
- else if (mpr->highlight_part == ED_MANIPULATOR_CAGE2D_PART_SCALE_MAX_X) {
- value_x = max_ff(value_x, (dims[0] * orig_scale[0]) * (pivot_center ? -2 : -1));
- if (pivot_center == false) {
- offset[0] = orig_offset[0] + value_x / 2.0f;
- }
- scale[0] = (dims[0] * orig_scale[0] + value_x) / dims[0];
- }
- else if (mpr->highlight_part == ED_MANIPULATOR_CAGE2D_PART_SCALE_MIN_Y) {
- int a = (transform_flag & ED_MANIPULATOR_CAGE2D_XFORM_FLAG_SCALE_UNIFORM) ? 0 : 1;
- value_y = min_ff(value_y, (dims[1] * orig_scale[a]) * (pivot_center ? 2 : 1));
- if (pivot_center == false) {
- offset[1] = orig_offset[1] + value_y / 2.0f;
- }
- scale[a] = (dims[1] * orig_scale[a] - value_y) / dims[1];
+ /* do this to prevent clamping from changing size */
+ copy_m4_m4(mpr->matrix_offset, data->orig_matrix_offset);
+ mpr->matrix_offset[3][0] = data->orig_matrix_offset[3][0] + value_xy[0];
+ mpr->matrix_offset[3][1] = data->orig_matrix_offset[3][1] + value_xy[1];
}
- else if (mpr->highlight_part == ED_MANIPULATOR_CAGE2D_PART_SCALE_MAX_Y) {
- int a = (transform_flag & ED_MANIPULATOR_CAGE2D_XFORM_FLAG_SCALE_UNIFORM) ? 0 : 1;
- value_y = max_ff(value_y, (dims[1] * orig_scale[a]) * (pivot_center ? -2 : -1));
- if (pivot_center == false) {
- offset[1] = orig_offset[1] + value_y / 2.0f;
- }
- scale[a] = (dims[1] * orig_scale[a] + value_y) / dims[1];
+ else if (mpr->highlight_part == ED_MANIPULATOR_CAGE2D_PART_ROTATE) {
+ /* rotate */
}
else {
- BLI_assert(0);
- }
+ /* scale */
+ copy_m4_m4(mpr->matrix_offset, data->orig_matrix_offset);
+ float pivot[2];
+ bool constrain_axis[2] = {false};
- /* TODO(campbell): Complicates things too much since not all scales are in the same space. */
-#if 0
- /* clamping - make sure manipulator is at least 5 pixels wide */
- if (use_clamp == false) {
- /* pass */
- }
- else if (transform_flag & ED_MANIPULATOR_CAGE2D_XFORM_FLAG_SCALE_UNIFORM) {
- if (scale[0] < MANIPULATOR_RECT_MIN_WIDTH / max_ff(dims[0], dims[1])) {
- scale[0] = max_ff(MANIPULATOR_RECT_MIN_WIDTH / dims[1], MANIPULATOR_RECT_MIN_WIDTH / dims[0]);
- offset[0] = orig_ofx;
- offset[1] = orig_ofy;
- }
- }
- else {
- if (scale[0] < MANIPULATOR_RECT_MIN_WIDTH / dims[0]) {
- scale[0] = MANIPULATOR_RECT_MIN_WIDTH / dims[0];
- offset[0] = orig_ofx;
+ if (transform_flag & ED_MANIPULATOR_CAGE2D_XFORM_FLAG_TRANSLATE) {
+ manipulator_rect_pivot_from_scale_part(mpr->highlight_part, pivot, constrain_axis);
}
- if (scale[1] < MANIPULATOR_RECT_MIN_WIDTH / dims[1]) {
- scale[1] = MANIPULATOR_RECT_MIN_WIDTH / dims[1];
- offset[1] = orig_ofy;
+ else {
+ zero_v2(pivot);
}
- }
-#endif
- {
- wmManipulatorProperty *mpr_prop = WM_manipulator_target_property_find(mpr, "scale");
- if (mpr_prop->type != NULL) {
- float range[2];
- if (WM_manipulator_target_property_range_get(mpr, mpr_prop, range)) {
- CLAMP(scale[0], range[0], range[1]);
- CLAMP(scale[1], range[0], range[1]);
+ /* scale around pivot */
+ float matrix_scale[4][4];
+ unit_m4(matrix_scale);
+
+ /* cursor deltas */
+ float delta_orig[2], delta_curr[2];
+ sub_v2_v2v2(delta_orig, data->orig_mouse, pivot);
+ sub_v2_v2v2(delta_curr, point_local, pivot);
+
+ /* NOTE: this works but we may want to apply the scale elsewhere. */
+ delta_orig[0] /= dims[0];
+ delta_orig[1] /= dims[1];
+
+ delta_curr[0] /= dims[0];
+ delta_curr[1] /= dims[1];
+
+ float scale[2] = {1.0f, 1.0f};
+ for (int i = 0; i < 2; i++) {
+ if (constrain_axis[i] == false) {
+ if (delta_orig[i] < 0.0f) {
+ delta_orig[i] *= -1.0f;
+ delta_curr[i] *= -1.0f;
+ }
+ scale[i] = 1.0f + ((delta_curr[i] - delta_orig[i]) / len_v3(data->orig_matrix_offset[i]));
}
}
- }
- /* Needed for when we're uniform transforming a 2D vector and need to write both. */
- if (transform_flag & ED_MANIPULATOR_CAGE2D_XFORM_FLAG_SCALE_UNIFORM) {
- scale[1] = scale[0];
- }
-
- mpr->matrix_offset[0][0] = scale[0];
- mpr->matrix_offset[1][1] = scale[1];
-
- wmManipulatorProperty *mpr_prop;
-
- mpr_prop = WM_manipulator_target_property_find(mpr, "scale");
- if (mpr_prop->type != NULL) {
if (transform_flag & ED_MANIPULATOR_CAGE2D_XFORM_FLAG_SCALE_UNIFORM) {
- scale[1] = scale[0];
- if (WM_manipulator_target_property_array_length(mpr, mpr_prop) == 2) {
- WM_manipulator_target_property_value_set_array(C, mpr, mpr_prop, scale);
+ if (fabsf(scale[0] - 1.0f) > fabsf(scale[1] - 1.0f)) {
+ scale[1] = scale[0];
}
else {
- WM_manipulator_target_property_value_set(C, mpr, mpr_prop, scale[0]);
+ scale[0] = scale[1];
}
}
- else {
- WM_manipulator_target_property_value_set_array(C, mpr, mpr_prop, scale);
- }
+
+ mul_v3_fl(matrix_scale[0], scale[0]);
+ mul_v3_fl(matrix_scale[1], scale[1]);
+
+ transform_pivot_set_m4(matrix_scale, (const float [3]){pivot[0], pivot[1], 0.0f});
+ mul_m4_m4m4(mpr->matrix_offset, data->orig_matrix_offset, matrix_scale);
}
- mpr_prop = WM_manipulator_target_property_find(mpr, "offset");
if (mpr_prop->type != NULL) {
- WM_manipulator_target_property_value_set_array(C, mpr, mpr_prop, offset);
+ WM_manipulator_target_property_value_set_array(C, mpr, mpr_prop, &mpr->matrix_offset[0][0]);
}
/* tag the region for redraw */
ED_region_tag_redraw(CTX_wm_region(C));
+ WM_event_add_mousemove(C);
return OPERATOR_RUNNING_MODAL;
}
static void manipulator_rect_transform_property_update(wmManipulator *mpr, wmManipulatorProperty *mpr_prop)
{
- if (STREQ(mpr_prop->type->idname, "scale")) {
- float scale[2];
- manipulator_rect_transform_get_prop_value(mpr, mpr_prop, scale);
- mpr->matrix_offset[0][0] = scale[0];
- mpr->matrix_offset[1][1] = scale[1];
- }
- else if (STREQ(mpr_prop->type->idname, "offset")) {
- manipulator_rect_transform_get_prop_value(mpr, mpr_prop, mpr->matrix_offset[3]);
+ if (STREQ(mpr_prop->type->idname, "matrix")) {
+ if (WM_manipulator_target_property_array_length(mpr, mpr_prop) == 16) {
+ WM_manipulator_target_property_value_get_array(mpr, mpr_prop, &mpr->matrix_offset[0][0]);
+ }
+ else {
+ BLI_assert(0);
+ }
}
else {
BLI_assert(0);
@@ -659,26 +664,9 @@ static void manipulator_rect_transform_exit(bContext *C, wmManipulator *mpr, con
wmManipulatorProperty *mpr_prop;
/* reset properties */
- mpr_prop = WM_manipulator_target_property_find(mpr, "scale");
- if (mpr_prop->type != NULL) {
- const float orig_scale[2] = {data->orig_matrix_offset[0][0], data->orig_matrix_offset[1][1]};
- const int transform_flag = RNA_enum_get(mpr->ptr, "transform");
- if (transform_flag & ED_MANIPULATOR_CAGE2D_XFORM_FLAG_SCALE_UNIFORM) {
- if (WM_manipulator_target_property_array_length(mpr, mpr_prop) == 2) {
- WM_manipulator_target_property_value_set_array(C, mpr, mpr_prop, orig_scale);
- }
- else {
- WM_manipulator_target_property_value_set(C, mpr, mpr_prop, orig_scale[0]);
- }
- }
- else {
- WM_manipulator_target_property_value_set_array(C, mpr, mpr_prop, orig_scale);
- }
- }
-
- mpr_prop = WM_manipulator_target_property_find(mpr, "offset");
+ mpr_prop = WM_manipulator_target_property_find(mpr, "matrix");
if (mpr_prop->type != NULL) {
- WM_manipulator_target_property_value_set_array(C, mpr, mpr_prop, data->orig_matrix_offset[3]);
+ WM_manipulator_target_property_value_set_array(C, mpr, mpr_prop, &data->orig_matrix_offset[0][0]);
}
copy_m4_m4(mpr->matrix_offset, data->orig_matrix_offset);
@@ -720,8 +708,7 @@ static void MANIPULATOR_WT_cage_2d(wmManipulatorType *wt)
RNA_def_float_vector(wt->srna, "dimensions", 2, unit_v2, 0, FLT_MAX, "Dimensions", "", 0.0f, FLT_MAX);
RNA_def_enum_flag(wt->srna, "transform", rna_enum_transform, 0, "Transform Options", "");
- WM_manipulatortype_target_property_def(wt, "offset", PROP_FLOAT, 2);
- WM_manipulatortype_target_property_def(wt, "scale", PROP_FLOAT, 2);
+ WM_manipulatortype_target_property_def(wt, "matrix", PROP_FLOAT, 16);
}
void ED_manipulatortypes_cage_2d(void)
diff --git a/source/blender/editors/manipulator_library/manipulator_types/cage2d_rotate_manipulator.c b/source/blender/editors/manipulator_library/manipulator_types/cage2d_rotate_manipulator.c
deleted file mode 100644
index 0406d3a0972..00000000000
--- a/source/blender/editors/manipulator_library/manipulator_types/cage2d_rotate_manipulator.c
+++ /dev/null
@@ -1,617 +0,0 @@
-/*
- * ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2014 Blender Foundation.
- * All rights reserved.
- *
- * Contributor(s): Blender Foundation
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file cage2d_manipulator.c
- * \ingroup wm
- *
- * \name Cage Manipulator
- *
- * 2D Manipulator
- *
- * \brief Rectangular manipulator acting as a 'cage' around its content.
- * Interacting scales or translates the manipulator.
- */
-
-#include "BIF_gl.h"
-
-#include "BKE_context.h"
-
-#include "BLI_math.h"
-#include "BLI_rect.h"
-
-#include "ED_screen.h"
-#include "ED_view3d.h"
-#include "ED_manipulator_library.h"
-
-#include "GPU_matrix.h"
-#include "GPU_shader.h"
-#include "GPU_immediate.h"
-#include "GPU_select.h"
-
-#include "MEM_guardedalloc.h"
-
-#include "RNA_access.h"
-#include "RNA_define.h"
-
-#include "WM_api.h"
-#include "WM_types.h"
-
-/* own includes */
-#include "../manipulator_library_intern.h"
-
-#define MANIPULATOR_RESIZER_WIDTH 20.0f
-
-/* -------------------------------------------------------------------- */
-
-static void rect_transform_draw_corners(
- const rctf *r, const float offsetx, const float offsety, const float color[3])
-{
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
-
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- immUniformColor3fv(color);
-
- immBegin(GWN_PRIM_LINES, 16);
-
- immVertex2f(pos, r->xmin, r->ymin + offsety);
- immVertex2f(pos, r->xmin, r->ymin);
- immVertex2f(pos, r->xmin, r->ymin);
- immVertex2f(pos, r->xmin + offsetx, r->ymin);
-
- immVertex2f(pos, r->xmax, r->ymin + offsety);
- immVertex2f(pos, r->xmax, r->ymin);
- immVertex2f(pos, r->xmax, r->ymin);
- immVertex2f(pos, r->xmax - offsetx, r->ymin);
-
- immVertex2f(pos, r->xmax, r->ymax - offsety);
- immVertex2f(pos, r->xmax, r->ymax);
- immVertex2f(pos, r->xmax, r->ymax);
- immVertex2f(pos, r->xmax - offsetx, r->ymax);
-
- immVertex2f(pos, r->xmin, r->ymax - offsety);
- immVertex2f(pos, r->xmin, r->ymax);
- immVertex2f(pos, r->xmin, r->ymax);
- immVertex2f(pos, r->xmin + offsetx, r->ymax);
-
- immEnd();
-
- immUnbindProgram();
-}
-
-static void rect_transform_draw_interaction(
- const float color[4], const int highlighted,
- const float size[2], const float margin[2],
- const float line_width)
-{
- /* 4 verts for translate, otherwise only 3 are used. */
- float verts[4][2];
- uint verts_len = 0;
-
- switch (highlighted) {
- case ED_MANIPULATOR_CAGE2D_PART_SCALE_MIN_X:
- ARRAY_SET_ITEMS(verts[0], -size[0] + margin[0], -size[1]);
- ARRAY_SET_ITEMS(verts[1], -size[0], -size[1]);
- ARRAY_SET_ITEMS(verts[2], -size[0], size[1]);
- verts_len = 3;
- break;
- case ED_MANIPULATOR_CAGE2D_PART_SCALE_MAX_X:
- ARRAY_SET_ITEMS(verts[0], size[0] - margin[0], -size[1]);
- ARRAY_SET_ITEMS(verts[1], size[0], -size[1]);
- ARRAY_SET_ITEMS(verts[2], size[0], size[1]);
- verts_len = 3;
- break;
- case ED_MANIPULATOR_CAGE2D_PART_SCALE_MIN_Y:
- ARRAY_SET_ITEMS(verts[0], -size[0], -size[1] + margin[1]);
- ARRAY_SET_ITEMS(verts[1], -size[0], -size[1]);
- ARRAY_SET_ITEMS(verts[2], size[0], -size[1]);
- verts_len = 3;
- break;
- case ED_MANIPULATOR_CAGE2D_PART_SCALE_MAX_Y:
- ARRAY_SET_ITEMS(verts[0], -size[0], size[1] - margin[1]);
- ARRAY_SET_ITEMS(verts[1], -size[0], size[1]);
- ARRAY_SET_ITEMS(verts[2], size[0], size[1]);
- verts_len = 3;
- break;
-
- case ED_MANIPULATOR_CAGE2D_PART_SCALE_MIN_X_MIN_Y:
- ARRAY_SET_ITEMS(verts[0], -size[0] + margin[0], -size[1]);
- ARRAY_SET_ITEMS(verts[1], -size[0] + margin[0], -size[1] + margin[1]);
- ARRAY_SET_ITEMS(verts[2], -size[0], -size[1] + margin[1]);
- verts_len = 3;
- break;
- case ED_MANIPULATOR_CAGE2D_PART_SCALE_MIN_X_MAX_Y:
- ARRAY_SET_ITEMS(verts[0], -size[0] + margin[0], size[1]);
- ARRAY_SET_ITEMS(verts[1], -size[0] + margin[0], size[1] - margin[1]);
- ARRAY_SET_ITEMS(verts[2], -size[0], size[1] - margin[1]);
- verts_len = 3;
- break;
- case ED_MANIPULATOR_CAGE2D_PART_SCALE_MAX_X_MIN_Y:
- ARRAY_SET_ITEMS(verts[0], size[0] - margin[0], -size[1]);
- ARRAY_SET_ITEMS(verts[1], size[0] - margin[0], -size[1] + margin[1]);
- ARRAY_SET_ITEMS(verts[2], size[0], -size[1] + margin[1]);
- verts_len = 3;
- break;
- case ED_MANIPULATOR_CAGE2D_PART_SCALE_MAX_X_MAX_Y:
- ARRAY_SET_ITEMS(verts[0], size[0] - margin[0], size[1]);
- ARRAY_SET_ITEMS(verts[1], size[0] - margin[0], size[1] - margin[1]);
- ARRAY_SET_ITEMS(verts[2], size[0], size[1] - margin[1]);
- verts_len = 3;
- break;
-
- case ED_MANIPULATOR_CAGE2D_PART_ROTATE:
- {
- const float rotate_pt[2] = {0.0f, size[1] + margin[1]};
- const rctf r_rotate = {
- .xmin = rotate_pt[0] - margin[0] / 2.0f,
- .xmax = rotate_pt[0] + margin[0] / 2.0f,
- .ymin = rotate_pt[1] - margin[1] / 2.0f,
- .ymax = rotate_pt[1] + margin[1] / 2.0f,
- };
-
- ARRAY_SET_ITEMS(verts[0], r_rotate.xmin, r_rotate.ymin);
- ARRAY_SET_ITEMS(verts[1], r_rotate.xmin, r_rotate.ymax);
- ARRAY_SET_ITEMS(verts[2], r_rotate.xmax, r_rotate.ymax);
- ARRAY_SET_ITEMS(verts[3], r_rotate.xmax, r_rotate.ymin);
- verts_len = 4;
- break;
- }
-
- /* Only used for 3D view selection, never displayed to the user. */
- case ED_MANIPULATOR_CAGE2D_PART_TRANSLATE:
- ARRAY_SET_ITEMS(verts[0], -size[0], -size[1]);
- ARRAY_SET_ITEMS(verts[1], -size[0], size[1]);
- ARRAY_SET_ITEMS(verts[2], size[0], size[1]);
- ARRAY_SET_ITEMS(verts[3], size[0], -size[1]);
- verts_len = 4;
- break;
- default:
- return;
- }
-
- Gwn_VertFormat *format = immVertexFormat();
- struct {
- uint pos, col;
- } attr_id = {
- .pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT),
- .col = GWN_vertformat_attr_add(format, "color", GWN_COMP_F32, 3, GWN_FETCH_FLOAT),
- };
- immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
-
- if (highlighted == ED_MANIPULATOR_CAGE2D_PART_TRANSLATE) {
- immBegin(GWN_PRIM_TRI_FAN, 4);
- immAttrib3f(attr_id.col, 0.0f, 0.0f, 0.0f);
- for (uint i = 0; i < verts_len; i++) {
- immVertex2fv(attr_id.pos, verts[i]);
- }
- immEnd();
- }
- else {
- glLineWidth(line_width + 3.0f);
-
- immBegin(GWN_PRIM_LINE_STRIP, verts_len);
- immAttrib3f(attr_id.col, 0.0f, 0.0f, 0.0f);
- for (uint i = 0; i < verts_len; i++) {
- immVertex2fv(attr_id.pos, verts[i]);
- }
- immEnd();
-
- glLineWidth(line_width);
-
- immBegin(GWN_PRIM_LINE_STRIP, verts_len);
- immAttrib3fv(attr_id.col, color);
- for (uint i = 0; i < verts_len; i++) {
- immVertex2fv(attr_id.pos, verts[i]);
- }
- immEnd();
- }
-
- immUnbindProgram();
-
-}
-
-static void manipulator_rect_transform_draw_intern(
- wmManipulator *mpr, const bool select, const bool highlight, const int select_id)
-{
- // const bool use_clamp = (mpr->parent_mgroup->type->flag & WM_MANIPULATORGROUPTYPE_3D) == 0;
- float dims[2];
- RNA_float_get_array(mpr->ptr, "dimensions", dims);
- const float w = dims[0] * (1.0f + (1.0f / 3.0f));
- const float h = dims[1] * (1.0f + (1.0f / 3.0f));
- float matrix_final[4][4];
-
- const int transform_flag = RNA_enum_get(mpr->ptr, "transform");
-
- float aspx = 1.0f, aspy = 1.0f;
- const float size[2] = {w / 2.0f, h / 2.0f};
- const rctf r = {
- .xmin = -size[0],
- .ymin = -size[1],
- .xmax = size[0],
- .ymax = size[1],
- };
-
- WM_manipulator_calc_matrix_final(mpr, matrix_final);
-
- gpuPushMatrix();
- gpuMultMatrix(matrix_final);
-
- if (w > h) {
- aspx = h / w;
- }
- else {
- aspy = w / h;
- }
-
- const float margin[2] = {
- aspx * w / MANIPULATOR_RESIZER_WIDTH,
- aspy * h / MANIPULATOR_RESIZER_WIDTH,
- };
-
- /* corner manipulators */
- glLineWidth(mpr->line_width + 3.0f);
- rect_transform_draw_corners(&r, margin[0], margin[1], (const float[3]){0, 0, 0});
-
- if (false) {
- glEnable(GL_BLEND);
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- immUniformColor4fv((const float[4]){1, 1, 1, 0.5f});
- float s = 2.0f / 3.0f;
- immRectf(pos, -s, -s, s, s);
- immUnbindProgram();
- glDisable(GL_BLEND);
- }
-
- /* corner manipulators */
- {
- float color[4];
- manipulator_color_get(mpr, highlight, color);
- glLineWidth(mpr->line_width);
- rect_transform_draw_corners(&r, margin[0], margin[1], color);
- }
-
- if (select) {
- if (transform_flag & ED_MANIPULATOR_CAGE2D_XFORM_FLAG_SCALE) {
- int scale_parts[] = {
- ED_MANIPULATOR_CAGE2D_PART_SCALE_MIN_X,
- ED_MANIPULATOR_CAGE2D_PART_SCALE_MAX_X,
- ED_MANIPULATOR_CAGE2D_PART_SCALE_MIN_Y,
- ED_MANIPULATOR_CAGE2D_PART_SCALE_MAX_Y,
-
- ED_MANIPULATOR_CAGE2D_PART_SCALE_MIN_X_MIN_Y,
- ED_MANIPULATOR_CAGE2D_PART_SCALE_MIN_X_MAX_Y,
- ED_MANIPULATOR_CAGE2D_PART_SCALE_MAX_X_MIN_Y,
- ED_MANIPULATOR_CAGE2D_PART_SCALE_MAX_X_MAX_Y,
- };
- for (int i = 0; i < ARRAY_SIZE(scale_parts); i++) {
- GPU_select_load_id(select_id | scale_parts[i]);
- rect_transform_draw_interaction(mpr->color, scale_parts[i], size, margin, mpr->line_width);
- }
- }
- if (transform_flag & ED_MANIPULATOR_CAGE2D_XFORM_FLAG_TRANSLATE) {
- const int transform_part = ED_MANIPULATOR_CAGE2D_PART_TRANSLATE;
- GPU_select_load_id(select_id | transform_part);
- rect_transform_draw_interaction(mpr->color, transform_part, size, margin, mpr->line_width);
- }
- if (transform_flag & ED_MANIPULATOR_CAGE2D_XFORM_FLAG_ROTATE) {
- rect_transform_draw_interaction(
- mpr->color, ED_MANIPULATOR_CAGE2D_PART_ROTATE, size, margin, mpr->line_width);
- }
- }
- else {
- /* Don't draw translate (only for selection). */
- if (mpr->highlight_part != ED_MANIPULATOR_CAGE2D_PART_TRANSLATE) {
- rect_transform_draw_interaction(mpr->color, mpr->highlight_part, size, margin, mpr->line_width);
- }
- if (transform_flag & ED_MANIPULATOR_CAGE2D_XFORM_FLAG_ROTATE) {
- rect_transform_draw_interaction(
- mpr->color, ED_MANIPULATOR_CAGE2D_PART_ROTATE, size, margin, mpr->line_width);
- }
- }
-
- glLineWidth(1.0);
- gpuPopMatrix();
-}
-
-/**
- * For when we want to draw 2d cage in 3d views.
- */
-static void manipulator_rect_transform_draw_select(const bContext *UNUSED(C), wmManipulator *mpr, int select_id)
-{
- manipulator_rect_transform_draw_intern(mpr, true, false, select_id);
-}
-
-static void manipulator_rect_transform_draw(const bContext *UNUSED(C), wmManipulator *mpr)
-{
- const bool is_highlight = (mpr->state & WM_MANIPULATOR_STATE_HIGHLIGHT) != 0;
- manipulator_rect_transform_draw_intern(mpr, false, is_highlight, -1);
-}
-
-static int manipulator_rect_transform_get_cursor(wmManipulator *mpr)
-{
- int highlight_part = mpr->highlight_part;
-
- if (mpr->parent_mgroup->type->flag & WM_MANIPULATORGROUPTYPE_3D) {
- return BC_NSEW_SCROLLCURSOR;
- }
-
- switch (highlight_part) {
- case ED_MANIPULATOR_CAGE2D_PART_TRANSLATE:
- return BC_HANDCURSOR;
- case ED_MANIPULATOR_CAGE2D_PART_SCALE_MIN_X:
- case ED_MANIPULATOR_CAGE2D_PART_SCALE_MAX_X:
- return CURSOR_X_MOVE;
- case ED_MANIPULATOR_CAGE2D_PART_SCALE_MIN_Y:
- case ED_MANIPULATOR_CAGE2D_PART_SCALE_MAX_Y:
- return CURSOR_Y_MOVE;
-
- /* TODO diagonal cursor */
- case ED_MANIPULATOR_CAGE2D_PART_SCALE_MIN_X_MIN_Y:
- case ED_MANIPULATOR_CAGE2D_PART_SCALE_MAX_X_MIN_Y:
- return BC_NSEW_SCROLLCURSOR;
- case ED_MANIPULATOR_CAGE2D_PART_SCALE_MIN_X_MAX_Y:
- case ED_MANIPULATOR_CAGE2D_PART_SCALE_MAX_X_MAX_Y:
- return BC_NSEW_SCROLLCURSOR;
- case ED_MANIPULATOR_CAGE2D_PART_ROTATE:
- return BC_CROSSCURSOR;
- default:
- return CURSOR_STD;
- }
-}
-
-static int manipulator_rect_transform_test_select(
- bContext *C, wmManipulator *mpr, const wmEvent *event)
-{
- //float matrot[2][2];
- float point_local[2];
- float dims[2];
- RNA_float_get_array(mpr->ptr, "dimensions", dims);
- const float w = dims[0] * 2;
- const float h = dims[1] * 2;
- const float size[2] = {w / 2.0f, h / 2.0f};
- float aspx = 1.0f, aspy = 1.0f;
-
- if (manipulator_window_project_2d(
- C, mpr, (const float[2]){UNPACK2(event->mval)}, 2, true, point_local) == false)
- {
- return 0;
- }
-
- const int transform_flag = RNA_enum_get(mpr->ptr, "transform");
- if (dims[0] > dims[1]) {
- aspx = h / w;
- }
- else {
- aspy = w / h;
- }
-
- const float margin[2] = {
- aspx * w / MANIPULATOR_RESIZER_WIDTH,
- aspy * h / MANIPULATOR_RESIZER_WIDTH,
- };
-
- rctf r;
-
- r.xmin = -size[0] + margin[0];
- r.ymin = -size[1] + margin[1];
- r.xmax = size[0] - margin[0];
- r.ymax = size[1] - margin[1];
-
- bool isect = BLI_rctf_isect_pt_v(&r, point_local);
-
- if (isect)
- return ED_MANIPULATOR_CAGE2D_PART_TRANSLATE;
-
- /* if manipulator does not have a scale intersection, don't do it */
- if (transform_flag &
- (ED_MANIPULATOR_CAGE2D_XFORM_FLAG_SCALE | ED_MANIPULATOR_CAGE2D_XFORM_FLAG_SCALE_UNIFORM))
- {
- const rctf r_xmin = {.xmin = -size[0], .ymin = -size[1], .xmax = -size[0] + margin[0], .ymax = size[1]};
- const rctf r_xmax = {.xmin = size[0] - margin[0], .ymin = -size[1], .xmax = size[0], .ymax = size[1]};
- const rctf r_ymin = {.xmin = -size[0], .ymin = -size[1], .xmax = size[0], .ymax = -size[1] + margin[1]};
- const rctf r_ymax = {.xmin = -size[0], .ymin = size[1] - margin[1], .xmax = size[0], .ymax = size[1]};
-
- if (BLI_rctf_isect_pt_v(&r_xmin, point_local)) {
- if (BLI_rctf_isect_pt_v(&r_ymin, point_local)) {
- return ED_MANIPULATOR_CAGE2D_PART_SCALE_MIN_X_MIN_Y;
- }
- if (BLI_rctf_isect_pt_v(&r_ymax, point_local)) {
- return ED_MANIPULATOR_CAGE2D_PART_SCALE_MIN_X_MAX_Y;
- }
- return ED_MANIPULATOR_CAGE2D_PART_SCALE_MIN_X;
- }
- if (BLI_rctf_isect_pt_v(&r_xmax, point_local)) {
- if (BLI_rctf_isect_pt_v(&r_ymin, point_local)) {
- return ED_MANIPULATOR_CAGE2D_PART_SCALE_MAX_X_MIN_Y;
- }
- if (BLI_rctf_isect_pt_v(&r_ymax, point_local)) {
- return ED_MANIPULATOR_CAGE2D_PART_SCALE_MAX_X_MAX_Y;
- }
- return ED_MANIPULATOR_CAGE2D_PART_SCALE_MAX_X;
- }
- if (BLI_rctf_isect_pt_v(&r_ymin, point_local)) {
- return ED_MANIPULATOR_CAGE2D_PART_SCALE_MIN_Y;
- }
- if (BLI_rctf_isect_pt_v(&r_ymax, point_local)) {
- return ED_MANIPULATOR_CAGE2D_PART_SCALE_MAX_Y;
- }
- }
-
- if (transform_flag & ED_MANIPULATOR_CAGE2D_XFORM_FLAG_ROTATE) {
- /* Rotate:
- * (*) <-- hot spot is here!
- * +---+
- * | |
- * +---+ */
- const float r_rotate_pt[2] = {0.0f, size[1] + margin[1]};
- const rctf r_rotate = {
- .xmin = r_rotate_pt[0] - margin[0] / 2.0f,
- .xmax = r_rotate_pt[0] + margin[0] / 2.0f,
- .ymin = r_rotate_pt[1] - margin[1] / 2.0f,
- .ymax = r_rotate_pt[1] + margin[1] / 2.0f,
- };
-
- if (BLI_rctf_isect_pt_v(&r_rotate, point_local)) {
- return ED_MANIPULATOR_CAGE2D_PART_ROTATE;
- }
- }
-
- return -1;
-}
-
-typedef struct RectTransformInteraction {
- float orig_mouse[2];
- float orig_matrix_offset[4][4];
-} RectTransformInteraction;
-
-static void manipulator_rect_transform_setup(wmManipulator *mpr)
-{
- mpr->flag |= WM_MANIPULATOR_DRAW_MODAL;
-}
-
-static int manipulator_rect_transform_invoke(
- bContext *C, wmManipulator *mpr, const wmEvent *event)
-{
- RectTransformInteraction *data = MEM_callocN(sizeof(RectTransformInteraction), "cage_interaction");
-
- copy_m4_m4(data->orig_matrix_offset, mpr->matrix_offset);
-
- if (manipulator_window_project_2d(
- C, mpr, (const float[2]){UNPACK2(event->mval)}, 2, false, data->orig_mouse) == 0)
- {
- zero_v2(data->orig_mouse);
- }
-
- mpr->interaction_data = data;
-
- return OPERATOR_RUNNING_MODAL;
-}
-
-static int manipulator_rect_transform_modal(
- bContext *C, wmManipulator *mpr, const wmEvent *event,
- eWM_ManipulatorTweak UNUSED(tweak_flag))
-{
- float point_local[2];
-
- if (manipulator_window_project_2d(
- C, mpr, (const float[2]){UNPACK2(event->mval)}, 2, false, point_local) == false)
- {
- return OPERATOR_RUNNING_MODAL;
- }
-
- /* TODO! (currently a nop) */
-
- wmManipulatorProperty *mpr_prop;
-
- mpr_prop = WM_manipulator_target_property_find(mpr, "matrix");
- if (mpr_prop->type != NULL) {
- WM_manipulator_target_property_value_set_array(C, mpr, mpr_prop, &mpr->matrix_offset[0][0]);
- }
-
- /* tag the region for redraw */
- ED_region_tag_redraw(CTX_wm_region(C));
- WM_event_add_mousemove(C);
-
- return OPERATOR_RUNNING_MODAL;
-}
-
-static void manipulator_rect_transform_property_update(wmManipulator *mpr, wmManipulatorProperty *mpr_prop)
-{
- if (STREQ(mpr_prop->type->idname, "matrix")) {
- if (WM_manipulator_target_property_array_length(mpr, mpr_prop) == 16) {
- WM_manipulator_target_property_value_get_array(mpr, mpr_prop, &mpr->matrix_offset[0][0]);
- }
- else {
- BLI_assert(0);
- }
- }
- else {
- BLI_assert(0);
- }
-}
-
-static void manipulator_rect_transform_exit(bContext *C, wmManipulator *mpr, const bool cancel)
-{
- RectTransformInteraction *data = mpr->interaction_data;
-
- if (!cancel)
- return;
-
- wmManipulatorProperty *mpr_prop;
-
- /* reset properties */
- mpr_prop = WM_manipulator_target_property_find(mpr, "matrix");
- if (mpr_prop->type != NULL) {
- WM_manipulator_target_property_value_set_array(C, mpr, mpr_prop, &data->orig_matrix_offset[0][0]);
- }
-
- copy_m4_m4(mpr->matrix_offset, data->orig_matrix_offset);
-}
-
-
-/* -------------------------------------------------------------------- */
-/** \name Cage Manipulator API
- *
- * \{ */
-
-static void MANIPULATOR_WT_cage_2d_rotate(wmManipulatorType *wt)
-{
- /* identifiers */
- wt->idname = "MANIPULATOR_WT_cage_2d_rotate";
-
- /* api callbacks */
- wt->draw = manipulator_rect_transform_draw;
- wt->draw_select = manipulator_rect_transform_draw_select;
- wt->test_select = manipulator_rect_transform_test_select;
- wt->setup = manipulator_rect_transform_setup;
- wt->invoke = manipulator_rect_transform_invoke;
- wt->property_update = manipulator_rect_transform_property_update;
- wt->modal = manipulator_rect_transform_modal;
- wt->exit = manipulator_rect_transform_exit;
- wt->cursor_get = manipulator_rect_transform_get_cursor;
-
- wt->struct_size = sizeof(wmManipulator);
-
- /* rna */
- static EnumPropertyItem rna_enum_transform[] = {
- {ED_MANIPULATOR_CAGE2D_XFORM_FLAG_TRANSLATE, "TRANSLATE", 0, "Translate", ""},
- {ED_MANIPULATOR_CAGE2D_XFORM_FLAG_ROTATE, "ROTATE", 0, "Rotate", ""},
- {ED_MANIPULATOR_CAGE2D_XFORM_FLAG_SCALE, "SCALE", 0, "Scale", ""},
- {ED_MANIPULATOR_CAGE2D_XFORM_FLAG_SCALE_UNIFORM, "SCALE_UNIFORM", 0, "Scale Uniform", ""},
- {0, NULL, 0, NULL, NULL}
- };
- static float unit_v2[2] = {1.0f, 1.0f};
- RNA_def_float_vector(wt->srna, "dimensions", 2, unit_v2, 0, FLT_MAX, "Dimensions", "", 0.0f, FLT_MAX);
- RNA_def_enum_flag(wt->srna, "transform", rna_enum_transform, 0, "Transform Options", "");
-
- WM_manipulatortype_target_property_def(wt, "matrix", PROP_FLOAT, 16);
-}
-
-void ED_manipulatortypes_cage_2d_rotate(void)
-{
- WM_manipulatortype_append(MANIPULATOR_WT_cage_2d_rotate);
-}
-
-/** \} */
diff --git a/source/blender/editors/space_api/spacetypes.c b/source/blender/editors/space_api/spacetypes.c
index c3a8333d378..e64e9841139 100644
--- a/source/blender/editors/space_api/spacetypes.c
+++ b/source/blender/editors/space_api/spacetypes.c
@@ -133,7 +133,6 @@ void ED_spacetypes_init(void)
ED_manipulatortypes_arrow_3d();
ED_manipulatortypes_primitive_3d();
ED_manipulatortypes_cage_2d();
- ED_manipulatortypes_cage_2d_rotate();
/* register types for operators and manipulators */
spacetypes = BKE_spacetypes_list();
diff --git a/source/blender/editors/space_node/node_manipulators.c b/source/blender/editors/space_node/node_manipulators.c
index 1c6aad549ec..8e736e47963 100644
--- a/source/blender/editors/space_node/node_manipulators.c
+++ b/source/blender/editors/space_node/node_manipulators.c
@@ -79,6 +79,32 @@ static void node_manipulator_calc_matrix_space_with_image_dims(
/** \name Backdrop Manipulator
* \{ */
+static void manipulator_node_backdrop_prop_matrix_get(
+ const wmManipulator *UNUSED(mpr), wmManipulatorProperty *mpr_prop,
+ void *value_p)
+{
+ float (*matrix)[4] = value_p;
+ BLI_assert(mpr_prop->type->array_length == 16);
+ const SpaceNode *snode = mpr_prop->custom_func.user_data;
+ matrix[0][0] = snode->zoom;
+ matrix[1][1] = snode->zoom;
+ matrix[3][0] = snode->xof;
+ matrix[3][1] = snode->yof;
+}
+
+static void manipulator_node_backdrop_prop_matrix_set(
+ const wmManipulator *UNUSED(mpr), wmManipulatorProperty *mpr_prop,
+ const void *value_p)
+{
+ const float (*matrix)[4] = value_p;
+ BLI_assert(mpr_prop->type->array_length == 16);
+ SpaceNode *snode = mpr_prop->custom_func.user_data;
+ snode->zoom = matrix[0][0];
+ snode->zoom = matrix[1][1];
+ snode->xof = matrix[3][0];
+ snode->yof = matrix[3][1];
+}
+
static bool WIDGETGROUP_node_transform_poll(const bContext *C, wmManipulatorGroupType *UNUSED(wgt))
{
SpaceNode *snode = CTX_wm_space_node(C);
@@ -133,10 +159,21 @@ static void WIDGETGROUP_node_transform_refresh(const bContext *C, wmManipulatorG
/* need to set property here for undo. TODO would prefer to do this in _init */
SpaceNode *snode = CTX_wm_space_node(C);
+#if 0
PointerRNA nodeptr;
RNA_pointer_create(snode->id, &RNA_SpaceNodeEditor, snode, &nodeptr);
WM_manipulator_target_property_def_rna(cage, "offset", &nodeptr, "backdrop_offset", -1);
WM_manipulator_target_property_def_rna(cage, "scale", &nodeptr, "backdrop_zoom", -1);
+#endif
+
+ WM_manipulator_target_property_def_func(
+ cage, "matrix",
+ &(const struct wmManipulatorPropertyFnParams) {
+ .value_get_fn = manipulator_node_backdrop_prop_matrix_get,
+ .value_set_fn = manipulator_node_backdrop_prop_matrix_set,
+ .range_get_fn = NULL,
+ .user_data = snode,
+ });
}
else {
WM_manipulator_set_flag(cage, WM_MANIPULATOR_HIDDEN, true);
@@ -216,82 +253,45 @@ static void two_xy_from_rect(NodeTwoXYs *nxy, const rctf *rect, const float dims
}
/* scale callbacks */
-static void manipulator_node_crop_prop_size_get(
+static void manipulator_node_crop_prop_matrix_get(
const wmManipulator *mpr, wmManipulatorProperty *mpr_prop,
void *value_p)
{
- float *value = value_p;
+ float (*matrix)[4] = value_p;
+ BLI_assert(mpr_prop->type->array_length == 16);
struct NodeCropWidgetGroup *crop_group = mpr->parent_mgroup->customdata;
const float *dims = crop_group->state.dims;
- BLI_assert(mpr_prop->type->array_length == 2);
const bNode *node = mpr_prop->custom_func.user_data;
const NodeTwoXYs *nxy = node->storage;
bool is_relative = (bool)node->custom2;
rctf rct;
two_xy_to_rect(nxy, &rct, dims, is_relative);
- value[0] = BLI_rctf_size_x(&rct);
- value[1] = BLI_rctf_size_y(&rct);
+ matrix[0][0] = BLI_rctf_size_x(&rct);
+ matrix[1][1] = BLI_rctf_size_y(&rct);
+ matrix[3][0] = (BLI_rctf_cent_x(&rct) - 0.5f) * dims[0];
+ matrix[3][1] = (BLI_rctf_cent_y(&rct) - 0.5f) * dims[1];
}
-static void manipulator_node_crop_prop_size_set(
+static void manipulator_node_crop_prop_matrix_set(
const wmManipulator *mpr, wmManipulatorProperty *mpr_prop,
const void *value_p)
{
- const float *value = value_p;
+ const float (*matrix)[4] = value_p;
+ BLI_assert(mpr_prop->type->array_length == 16);
struct NodeCropWidgetGroup *crop_group = mpr->parent_mgroup->customdata;
const float *dims = crop_group->state.dims;
bNode *node = mpr_prop->custom_func.user_data;
NodeTwoXYs *nxy = node->storage;
bool is_relative = (bool)node->custom2;
- BLI_assert(mpr_prop->type->array_length == 2);
rctf rct;
two_xy_to_rect(nxy, &rct, dims, is_relative);
- BLI_rctf_resize(&rct, value[0], value[1]);
+ BLI_rctf_resize(&rct, matrix[0][0], matrix[1][1]);
+ BLI_rctf_recenter(&rct, (matrix[3][0] / dims[0]) + 0.5f, (matrix[3][1] / dims[1]) + 0.5f);
BLI_rctf_isect(&(rctf){.xmin = 0, .ymin = 0, .xmax = 1, .ymax = 1}, &rct, &rct);
two_xy_from_rect(nxy, &rct, dims, is_relative);
-
manipulator_node_crop_update(crop_group);
}
-/* offset callbacks */
-static void manipulator_node_crop_prop_offset_get(
- const wmManipulator *mpr, wmManipulatorProperty *mpr_prop,
- void *value_p)
-{
- float *value = value_p;
- struct NodeCropWidgetGroup *crop_group = mpr->parent_mgroup->customdata;
- const float *dims = crop_group->state.dims;
- BLI_assert(mpr_prop->type->array_length == 2);
- const bNode *node = mpr_prop->custom_func.user_data;
- const NodeTwoXYs *nxy = node->storage;
- bool is_relative = (bool)node->custom2;
- rctf rct;
- two_xy_to_rect(nxy, &rct, dims, is_relative);
- value[0] = (BLI_rctf_cent_x(&rct) - 0.5f) * dims[0];
- value[1] = (BLI_rctf_cent_y(&rct) - 0.5f) * dims[1];
-}
-
-static void manipulator_node_crop_prop_offset_set(
- const wmManipulator *mpr, wmManipulatorProperty *mpr_prop,
- const void *value_p)
-{
- const float *value = value_p;
- struct NodeCropWidgetGroup *crop_group = mpr->parent_mgroup->customdata;
- const float *dims = crop_group->state.dims;
- bNode *node = mpr_prop->custom_func.user_data;
- NodeTwoXYs *nxy = node->storage;
- bool is_relative = (bool)node->custom2;
- BLI_assert(mpr_prop->type->array_length == 2);
- rctf rct;
- two_xy_to_rect(nxy, &rct, dims, is_relative);
- BLI_rctf_recenter(&rct, (value[0] / dims[0]) + 0.5f, (value[1] / dims[1]) + 0.5f);
- BLI_rctf_isect(&(rctf){.xmin = 0, .ymin = 0, .xmax = 1, .ymax = 1}, &rct, &rct);
- two_xy_from_rect(nxy, &rct, dims, is_relative);
-
- manipulator_node_crop_update(crop_group);
-}
-
-
static bool WIDGETGROUP_node_crop_poll(const bContext *C, wmManipulatorGroupType *UNUSED(wgt))
{
SpaceNode *snode = CTX_wm_space_node(C);
@@ -360,19 +360,10 @@ static void WIDGETGROUP_node_crop_refresh(const bContext *C, wmManipulatorGroup
crop_group->update_data.prop = RNA_struct_find_property(&crop_group->update_data.ptr, "relative");
WM_manipulator_target_property_def_func(
- mpr, "offset",
- &(const struct wmManipulatorPropertyFnParams) {
- .value_get_fn = manipulator_node_crop_prop_offset_get,
- .value_set_fn = manipulator_node_crop_prop_offset_set,
- .range_get_fn = NULL,
- .user_data = node,
- });
-
- WM_manipulator_target_property_def_func(
- mpr, "scale",
+ mpr, "matrix",
&(const struct wmManipulatorPropertyFnParams) {
- .value_get_fn = manipulator_node_crop_prop_size_get,
- .value_set_fn = manipulator_node_crop_prop_size_set,
+ .value_get_fn = manipulator_node_crop_prop_matrix_get,
+ .value_set_fn = manipulator_node_crop_prop_matrix_set,
.range_get_fn = NULL,
.user_data = node,
});
diff --git a/source/blender/editors/space_view3d/view3d_manipulator_camera.c b/source/blender/editors/space_view3d/view3d_manipulator_camera.c
index e93c2aaf735..948758318f5 100644
--- a/source/blender/editors/space_view3d/view3d_manipulator_camera.c
+++ b/source/blender/editors/space_view3d/view3d_manipulator_camera.c
@@ -120,6 +120,7 @@ static void WIDGETGROUP_camera_setup(const bContext *C, wmManipulatorGroup *mgro
{
wmManipulator *mpr;
mpr = camgroup->focal_len = WM_manipulator_new_ptr(wt_arrow, mgroup, NULL);
+ mpr->flag |= WM_MANIPULATOR_DRAW_NO_SCALE;
RNA_enum_set(mpr->ptr, "draw_style", ED_MANIPULATOR_ARROW_STYLE_CONE);
RNA_enum_set(mpr->ptr, "draw_options", ED_MANIPULATOR_ARROW_STYLE_CONSTRAINED);
@@ -128,6 +129,7 @@ static void WIDGETGROUP_camera_setup(const bContext *C, wmManipulatorGroup *mgro
cameragroup_property_setup(mpr, ob, ca, false);
mpr = camgroup->ortho_scale = WM_manipulator_new_ptr(wt_arrow, mgroup, NULL);
+ mpr->flag |= WM_MANIPULATOR_DRAW_NO_SCALE;
RNA_enum_set(mpr->ptr, "draw_style", ED_MANIPULATOR_ARROW_STYLE_CONE);
RNA_enum_set(mpr->ptr, "draw_options", ED_MANIPULATOR_ARROW_STYLE_CONSTRAINED);
@@ -240,57 +242,33 @@ struct CameraViewWidgetGroup {
};
/* scale callbacks */
-static void manipulator_render_border_prop_size_get(
+static void manipulator_render_border_prop_matrix_get(
const wmManipulator *UNUSED(mpr), wmManipulatorProperty *mpr_prop,
void *value_p)
{
- float *value = value_p;
- BLI_assert(mpr_prop->type->array_length == 2);
+ float (*matrix)[4] = value_p;
+ BLI_assert(mpr_prop->type->array_length == 16);
struct CameraViewWidgetGroup *viewgroup = mpr_prop->custom_func.user_data;
const rctf *border = viewgroup->state.edit_border;
- value[0] = BLI_rctf_size_x(border);
- value[1] = BLI_rctf_size_y(border);
+ unit_m4(matrix);
+ matrix[0][0] = BLI_rctf_size_x(border);
+ matrix[1][1] = BLI_rctf_size_y(border);
+ matrix[3][0] = BLI_rctf_cent_x(border);
+ matrix[3][1] = BLI_rctf_cent_y(border);
}
-static void manipulator_render_border_prop_size_set(
+static void manipulator_render_border_prop_matrix_set(
const wmManipulator *UNUSED(mpr), wmManipulatorProperty *mpr_prop,
const void *value_p)
{
- const float *value = value_p;
+ const float (*matrix)[4] = value_p;
struct CameraViewWidgetGroup *viewgroup = mpr_prop->custom_func.user_data;
rctf *border = viewgroup->state.edit_border;
- BLI_assert(mpr_prop->type->array_length == 2);
+ BLI_assert(mpr_prop->type->array_length == 16);
- BLI_rctf_resize(border, value[0], value[1]);
- BLI_rctf_isect(&(rctf){.xmin = 0, .ymin = 0, .xmax = 1, .ymax = 1}, border, border);
-}
-
-/* offset callbacks */
-static void manipulator_render_border_prop_offset_get(
- const wmManipulator *UNUSED(mpr), wmManipulatorProperty *mpr_prop,
- void *value_p)
-{
- float *value = value_p;
- BLI_assert(mpr_prop->type->array_length == 2);
- struct CameraViewWidgetGroup *viewgroup = mpr_prop->custom_func.user_data;
- const rctf *border = viewgroup->state.edit_border;
-
- value[0] = BLI_rctf_cent_x(border);
- value[1] = BLI_rctf_cent_y(border);
-}
-
-static void manipulator_render_border_prop_offset_set(
- const wmManipulator *UNUSED(mpr), wmManipulatorProperty *mpr_prop,
- const void *value_p)
-{
- const float *value = value_p;
- struct CameraViewWidgetGroup *viewgroup = mpr_prop->custom_func.user_data;
- rctf *border = viewgroup->state.edit_border;
-
- BLI_assert(mpr_prop->type->array_length == 2);
-
- BLI_rctf_recenter(border, value[0], value[1]);
+ BLI_rctf_resize(border, len_v3(matrix[0]), len_v3(matrix[1]));
+ BLI_rctf_recenter(border, matrix[3][0], matrix[3][1]);
BLI_rctf_isect(&(rctf){.xmin = 0, .ymin = 0, .xmax = 1, .ymax = 1}, border, border);
}
@@ -382,19 +360,10 @@ static void WIDGETGROUP_camera_view_refresh(const bContext *C, wmManipulatorGrou
}
WM_manipulator_target_property_def_func(
- mpr, "offset",
- &(const struct wmManipulatorPropertyFnParams) {
- .value_get_fn = manipulator_render_border_prop_offset_get,
- .value_set_fn = manipulator_render_border_prop_offset_set,
- .range_get_fn = NULL,
- .user_data = viewgroup,
- });
-
- WM_manipulator_target_property_def_func(
- mpr, "scale",
+ mpr, "matrix",
&(const struct wmManipulatorPropertyFnParams) {
- .value_get_fn = manipulator_render_border_prop_size_get,
- .value_set_fn = manipulator_render_border_prop_size_set,
+ .value_get_fn = manipulator_render_border_prop_matrix_get,
+ .value_set_fn = manipulator_render_border_prop_matrix_set,
.range_get_fn = NULL,
.user_data = viewgroup,
});
diff --git a/source/blender/editors/space_view3d/view3d_manipulator_empty.c b/source/blender/editors/space_view3d/view3d_manipulator_empty.c
index dcf766ee591..4c5f3c259f7 100644
--- a/source/blender/editors/space_view3d/view3d_manipulator_empty.c
+++ b/source/blender/editors/space_view3d/view3d_manipulator_empty.c
@@ -62,63 +62,46 @@ struct EmptyImageWidgetGroup {
};
/* translate callbacks */
-static void manipulator_empty_image_prop_size_get(
- const wmManipulator *UNUSED(mpr), wmManipulatorProperty *mpr_prop,
+static void manipulator_empty_image_prop_matrix_get(
+ const wmManipulator *mpr, wmManipulatorProperty *mpr_prop,
void *value_p)
{
- float *value = value_p;
+ float (*matrix)[4] = value_p;
+ BLI_assert(mpr_prop->type->array_length == 16);
struct EmptyImageWidgetGroup *imgroup = mpr_prop->custom_func.user_data;
const Object *ob = imgroup->state.ob;
- value[0] = ob->empty_drawsize;
- value[1] = ob->empty_drawsize;
-}
-static void manipulator_empty_image_prop_size_set(
- const wmManipulator *UNUSED(mpr), wmManipulatorProperty *mpr_prop,
- const void *value_p)
-{
- const float *value = value_p;
- BLI_assert(mpr_prop->type->array_length == 2);
- struct EmptyImageWidgetGroup *imgroup = mpr_prop->custom_func.user_data;
- Object *ob = imgroup->state.ob;
- ob->empty_drawsize = value[0];
-}
-
-/* translate callbacks */
-static void manipulator_empty_image_prop_offset_get(
- const wmManipulator *mpr, wmManipulatorProperty *mpr_prop,
- void *value_p)
-{
- float *value = value_p;
- BLI_assert(mpr_prop->type->array_length == 2);
- const struct EmptyImageWidgetGroup *imgroup = mpr_prop->custom_func.user_data;
- const Object *ob = imgroup->state.ob;
+ unit_m4(matrix);
+ matrix[0][0] = ob->empty_drawsize;
+ matrix[1][1] = ob->empty_drawsize;
float dims[2] = {0.0f, 0.0f};
RNA_float_get_array(mpr->ptr, "dimensions", dims);
dims[0] *= ob->empty_drawsize;
dims[1] *= ob->empty_drawsize;
- value[0] = (ob->ima_ofs[0] * dims[0]) + (0.5f * dims[0]);
- value[1] = (ob->ima_ofs[1] * dims[1]) + (0.5f * dims[1]);
+ matrix[3][0] = (ob->ima_ofs[0] * dims[0]) + (0.5f * dims[0]);
+ matrix[3][1] = (ob->ima_ofs[1] * dims[1]) + (0.5f * dims[1]);
}
-static void manipulator_empty_image_prop_offset_set(
+static void manipulator_empty_image_prop_matrix_set(
const wmManipulator *mpr, wmManipulatorProperty *mpr_prop,
const void *value_p)
{
- const float *value = value_p;
- BLI_assert(mpr_prop->type->array_length == 2);
+ const float (*matrix)[4] = value_p;
+ BLI_assert(mpr_prop->type->array_length == 16);
struct EmptyImageWidgetGroup *imgroup = mpr_prop->custom_func.user_data;
Object *ob = imgroup->state.ob;
+ ob->empty_drawsize = matrix[0][0];
+
float dims[2];
RNA_float_get_array(mpr->ptr, "dimensions", dims);
dims[0] *= ob->empty_drawsize;
dims[1] *= ob->empty_drawsize;
- ob->ima_ofs[0] = (value[0] - (0.5f * dims[0])) / dims[0];
- ob->ima_ofs[1] = (value[1] - (0.5f * dims[1])) / dims[1];
+ ob->ima_ofs[0] = (matrix[3][0] - (0.5f * dims[0])) / dims[0];
+ ob->ima_ofs[1] = (matrix[3][1] - (0.5f * dims[1])) / dims[1];
}
static bool WIDGETGROUP_empty_image_poll(const bContext *C, wmManipulatorGroupType *UNUSED(wgt))
@@ -177,18 +160,10 @@ static void WIDGETGROUP_empty_image_refresh(const bContext *C, wmManipulatorGrou
RNA_float_set_array(mpr->ptr, "dimensions", imgroup->state.dims);
WM_manipulator_target_property_def_func(
- mpr, "scale",
- &(const struct wmManipulatorPropertyFnParams) {
- .value_get_fn = manipulator_empty_image_prop_size_get,
- .value_set_fn = manipulator_empty_image_prop_size_set,
- .range_get_fn = NULL,
- .user_data = imgroup,
- });
- WM_manipulator_target_property_def_func(
- mpr, "offset",
+ mpr, "matrix",
&(const struct wmManipulatorPropertyFnParams) {
- .value_get_fn = manipulator_empty_image_prop_offset_get,
- .value_set_fn = manipulator_empty_image_prop_offset_set,
+ .value_get_fn = manipulator_empty_image_prop_matrix_get,
+ .value_set_fn = manipulator_empty_image_prop_matrix_set,
.range_get_fn = NULL,
.user_data = imgroup,
});
diff --git a/source/blender/editors/space_view3d/view3d_manipulator_lamp.c b/source/blender/editors/space_view3d/view3d_manipulator_lamp.c
index 14894e1bc21..93b6b69a105 100644
--- a/source/blender/editors/space_view3d/view3d_manipulator_lamp.c
+++ b/source/blender/editors/space_view3d/view3d_manipulator_lamp.c
@@ -119,45 +119,36 @@ void VIEW3D_WGT_lamp_spot(wmManipulatorGroupType *wgt)
/** \name Area Lamp Manipulators
* \{ */
-/* translate callbacks */
-static void manipulator_area_lamp_prop_size_get(
+/* scale callbacks */
+static void manipulator_area_lamp_prop_matrix_get(
const wmManipulator *UNUSED(mpr), wmManipulatorProperty *mpr_prop,
void *value_p)
{
- float *value = value_p;
- BLI_assert(mpr_prop->type->array_length == 2);
- Lamp *la = mpr_prop->custom_func.user_data;
+ BLI_assert(mpr_prop->type->array_length == 16);
+ float (*matrix)[4] = value_p;
+ const Lamp *la = mpr_prop->custom_func.user_data;
- value[0] = la->area_size;
- value[1] = (la->area_shape == LA_AREA_RECT) ? la->area_sizey : la->area_size;
+ matrix[0][0] = la->area_size;
+ matrix[1][1] = (la->area_shape == LA_AREA_RECT) ? la->area_sizey : la->area_size;
}
-static void manipulator_area_lamp_prop_size_set(
+static void manipulator_area_lamp_prop_matrix_set(
const wmManipulator *UNUSED(mpr), wmManipulatorProperty *mpr_prop,
const void *value_p)
{
- const float *value = value_p;
-
- BLI_assert(mpr_prop->type->array_length == 2);
+ const float (*matrix)[4] = value_p;
+ BLI_assert(mpr_prop->type->array_length == 16);
Lamp *la = mpr_prop->custom_func.user_data;
+
if (la->area_shape == LA_AREA_RECT) {
- la->area_size = value[0];
- la->area_sizey = value[1];
+ la->area_size = len_v3(matrix[0]);
+ la->area_sizey = len_v3(matrix[1]);
}
else {
- la->area_size = value[0];
+ la->area_size = len_v3(matrix[0]);
}
}
-static void manipulator_area_lamp_prop_size_range(
- const wmManipulator *UNUSED(mpr), wmManipulatorProperty *UNUSED(mpr_prop),
- void *value_p)
-{
- float *value = value_p;
- value[0] = 0.0f;
- value[1] = FLT_MAX;
-}
-
static bool WIDGETGROUP_lamp_area_poll(const bContext *C, wmManipulatorGroupType *UNUSED(wgt))
{
Object *ob = CTX_data_active_object(C);
@@ -200,11 +191,11 @@ static void WIDGETGROUP_lamp_area_refresh(const bContext *C, wmManipulatorGroup
/* need to set property here for undo. TODO would prefer to do this in _init */
WM_manipulator_target_property_def_func(
- mpr, "scale",
+ mpr, "matrix",
&(const struct wmManipulatorPropertyFnParams) {
- .value_get_fn = manipulator_area_lamp_prop_size_get,
- .value_set_fn = manipulator_area_lamp_prop_size_set,
- .range_get_fn = manipulator_area_lamp_prop_size_range,
+ .value_get_fn = manipulator_area_lamp_prop_matrix_get,
+ .value_set_fn = manipulator_area_lamp_prop_matrix_set,
+ .range_get_fn = NULL,
.user_data = la,
});
}
diff --git a/source/blender/editors/transform/transform_manipulator2d.c b/source/blender/editors/transform/transform_manipulator2d.c
index 9846dfbeee8..94f425eb9f0 100644
--- a/source/blender/editors/transform/transform_manipulator2d.c
+++ b/source/blender/editors/transform/transform_manipulator2d.c
@@ -136,7 +136,7 @@ static void manipulator2d_get_axis_color(const int axis_idx, float *r_col, float
static ManipulatorGroup2D *manipulatorgroup2d_init(wmManipulatorGroup *mgroup)
{
const wmManipulatorType *wt_arrow = WM_manipulatortype_find("MANIPULATOR_WT_arrow_2d", true);
- const wmManipulatorType *wt_cage = WM_manipulatortype_find("MANIPULATOR_WT_cage_2d_rotate", true);
+ const wmManipulatorType *wt_cage = WM_manipulatortype_find("MANIPULATOR_WT_cage_2d", true);
ManipulatorGroup2D *man = MEM_callocN(sizeof(ManipulatorGroup2D), __func__);
@@ -144,9 +144,6 @@ static ManipulatorGroup2D *manipulatorgroup2d_init(wmManipulatorGroup *mgroup)
man->translate_y = WM_manipulator_new_ptr(wt_arrow, mgroup, NULL);
man->cage = WM_manipulator_new_ptr(wt_cage, mgroup, NULL);
- /* Workaround for missing refresh while interacting with the bound-box. */
- man->cage->flag &= ~WM_MANIPULATOR_DRAW_MODAL;
-
RNA_enum_set(man->cage->ptr, "transform",
ED_MANIPULATOR_CAGE2D_XFORM_FLAG_TRANSLATE |
ED_MANIPULATOR_CAGE2D_XFORM_FLAG_SCALE |
@@ -346,8 +343,8 @@ void ED_widgetgroup_manipulator2d_draw_prepare(const bContext *C, wmManipulatorG
UI_view2d_view_to_region_m4(&ar->v2d, man->cage->matrix_space);
WM_manipulator_set_matrix_offset_location(man->cage, origin_aa);
- man->cage->matrix_offset[0][0] = (man->max[0] - man->min[0]) / 2.0f;
- man->cage->matrix_offset[1][1] = (man->max[1] - man->min[1]) / 2.0f;
+ man->cage->matrix_offset[0][0] = (man->max[0] - man->min[0]);
+ man->cage->matrix_offset[1][1] = (man->max[1] - man->min[1]);
}
/* TODO (Julian)
diff --git a/source/blender/makesrna/intern/rna_wm_manipulator.c b/source/blender/makesrna/intern/rna_wm_manipulator.c
index 4f94b996046..8b1e681f227 100644
--- a/source/blender/makesrna/intern/rna_wm_manipulator.c
+++ b/source/blender/makesrna/intern/rna_wm_manipulator.c
@@ -359,6 +359,19 @@ static void rna_Manipulator_##func_id##_set(PointerRNA *ptr, int value) \
BKE_BIT_TEST_SET(mpr->member_id, value, flag_value); \
}
+/* wmManipulator.flag (negative) */
+#define RNA_MANIPULATOR_GENERIC_FLAG_NEG_RW_DEF(func_id, member_id, flag_value) \
+static int rna_Manipulator_##func_id##_get(PointerRNA *ptr) \
+{ \
+ wmManipulator *mpr = ptr->data; \
+ return (mpr->member_id & flag_value) == 0; \
+} \
+static void rna_Manipulator_##func_id##_set(PointerRNA *ptr, int value) \
+{ \
+ wmManipulator *mpr = ptr->data; \
+ BKE_BIT_TEST_SET(mpr->member_id, !value, flag_value); \
+}
+
#define RNA_MANIPULATOR_FLAG_RO_DEF(func_id, member_id, flag_value) \
static int rna_Manipulator_##func_id##_get(PointerRNA *ptr) \
{ \
@@ -389,6 +402,7 @@ RNA_MANIPULATOR_GENERIC_FLAG_RW_DEF(flag_use_draw_hover, flag, WM_MANIPULATOR_DR
RNA_MANIPULATOR_GENERIC_FLAG_RW_DEF(flag_use_draw_modal, flag, WM_MANIPULATOR_DRAW_MODAL);
RNA_MANIPULATOR_GENERIC_FLAG_RW_DEF(flag_use_draw_value, flag, WM_MANIPULATOR_DRAW_VALUE);
RNA_MANIPULATOR_GENERIC_FLAG_RW_DEF(flag_use_draw_offset_scale, flag, WM_MANIPULATOR_DRAW_OFFSET_SCALE);
+RNA_MANIPULATOR_GENERIC_FLAG_NEG_RW_DEF(flag_use_draw_scale, flag, WM_MANIPULATOR_DRAW_OFFSET_SCALE);
RNA_MANIPULATOR_GENERIC_FLAG_RW_DEF(flag_hide, flag, WM_MANIPULATOR_HIDDEN);
/* wmManipulator.state */
@@ -1098,7 +1112,13 @@ static void rna_def_manipulator(BlenderRNA *brna, PropertyRNA *cprop)
prop = RNA_def_property(srna, "use_draw_offset_scale", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_funcs(
prop, "rna_Manipulator_flag_use_draw_offset_scale_get", "rna_Manipulator_flag_use_draw_offset_scale_set");
- RNA_def_property_ui_text(prop, "Draw Value", "Scale the offset matrix (use to apply screen-space offset)");
+ RNA_def_property_ui_text(prop, "Scale Offset", "Scale the offset matrix (use to apply screen-space offset)");
+ RNA_def_property_update(prop, NC_SCREEN | NA_EDITED, NULL);
+ /* WM_MANIPULATOR_DRAW_NO_SCALE (negated) */
+ prop = RNA_def_property(srna, "use_draw_scale", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_funcs(
+ prop, "rna_Manipulator_flag_use_draw_scale_get", "rna_Manipulator_flag_use_draw_scale_set");
+ RNA_def_property_ui_text(prop, "Scale", "Use scale when calculating the matrix");
RNA_def_property_update(prop, NC_SCREEN | NA_EDITED, NULL);
/* wmManipulator.state (readonly) */
diff --git a/source/blender/windowmanager/manipulators/WM_manipulator_types.h b/source/blender/windowmanager/manipulators/WM_manipulator_types.h
index 0894a21e925..22f1eb68181 100644
--- a/source/blender/windowmanager/manipulators/WM_manipulator_types.h
+++ b/source/blender/windowmanager/manipulators/WM_manipulator_types.h
@@ -75,6 +75,11 @@ typedef enum eWM_ManipulatorFlag {
* When set 'scale_final' value also scales the offset.
* Use when offset is to avoid screen-space overlap instead of absolute positioning. */
WM_MANIPULATOR_DRAW_OFFSET_SCALE = (1 << 4),
+ /**
+ * User should still use 'scale_final' for any handles and UI elements.
+ * This simply skips scale when calculating the final matrix.
+ * Needed when the manipulator needs to align with the interface underneath it. */
+ WM_MANIPULATOR_DRAW_NO_SCALE = (1 << 5),
} eWM_ManipulatorFlag;
/**
diff --git a/source/blender/windowmanager/manipulators/intern/wm_manipulator.c b/source/blender/windowmanager/manipulators/intern/wm_manipulator.c
index 5693c4854c9..3df4124ba65 100644
--- a/source/blender/windowmanager/manipulators/intern/wm_manipulator.c
+++ b/source/blender/windowmanager/manipulators/intern/wm_manipulator.c
@@ -548,13 +548,18 @@ void WM_manipulator_calc_matrix_final_params(
copy_m4_m4(final_matrix, matrix_basis);
}
- if (mpr->flag & WM_MANIPULATOR_DRAW_OFFSET_SCALE) {
- mul_mat3_m4_fl(final_matrix, *scale_final);
+ if (mpr->flag & WM_MANIPULATOR_DRAW_NO_SCALE) {
mul_m4_m4m4(final_matrix, final_matrix, matrix_offset);
}
else {
- mul_m4_m4m4(final_matrix, final_matrix, matrix_offset);
- mul_mat3_m4_fl(final_matrix, *scale_final);
+ if (mpr->flag & WM_MANIPULATOR_DRAW_OFFSET_SCALE) {
+ mul_mat3_m4_fl(final_matrix, *scale_final);
+ mul_m4_m4m4(final_matrix, final_matrix, matrix_offset);
+ }
+ else {
+ mul_m4_m4m4(final_matrix, final_matrix, matrix_offset);
+ mul_mat3_m4_fl(final_matrix, *scale_final);
+ }
}
mul_m4_m4m4(r_mat, matrix_space, final_matrix);