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:
-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);