UI: offset scale gizmos instead of scaling their shape
Scaling handles while dragging could be distracting, especially at extreme values where handles could become large on-screen. Now all gizmos are shown while scaling. GIZMO_GT_arrow_3d now now support changing their length while being dragged as well as negative lengths.
This commit is contained in:
parent
bb34afac56
commit
011d9cce19
|
@ -58,6 +58,11 @@ typedef struct ArrowGizmo3D {
|
|||
GizmoCommonData data;
|
||||
} ArrowGizmo3D;
|
||||
|
||||
typedef struct ArrowGizmoInteraction {
|
||||
GizmoInteraction inter;
|
||||
float init_arrow_length;
|
||||
} ArrowGizmoInteraction;
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
||||
static void gizmo_arrow_matrix_basis_get(const wmGizmo *gz, float r_matrix[4][4])
|
||||
|
@ -68,7 +73,10 @@ static void gizmo_arrow_matrix_basis_get(const wmGizmo *gz, float r_matrix[4][4]
|
|||
madd_v3_v3fl(r_matrix[3], arrow->gizmo.matrix_basis[2], arrow->data.offset);
|
||||
}
|
||||
|
||||
static void arrow_draw_geom(const ArrowGizmo3D *arrow, const bool select, const float color[4])
|
||||
static void arrow_draw_geom(const ArrowGizmo3D *arrow,
|
||||
const bool select,
|
||||
const float color[4],
|
||||
const float arrow_length)
|
||||
{
|
||||
uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
|
||||
bool unbind_shader = true;
|
||||
|
@ -111,8 +119,6 @@ static void arrow_draw_geom(const ArrowGizmo3D *arrow, const bool select, const
|
|||
#ifdef USE_GIZMO_CUSTOM_ARROWS
|
||||
wm_gizmo_geometryinfo_draw(&wm_gizmo_geom_data_arrow, select, color);
|
||||
#else
|
||||
const float arrow_length = RNA_float_get(arrow->gizmo.ptr, "length");
|
||||
|
||||
const float vec[2][3] = {
|
||||
{0.0f, 0.0f, 0.0f},
|
||||
{0.0f, 0.0f, arrow_length},
|
||||
|
@ -176,6 +182,7 @@ static void arrow_draw_geom(const ArrowGizmo3D *arrow, const bool select, const
|
|||
static void arrow_draw_intern(ArrowGizmo3D *arrow, const bool select, const bool highlight)
|
||||
{
|
||||
wmGizmo *gz = &arrow->gizmo;
|
||||
const float arrow_length = RNA_float_get(gz->ptr, "length");
|
||||
float color[4];
|
||||
float matrix_final[4][4];
|
||||
|
||||
|
@ -186,19 +193,20 @@ static void arrow_draw_intern(ArrowGizmo3D *arrow, const bool select, const bool
|
|||
GPU_matrix_push();
|
||||
GPU_matrix_mul(matrix_final);
|
||||
GPU_blend(GPU_BLEND_ALPHA);
|
||||
arrow_draw_geom(arrow, select, color);
|
||||
arrow_draw_geom(arrow, select, color, arrow_length);
|
||||
GPU_blend(GPU_BLEND_NONE);
|
||||
|
||||
GPU_matrix_pop();
|
||||
|
||||
if (gz->interaction_data) {
|
||||
GizmoInteraction *inter = gz->interaction_data;
|
||||
ArrowGizmoInteraction *arrow_inter = gz->interaction_data;
|
||||
|
||||
GPU_matrix_push();
|
||||
GPU_matrix_mul(inter->init_matrix_final);
|
||||
GPU_matrix_mul(arrow_inter->inter.init_matrix_final);
|
||||
|
||||
GPU_blend(GPU_BLEND_ALPHA);
|
||||
arrow_draw_geom(arrow, select, (const float[4]){0.5f, 0.5f, 0.5f, 0.5f});
|
||||
arrow_draw_geom(
|
||||
arrow, select, (const float[4]){0.5f, 0.5f, 0.5f, 0.5f}, arrow_inter->init_arrow_length);
|
||||
GPU_blend(GPU_BLEND_NONE);
|
||||
|
||||
GPU_matrix_pop();
|
||||
|
@ -380,7 +388,7 @@ static void gizmo_arrow_setup(wmGizmo *gz)
|
|||
static int gizmo_arrow_invoke(bContext *UNUSED(C), wmGizmo *gz, const wmEvent *event)
|
||||
{
|
||||
ArrowGizmo3D *arrow = (ArrowGizmo3D *)gz;
|
||||
GizmoInteraction *inter = MEM_callocN(sizeof(GizmoInteraction), __func__);
|
||||
GizmoInteraction *inter = MEM_callocN(sizeof(ArrowGizmoInteraction), __func__);
|
||||
wmGizmoProperty *gz_prop = WM_gizmo_target_property_find(gz, "offset");
|
||||
|
||||
/* Some gizmos don't use properties. */
|
||||
|
@ -396,6 +404,8 @@ static int gizmo_arrow_invoke(bContext *UNUSED(C), wmGizmo *gz, const wmEvent *e
|
|||
gizmo_arrow_matrix_basis_get(gz, inter->init_matrix_basis);
|
||||
WM_gizmo_calc_matrix_final(gz, inter->init_matrix_final);
|
||||
|
||||
((ArrowGizmoInteraction *)inter)->init_arrow_length = RNA_float_get(gz->ptr, "length");
|
||||
|
||||
gz->interaction_data = inter;
|
||||
|
||||
return OPERATOR_RUNNING_MODAL;
|
||||
|
@ -520,7 +530,8 @@ static void GIZMO_GT_arrow_3d(wmGizmoType *gzt)
|
|||
"");
|
||||
RNA_def_enum_flag(gzt->srna, "transform", rna_enum_transform_items, 0, "Transform", "");
|
||||
|
||||
RNA_def_float(gzt->srna, "length", 1.0f, 0.0f, FLT_MAX, "Arrow Line Length", "", 0.0f, FLT_MAX);
|
||||
RNA_def_float(
|
||||
gzt->srna, "length", 1.0f, -FLT_MAX, FLT_MAX, "Arrow Line Length", "", -FLT_MAX, FLT_MAX);
|
||||
RNA_def_float_vector(
|
||||
gzt->srna, "aspect", 2, NULL, 0, FLT_MAX, "Aspect", "Cone/box style only", 0.0f, FLT_MAX);
|
||||
|
||||
|
|
|
@ -1378,6 +1378,11 @@ void drawDial3d(const TransInfo *t)
|
|||
/** \name Transform Gizmo
|
||||
* \{ */
|
||||
|
||||
/** Scale of the two-axis planes. */
|
||||
#define MAN_AXIS_SCALE_PLANE_SCALE 0.07f
|
||||
/** Offset of the two-axis planes, depends on the gizmos scale. Define to avoid repeating. */
|
||||
#define MAN_AXIS_SCALE_PLANE_OFFSET 7.0f
|
||||
|
||||
static GizmoGroup *gizmogroup_init(wmGizmoGroup *gzgroup)
|
||||
{
|
||||
GizmoGroup *ggd;
|
||||
|
@ -1503,12 +1508,10 @@ static int gizmo_modal(bContext *C,
|
|||
|
||||
/* 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.
|
||||
* - For scale: showing the other axes isn't so useful and can be distracting
|
||||
* since the handles can get very big-small.
|
||||
* For rotate: global axis will reset after finish.
|
||||
* Also, gimbal axis isn't properly recalculated while transforming.
|
||||
*/
|
||||
if (ELEM(axis_type, MAN_AXES_ROTATE, MAN_AXES_SCALE)) {
|
||||
if (axis_type == MAN_AXES_ROTATE) {
|
||||
MAN_ITER_AXES_BEGIN (axis, axis_idx) {
|
||||
if (axis == widget) {
|
||||
continue;
|
||||
|
@ -1608,9 +1611,8 @@ static void gizmogroup_init_properties_from_twtype(wmGizmoGroup *gzgroup)
|
|||
case MAN_AXIS_SCALE_XY:
|
||||
case MAN_AXIS_SCALE_YZ:
|
||||
case MAN_AXIS_SCALE_ZX: {
|
||||
const float ofs_ax = 7.0f;
|
||||
const float ofs[3] = {ofs_ax, ofs_ax, 0.0f};
|
||||
WM_gizmo_set_scale(axis, 0.07f);
|
||||
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;
|
||||
|
@ -1762,7 +1764,6 @@ static void gizmo_refresh_from_matrix(wmGizmoGroup *gzgroup,
|
|||
else {
|
||||
WM_gizmo_set_matrix_rotation_from_z_axis(axis, z_axis);
|
||||
}
|
||||
RNA_float_set(axis->ptr, "length", len);
|
||||
|
||||
if (axis_idx >= MAN_AXIS_RANGE_TRANS_START && axis_idx < MAN_AXIS_RANGE_TRANS_END) {
|
||||
if (ggd->twtype & V3D_GIZMO_SHOW_OBJECT_ROTATE) {
|
||||
|
@ -1770,15 +1771,19 @@ static void gizmo_refresh_from_matrix(wmGizmoGroup *gzgroup,
|
|||
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);
|
||||
|
||||
if (scale) {
|
||||
if (axis_type == MAN_AXES_SCALE) {
|
||||
mul_v3_fl(axis->matrix_basis[2], scale[aidx_norm]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MAN_AXIS_ROT_X:
|
||||
|
@ -1798,11 +1803,13 @@ static void gizmo_refresh_from_matrix(wmGizmoGroup *gzgroup,
|
|||
const float *z_axis = twmat[aidx_norm];
|
||||
WM_gizmo_set_matrix_rotation_from_yz_axis(axis, y_axis, z_axis);
|
||||
|
||||
if (scale) {
|
||||
if (axis_type == MAN_AXES_SCALE) {
|
||||
mul_v3_fl(axis->matrix_basis[0], scale[aidx_norm_x]);
|
||||
mul_v3_fl(axis->matrix_basis[1], scale[aidx_norm_y]);
|
||||
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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue