|
|
|
@ -70,9 +70,13 @@
|
|
|
|
|
|
|
|
|
|
#include "GPU_state.h"
|
|
|
|
|
|
|
|
|
|
static void gizmo_refresh_from_matrix(wmGizmoGroup *gzgroup,
|
|
|
|
|
const float twmat[4][4],
|
|
|
|
|
const float scale[3]);
|
|
|
|
|
static wmGizmoGroupType *g_GGT_xform_gizmo = NULL;
|
|
|
|
|
static wmGizmoGroupType *g_GGT_xform_gizmo_context = NULL;
|
|
|
|
|
|
|
|
|
|
static void gizmogroup_refresh_from_matrix(wmGizmoGroup *gzgroup,
|
|
|
|
|
const float twmat[4][4],
|
|
|
|
|
const float scale[3],
|
|
|
|
|
const bool ignore_hidden);
|
|
|
|
|
|
|
|
|
|
/* return codes for select, and drawing flags */
|
|
|
|
|
|
|
|
|
@ -1135,30 +1139,36 @@ static void gizmo_prepare_mat(const bContext *C,
|
|
|
|
|
* Sets up \a r_start and \a r_len to define arrow line range.
|
|
|
|
|
* Needed to adjust line drawing for combined gizmo axis types.
|
|
|
|
|
*/
|
|
|
|
|
static void gizmo_line_range(const int twtype, const short axis_type, float *r_start, float *r_len)
|
|
|
|
|
static void gizmo_line_range(const int twtype, const short axis_type, float *r_start, float *r_end)
|
|
|
|
|
{
|
|
|
|
|
const float ofs = 0.2f;
|
|
|
|
|
|
|
|
|
|
*r_start = 0.2f;
|
|
|
|
|
*r_len = 1.0f;
|
|
|
|
|
float start = 0.2f;
|
|
|
|
|
float end = 1.0f;
|
|
|
|
|
|
|
|
|
|
switch (axis_type) {
|
|
|
|
|
case MAN_AXES_TRANSLATE:
|
|
|
|
|
if (twtype & V3D_GIZMO_SHOW_OBJECT_SCALE) {
|
|
|
|
|
*r_start = *r_len - ofs + 0.075f;
|
|
|
|
|
start = end - 0.125f;
|
|
|
|
|
}
|
|
|
|
|
if (twtype & V3D_GIZMO_SHOW_OBJECT_ROTATE) {
|
|
|
|
|
*r_len += ofs;
|
|
|
|
|
/* Avoid rotate and translate gizmos overlap. */
|
|
|
|
|
const float rotate_offset = 0.215f;
|
|
|
|
|
start += rotate_offset;
|
|
|
|
|
end += rotate_offset + 0.2f;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case MAN_AXES_SCALE:
|
|
|
|
|
if (twtype & (V3D_GIZMO_SHOW_OBJECT_TRANSLATE | V3D_GIZMO_SHOW_OBJECT_ROTATE)) {
|
|
|
|
|
*r_len -= ofs + 0.025f;
|
|
|
|
|
end -= 0.225f;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*r_len -= *r_start;
|
|
|
|
|
if (r_start) {
|
|
|
|
|
*r_start = start;
|
|
|
|
|
}
|
|
|
|
|
if (r_end) {
|
|
|
|
|
*r_end = end;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void gizmo_xform_message_subscribe(wmGizmoGroup *gzgroup,
|
|
|
|
@ -1280,9 +1290,9 @@ static void gizmo_xform_message_subscribe(wmGizmoGroup *gzgroup,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void gizmo_3d_dial_matrixbasis_calc(const ARegion *region,
|
|
|
|
|
float axis[3],
|
|
|
|
|
float center_global[3],
|
|
|
|
|
float mval_init[2],
|
|
|
|
|
const float axis[3],
|
|
|
|
|
const float center_global[3],
|
|
|
|
|
const float mval_init[2],
|
|
|
|
|
float r_mat_basis[4][4])
|
|
|
|
|
{
|
|
|
|
|
copy_v3_v3(r_mat_basis[2], axis);
|
|
|
|
@ -1329,6 +1339,169 @@ static void rotation_set_fn(const wmGizmo *UNUSED(gz), wmGizmoProperty *gz_prop,
|
|
|
|
|
ggd->rotation = *(const float *)value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void gizmo_3d_setup_draw_default(wmGizmo *axis, const int axis_idx)
|
|
|
|
|
{
|
|
|
|
|
switch (axis_idx) {
|
|
|
|
|
/* Arrow. */
|
|
|
|
|
case MAN_AXIS_TRANS_X:
|
|
|
|
|
case MAN_AXIS_TRANS_Y:
|
|
|
|
|
case MAN_AXIS_TRANS_Z:
|
|
|
|
|
RNA_enum_set(axis->ptr, "draw_style", ED_GIZMO_ARROW_STYLE_NORMAL);
|
|
|
|
|
break;
|
|
|
|
|
case MAN_AXIS_SCALE_X:
|
|
|
|
|
case MAN_AXIS_SCALE_Y:
|
|
|
|
|
case MAN_AXIS_SCALE_Z:
|
|
|
|
|
RNA_enum_set(axis->ptr, "draw_style", ED_GIZMO_ARROW_STYLE_BOX);
|
|
|
|
|
RNA_enum_set(axis->ptr, "draw_options", ED_GIZMO_ARROW_DRAW_FLAG_STEM);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
/* Primitive. */
|
|
|
|
|
case MAN_AXIS_TRANS_XY:
|
|
|
|
|
case MAN_AXIS_TRANS_YZ:
|
|
|
|
|
case MAN_AXIS_TRANS_ZX:
|
|
|
|
|
case MAN_AXIS_SCALE_XY:
|
|
|
|
|
case MAN_AXIS_SCALE_YZ:
|
|
|
|
|
case MAN_AXIS_SCALE_ZX: {
|
|
|
|
|
RNA_enum_set(axis->ptr, "draw_style", ED_GIZMO_PRIMITIVE_STYLE_PLANE);
|
|
|
|
|
|
|
|
|
|
const float ofs[3] = {MAN_AXIS_SCALE_PLANE_OFFSET, MAN_AXIS_SCALE_PLANE_OFFSET, 0.0f};
|
|
|
|
|
WM_gizmo_set_scale(axis, MAN_AXIS_SCALE_PLANE_SCALE);
|
|
|
|
|
WM_gizmo_set_matrix_offset_location(axis, ofs);
|
|
|
|
|
WM_gizmo_set_flag(axis, WM_GIZMO_DRAW_OFFSET_SCALE, true);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Dial. */
|
|
|
|
|
case MAN_AXIS_TRANS_C:
|
|
|
|
|
RNA_enum_set(axis->ptr, "draw_options", ED_GIZMO_DIAL_DRAW_FLAG_FILL_SELECT);
|
|
|
|
|
WM_gizmo_set_flag(axis, WM_GIZMO_DRAW_MODAL, true);
|
|
|
|
|
WM_gizmo_set_scale(axis, 0.2f);
|
|
|
|
|
|
|
|
|
|
/* Prevent axis gizmos overlapping the center point, see: T63744. */
|
|
|
|
|
axis->select_bias = 2.0f;
|
|
|
|
|
break;
|
|
|
|
|
case MAN_AXIS_SCALE_C:
|
|
|
|
|
RNA_enum_set(axis->ptr, "draw_options", ED_GIZMO_DIAL_DRAW_FLAG_FILL_SELECT);
|
|
|
|
|
|
|
|
|
|
/* Use 1/6 since this is '0.2' if the main scale is 1.2. */
|
|
|
|
|
RNA_float_set(axis->ptr, "arc_inner_factor", 1.0 / 6.0);
|
|
|
|
|
WM_gizmo_set_scale(axis, 1.2f);
|
|
|
|
|
|
|
|
|
|
/* Prevent axis gizmos overlapping the center point, see: T63744. */
|
|
|
|
|
axis->select_bias = -2.0f;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case MAN_AXIS_ROT_X:
|
|
|
|
|
case MAN_AXIS_ROT_Y:
|
|
|
|
|
case MAN_AXIS_ROT_Z:
|
|
|
|
|
RNA_enum_set(axis->ptr, "draw_options", ED_GIZMO_DIAL_DRAW_FLAG_CLIP);
|
|
|
|
|
WM_gizmo_set_flag(axis, WM_GIZMO_DRAW_VALUE, true);
|
|
|
|
|
break;
|
|
|
|
|
case MAN_AXIS_ROT_C:
|
|
|
|
|
RNA_enum_set(axis->ptr, "draw_options", ED_GIZMO_DIAL_DRAW_FLAG_NOP);
|
|
|
|
|
WM_gizmo_set_flag(axis, WM_GIZMO_DRAW_VALUE, true);
|
|
|
|
|
WM_gizmo_set_scale(axis, 1.2f);
|
|
|
|
|
break;
|
|
|
|
|
case MAN_AXIS_ROT_T:
|
|
|
|
|
RNA_enum_set(axis->ptr, "draw_options", ED_GIZMO_DIAL_DRAW_FLAG_FILL);
|
|
|
|
|
WM_gizmo_set_flag(axis, WM_GIZMO_SELECT_BACKGROUND, true);
|
|
|
|
|
WM_gizmo_set_flag(axis, WM_GIZMO_DRAW_HOVER, true);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch (axis_idx) {
|
|
|
|
|
case MAN_AXIS_ROT_X:
|
|
|
|
|
case MAN_AXIS_ROT_Y:
|
|
|
|
|
case MAN_AXIS_ROT_Z:
|
|
|
|
|
/* Increased line width for better display. */
|
|
|
|
|
WM_gizmo_set_line_width(axis, GIZMO_AXIS_LINE_WIDTH + 1.0f);
|
|
|
|
|
break;
|
|
|
|
|
case MAN_AXIS_TRANS_XY:
|
|
|
|
|
case MAN_AXIS_TRANS_YZ:
|
|
|
|
|
case MAN_AXIS_TRANS_ZX:
|
|
|
|
|
case MAN_AXIS_SCALE_XY:
|
|
|
|
|
case MAN_AXIS_SCALE_YZ:
|
|
|
|
|
case MAN_AXIS_SCALE_ZX:
|
|
|
|
|
WM_gizmo_set_line_width(axis, 1.0f);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
WM_gizmo_set_line_width(axis, GIZMO_AXIS_LINE_WIDTH);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const short axis_type = gizmo_get_axis_type(axis_idx);
|
|
|
|
|
switch (axis_type) {
|
|
|
|
|
case MAN_AXES_ROTATE: {
|
|
|
|
|
RNA_float_set(axis->ptr, "incremental_angle", 0.0f);
|
|
|
|
|
axis->select_bias = 0.0f;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void gizmo_3d_setup_draw_from_twtype(wmGizmo *axis, const int axis_idx, const int twtype)
|
|
|
|
|
{
|
|
|
|
|
switch (axis_idx) {
|
|
|
|
|
case MAN_AXIS_TRANS_X:
|
|
|
|
|
case MAN_AXIS_TRANS_Y:
|
|
|
|
|
case MAN_AXIS_TRANS_Z:
|
|
|
|
|
RNA_enum_set(axis->ptr,
|
|
|
|
|
"draw_options",
|
|
|
|
|
(twtype & (V3D_GIZMO_SHOW_OBJECT_ROTATE | V3D_GIZMO_SHOW_OBJECT_SCALE)) ?
|
|
|
|
|
0 :
|
|
|
|
|
ED_GIZMO_ARROW_DRAW_FLAG_STEM);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const short axis_type = gizmo_get_axis_type(axis_idx);
|
|
|
|
|
switch (axis_idx) {
|
|
|
|
|
case MAN_AXIS_TRANS_X:
|
|
|
|
|
case MAN_AXIS_TRANS_Y:
|
|
|
|
|
case MAN_AXIS_TRANS_Z:
|
|
|
|
|
case MAN_AXIS_SCALE_X:
|
|
|
|
|
case MAN_AXIS_SCALE_Y:
|
|
|
|
|
case MAN_AXIS_SCALE_Z: {
|
|
|
|
|
float start_co[3] = {0.0f, 0.0f, 0.0f};
|
|
|
|
|
float end;
|
|
|
|
|
gizmo_line_range(twtype, axis_type, &start_co[2], &end);
|
|
|
|
|
|
|
|
|
|
WM_gizmo_set_matrix_offset_location(axis, start_co);
|
|
|
|
|
RNA_float_set(axis->ptr, "length", end - start_co[2]);
|
|
|
|
|
WM_gizmo_set_flag(axis, WM_GIZMO_DRAW_OFFSET_SCALE, true);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch (axis_type) {
|
|
|
|
|
case MAN_AXES_ROTATE: {
|
|
|
|
|
if ((twtype & V3D_GIZMO_SHOW_OBJECT_SCALE) && twtype & V3D_GIZMO_SHOW_OBJECT_ROTATE) {
|
|
|
|
|
axis->select_bias = -2.0f;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void gizmo_3d_setup_draw_modal(wmGizmo *axis, const int axis_idx)
|
|
|
|
|
{
|
|
|
|
|
const short axis_type = gizmo_get_axis_type(axis_idx);
|
|
|
|
|
switch (axis_type) {
|
|
|
|
|
case MAN_AXES_ROTATE: {
|
|
|
|
|
PropertyRNA *prop = RNA_struct_find_property(axis->ptr, "draw_options");
|
|
|
|
|
const int dial_flag = RNA_property_enum_get(axis->ptr, prop);
|
|
|
|
|
RNA_property_enum_set(axis->ptr, prop, dial_flag | ED_GIZMO_DIAL_DRAW_FLAG_ANGLE_VALUE);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static GizmoGroup *gizmogroup_init(wmGizmoGroup *gzgroup)
|
|
|
|
|
{
|
|
|
|
|
GizmoGroup *ggd;
|
|
|
|
@ -1342,65 +1515,57 @@ static GizmoGroup *gizmogroup_init(wmGizmoGroup *gzgroup)
|
|
|
|
|
wmGizmoPropertyFnParams params = {
|
|
|
|
|
.value_get_fn = rotation_get_fn, .value_set_fn = rotation_set_fn, .user_data = ggd};
|
|
|
|
|
|
|
|
|
|
#define GIZMO_NEW_ARROW(v, draw_style) \
|
|
|
|
|
#define GIZMO_NEW_ARROW(v) \
|
|
|
|
|
{ \
|
|
|
|
|
ggd->gizmos[v] = WM_gizmo_new_ptr(gzt_arrow, gzgroup, NULL); \
|
|
|
|
|
RNA_enum_set(ggd->gizmos[v]->ptr, "draw_style", draw_style); \
|
|
|
|
|
} \
|
|
|
|
|
((void)0)
|
|
|
|
|
#define GIZMO_NEW_DIAL(v, draw_options) \
|
|
|
|
|
#define GIZMO_NEW_DIAL(v) \
|
|
|
|
|
{ \
|
|
|
|
|
ggd->gizmos[v] = WM_gizmo_new_ptr(gzt_dial, gzgroup, NULL); \
|
|
|
|
|
RNA_enum_set(ggd->gizmos[v]->ptr, "draw_options", draw_options); \
|
|
|
|
|
WM_gizmo_target_property_def_func(ggd->gizmos[v], "offset", ¶ms); \
|
|
|
|
|
} \
|
|
|
|
|
((void)0)
|
|
|
|
|
#define GIZMO_NEW_PRIM(v, draw_style) \
|
|
|
|
|
#define GIZMO_NEW_PRIM(v) \
|
|
|
|
|
{ \
|
|
|
|
|
ggd->gizmos[v] = WM_gizmo_new_ptr(gzt_prim, gzgroup, NULL); \
|
|
|
|
|
RNA_enum_set(ggd->gizmos[v]->ptr, "draw_style", draw_style); \
|
|
|
|
|
} \
|
|
|
|
|
((void)0)
|
|
|
|
|
|
|
|
|
|
/* add/init widgets - order matters! */
|
|
|
|
|
GIZMO_NEW_DIAL(MAN_AXIS_ROT_T, ED_GIZMO_DIAL_DRAW_FLAG_FILL);
|
|
|
|
|
GIZMO_NEW_DIAL(MAN_AXIS_ROT_T);
|
|
|
|
|
|
|
|
|
|
GIZMO_NEW_DIAL(MAN_AXIS_SCALE_C, ED_GIZMO_DIAL_DRAW_FLAG_FILL_SELECT);
|
|
|
|
|
GIZMO_NEW_DIAL(MAN_AXIS_SCALE_C);
|
|
|
|
|
|
|
|
|
|
GIZMO_NEW_ARROW(MAN_AXIS_SCALE_X, ED_GIZMO_ARROW_STYLE_BOX);
|
|
|
|
|
GIZMO_NEW_ARROW(MAN_AXIS_SCALE_Y, ED_GIZMO_ARROW_STYLE_BOX);
|
|
|
|
|
GIZMO_NEW_ARROW(MAN_AXIS_SCALE_Z, ED_GIZMO_ARROW_STYLE_BOX);
|
|
|
|
|
GIZMO_NEW_ARROW(MAN_AXIS_SCALE_X);
|
|
|
|
|
GIZMO_NEW_ARROW(MAN_AXIS_SCALE_Y);
|
|
|
|
|
GIZMO_NEW_ARROW(MAN_AXIS_SCALE_Z);
|
|
|
|
|
|
|
|
|
|
GIZMO_NEW_PRIM(MAN_AXIS_SCALE_XY, ED_GIZMO_PRIMITIVE_STYLE_PLANE);
|
|
|
|
|
GIZMO_NEW_PRIM(MAN_AXIS_SCALE_YZ, ED_GIZMO_PRIMITIVE_STYLE_PLANE);
|
|
|
|
|
GIZMO_NEW_PRIM(MAN_AXIS_SCALE_ZX, ED_GIZMO_PRIMITIVE_STYLE_PLANE);
|
|
|
|
|
GIZMO_NEW_PRIM(MAN_AXIS_SCALE_XY);
|
|
|
|
|
GIZMO_NEW_PRIM(MAN_AXIS_SCALE_YZ);
|
|
|
|
|
GIZMO_NEW_PRIM(MAN_AXIS_SCALE_ZX);
|
|
|
|
|
|
|
|
|
|
GIZMO_NEW_DIAL(MAN_AXIS_ROT_X, ED_GIZMO_DIAL_DRAW_FLAG_CLIP);
|
|
|
|
|
GIZMO_NEW_DIAL(MAN_AXIS_ROT_Y, ED_GIZMO_DIAL_DRAW_FLAG_CLIP);
|
|
|
|
|
GIZMO_NEW_DIAL(MAN_AXIS_ROT_Z, ED_GIZMO_DIAL_DRAW_FLAG_CLIP);
|
|
|
|
|
GIZMO_NEW_DIAL(MAN_AXIS_ROT_X);
|
|
|
|
|
GIZMO_NEW_DIAL(MAN_AXIS_ROT_Y);
|
|
|
|
|
GIZMO_NEW_DIAL(MAN_AXIS_ROT_Z);
|
|
|
|
|
|
|
|
|
|
/* init screen aligned widget last here, looks better, behaves better */
|
|
|
|
|
GIZMO_NEW_DIAL(MAN_AXIS_ROT_C, ED_GIZMO_DIAL_DRAW_FLAG_NOP);
|
|
|
|
|
GIZMO_NEW_DIAL(MAN_AXIS_ROT_C);
|
|
|
|
|
|
|
|
|
|
GIZMO_NEW_DIAL(MAN_AXIS_TRANS_C, ED_GIZMO_DIAL_DRAW_FLAG_FILL_SELECT);
|
|
|
|
|
GIZMO_NEW_DIAL(MAN_AXIS_TRANS_C);
|
|
|
|
|
|
|
|
|
|
GIZMO_NEW_ARROW(MAN_AXIS_TRANS_X, ED_GIZMO_ARROW_STYLE_NORMAL);
|
|
|
|
|
GIZMO_NEW_ARROW(MAN_AXIS_TRANS_Y, ED_GIZMO_ARROW_STYLE_NORMAL);
|
|
|
|
|
GIZMO_NEW_ARROW(MAN_AXIS_TRANS_Z, ED_GIZMO_ARROW_STYLE_NORMAL);
|
|
|
|
|
GIZMO_NEW_ARROW(MAN_AXIS_TRANS_X);
|
|
|
|
|
GIZMO_NEW_ARROW(MAN_AXIS_TRANS_Y);
|
|
|
|
|
GIZMO_NEW_ARROW(MAN_AXIS_TRANS_Z);
|
|
|
|
|
|
|
|
|
|
GIZMO_NEW_PRIM(MAN_AXIS_TRANS_XY, ED_GIZMO_PRIMITIVE_STYLE_PLANE);
|
|
|
|
|
GIZMO_NEW_PRIM(MAN_AXIS_TRANS_YZ, ED_GIZMO_PRIMITIVE_STYLE_PLANE);
|
|
|
|
|
GIZMO_NEW_PRIM(MAN_AXIS_TRANS_ZX, ED_GIZMO_PRIMITIVE_STYLE_PLANE);
|
|
|
|
|
GIZMO_NEW_PRIM(MAN_AXIS_TRANS_XY);
|
|
|
|
|
GIZMO_NEW_PRIM(MAN_AXIS_TRANS_YZ);
|
|
|
|
|
GIZMO_NEW_PRIM(MAN_AXIS_TRANS_ZX);
|
|
|
|
|
|
|
|
|
|
ggd->gizmos[MAN_AXIS_ROT_T]->flag |= WM_GIZMO_SELECT_BACKGROUND;
|
|
|
|
|
|
|
|
|
|
/* Prevent axis gizmos overlapping the center point, see: T63744. */
|
|
|
|
|
ggd->gizmos[MAN_AXIS_TRANS_C]->select_bias = 2.0f;
|
|
|
|
|
|
|
|
|
|
ggd->gizmos[MAN_AXIS_SCALE_C]->select_bias = -2.0f;
|
|
|
|
|
|
|
|
|
|
/* Use 1/6 since this is '0.2' if the main scale is 1.2. */
|
|
|
|
|
RNA_float_set(ggd->gizmos[MAN_AXIS_SCALE_C]->ptr, "arc_inner_factor", 1.0 / 6.0);
|
|
|
|
|
MAN_ITER_AXES_BEGIN (axis, axis_idx) {
|
|
|
|
|
gizmo_3d_setup_draw_default(axis, axis_idx);
|
|
|
|
|
}
|
|
|
|
|
MAN_ITER_AXES_END;
|
|
|
|
|
|
|
|
|
|
return ggd;
|
|
|
|
|
}
|
|
|
|
@ -1445,39 +1610,6 @@ static int gizmo_modal(bContext *C,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
GizmoGroup *ggd = gzgroup->customdata;
|
|
|
|
|
|
|
|
|
|
short axis_type = 0;
|
|
|
|
|
MAN_ITER_AXES_BEGIN (axis, axis_idx) {
|
|
|
|
|
if (axis == widget) {
|
|
|
|
|
axis_type = gizmo_get_axis_type(axis_idx);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
MAN_ITER_AXES_END;
|
|
|
|
|
|
|
|
|
|
/* Showing axes which aren't being manipulated doesn't always work so well.
|
|
|
|
|
*
|
|
|
|
|
* For rotate: global axis will reset after finish.
|
|
|
|
|
* Also, gimbal axis isn't properly recalculated while transforming.
|
|
|
|
|
*/
|
|
|
|
|
if (axis_type == MAN_AXES_ROTATE) {
|
|
|
|
|
MAN_ITER_AXES_BEGIN (axis, axis_idx) {
|
|
|
|
|
if (axis == widget) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool is_plane_dummy;
|
|
|
|
|
const uint aidx_norm = gizmo_orientation_axis(axis_idx, &is_plane_dummy);
|
|
|
|
|
/* Always show the axis-aligned handle as it's distracting when it's disabled. */
|
|
|
|
|
if (aidx_norm == 3) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
WM_gizmo_set_flag(axis, WM_GIZMO_HIDDEN, true);
|
|
|
|
|
}
|
|
|
|
|
MAN_ITER_AXES_END;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
wmWindow *win = CTX_wm_window(C);
|
|
|
|
|
wmOperator *op = NULL;
|
|
|
|
|
for (int i = 0; i < widget->op_data_len; i++) {
|
|
|
|
@ -1489,6 +1621,10 @@ static int gizmo_modal(bContext *C,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (op != NULL) {
|
|
|
|
|
GizmoGroup *ggd = gzgroup->customdata;
|
|
|
|
|
const int axis_idx = BLI_array_findindex(ggd->gizmos, ARRAY_SIZE(ggd->gizmos), &widget);
|
|
|
|
|
const short axis_type = gizmo_get_axis_type(axis_idx);
|
|
|
|
|
|
|
|
|
|
float twmat[4][4];
|
|
|
|
|
float scale_buf[3];
|
|
|
|
|
float *scale = NULL;
|
|
|
|
@ -1513,7 +1649,7 @@ static int gizmo_modal(bContext *C,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (update) {
|
|
|
|
|
gizmo_refresh_from_matrix(gzgroup, twmat, scale);
|
|
|
|
|
gizmogroup_refresh_from_matrix(gzgroup, twmat, scale, true);
|
|
|
|
|
ED_region_tag_redraw_editor_overlays(region);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -1539,62 +1675,7 @@ static void gizmogroup_init_properties_from_twtype(wmGizmoGroup *gzgroup)
|
|
|
|
|
/* custom handler! */
|
|
|
|
|
WM_gizmo_set_fn_custom_modal(axis, gizmo_modal);
|
|
|
|
|
|
|
|
|
|
switch (axis_idx) {
|
|
|
|
|
case MAN_AXIS_TRANS_X:
|
|
|
|
|
case MAN_AXIS_TRANS_Y:
|
|
|
|
|
case MAN_AXIS_TRANS_Z:
|
|
|
|
|
case MAN_AXIS_SCALE_X:
|
|
|
|
|
case MAN_AXIS_SCALE_Y:
|
|
|
|
|
case MAN_AXIS_SCALE_Z:
|
|
|
|
|
if (axis_idx >= MAN_AXIS_RANGE_TRANS_START && axis_idx < MAN_AXIS_RANGE_TRANS_END) {
|
|
|
|
|
int draw_options = 0;
|
|
|
|
|
if ((ggd->twtype & (V3D_GIZMO_SHOW_OBJECT_ROTATE | V3D_GIZMO_SHOW_OBJECT_SCALE)) == 0) {
|
|
|
|
|
draw_options |= ED_GIZMO_ARROW_DRAW_FLAG_STEM;
|
|
|
|
|
}
|
|
|
|
|
RNA_enum_set(axis->ptr, "draw_options", draw_options);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
WM_gizmo_set_line_width(axis, GIZMO_AXIS_LINE_WIDTH);
|
|
|
|
|
break;
|
|
|
|
|
case MAN_AXIS_ROT_X:
|
|
|
|
|
case MAN_AXIS_ROT_Y:
|
|
|
|
|
case MAN_AXIS_ROT_Z:
|
|
|
|
|
/* increased line width for better display */
|
|
|
|
|
WM_gizmo_set_line_width(axis, GIZMO_AXIS_LINE_WIDTH + 1.0f);
|
|
|
|
|
WM_gizmo_set_flag(axis, WM_GIZMO_DRAW_VALUE, true);
|
|
|
|
|
break;
|
|
|
|
|
case MAN_AXIS_TRANS_XY:
|
|
|
|
|
case MAN_AXIS_TRANS_YZ:
|
|
|
|
|
case MAN_AXIS_TRANS_ZX:
|
|
|
|
|
case MAN_AXIS_SCALE_XY:
|
|
|
|
|
case MAN_AXIS_SCALE_YZ:
|
|
|
|
|
case MAN_AXIS_SCALE_ZX: {
|
|
|
|
|
const float ofs[3] = {MAN_AXIS_SCALE_PLANE_OFFSET, MAN_AXIS_SCALE_PLANE_OFFSET, 0.0f};
|
|
|
|
|
WM_gizmo_set_scale(axis, MAN_AXIS_SCALE_PLANE_SCALE);
|
|
|
|
|
WM_gizmo_set_matrix_offset_location(axis, ofs);
|
|
|
|
|
WM_gizmo_set_flag(axis, WM_GIZMO_DRAW_OFFSET_SCALE, true);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case MAN_AXIS_TRANS_C:
|
|
|
|
|
case MAN_AXIS_ROT_C:
|
|
|
|
|
case MAN_AXIS_SCALE_C:
|
|
|
|
|
case MAN_AXIS_ROT_T:
|
|
|
|
|
WM_gizmo_set_line_width(axis, GIZMO_AXIS_LINE_WIDTH);
|
|
|
|
|
if (axis_idx == MAN_AXIS_ROT_T) {
|
|
|
|
|
WM_gizmo_set_flag(axis, WM_GIZMO_DRAW_HOVER, true);
|
|
|
|
|
}
|
|
|
|
|
else if (axis_idx == MAN_AXIS_ROT_C) {
|
|
|
|
|
WM_gizmo_set_flag(axis, WM_GIZMO_DRAW_VALUE, true);
|
|
|
|
|
WM_gizmo_set_scale(axis, 1.2f);
|
|
|
|
|
}
|
|
|
|
|
else if (axis_idx == MAN_AXIS_SCALE_C) {
|
|
|
|
|
WM_gizmo_set_scale(axis, 1.2f);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
WM_gizmo_set_scale(axis, 0.2f);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
gizmo_3d_setup_draw_from_twtype(axis, axis_idx, ggd->twtype);
|
|
|
|
|
|
|
|
|
|
switch (axis_type) {
|
|
|
|
|
case MAN_AXES_TRANSLATE:
|
|
|
|
@ -1688,111 +1769,87 @@ static void WIDGETGROUP_gizmo_setup(const bContext *C, wmGizmoGroup *gzgroup)
|
|
|
|
|
* \param twmat: The transform matrix (typically #RegionView3D.twmat).
|
|
|
|
|
* \param scale: Optional scale, to show scale while modally dragging the scale handles.
|
|
|
|
|
*/
|
|
|
|
|
static void gizmo_refresh_from_matrix(wmGizmoGroup *gzgroup,
|
|
|
|
|
static void gizmo_refresh_from_matrix(wmGizmo *axis,
|
|
|
|
|
const int axis_idx,
|
|
|
|
|
const int twtype,
|
|
|
|
|
const float twmat[4][4],
|
|
|
|
|
const float scale[3])
|
|
|
|
|
{
|
|
|
|
|
const short axis_type = gizmo_get_axis_type(axis_idx);
|
|
|
|
|
const int aidx_norm = gizmo_orientation_axis(axis_idx, NULL);
|
|
|
|
|
|
|
|
|
|
WM_gizmo_set_matrix_location(axis, twmat[3]);
|
|
|
|
|
switch (axis_idx) {
|
|
|
|
|
case MAN_AXIS_TRANS_X:
|
|
|
|
|
case MAN_AXIS_TRANS_Y:
|
|
|
|
|
case MAN_AXIS_TRANS_Z:
|
|
|
|
|
case MAN_AXIS_SCALE_X:
|
|
|
|
|
case MAN_AXIS_SCALE_Y:
|
|
|
|
|
case MAN_AXIS_SCALE_Z: {
|
|
|
|
|
const float *z_axis = twmat[aidx_norm];
|
|
|
|
|
if (axis_type == MAN_AXES_SCALE) {
|
|
|
|
|
/* Scale handles are cubes that don't look right when not aligned with other axes.
|
|
|
|
|
* This is noticeable when the axis is rotated to something besides the global-axis. */
|
|
|
|
|
const int aidx_norm_y = (aidx_norm + 2) % 3;
|
|
|
|
|
const float *y_axis = twmat[aidx_norm_y];
|
|
|
|
|
WM_gizmo_set_matrix_rotation_from_yz_axis(axis, y_axis, z_axis);
|
|
|
|
|
|
|
|
|
|
if (scale) {
|
|
|
|
|
float start, end;
|
|
|
|
|
gizmo_line_range(twtype, axis_type, &start, &end);
|
|
|
|
|
RNA_float_set(axis->ptr, "length", (end * scale[aidx_norm]) - start);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
WM_gizmo_set_matrix_rotation_from_z_axis(axis, z_axis);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case MAN_AXIS_ROT_X:
|
|
|
|
|
case MAN_AXIS_ROT_Y:
|
|
|
|
|
case MAN_AXIS_ROT_Z:
|
|
|
|
|
WM_gizmo_set_matrix_rotation_from_z_axis(axis, twmat[aidx_norm]);
|
|
|
|
|
break;
|
|
|
|
|
case MAN_AXIS_TRANS_XY:
|
|
|
|
|
case MAN_AXIS_TRANS_YZ:
|
|
|
|
|
case MAN_AXIS_TRANS_ZX:
|
|
|
|
|
case MAN_AXIS_SCALE_XY:
|
|
|
|
|
case MAN_AXIS_SCALE_YZ:
|
|
|
|
|
case MAN_AXIS_SCALE_ZX: {
|
|
|
|
|
const int aidx_norm_x = (aidx_norm + 1) % 3;
|
|
|
|
|
const int aidx_norm_y = (aidx_norm + 2) % 3;
|
|
|
|
|
const float *y_axis = twmat[aidx_norm_y];
|
|
|
|
|
const float *z_axis = twmat[aidx_norm];
|
|
|
|
|
WM_gizmo_set_matrix_rotation_from_yz_axis(axis, y_axis, z_axis);
|
|
|
|
|
|
|
|
|
|
if (axis_type == MAN_AXES_SCALE) {
|
|
|
|
|
float ofs[3] = {MAN_AXIS_SCALE_PLANE_OFFSET, MAN_AXIS_SCALE_PLANE_OFFSET, 0.0f};
|
|
|
|
|
if (scale) {
|
|
|
|
|
ofs[0] *= scale[aidx_norm_x];
|
|
|
|
|
ofs[1] *= scale[aidx_norm_y];
|
|
|
|
|
}
|
|
|
|
|
WM_gizmo_set_matrix_offset_location(axis, ofs);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void gizmogroup_refresh_from_matrix(wmGizmoGroup *gzgroup,
|
|
|
|
|
const float twmat[4][4],
|
|
|
|
|
const float scale[3],
|
|
|
|
|
const bool ignore_hidden)
|
|
|
|
|
{
|
|
|
|
|
GizmoGroup *ggd = gzgroup->customdata;
|
|
|
|
|
|
|
|
|
|
MAN_ITER_AXES_BEGIN (axis, axis_idx) {
|
|
|
|
|
const short axis_type = gizmo_get_axis_type(axis_idx);
|
|
|
|
|
const int aidx_norm = gizmo_orientation_axis(axis_idx, NULL);
|
|
|
|
|
|
|
|
|
|
WM_gizmo_set_matrix_location(axis, twmat[3]);
|
|
|
|
|
switch (axis_idx) {
|
|
|
|
|
case MAN_AXIS_TRANS_X:
|
|
|
|
|
case MAN_AXIS_TRANS_Y:
|
|
|
|
|
case MAN_AXIS_TRANS_Z:
|
|
|
|
|
case MAN_AXIS_SCALE_X:
|
|
|
|
|
case MAN_AXIS_SCALE_Y:
|
|
|
|
|
case MAN_AXIS_SCALE_Z: {
|
|
|
|
|
float start_co[3] = {0.0f, 0.0f, 0.0f};
|
|
|
|
|
float len;
|
|
|
|
|
|
|
|
|
|
gizmo_line_range(ggd->twtype, axis_type, &start_co[2], &len);
|
|
|
|
|
|
|
|
|
|
const float *z_axis = twmat[aidx_norm];
|
|
|
|
|
if (axis_type == MAN_AXES_SCALE) {
|
|
|
|
|
/* Scale handles are cubes that don't look right when not aligned with other axes.
|
|
|
|
|
* This is noticeable when the axis is rotated to something besides the global-axis. */
|
|
|
|
|
const int aidx_norm_y = (aidx_norm + 2) % 3;
|
|
|
|
|
const float *y_axis = twmat[aidx_norm_y];
|
|
|
|
|
WM_gizmo_set_matrix_rotation_from_yz_axis(axis, y_axis, z_axis);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
WM_gizmo_set_matrix_rotation_from_z_axis(axis, z_axis);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (axis_idx >= MAN_AXIS_RANGE_TRANS_START && axis_idx < MAN_AXIS_RANGE_TRANS_END) {
|
|
|
|
|
if (ggd->twtype & V3D_GIZMO_SHOW_OBJECT_ROTATE) {
|
|
|
|
|
/* Avoid rotate and translate arrows overlap. */
|
|
|
|
|
start_co[2] += 0.215f;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (scale) {
|
|
|
|
|
if (axis_type == MAN_AXES_SCALE) {
|
|
|
|
|
len = ((start_co[2] + len) * scale[aidx_norm]) - start_co[2];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
RNA_float_set(axis->ptr, "length", len);
|
|
|
|
|
|
|
|
|
|
WM_gizmo_set_matrix_offset_location(axis, start_co);
|
|
|
|
|
|
|
|
|
|
WM_gizmo_set_flag(axis, WM_GIZMO_DRAW_OFFSET_SCALE, true);
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case MAN_AXIS_ROT_X:
|
|
|
|
|
case MAN_AXIS_ROT_Y:
|
|
|
|
|
case MAN_AXIS_ROT_Z:
|
|
|
|
|
case MAN_AXIS_ROT_C: {
|
|
|
|
|
if (axis_idx != MAN_AXIS_ROT_C) {
|
|
|
|
|
WM_gizmo_set_matrix_rotation_from_z_axis(axis, twmat[aidx_norm]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Remove #ED_GIZMO_DIAL_DRAW_FLAG_ANGLE_VALUE. It is used only for modal drawing. */
|
|
|
|
|
PropertyRNA *prop = RNA_struct_find_property(axis->ptr, "draw_options");
|
|
|
|
|
RNA_property_enum_set(axis->ptr,
|
|
|
|
|
prop,
|
|
|
|
|
RNA_property_enum_get(axis->ptr, prop) &
|
|
|
|
|
~ED_GIZMO_DIAL_DRAW_FLAG_ANGLE_VALUE);
|
|
|
|
|
} break;
|
|
|
|
|
case MAN_AXIS_TRANS_XY:
|
|
|
|
|
case MAN_AXIS_TRANS_YZ:
|
|
|
|
|
case MAN_AXIS_TRANS_ZX:
|
|
|
|
|
case MAN_AXIS_SCALE_XY:
|
|
|
|
|
case MAN_AXIS_SCALE_YZ:
|
|
|
|
|
case MAN_AXIS_SCALE_ZX: {
|
|
|
|
|
const int aidx_norm_x = (aidx_norm + 1) % 3;
|
|
|
|
|
const int aidx_norm_y = (aidx_norm + 2) % 3;
|
|
|
|
|
const float *y_axis = twmat[aidx_norm_y];
|
|
|
|
|
const float *z_axis = twmat[aidx_norm];
|
|
|
|
|
WM_gizmo_set_matrix_rotation_from_yz_axis(axis, y_axis, z_axis);
|
|
|
|
|
|
|
|
|
|
if (axis_type == MAN_AXES_SCALE) {
|
|
|
|
|
float ofs[3] = {MAN_AXIS_SCALE_PLANE_OFFSET, MAN_AXIS_SCALE_PLANE_OFFSET, 0.0f};
|
|
|
|
|
if (scale) {
|
|
|
|
|
ofs[0] *= scale[aidx_norm_x];
|
|
|
|
|
ofs[1] *= scale[aidx_norm_y];
|
|
|
|
|
}
|
|
|
|
|
WM_gizmo_set_matrix_offset_location(axis, ofs);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (ignore_hidden && axis->flag & WM_GIZMO_HIDDEN) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
gizmo_refresh_from_matrix(axis, axis_idx, ggd->twtype, twmat, scale);
|
|
|
|
|
}
|
|
|
|
|
MAN_ITER_AXES_END;
|
|
|
|
|
|
|
|
|
|
/* Ensure rotate disks don't overlap scale arrows, especially in ortho view. */
|
|
|
|
|
float rotate_select_bias = 0.0f;
|
|
|
|
|
if ((ggd->twtype & V3D_GIZMO_SHOW_OBJECT_SCALE) && ggd->twtype & V3D_GIZMO_SHOW_OBJECT_ROTATE) {
|
|
|
|
|
rotate_select_bias = -2.0f;
|
|
|
|
|
}
|
|
|
|
|
for (int i = MAN_AXIS_RANGE_ROT_START; i < MAN_AXIS_RANGE_ROT_END; i++) {
|
|
|
|
|
ggd->gizmos[i]->select_bias = rotate_select_bias;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void WIDGETGROUP_gizmo_refresh(const bContext *C, wmGizmoGroup *gzgroup)
|
|
|
|
@ -1835,7 +1892,7 @@ static void WIDGETGROUP_gizmo_refresh(const bContext *C, wmGizmoGroup *gzgroup)
|
|
|
|
|
|
|
|
|
|
gizmo_prepare_mat(C, rv3d, &tbounds);
|
|
|
|
|
|
|
|
|
|
gizmo_refresh_from_matrix(gzgroup, rv3d->twmat, NULL);
|
|
|
|
|
gizmogroup_refresh_from_matrix(gzgroup, rv3d->twmat, NULL, false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void WIDGETGROUP_gizmo_message_subscribe(const bContext *C,
|
|
|
|
@ -1850,6 +1907,14 @@ static void WIDGETGROUP_gizmo_message_subscribe(const bContext *C,
|
|
|
|
|
gzgroup, mbus, scene, screen, area, region, VIEW3D_GGT_xform_gizmo);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void gizmogroup_hide_all(GizmoGroup *ggd)
|
|
|
|
|
{
|
|
|
|
|
MAN_ITER_AXES_BEGIN (axis, axis_idx) {
|
|
|
|
|
WM_gizmo_set_flag(axis, WM_GIZMO_HIDDEN, true);
|
|
|
|
|
}
|
|
|
|
|
MAN_ITER_AXES_END;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void WIDGETGROUP_gizmo_draw_prepare(const bContext *C, wmGizmoGroup *gzgroup)
|
|
|
|
|
{
|
|
|
|
|
GizmoGroup *ggd = gzgroup->customdata;
|
|
|
|
@ -1873,38 +1938,32 @@ static void WIDGETGROUP_gizmo_draw_prepare(const bContext *C, wmGizmoGroup *gzgr
|
|
|
|
|
/* when looking through a selected camera, the gizmo can be at the
|
|
|
|
|
* exact same position as the view, skip so we don't break selection */
|
|
|
|
|
if (ggd->all_hidden || fabsf(ED_view3d_pixel_size(rv3d, rv3d->twmat[3])) < 5e-7f) {
|
|
|
|
|
MAN_ITER_AXES_BEGIN (axis, axis_idx) {
|
|
|
|
|
if (!is_modal) {
|
|
|
|
|
WM_gizmo_set_flag(axis, WM_GIZMO_HIDDEN, true);
|
|
|
|
|
}
|
|
|
|
|
if (!is_modal) {
|
|
|
|
|
gizmogroup_hide_all(ggd);
|
|
|
|
|
}
|
|
|
|
|
MAN_ITER_AXES_END;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
gizmo_get_idot(rv3d, idot);
|
|
|
|
|
|
|
|
|
|
/* *** set properties for axes *** */
|
|
|
|
|
MAN_ITER_AXES_BEGIN (axis, axis_idx) {
|
|
|
|
|
const short axis_type = gizmo_get_axis_type(axis_idx);
|
|
|
|
|
/* XXX maybe unset _HIDDEN flag on redraw? */
|
|
|
|
|
if (gizmo_is_axis_visible(rv3d, ggd->twtype, idot, axis_type, axis_idx)) {
|
|
|
|
|
if (!is_modal) {
|
|
|
|
|
WM_gizmo_set_flag(axis, WM_GIZMO_HIDDEN, false);
|
|
|
|
|
if (is_modal) {
|
|
|
|
|
if (axis->flag & WM_GIZMO_HIDDEN) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
if (!is_modal) {
|
|
|
|
|
WM_gizmo_set_flag(axis, WM_GIZMO_HIDDEN, true);
|
|
|
|
|
const short axis_type = gizmo_get_axis_type(axis_idx);
|
|
|
|
|
if (gizmo_is_axis_visible(rv3d, ggd->twtype, idot, axis_type, axis_idx)) {
|
|
|
|
|
/* XXX maybe unset _HIDDEN flag on redraw? */
|
|
|
|
|
WM_gizmo_set_flag(axis, WM_GIZMO_HIDDEN, false);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
WM_gizmo_set_flag(axis, WM_GIZMO_HIDDEN, true);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
float color[4], color_hi[4];
|
|
|
|
|
gizmo_get_axis_color(axis_idx, idot, color, color_hi);
|
|
|
|
|
WM_gizmo_set_color(axis, color);
|
|
|
|
|
WM_gizmo_set_color_highlight(axis, color_hi);
|
|
|
|
|
|
|
|
|
|
if (!is_modal) {
|
|
|
|
|
/* Align to view. */
|
|
|
|
|
switch (axis_idx) {
|
|
|
|
|
case MAN_AXIS_TRANS_C:
|
|
|
|
|
case MAN_AXIS_ROT_C:
|
|
|
|
@ -1914,6 +1973,11 @@ static void WIDGETGROUP_gizmo_draw_prepare(const bContext *C, wmGizmoGroup *gzgr
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
float color[4], color_hi[4];
|
|
|
|
|
gizmo_get_axis_color(axis_idx, idot, color, color_hi);
|
|
|
|
|
WM_gizmo_set_color(axis, color);
|
|
|
|
|
WM_gizmo_set_color_highlight(axis, color_hi);
|
|
|
|
|
}
|
|
|
|
|
MAN_ITER_AXES_END;
|
|
|
|
|
|
|
|
|
@ -1934,13 +1998,59 @@ static void WIDGETGROUP_gizmo_draw_prepare(const bContext *C, wmGizmoGroup *gzgr
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void gizmo_3d_draw_invoke(wmGizmoGroup *gzgroup,
|
|
|
|
|
const ARegion *region,
|
|
|
|
|
const int axis_idx_active,
|
|
|
|
|
const float mval[2])
|
|
|
|
|
{
|
|
|
|
|
GizmoGroup *ggd = gzgroup->customdata;
|
|
|
|
|
const RegionView3D *rv3d = region->regiondata;
|
|
|
|
|
|
|
|
|
|
struct wmGizmo *axis_active = ggd->gizmos[axis_idx_active];
|
|
|
|
|
|
|
|
|
|
const short axis_active_type = gizmo_get_axis_type(axis_idx_active);
|
|
|
|
|
if (axis_active_type == MAN_AXES_ROTATE) {
|
|
|
|
|
/* Hide other gizmos except the active one and #MAN_AXIS_ROT_C.
|
|
|
|
|
* #MAN_AXIS_ROT_C was displayed before and remains visible by convention. */
|
|
|
|
|
gizmogroup_hide_all(ggd);
|
|
|
|
|
WM_gizmo_set_flag(axis_active, WM_GIZMO_HIDDEN, false);
|
|
|
|
|
WM_gizmo_set_flag(ggd->gizmos[MAN_AXIS_ROT_C], WM_GIZMO_HIDDEN, false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
MAN_ITER_AXES_BEGIN (axis, axis_idx) {
|
|
|
|
|
if (axis->flag & WM_GIZMO_HIDDEN) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
gizmo_refresh_from_matrix(axis, axis_idx, ggd->twtype, rv3d->twmat, NULL);
|
|
|
|
|
|
|
|
|
|
if (ELEM(axis_idx, MAN_AXIS_TRANS_C, MAN_AXIS_SCALE_C, MAN_AXIS_ROT_C, MAN_AXIS_ROT_T)) {
|
|
|
|
|
WM_gizmo_set_matrix_rotation_from_z_axis(axis, rv3d->viewinv[2]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (axis == axis_active) {
|
|
|
|
|
if (axis_active_type == MAN_AXES_ROTATE) {
|
|
|
|
|
gizmo_3d_dial_matrixbasis_calc(region,
|
|
|
|
|
axis_active->matrix_basis[2],
|
|
|
|
|
axis_active->matrix_basis[3],
|
|
|
|
|
mval,
|
|
|
|
|
axis_active->matrix_basis);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
gizmo_3d_setup_draw_modal(axis_active, axis_idx);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
MAN_ITER_AXES_END;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void WIDGETGROUP_gizmo_invoke_prepare(const bContext *C,
|
|
|
|
|
wmGizmoGroup *gzgroup,
|
|
|
|
|
wmGizmo *gz,
|
|
|
|
|
const wmEvent *event)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
GizmoGroup *ggd = gzgroup->customdata;
|
|
|
|
|
const int axis_idx = BLI_array_findindex(ggd->gizmos, ARRAY_SIZE(ggd->gizmos), &gz);
|
|
|
|
|
|
|
|
|
|
gizmo_3d_draw_invoke(gzgroup, CTX_wm_region(C), axis_idx, (float[2]){UNPACK2(event->mval)});
|
|
|
|
|
|
|
|
|
|
/* Support gizmo specific orientation. */
|
|
|
|
|
if (gz != ggd->gizmos[MAN_AXIS_ROT_T]) {
|
|
|
|
@ -1964,7 +2074,6 @@ static void WIDGETGROUP_gizmo_invoke_prepare(const bContext *C,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Support shift click to constrain axis. */
|
|
|
|
|
const int axis_idx = BLI_array_findindex(ggd->gizmos, ARRAY_SIZE(ggd->gizmos), &gz);
|
|
|
|
|
int axis = -1;
|
|
|
|
|
switch (axis_idx) {
|
|
|
|
|
case MAN_AXIS_TRANS_X:
|
|
|
|
@ -2000,17 +2109,6 @@ static void WIDGETGROUP_gizmo_invoke_prepare(const bContext *C,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (ELEM(axis_idx, MAN_AXIS_ROT_X, MAN_AXIS_ROT_Y, MAN_AXIS_ROT_Z, MAN_AXIS_ROT_C)) {
|
|
|
|
|
gizmo_3d_dial_matrixbasis_calc(CTX_wm_region(C),
|
|
|
|
|
gz->matrix_basis[2],
|
|
|
|
|
gz->matrix_basis[3],
|
|
|
|
|
(float[2]){UNPACK2(event->mval)},
|
|
|
|
|
gz->matrix_basis);
|
|
|
|
|
PropertyRNA *prop = RNA_struct_find_property(gz->ptr, "draw_options");
|
|
|
|
|
RNA_property_enum_set(
|
|
|
|
|
gz->ptr, prop, RNA_property_enum_get(gz->ptr, prop) | ED_GIZMO_DIAL_DRAW_FLAG_ANGLE_VALUE);
|
|
|
|
|
RNA_float_set(gz->ptr, "incremental_angle", 0.0f);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool WIDGETGROUP_gizmo_poll_generic(View3D *v3d)
|
|
|
|
@ -2103,6 +2201,8 @@ void VIEW3D_GGT_xform_gizmo(wmGizmoGroupType *gzgt)
|
|
|
|
|
V3D_GIZMO_SHOW_OBJECT_TRANSLATE,
|
|
|
|
|
"Drag Action",
|
|
|
|
|
"");
|
|
|
|
|
|
|
|
|
|
g_GGT_xform_gizmo = gzgt;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void VIEW3D_GGT_xform_gizmo_context(wmGizmoGroupType *gzgt)
|
|
|
|
@ -2120,6 +2220,8 @@ void VIEW3D_GGT_xform_gizmo_context(wmGizmoGroupType *gzgt)
|
|
|
|
|
gzgt->message_subscribe = WIDGETGROUP_gizmo_message_subscribe;
|
|
|
|
|
gzgt->draw_prepare = WIDGETGROUP_gizmo_draw_prepare;
|
|
|
|
|
gzgt->invoke_prepare = WIDGETGROUP_gizmo_invoke_prepare;
|
|
|
|
|
|
|
|
|
|
g_GGT_xform_gizmo_context = gzgt;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** \} */
|
|
|
|
@ -2558,3 +2660,151 @@ void VIEW3D_GGT_xform_shear(wmGizmoGroupType *gzgt)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
static wmGizmoGroup *gizmogroup_xform_find(TransInfo *t)
|
|
|
|
|
{
|
|
|
|
|
wmGizmo *gizmo_modal_current = WM_gizmomap_get_modal(t->region->gizmo_map);
|
|
|
|
|
if (gizmo_modal_current) {
|
|
|
|
|
wmGizmoGroup *gzgroup = gizmo_modal_current->parent_gzgroup;
|
|
|
|
|
/* Check #wmGizmoGroup::customdata to make sure the GizmoGroup has been initialized. */
|
|
|
|
|
if (gzgroup->customdata && ELEM(gzgroup->type, g_GGT_xform_gizmo, g_GGT_xform_gizmo_context)) {
|
|
|
|
|
return gzgroup;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* See #WM_gizmomap_group_find_ptr. */
|
|
|
|
|
LISTBASE_FOREACH (wmGizmoGroup *, gzgroup, WM_gizmomap_group_list(t->region->gizmo_map)) {
|
|
|
|
|
if (ELEM(gzgroup->type, g_GGT_xform_gizmo, g_GGT_xform_gizmo_context)) {
|
|
|
|
|
/* Choose the one that has been initialized. */
|
|
|
|
|
if (gzgroup->customdata) {
|
|
|
|
|
return gzgroup;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void transform_gizmo_3d_model_from_constraint_and_mode_init(TransInfo *t)
|
|
|
|
|
{
|
|
|
|
|
wmGizmo *gizmo_modal_current = WM_gizmomap_get_modal(t->region->gizmo_map);
|
|
|
|
|
if (!gizmo_modal_current || !ELEM(gizmo_modal_current->parent_gzgroup->type,
|
|
|
|
|
g_GGT_xform_gizmo,
|
|
|
|
|
g_GGT_xform_gizmo_context)) {
|
|
|
|
|
t->flag |= T_NO_GIZMO;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void transform_gizmo_3d_model_from_constraint_and_mode_set(TransInfo *t)
|
|
|
|
|
{
|
|
|
|
|
if (t->flag & T_NO_GIZMO) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
wmGizmoGroup *gzgroup_xform = gizmogroup_xform_find(t);
|
|
|
|
|
if (gzgroup_xform == NULL) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int axis_idx = -1;
|
|
|
|
|
if (t->mode == TFM_TRACKBALL) {
|
|
|
|
|
axis_idx = MAN_AXIS_ROT_T;
|
|
|
|
|
}
|
|
|
|
|
else if (ELEM(t->mode, TFM_TRANSLATION, TFM_ROTATION, TFM_RESIZE)) {
|
|
|
|
|
const int axis_map[3][7] = {
|
|
|
|
|
{MAN_AXIS_TRANS_X,
|
|
|
|
|
MAN_AXIS_TRANS_Y,
|
|
|
|
|
MAN_AXIS_TRANS_XY,
|
|
|
|
|
MAN_AXIS_TRANS_Z,
|
|
|
|
|
MAN_AXIS_TRANS_ZX,
|
|
|
|
|
MAN_AXIS_TRANS_YZ,
|
|
|
|
|
MAN_AXIS_TRANS_C},
|
|
|
|
|
{MAN_AXIS_ROT_X,
|
|
|
|
|
MAN_AXIS_ROT_Y,
|
|
|
|
|
MAN_AXIS_ROT_Z,
|
|
|
|
|
MAN_AXIS_ROT_Z,
|
|
|
|
|
MAN_AXIS_ROT_Y,
|
|
|
|
|
MAN_AXIS_ROT_X,
|
|
|
|
|
MAN_AXIS_ROT_C},
|
|
|
|
|
{MAN_AXIS_SCALE_X,
|
|
|
|
|
MAN_AXIS_SCALE_Y,
|
|
|
|
|
MAN_AXIS_SCALE_XY,
|
|
|
|
|
MAN_AXIS_SCALE_Z,
|
|
|
|
|
MAN_AXIS_SCALE_ZX,
|
|
|
|
|
MAN_AXIS_SCALE_YZ,
|
|
|
|
|
MAN_AXIS_SCALE_C},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
BLI_STATIC_ASSERT(
|
|
|
|
|
/* Assert mode values. */
|
|
|
|
|
((TFM_ROTATION == TFM_TRANSLATION + 1) && (TFM_RESIZE == TFM_TRANSLATION + 2) &&
|
|
|
|
|
/* Assert constrain values. */
|
|
|
|
|
(CON_AXIS0 == (1 << 1)) && (CON_AXIS1 == (1 << 2)) && (CON_AXIS2 == (1 << 3))),
|
|
|
|
|
"");
|
|
|
|
|
|
|
|
|
|
const int trans_mode = t->mode - TFM_TRANSLATION;
|
|
|
|
|
int con_mode = ((CON_AXIS0 | CON_AXIS1 | CON_AXIS2) >> 1) - 1;
|
|
|
|
|
if (t->con.mode & CON_APPLY) {
|
|
|
|
|
con_mode = ((t->con.mode & (CON_AXIS0 | CON_AXIS1 | CON_AXIS2)) >> 1) - 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
axis_idx = axis_map[trans_mode][con_mode];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
wmGizmo *gizmo_modal_current = WM_gizmomap_get_modal(t->region->gizmo_map);
|
|
|
|
|
if (axis_idx != -1) {
|
|
|
|
|
RegionView3D *rv3d = t->region->regiondata;
|
|
|
|
|
bool update_orientation = !(equals_v3v3(rv3d->twmat[0], t->spacemtx[0]) &&
|
|
|
|
|
equals_v3v3(rv3d->twmat[1], t->spacemtx[1]) &&
|
|
|
|
|
equals_v3v3(rv3d->twmat[2], t->spacemtx[2]));
|
|
|
|
|
|
|
|
|
|
GizmoGroup *ggd = gzgroup_xform->customdata;
|
|
|
|
|
wmGizmo *gizmo_expected = ggd->gizmos[axis_idx];
|
|
|
|
|
if (update_orientation || gizmo_modal_current != gizmo_expected) {
|
|
|
|
|
if (update_orientation) {
|
|
|
|
|
copy_m4_m3(rv3d->twmat, t->spacemtx);
|
|
|
|
|
copy_v3_v3(rv3d->twmat[3], t->center_global);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
wmEvent event = {NULL};
|
|
|
|
|
|
|
|
|
|
/* Set the initial mouse value. Used for rotation gizmos. */
|
|
|
|
|
copy_v2_v2_int(event.mval, t->mouse.imval);
|
|
|
|
|
|
|
|
|
|
/* We need to update the position of the gizmo before invoking otherwise
|
|
|
|
|
* #wmGizmo::scale_final could be calculated wrong. */
|
|
|
|
|
gizmo_refresh_from_matrix(gizmo_expected, axis_idx, ggd->twtype, rv3d->twmat, NULL);
|
|
|
|
|
|
|
|
|
|
BLI_assert_msg(!gizmo_modal_current || gizmo_modal_current->highlight_part == 0,
|
|
|
|
|
"Avoid changing the highlight part");
|
|
|
|
|
gizmo_expected->highlight_part = 0;
|
|
|
|
|
WM_gizmo_modal_set_while_modal(t->region->gizmo_map, t->context, gizmo_expected, &event);
|
|
|
|
|
WM_gizmo_highlight_set(t->region->gizmo_map, gizmo_expected);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (gizmo_modal_current) {
|
|
|
|
|
WM_gizmo_modal_set_while_modal(t->region->gizmo_map, t->context, NULL, NULL);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void transform_gizmo_3d_model_from_constraint_and_mode_restore(TransInfo *t)
|
|
|
|
|
{
|
|
|
|
|
if (t->flag & T_NO_GIZMO) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
wmGizmoGroup *gzgroup_xform = gizmogroup_xform_find(t);
|
|
|
|
|
if (gzgroup_xform == NULL) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
GizmoGroup *ggd = gzgroup_xform->customdata;
|
|
|
|
|
|
|
|
|
|
/* #wmGizmoGroup::draw_prepare will handle the rest. */
|
|
|
|
|
MAN_ITER_AXES_BEGIN (axis, axis_idx) {
|
|
|
|
|
gizmo_3d_setup_draw_default(axis, axis_idx);
|
|
|
|
|
gizmo_3d_setup_draw_from_twtype(axis, axis_idx, ggd->twtype);
|
|
|
|
|
}
|
|
|
|
|
MAN_ITER_AXES_END;
|
|
|
|
|
}
|
|
|
|
|