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/editors/manipulator_library
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/editors/manipulator_library')
-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
3 files changed, 297 insertions, 928 deletions
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);
-}
-
-/** \} */