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:
Diffstat (limited to 'source/blender/editors/transform/transform_gizmo_3d.c')
-rw-r--r--source/blender/editors/transform/transform_gizmo_3d.c3969
1 files changed, 1989 insertions, 1980 deletions
diff --git a/source/blender/editors/transform/transform_gizmo_3d.c b/source/blender/editors/transform/transform_gizmo_3d.c
index 77480e1a8ce..1fde0006c2b 100644
--- a/source/blender/editors/transform/transform_gizmo_3d.c
+++ b/source/blender/editors/transform/transform_gizmo_3d.c
@@ -94,89 +94,89 @@
/* return codes for select, and drawing flags */
-#define MAN_TRANS_X (1 << 0)
-#define MAN_TRANS_Y (1 << 1)
-#define MAN_TRANS_Z (1 << 2)
-#define MAN_TRANS_C (MAN_TRANS_X | MAN_TRANS_Y | MAN_TRANS_Z)
+#define MAN_TRANS_X (1 << 0)
+#define MAN_TRANS_Y (1 << 1)
+#define MAN_TRANS_Z (1 << 2)
+#define MAN_TRANS_C (MAN_TRANS_X | MAN_TRANS_Y | MAN_TRANS_Z)
-#define MAN_ROT_X (1 << 3)
-#define MAN_ROT_Y (1 << 4)
-#define MAN_ROT_Z (1 << 5)
-#define MAN_ROT_C (MAN_ROT_X | MAN_ROT_Y | MAN_ROT_Z)
+#define MAN_ROT_X (1 << 3)
+#define MAN_ROT_Y (1 << 4)
+#define MAN_ROT_Z (1 << 5)
+#define MAN_ROT_C (MAN_ROT_X | MAN_ROT_Y | MAN_ROT_Z)
-#define MAN_SCALE_X (1 << 8)
-#define MAN_SCALE_Y (1 << 9)
-#define MAN_SCALE_Z (1 << 10)
-#define MAN_SCALE_C (MAN_SCALE_X | MAN_SCALE_Y | MAN_SCALE_Z)
+#define MAN_SCALE_X (1 << 8)
+#define MAN_SCALE_Y (1 << 9)
+#define MAN_SCALE_Z (1 << 10)
+#define MAN_SCALE_C (MAN_SCALE_X | MAN_SCALE_Y | MAN_SCALE_Z)
/* threshold for testing view aligned gizmo axis */
static struct {
- float min, max;
+ float min, max;
} g_tw_axis_range[2] = {
- /* Regular range */
- {0.02f, 0.1f},
- /* Use a different range because we flip the dot product,
- * also the view aligned planes are harder to see so hiding early is preferred. */
- {0.175f, 0.25f},
+ /* Regular range */
+ {0.02f, 0.1f},
+ /* Use a different range because we flip the dot product,
+ * also the view aligned planes are harder to see so hiding early is preferred. */
+ {0.175f, 0.25f},
};
/* axes as index */
enum {
- MAN_AXIS_TRANS_X = 0,
- MAN_AXIS_TRANS_Y,
- MAN_AXIS_TRANS_Z,
- MAN_AXIS_TRANS_C,
-
- MAN_AXIS_TRANS_XY,
- MAN_AXIS_TRANS_YZ,
- MAN_AXIS_TRANS_ZX,
+ MAN_AXIS_TRANS_X = 0,
+ MAN_AXIS_TRANS_Y,
+ MAN_AXIS_TRANS_Z,
+ MAN_AXIS_TRANS_C,
+
+ MAN_AXIS_TRANS_XY,
+ MAN_AXIS_TRANS_YZ,
+ MAN_AXIS_TRANS_ZX,
#define MAN_AXIS_RANGE_TRANS_START MAN_AXIS_TRANS_X
#define MAN_AXIS_RANGE_TRANS_END (MAN_AXIS_TRANS_ZX + 1)
- MAN_AXIS_ROT_X,
- MAN_AXIS_ROT_Y,
- MAN_AXIS_ROT_Z,
- MAN_AXIS_ROT_C,
- MAN_AXIS_ROT_T, /* trackball rotation */
+ MAN_AXIS_ROT_X,
+ MAN_AXIS_ROT_Y,
+ MAN_AXIS_ROT_Z,
+ MAN_AXIS_ROT_C,
+ MAN_AXIS_ROT_T, /* trackball rotation */
#define MAN_AXIS_RANGE_ROT_START MAN_AXIS_ROT_X
#define MAN_AXIS_RANGE_ROT_END (MAN_AXIS_ROT_T + 1)
- MAN_AXIS_SCALE_X,
- MAN_AXIS_SCALE_Y,
- MAN_AXIS_SCALE_Z,
- MAN_AXIS_SCALE_C,
- MAN_AXIS_SCALE_XY,
- MAN_AXIS_SCALE_YZ,
- MAN_AXIS_SCALE_ZX,
+ MAN_AXIS_SCALE_X,
+ MAN_AXIS_SCALE_Y,
+ MAN_AXIS_SCALE_Z,
+ MAN_AXIS_SCALE_C,
+ MAN_AXIS_SCALE_XY,
+ MAN_AXIS_SCALE_YZ,
+ MAN_AXIS_SCALE_ZX,
#define MAN_AXIS_RANGE_SCALE_START MAN_AXIS_SCALE_X
#define MAN_AXIS_RANGE_SCALE_END (MAN_AXIS_SCALE_ZX + 1)
- MAN_AXIS_LAST = MAN_AXIS_SCALE_ZX + 1,
+ MAN_AXIS_LAST = MAN_AXIS_SCALE_ZX + 1,
};
/* axis types */
enum {
- MAN_AXES_ALL = 0,
- MAN_AXES_TRANSLATE,
- MAN_AXES_ROTATE,
- MAN_AXES_SCALE,
+ MAN_AXES_ALL = 0,
+ MAN_AXES_TRANSLATE,
+ MAN_AXES_ROTATE,
+ MAN_AXES_SCALE,
};
typedef struct GizmoGroup {
- bool all_hidden;
- int twtype;
+ bool all_hidden;
+ int twtype;
- /* Users may change the twtype, detect changes to re-setup gizmo options. */
- int twtype_init;
- int twtype_prev;
- int use_twtype_refresh;
+ /* Users may change the twtype, detect changes to re-setup gizmo options. */
+ int twtype_init;
+ int twtype_prev;
+ int use_twtype_refresh;
- /* Only for view orientation. */
- struct {
- float viewinv_m3[3][3];
- } prev;
+ /* Only for view orientation. */
+ struct {
+ float viewinv_m3[3][3];
+ } prev;
- struct wmGizmo *gizmos[MAN_AXIS_LAST];
+ struct wmGizmo *gizmos[MAN_AXIS_LAST];
} GizmoGroup;
/* -------------------------------------------------------------------- */
@@ -185,991 +185,987 @@ typedef struct GizmoGroup {
/* loop over axes */
#define MAN_ITER_AXES_BEGIN(axis, axis_idx) \
- { \
- wmGizmo *axis; \
- int axis_idx; \
- for (axis_idx = 0; axis_idx < MAN_AXIS_LAST; axis_idx++) { \
- axis = gizmo_get_axis_from_index(ggd, axis_idx);
+ { \
+ wmGizmo *axis; \
+ int axis_idx; \
+ for (axis_idx = 0; axis_idx < MAN_AXIS_LAST; axis_idx++) { \
+ axis = gizmo_get_axis_from_index(ggd, axis_idx);
#define MAN_ITER_AXES_END \
- } \
- } ((void)0)
+ } \
+ } \
+ ((void)0)
static wmGizmo *gizmo_get_axis_from_index(const GizmoGroup *ggd, const short axis_idx)
{
- BLI_assert(IN_RANGE_INCL(axis_idx, (float)MAN_AXIS_TRANS_X, (float)MAN_AXIS_LAST));
- return ggd->gizmos[axis_idx];
+ BLI_assert(IN_RANGE_INCL(axis_idx, (float)MAN_AXIS_TRANS_X, (float)MAN_AXIS_LAST));
+ return ggd->gizmos[axis_idx];
}
static short gizmo_get_axis_type(const int axis_idx)
{
- if (axis_idx >= MAN_AXIS_RANGE_TRANS_START && axis_idx < MAN_AXIS_RANGE_TRANS_END) {
- return MAN_AXES_TRANSLATE;
- }
- if (axis_idx >= MAN_AXIS_RANGE_ROT_START && axis_idx < MAN_AXIS_RANGE_ROT_END) {
- return MAN_AXES_ROTATE;
- }
- if (axis_idx >= MAN_AXIS_RANGE_SCALE_START && axis_idx < MAN_AXIS_RANGE_SCALE_END) {
- return MAN_AXES_SCALE;
- }
- BLI_assert(0);
- return -1;
+ if (axis_idx >= MAN_AXIS_RANGE_TRANS_START && axis_idx < MAN_AXIS_RANGE_TRANS_END) {
+ return MAN_AXES_TRANSLATE;
+ }
+ if (axis_idx >= MAN_AXIS_RANGE_ROT_START && axis_idx < MAN_AXIS_RANGE_ROT_END) {
+ return MAN_AXES_ROTATE;
+ }
+ if (axis_idx >= MAN_AXIS_RANGE_SCALE_START && axis_idx < MAN_AXIS_RANGE_SCALE_END) {
+ return MAN_AXES_SCALE;
+ }
+ BLI_assert(0);
+ return -1;
}
static uint gizmo_orientation_axis(const int axis_idx, bool *r_is_plane)
{
- switch (axis_idx) {
- case MAN_AXIS_TRANS_YZ:
- case MAN_AXIS_SCALE_YZ:
- if (r_is_plane) {
- *r_is_plane = true;
- }
- ATTR_FALLTHROUGH;
- case MAN_AXIS_TRANS_X:
- case MAN_AXIS_ROT_X:
- case MAN_AXIS_SCALE_X:
- return 0;
-
- case MAN_AXIS_TRANS_ZX:
- case MAN_AXIS_SCALE_ZX:
- if (r_is_plane) {
- *r_is_plane = true;
- }
- ATTR_FALLTHROUGH;
- case MAN_AXIS_TRANS_Y:
- case MAN_AXIS_ROT_Y:
- case MAN_AXIS_SCALE_Y:
- return 1;
-
- case MAN_AXIS_TRANS_XY:
- case MAN_AXIS_SCALE_XY:
- if (r_is_plane) {
- *r_is_plane = true;
- }
- ATTR_FALLTHROUGH;
- case MAN_AXIS_TRANS_Z:
- case MAN_AXIS_ROT_Z:
- case MAN_AXIS_SCALE_Z:
- return 2;
- }
- return 3;
+ switch (axis_idx) {
+ case MAN_AXIS_TRANS_YZ:
+ case MAN_AXIS_SCALE_YZ:
+ if (r_is_plane) {
+ *r_is_plane = true;
+ }
+ ATTR_FALLTHROUGH;
+ case MAN_AXIS_TRANS_X:
+ case MAN_AXIS_ROT_X:
+ case MAN_AXIS_SCALE_X:
+ return 0;
+
+ case MAN_AXIS_TRANS_ZX:
+ case MAN_AXIS_SCALE_ZX:
+ if (r_is_plane) {
+ *r_is_plane = true;
+ }
+ ATTR_FALLTHROUGH;
+ case MAN_AXIS_TRANS_Y:
+ case MAN_AXIS_ROT_Y:
+ case MAN_AXIS_SCALE_Y:
+ return 1;
+
+ case MAN_AXIS_TRANS_XY:
+ case MAN_AXIS_SCALE_XY:
+ if (r_is_plane) {
+ *r_is_plane = true;
+ }
+ ATTR_FALLTHROUGH;
+ case MAN_AXIS_TRANS_Z:
+ case MAN_AXIS_ROT_Z:
+ case MAN_AXIS_SCALE_Z:
+ return 2;
+ }
+ return 3;
}
-static bool gizmo_is_axis_visible(
- const RegionView3D *rv3d, const int twtype,
- const float idot[3], const int axis_type, const int axis_idx)
+static bool gizmo_is_axis_visible(const RegionView3D *rv3d,
+ const int twtype,
+ const float idot[3],
+ const int axis_type,
+ const int axis_idx)
{
- if ((axis_idx >= MAN_AXIS_RANGE_ROT_START && axis_idx < MAN_AXIS_RANGE_ROT_END) == 0) {
- bool is_plane = false;
- const uint aidx_norm = gizmo_orientation_axis(axis_idx, &is_plane);
- /* don't draw axis perpendicular to the view */
- if (aidx_norm < 3) {
- float idot_axis = idot[aidx_norm];
- if (is_plane) {
- idot_axis = 1.0f - idot_axis;
- }
- if (idot_axis < g_tw_axis_range[is_plane].min) {
- return false;
- }
- }
- }
-
- if ((axis_type == MAN_AXES_TRANSLATE && !(twtype & V3D_GIZMO_SHOW_OBJECT_TRANSLATE)) ||
- (axis_type == MAN_AXES_ROTATE && !(twtype & V3D_GIZMO_SHOW_OBJECT_ROTATE)) ||
- (axis_type == MAN_AXES_SCALE && !(twtype & V3D_GIZMO_SHOW_OBJECT_SCALE)))
- {
- return false;
- }
-
- switch (axis_idx) {
- case MAN_AXIS_TRANS_X:
- return (rv3d->twdrawflag & MAN_TRANS_X);
- case MAN_AXIS_TRANS_Y:
- return (rv3d->twdrawflag & MAN_TRANS_Y);
- case MAN_AXIS_TRANS_Z:
- return (rv3d->twdrawflag & MAN_TRANS_Z);
- case MAN_AXIS_TRANS_C:
- return (rv3d->twdrawflag & MAN_TRANS_C);
- case MAN_AXIS_ROT_X:
- return (rv3d->twdrawflag & MAN_ROT_X);
- case MAN_AXIS_ROT_Y:
- return (rv3d->twdrawflag & MAN_ROT_Y);
- case MAN_AXIS_ROT_Z:
- return (rv3d->twdrawflag & MAN_ROT_Z);
- case MAN_AXIS_ROT_C:
- case MAN_AXIS_ROT_T:
- return (rv3d->twdrawflag & MAN_ROT_C);
- case MAN_AXIS_SCALE_X:
- return (rv3d->twdrawflag & MAN_SCALE_X);
- case MAN_AXIS_SCALE_Y:
- return (rv3d->twdrawflag & MAN_SCALE_Y);
- case MAN_AXIS_SCALE_Z:
- return (rv3d->twdrawflag & MAN_SCALE_Z);
- case MAN_AXIS_SCALE_C:
- return (rv3d->twdrawflag & MAN_SCALE_C && (twtype & V3D_GIZMO_SHOW_OBJECT_TRANSLATE) == 0);
- case MAN_AXIS_TRANS_XY:
- return (rv3d->twdrawflag & MAN_TRANS_X &&
- rv3d->twdrawflag & MAN_TRANS_Y &&
- (twtype & V3D_GIZMO_SHOW_OBJECT_ROTATE) == 0);
- case MAN_AXIS_TRANS_YZ:
- return (rv3d->twdrawflag & MAN_TRANS_Y &&
- rv3d->twdrawflag & MAN_TRANS_Z &&
- (twtype & V3D_GIZMO_SHOW_OBJECT_ROTATE) == 0);
- case MAN_AXIS_TRANS_ZX:
- return (rv3d->twdrawflag & MAN_TRANS_Z &&
- rv3d->twdrawflag & MAN_TRANS_X &&
- (twtype & V3D_GIZMO_SHOW_OBJECT_ROTATE) == 0);
- case MAN_AXIS_SCALE_XY:
- return (rv3d->twdrawflag & MAN_SCALE_X &&
- rv3d->twdrawflag & MAN_SCALE_Y &&
- (twtype & V3D_GIZMO_SHOW_OBJECT_TRANSLATE) == 0 &&
- (twtype & V3D_GIZMO_SHOW_OBJECT_ROTATE) == 0);
- case MAN_AXIS_SCALE_YZ:
- return (rv3d->twdrawflag & MAN_SCALE_Y &&
- rv3d->twdrawflag & MAN_SCALE_Z &&
- (twtype & V3D_GIZMO_SHOW_OBJECT_TRANSLATE) == 0 &&
- (twtype & V3D_GIZMO_SHOW_OBJECT_ROTATE) == 0);
- case MAN_AXIS_SCALE_ZX:
- return (rv3d->twdrawflag & MAN_SCALE_Z &&
- rv3d->twdrawflag & MAN_SCALE_X &&
- (twtype & V3D_GIZMO_SHOW_OBJECT_TRANSLATE) == 0 &&
- (twtype & V3D_GIZMO_SHOW_OBJECT_ROTATE) == 0);
- }
- return false;
+ if ((axis_idx >= MAN_AXIS_RANGE_ROT_START && axis_idx < MAN_AXIS_RANGE_ROT_END) == 0) {
+ bool is_plane = false;
+ const uint aidx_norm = gizmo_orientation_axis(axis_idx, &is_plane);
+ /* don't draw axis perpendicular to the view */
+ if (aidx_norm < 3) {
+ float idot_axis = idot[aidx_norm];
+ if (is_plane) {
+ idot_axis = 1.0f - idot_axis;
+ }
+ if (idot_axis < g_tw_axis_range[is_plane].min) {
+ return false;
+ }
+ }
+ }
+
+ if ((axis_type == MAN_AXES_TRANSLATE && !(twtype & V3D_GIZMO_SHOW_OBJECT_TRANSLATE)) ||
+ (axis_type == MAN_AXES_ROTATE && !(twtype & V3D_GIZMO_SHOW_OBJECT_ROTATE)) ||
+ (axis_type == MAN_AXES_SCALE && !(twtype & V3D_GIZMO_SHOW_OBJECT_SCALE))) {
+ return false;
+ }
+
+ switch (axis_idx) {
+ case MAN_AXIS_TRANS_X:
+ return (rv3d->twdrawflag & MAN_TRANS_X);
+ case MAN_AXIS_TRANS_Y:
+ return (rv3d->twdrawflag & MAN_TRANS_Y);
+ case MAN_AXIS_TRANS_Z:
+ return (rv3d->twdrawflag & MAN_TRANS_Z);
+ case MAN_AXIS_TRANS_C:
+ return (rv3d->twdrawflag & MAN_TRANS_C);
+ case MAN_AXIS_ROT_X:
+ return (rv3d->twdrawflag & MAN_ROT_X);
+ case MAN_AXIS_ROT_Y:
+ return (rv3d->twdrawflag & MAN_ROT_Y);
+ case MAN_AXIS_ROT_Z:
+ return (rv3d->twdrawflag & MAN_ROT_Z);
+ case MAN_AXIS_ROT_C:
+ case MAN_AXIS_ROT_T:
+ return (rv3d->twdrawflag & MAN_ROT_C);
+ case MAN_AXIS_SCALE_X:
+ return (rv3d->twdrawflag & MAN_SCALE_X);
+ case MAN_AXIS_SCALE_Y:
+ return (rv3d->twdrawflag & MAN_SCALE_Y);
+ case MAN_AXIS_SCALE_Z:
+ return (rv3d->twdrawflag & MAN_SCALE_Z);
+ case MAN_AXIS_SCALE_C:
+ return (rv3d->twdrawflag & MAN_SCALE_C && (twtype & V3D_GIZMO_SHOW_OBJECT_TRANSLATE) == 0);
+ case MAN_AXIS_TRANS_XY:
+ return (rv3d->twdrawflag & MAN_TRANS_X && rv3d->twdrawflag & MAN_TRANS_Y &&
+ (twtype & V3D_GIZMO_SHOW_OBJECT_ROTATE) == 0);
+ case MAN_AXIS_TRANS_YZ:
+ return (rv3d->twdrawflag & MAN_TRANS_Y && rv3d->twdrawflag & MAN_TRANS_Z &&
+ (twtype & V3D_GIZMO_SHOW_OBJECT_ROTATE) == 0);
+ case MAN_AXIS_TRANS_ZX:
+ return (rv3d->twdrawflag & MAN_TRANS_Z && rv3d->twdrawflag & MAN_TRANS_X &&
+ (twtype & V3D_GIZMO_SHOW_OBJECT_ROTATE) == 0);
+ case MAN_AXIS_SCALE_XY:
+ return (rv3d->twdrawflag & MAN_SCALE_X && rv3d->twdrawflag & MAN_SCALE_Y &&
+ (twtype & V3D_GIZMO_SHOW_OBJECT_TRANSLATE) == 0 &&
+ (twtype & V3D_GIZMO_SHOW_OBJECT_ROTATE) == 0);
+ case MAN_AXIS_SCALE_YZ:
+ return (rv3d->twdrawflag & MAN_SCALE_Y && rv3d->twdrawflag & MAN_SCALE_Z &&
+ (twtype & V3D_GIZMO_SHOW_OBJECT_TRANSLATE) == 0 &&
+ (twtype & V3D_GIZMO_SHOW_OBJECT_ROTATE) == 0);
+ case MAN_AXIS_SCALE_ZX:
+ return (rv3d->twdrawflag & MAN_SCALE_Z && rv3d->twdrawflag & MAN_SCALE_X &&
+ (twtype & V3D_GIZMO_SHOW_OBJECT_TRANSLATE) == 0 &&
+ (twtype & V3D_GIZMO_SHOW_OBJECT_ROTATE) == 0);
+ }
+ return false;
}
-static void gizmo_get_axis_color(
- const int axis_idx, const float idot[3],
- float r_col[4], float r_col_hi[4])
+static void gizmo_get_axis_color(const int axis_idx,
+ const float idot[3],
+ float r_col[4],
+ float r_col_hi[4])
{
- /* alpha values for normal/highlighted states */
- const float alpha = 0.6f;
- const float alpha_hi = 1.0f;
- float alpha_fac;
-
- if (axis_idx >= MAN_AXIS_RANGE_ROT_START && axis_idx < MAN_AXIS_RANGE_ROT_END) {
- /* Never fade rotation rings. */
- /* trackball rotation axis is a special case, we only draw a slight overlay */
- alpha_fac = (axis_idx == MAN_AXIS_ROT_T) ? 0.1f : 1.0f;
- }
- else {
- bool is_plane = false;
- const int axis_idx_norm = gizmo_orientation_axis(axis_idx, &is_plane);
- /* get alpha fac based on axis angle, to fade axis out when hiding it because it points towards view */
- if (axis_idx_norm < 3) {
- const float idot_min = g_tw_axis_range[is_plane].min;
- const float idot_max = g_tw_axis_range[is_plane].max;
- float idot_axis = idot[axis_idx_norm];
- if (is_plane) {
- idot_axis = 1.0f - idot_axis;
- }
- alpha_fac = (
- (idot_axis > idot_max) ?
- 1.0f : (idot_axis < idot_min) ?
- 0.0f : ((idot_axis - idot_min) / (idot_max - idot_min)));
- }
- else {
- alpha_fac = 1.0f;
- }
- }
-
- switch (axis_idx) {
- case MAN_AXIS_TRANS_X:
- case MAN_AXIS_ROT_X:
- case MAN_AXIS_SCALE_X:
- case MAN_AXIS_TRANS_YZ:
- case MAN_AXIS_SCALE_YZ:
- UI_GetThemeColor4fv(TH_AXIS_X, r_col);
- break;
- case MAN_AXIS_TRANS_Y:
- case MAN_AXIS_ROT_Y:
- case MAN_AXIS_SCALE_Y:
- case MAN_AXIS_TRANS_ZX:
- case MAN_AXIS_SCALE_ZX:
- UI_GetThemeColor4fv(TH_AXIS_Y, r_col);
- break;
- case MAN_AXIS_TRANS_Z:
- case MAN_AXIS_ROT_Z:
- case MAN_AXIS_SCALE_Z:
- case MAN_AXIS_TRANS_XY:
- case MAN_AXIS_SCALE_XY:
- UI_GetThemeColor4fv(TH_AXIS_Z, r_col);
- break;
- case MAN_AXIS_TRANS_C:
- case MAN_AXIS_ROT_C:
- case MAN_AXIS_SCALE_C:
- case MAN_AXIS_ROT_T:
- copy_v4_fl(r_col, 1.0f);
- break;
- }
-
- copy_v4_v4(r_col_hi, r_col);
-
- r_col[3] = alpha * alpha_fac;
- r_col_hi[3] = alpha_hi * alpha_fac;
+ /* alpha values for normal/highlighted states */
+ const float alpha = 0.6f;
+ const float alpha_hi = 1.0f;
+ float alpha_fac;
+
+ if (axis_idx >= MAN_AXIS_RANGE_ROT_START && axis_idx < MAN_AXIS_RANGE_ROT_END) {
+ /* Never fade rotation rings. */
+ /* trackball rotation axis is a special case, we only draw a slight overlay */
+ alpha_fac = (axis_idx == MAN_AXIS_ROT_T) ? 0.1f : 1.0f;
+ }
+ else {
+ bool is_plane = false;
+ const int axis_idx_norm = gizmo_orientation_axis(axis_idx, &is_plane);
+ /* get alpha fac based on axis angle, to fade axis out when hiding it because it points towards view */
+ if (axis_idx_norm < 3) {
+ const float idot_min = g_tw_axis_range[is_plane].min;
+ const float idot_max = g_tw_axis_range[is_plane].max;
+ float idot_axis = idot[axis_idx_norm];
+ if (is_plane) {
+ idot_axis = 1.0f - idot_axis;
+ }
+ alpha_fac = ((idot_axis > idot_max) ?
+ 1.0f :
+ (idot_axis < idot_min) ? 0.0f :
+ ((idot_axis - idot_min) / (idot_max - idot_min)));
+ }
+ else {
+ alpha_fac = 1.0f;
+ }
+ }
+
+ switch (axis_idx) {
+ case MAN_AXIS_TRANS_X:
+ case MAN_AXIS_ROT_X:
+ case MAN_AXIS_SCALE_X:
+ case MAN_AXIS_TRANS_YZ:
+ case MAN_AXIS_SCALE_YZ:
+ UI_GetThemeColor4fv(TH_AXIS_X, r_col);
+ break;
+ case MAN_AXIS_TRANS_Y:
+ case MAN_AXIS_ROT_Y:
+ case MAN_AXIS_SCALE_Y:
+ case MAN_AXIS_TRANS_ZX:
+ case MAN_AXIS_SCALE_ZX:
+ UI_GetThemeColor4fv(TH_AXIS_Y, r_col);
+ break;
+ case MAN_AXIS_TRANS_Z:
+ case MAN_AXIS_ROT_Z:
+ case MAN_AXIS_SCALE_Z:
+ case MAN_AXIS_TRANS_XY:
+ case MAN_AXIS_SCALE_XY:
+ UI_GetThemeColor4fv(TH_AXIS_Z, r_col);
+ break;
+ case MAN_AXIS_TRANS_C:
+ case MAN_AXIS_ROT_C:
+ case MAN_AXIS_SCALE_C:
+ case MAN_AXIS_ROT_T:
+ copy_v4_fl(r_col, 1.0f);
+ break;
+ }
+
+ copy_v4_v4(r_col_hi, r_col);
+
+ r_col[3] = alpha * alpha_fac;
+ r_col_hi[3] = alpha_hi * alpha_fac;
}
static void gizmo_get_axis_constraint(const int axis_idx, bool r_axis[3])
{
- ARRAY_SET_ITEMS(r_axis, 0, 0, 0);
-
- switch (axis_idx) {
- case MAN_AXIS_TRANS_X:
- case MAN_AXIS_ROT_X:
- case MAN_AXIS_SCALE_X:
- r_axis[0] = 1;
- break;
- case MAN_AXIS_TRANS_Y:
- case MAN_AXIS_ROT_Y:
- case MAN_AXIS_SCALE_Y:
- r_axis[1] = 1;
- break;
- case MAN_AXIS_TRANS_Z:
- case MAN_AXIS_ROT_Z:
- case MAN_AXIS_SCALE_Z:
- r_axis[2] = 1;
- break;
- case MAN_AXIS_TRANS_XY:
- case MAN_AXIS_SCALE_XY:
- r_axis[0] = r_axis[1] = 1;
- break;
- case MAN_AXIS_TRANS_YZ:
- case MAN_AXIS_SCALE_YZ:
- r_axis[1] = r_axis[2] = 1;
- break;
- case MAN_AXIS_TRANS_ZX:
- case MAN_AXIS_SCALE_ZX:
- r_axis[2] = r_axis[0] = 1;
- break;
- default:
- break;
- }
+ ARRAY_SET_ITEMS(r_axis, 0, 0, 0);
+
+ switch (axis_idx) {
+ case MAN_AXIS_TRANS_X:
+ case MAN_AXIS_ROT_X:
+ case MAN_AXIS_SCALE_X:
+ r_axis[0] = 1;
+ break;
+ case MAN_AXIS_TRANS_Y:
+ case MAN_AXIS_ROT_Y:
+ case MAN_AXIS_SCALE_Y:
+ r_axis[1] = 1;
+ break;
+ case MAN_AXIS_TRANS_Z:
+ case MAN_AXIS_ROT_Z:
+ case MAN_AXIS_SCALE_Z:
+ r_axis[2] = 1;
+ break;
+ case MAN_AXIS_TRANS_XY:
+ case MAN_AXIS_SCALE_XY:
+ r_axis[0] = r_axis[1] = 1;
+ break;
+ case MAN_AXIS_TRANS_YZ:
+ case MAN_AXIS_SCALE_YZ:
+ r_axis[1] = r_axis[2] = 1;
+ break;
+ case MAN_AXIS_TRANS_ZX:
+ case MAN_AXIS_SCALE_ZX:
+ r_axis[2] = r_axis[0] = 1;
+ break;
+ default:
+ break;
+ }
}
-
/* **************** Preparation Stuff **************** */
static void reset_tw_center(struct TransformBounds *tbounds)
{
- INIT_MINMAX(tbounds->min, tbounds->max);
- zero_v3(tbounds->center);
+ INIT_MINMAX(tbounds->min, tbounds->max);
+ zero_v3(tbounds->center);
- for (int i = 0; i < 3; i++) {
- tbounds->axis_min[i] = +FLT_MAX;
- tbounds->axis_max[i] = -FLT_MAX;
- }
+ for (int i = 0; i < 3; i++) {
+ tbounds->axis_min[i] = +FLT_MAX;
+ tbounds->axis_max[i] = -FLT_MAX;
+ }
}
/* transform widget center calc helper for below */
static void calc_tw_center(struct TransformBounds *tbounds, const float co[3])
{
- minmax_v3v3_v3(tbounds->min, tbounds->max, co);
- add_v3_v3(tbounds->center, co);
-
- for (int i = 0; i < 3; i++) {
- const float d = dot_v3v3(tbounds->axis[i], co);
- tbounds->axis_min[i] = min_ff(d, tbounds->axis_min[i]);
- tbounds->axis_max[i] = max_ff(d, tbounds->axis_max[i]);
- }
+ minmax_v3v3_v3(tbounds->min, tbounds->max, co);
+ add_v3_v3(tbounds->center, co);
+
+ for (int i = 0; i < 3; i++) {
+ const float d = dot_v3v3(tbounds->axis[i], co);
+ tbounds->axis_min[i] = min_ff(d, tbounds->axis_min[i]);
+ tbounds->axis_max[i] = max_ff(d, tbounds->axis_max[i]);
+ }
}
-static void calc_tw_center_with_matrix(
- struct TransformBounds *tbounds, const float co[3],
- const bool use_matrix, const float matrix[4][4])
+static void calc_tw_center_with_matrix(struct TransformBounds *tbounds,
+ const float co[3],
+ const bool use_matrix,
+ const float matrix[4][4])
{
- float co_world[3];
- if (use_matrix) {
- mul_v3_m4v3(co_world, matrix, co);
- co = co_world;
- }
- calc_tw_center(tbounds, co);
+ float co_world[3];
+ if (use_matrix) {
+ mul_v3_m4v3(co_world, matrix, co);
+ co = co_world;
+ }
+ calc_tw_center(tbounds, co);
}
static void protectflag_to_drawflags(short protectflag, short *drawflags)
{
- if (protectflag & OB_LOCK_LOCX)
- *drawflags &= ~MAN_TRANS_X;
- if (protectflag & OB_LOCK_LOCY)
- *drawflags &= ~MAN_TRANS_Y;
- if (protectflag & OB_LOCK_LOCZ)
- *drawflags &= ~MAN_TRANS_Z;
-
- if (protectflag & OB_LOCK_ROTX)
- *drawflags &= ~MAN_ROT_X;
- if (protectflag & OB_LOCK_ROTY)
- *drawflags &= ~MAN_ROT_Y;
- if (protectflag & OB_LOCK_ROTZ)
- *drawflags &= ~MAN_ROT_Z;
-
- if (protectflag & OB_LOCK_SCALEX)
- *drawflags &= ~MAN_SCALE_X;
- if (protectflag & OB_LOCK_SCALEY)
- *drawflags &= ~MAN_SCALE_Y;
- if (protectflag & OB_LOCK_SCALEZ)
- *drawflags &= ~MAN_SCALE_Z;
+ if (protectflag & OB_LOCK_LOCX)
+ *drawflags &= ~MAN_TRANS_X;
+ if (protectflag & OB_LOCK_LOCY)
+ *drawflags &= ~MAN_TRANS_Y;
+ if (protectflag & OB_LOCK_LOCZ)
+ *drawflags &= ~MAN_TRANS_Z;
+
+ if (protectflag & OB_LOCK_ROTX)
+ *drawflags &= ~MAN_ROT_X;
+ if (protectflag & OB_LOCK_ROTY)
+ *drawflags &= ~MAN_ROT_Y;
+ if (protectflag & OB_LOCK_ROTZ)
+ *drawflags &= ~MAN_ROT_Z;
+
+ if (protectflag & OB_LOCK_SCALEX)
+ *drawflags &= ~MAN_SCALE_X;
+ if (protectflag & OB_LOCK_SCALEY)
+ *drawflags &= ~MAN_SCALE_Y;
+ if (protectflag & OB_LOCK_SCALEZ)
+ *drawflags &= ~MAN_SCALE_Z;
}
/* for pose mode */
static void protectflag_to_drawflags_pchan(RegionView3D *rv3d, const bPoseChannel *pchan)
{
- protectflag_to_drawflags(pchan->protectflag, &rv3d->twdrawflag);
+ protectflag_to_drawflags(pchan->protectflag, &rv3d->twdrawflag);
}
/* for editmode*/
static void protectflag_to_drawflags_ebone(RegionView3D *rv3d, const EditBone *ebo)
{
- if (ebo->flag & BONE_EDITMODE_LOCKED) {
- protectflag_to_drawflags(OB_LOCK_LOC | OB_LOCK_ROT | OB_LOCK_SCALE, &rv3d->twdrawflag);
- }
+ if (ebo->flag & BONE_EDITMODE_LOCKED) {
+ protectflag_to_drawflags(OB_LOCK_LOC | OB_LOCK_ROT | OB_LOCK_SCALE, &rv3d->twdrawflag);
+ }
}
/* could move into BLI_math however this is only useful for display/editing purposes */
static void axis_angle_to_gimbal_axis(float gmat[3][3], const float axis[3], const float angle)
{
- /* X/Y are arbitrary axies, most importantly Z is the axis of rotation */
+ /* X/Y are arbitrary axies, most importantly Z is the axis of rotation */
- float cross_vec[3];
- float quat[4];
+ float cross_vec[3];
+ float quat[4];
- /* this is an un-scientific method to get a vector to cross with
- * XYZ intentionally YZX */
- cross_vec[0] = axis[1];
- cross_vec[1] = axis[2];
- cross_vec[2] = axis[0];
+ /* this is an un-scientific method to get a vector to cross with
+ * XYZ intentionally YZX */
+ cross_vec[0] = axis[1];
+ cross_vec[1] = axis[2];
+ cross_vec[2] = axis[0];
- /* X-axis */
- cross_v3_v3v3(gmat[0], cross_vec, axis);
- normalize_v3(gmat[0]);
- axis_angle_to_quat(quat, axis, angle);
- mul_qt_v3(quat, gmat[0]);
+ /* X-axis */
+ cross_v3_v3v3(gmat[0], cross_vec, axis);
+ normalize_v3(gmat[0]);
+ axis_angle_to_quat(quat, axis, angle);
+ mul_qt_v3(quat, gmat[0]);
- /* Y-axis */
- axis_angle_to_quat(quat, axis, M_PI_2);
- copy_v3_v3(gmat[1], gmat[0]);
- mul_qt_v3(quat, gmat[1]);
+ /* Y-axis */
+ axis_angle_to_quat(quat, axis, M_PI_2);
+ copy_v3_v3(gmat[1], gmat[0]);
+ mul_qt_v3(quat, gmat[1]);
- /* Z-axis */
- copy_v3_v3(gmat[2], axis);
+ /* Z-axis */
+ copy_v3_v3(gmat[2], axis);
- normalize_m3(gmat);
+ normalize_m3(gmat);
}
-
static bool test_rotmode_euler(short rotmode)
{
- return (ELEM(rotmode, ROT_MODE_AXISANGLE, ROT_MODE_QUAT)) ? 0 : 1;
+ return (ELEM(rotmode, ROT_MODE_AXISANGLE, ROT_MODE_QUAT)) ? 0 : 1;
}
bool gimbal_axis(Object *ob, float gmat[3][3])
{
- if (ob->mode & OB_MODE_POSE) {
- bPoseChannel *pchan = BKE_pose_channel_active(ob);
-
- if (pchan) {
- float mat[3][3], tmat[3][3], obmat[3][3];
- if (test_rotmode_euler(pchan->rotmode)) {
- eulO_to_gimbal_axis(mat, pchan->eul, pchan->rotmode);
- }
- else if (pchan->rotmode == ROT_MODE_AXISANGLE) {
- axis_angle_to_gimbal_axis(mat, pchan->rotAxis, pchan->rotAngle);
- }
- else { /* quat */
- return 0;
- }
-
-
- /* apply bone transformation */
- mul_m3_m3m3(tmat, pchan->bone->bone_mat, mat);
-
- if (pchan->parent) {
- float parent_mat[3][3];
-
- copy_m3_m4(parent_mat, pchan->parent->pose_mat);
- mul_m3_m3m3(mat, parent_mat, tmat);
-
- /* needed if object transformation isn't identity */
- copy_m3_m4(obmat, ob->obmat);
- mul_m3_m3m3(gmat, obmat, mat);
- }
- else {
- /* needed if object transformation isn't identity */
- copy_m3_m4(obmat, ob->obmat);
- mul_m3_m3m3(gmat, obmat, tmat);
- }
-
- normalize_m3(gmat);
- return 1;
- }
- }
- else {
- if (test_rotmode_euler(ob->rotmode)) {
- eulO_to_gimbal_axis(gmat, ob->rot, ob->rotmode);
- }
- else if (ob->rotmode == ROT_MODE_AXISANGLE) {
- axis_angle_to_gimbal_axis(gmat, ob->rotAxis, ob->rotAngle);
- }
- else { /* quat */
- return 0;
- }
-
- if (ob->parent) {
- float parent_mat[3][3];
- copy_m3_m4(parent_mat, ob->parent->obmat);
- normalize_m3(parent_mat);
- mul_m3_m3m3(gmat, parent_mat, gmat);
- }
- return 1;
- }
-
- return 0;
+ if (ob->mode & OB_MODE_POSE) {
+ bPoseChannel *pchan = BKE_pose_channel_active(ob);
+
+ if (pchan) {
+ float mat[3][3], tmat[3][3], obmat[3][3];
+ if (test_rotmode_euler(pchan->rotmode)) {
+ eulO_to_gimbal_axis(mat, pchan->eul, pchan->rotmode);
+ }
+ else if (pchan->rotmode == ROT_MODE_AXISANGLE) {
+ axis_angle_to_gimbal_axis(mat, pchan->rotAxis, pchan->rotAngle);
+ }
+ else { /* quat */
+ return 0;
+ }
+
+ /* apply bone transformation */
+ mul_m3_m3m3(tmat, pchan->bone->bone_mat, mat);
+
+ if (pchan->parent) {
+ float parent_mat[3][3];
+
+ copy_m3_m4(parent_mat, pchan->parent->pose_mat);
+ mul_m3_m3m3(mat, parent_mat, tmat);
+
+ /* needed if object transformation isn't identity */
+ copy_m3_m4(obmat, ob->obmat);
+ mul_m3_m3m3(gmat, obmat, mat);
+ }
+ else {
+ /* needed if object transformation isn't identity */
+ copy_m3_m4(obmat, ob->obmat);
+ mul_m3_m3m3(gmat, obmat, tmat);
+ }
+
+ normalize_m3(gmat);
+ return 1;
+ }
+ }
+ else {
+ if (test_rotmode_euler(ob->rotmode)) {
+ eulO_to_gimbal_axis(gmat, ob->rot, ob->rotmode);
+ }
+ else if (ob->rotmode == ROT_MODE_AXISANGLE) {
+ axis_angle_to_gimbal_axis(gmat, ob->rotAxis, ob->rotAngle);
+ }
+ else { /* quat */
+ return 0;
+ }
+
+ if (ob->parent) {
+ float parent_mat[3][3];
+ copy_m3_m4(parent_mat, ob->parent->obmat);
+ normalize_m3(parent_mat);
+ mul_m3_m3m3(gmat, parent_mat, gmat);
+ }
+ return 1;
+ }
+
+ return 0;
}
-void ED_transform_calc_orientation_from_type(
- const bContext *C, float r_mat[3][3])
+void ED_transform_calc_orientation_from_type(const bContext *C, float r_mat[3][3])
{
- ARegion *ar = CTX_wm_region(C);
- Scene *scene = CTX_data_scene(C);
- ViewLayer *view_layer = CTX_data_view_layer(C);
- Object *obedit = CTX_data_edit_object(C);
- RegionView3D *rv3d = ar->regiondata;
- Object *ob = OBACT(view_layer);
- const short orientation_type = scene->orientation_slots[SCE_ORIENT_DEFAULT].type;
- const short orientation_index_custom = scene->orientation_slots[SCE_ORIENT_DEFAULT].index_custom;
- const int pivot_point = scene->toolsettings->transform_pivot_point;
-
- ED_transform_calc_orientation_from_type_ex(
- C, r_mat,
- scene, rv3d, ob, obedit, orientation_type, orientation_index_custom, pivot_point);
+ ARegion *ar = CTX_wm_region(C);
+ Scene *scene = CTX_data_scene(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ Object *obedit = CTX_data_edit_object(C);
+ RegionView3D *rv3d = ar->regiondata;
+ Object *ob = OBACT(view_layer);
+ const short orientation_type = scene->orientation_slots[SCE_ORIENT_DEFAULT].type;
+ const short orientation_index_custom = scene->orientation_slots[SCE_ORIENT_DEFAULT].index_custom;
+ const int pivot_point = scene->toolsettings->transform_pivot_point;
+
+ ED_transform_calc_orientation_from_type_ex(
+ C, r_mat, scene, rv3d, ob, obedit, orientation_type, orientation_index_custom, pivot_point);
}
-void ED_transform_calc_orientation_from_type_ex(
- const bContext *C, float r_mat[3][3],
- /* extra args (can be accessed from context) */
- Scene *scene, RegionView3D *rv3d, Object *ob, Object *obedit,
- const short orientation_type, int orientation_index_custom,
- const int pivot_point)
+void ED_transform_calc_orientation_from_type_ex(const bContext *C,
+ float r_mat[3][3],
+ /* extra args (can be accessed from context) */
+ Scene *scene,
+ RegionView3D *rv3d,
+ Object *ob,
+ Object *obedit,
+ const short orientation_type,
+ int orientation_index_custom,
+ const int pivot_point)
{
- bool ok = false;
-
- switch (orientation_type) {
- case V3D_ORIENT_GLOBAL:
- {
- break; /* nothing to do */
- }
- case V3D_ORIENT_GIMBAL:
- {
- if (gimbal_axis(ob, r_mat)) {
- ok = true;
- break;
- }
- /* if not gimbal, fall through to normal */
- ATTR_FALLTHROUGH;
- }
- case V3D_ORIENT_NORMAL:
- {
- if (obedit || ob->mode & OB_MODE_POSE) {
- ED_getTransformOrientationMatrix(C, r_mat, pivot_point);
- ok = true;
- break;
- }
- /* no break we define 'normal' as 'local' in Object mode */
- ATTR_FALLTHROUGH;
- }
- case V3D_ORIENT_LOCAL:
- {
- if (ob->mode & OB_MODE_POSE) {
- /* each bone moves on its own local axis, but to avoid confusion,
- * use the active pones axis for display [#33575], this works as expected on a single bone
- * and users who select many bones will understand what's going on and what local means
- * when they start transforming */
- ED_getTransformOrientationMatrix(C, r_mat, pivot_point);
- ok = true;
- break;
- }
- copy_m3_m4(r_mat, ob->obmat);
- normalize_m3(r_mat);
- ok = true;
- break;
- }
- case V3D_ORIENT_VIEW:
- {
- if (rv3d != NULL) {
- copy_m3_m4(r_mat, rv3d->viewinv);
- normalize_m3(r_mat);
- ok = true;
- }
- break;
- }
- case V3D_ORIENT_CURSOR:
- {
- ED_view3d_cursor3d_calc_mat3(scene, r_mat);
- ok = true;
- break;
- }
- case V3D_ORIENT_CUSTOM:
- {
- TransformOrientation *custom_orientation = BKE_scene_transform_orientation_find(
- scene, orientation_index_custom);
- if (applyTransformOrientation(custom_orientation, r_mat, NULL)) {
- ok = true;
- }
- break;
- }
- }
-
- if (!ok) {
- unit_m3(r_mat);
- }
+ bool ok = false;
+
+ switch (orientation_type) {
+ case V3D_ORIENT_GLOBAL: {
+ break; /* nothing to do */
+ }
+ case V3D_ORIENT_GIMBAL: {
+ if (gimbal_axis(ob, r_mat)) {
+ ok = true;
+ break;
+ }
+ /* if not gimbal, fall through to normal */
+ ATTR_FALLTHROUGH;
+ }
+ case V3D_ORIENT_NORMAL: {
+ if (obedit || ob->mode & OB_MODE_POSE) {
+ ED_getTransformOrientationMatrix(C, r_mat, pivot_point);
+ ok = true;
+ break;
+ }
+ /* no break we define 'normal' as 'local' in Object mode */
+ ATTR_FALLTHROUGH;
+ }
+ case V3D_ORIENT_LOCAL: {
+ if (ob->mode & OB_MODE_POSE) {
+ /* each bone moves on its own local axis, but to avoid confusion,
+ * use the active pones axis for display [#33575], this works as expected on a single bone
+ * and users who select many bones will understand what's going on and what local means
+ * when they start transforming */
+ ED_getTransformOrientationMatrix(C, r_mat, pivot_point);
+ ok = true;
+ break;
+ }
+ copy_m3_m4(r_mat, ob->obmat);
+ normalize_m3(r_mat);
+ ok = true;
+ break;
+ }
+ case V3D_ORIENT_VIEW: {
+ if (rv3d != NULL) {
+ copy_m3_m4(r_mat, rv3d->viewinv);
+ normalize_m3(r_mat);
+ ok = true;
+ }
+ break;
+ }
+ case V3D_ORIENT_CURSOR: {
+ ED_view3d_cursor3d_calc_mat3(scene, r_mat);
+ ok = true;
+ break;
+ }
+ case V3D_ORIENT_CUSTOM: {
+ TransformOrientation *custom_orientation = BKE_scene_transform_orientation_find(
+ scene, orientation_index_custom);
+ if (applyTransformOrientation(custom_orientation, r_mat, NULL)) {
+ ok = true;
+ }
+ break;
+ }
+ }
+
+ if (!ok) {
+ unit_m3(r_mat);
+ }
}
/* centroid, boundbox, of selection */
/* returns total items selected */
-int ED_transform_calc_gizmo_stats(
- const bContext *C,
- const struct TransformCalcParams *params,
- struct TransformBounds *tbounds)
+int ED_transform_calc_gizmo_stats(const bContext *C,
+ const struct TransformCalcParams *params,
+ struct TransformBounds *tbounds)
{
- ScrArea *sa = CTX_wm_area(C);
- ARegion *ar = CTX_wm_region(C);
- Scene *scene = CTX_data_scene(C);
- Depsgraph *depsgraph = CTX_data_depsgraph(C);
- ViewLayer *view_layer = CTX_data_view_layer(C);
- View3D *v3d = sa->spacedata.first;
- Object *obedit = CTX_data_edit_object(C);
- RegionView3D *rv3d = ar->regiondata;
- Base *base;
- Object *ob = OBACT(view_layer);
- bGPdata *gpd = CTX_data_gpencil_data(C);
- const bool is_gp_edit = GPENCIL_ANY_MODE(gpd);
- int a, totsel = 0;
- const int pivot_point = scene->toolsettings->transform_pivot_point;
-
- /* transform widget matrix */
- unit_m4(rv3d->twmat);
-
- unit_m3(rv3d->tw_axis_matrix);
- zero_v3(rv3d->tw_axis_min);
- zero_v3(rv3d->tw_axis_max);
-
- rv3d->twdrawflag = 0xFFFF;
-
- /* global, local or normal orientation?
- * if we could check 'totsel' now, this should be skipped with no selection. */
- if (ob) {
- const short orientation_type = params->orientation_type ?
- (params->orientation_type - 1) : scene->orientation_slots[SCE_ORIENT_DEFAULT].type;
- const short orientation_index_custom = params->orientation_type ?
- params->orientation_index_custom : scene->orientation_slots[SCE_ORIENT_DEFAULT].index_custom;
- float mat[3][3];
- ED_transform_calc_orientation_from_type_ex(
- C, mat,
- scene, rv3d, ob, obedit, orientation_type, orientation_index_custom, pivot_point);
- copy_m4_m3(rv3d->twmat, mat);
- }
-
- /* transform widget centroid/center */
- reset_tw_center(tbounds);
-
- copy_m3_m4(tbounds->axis, rv3d->twmat);
- if (params->use_local_axis && (ob && ob->mode & OB_MODE_EDIT)) {
- float diff_mat[3][3];
- copy_m3_m4(diff_mat, ob->obmat);
- normalize_m3(diff_mat);
- invert_m3(diff_mat);
- mul_m3_m3m3(tbounds->axis, tbounds->axis, diff_mat);
- normalize_m3(tbounds->axis);
- }
-
- if (is_gp_edit) {
- float diff_mat[4][4];
- const bool use_mat_local = true;
- for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
- /* only editable and visible layers are considered */
-
- if (gpencil_layer_is_editable(gpl) && (gpl->actframe != NULL)) {
-
- /* calculate difference matrix */
- ED_gpencil_parent_location(depsgraph, ob, gpd, gpl, diff_mat);
-
- for (bGPDstroke *gps = gpl->actframe->strokes.first; gps; gps = gps->next) {
- /* skip strokes that are invalid for current view */
- if (ED_gpencil_stroke_can_use(C, gps) == false) {
- continue;
- }
-
- /* we're only interested in selected points here... */
- if (gps->flag & GP_STROKE_SELECT) {
- bGPDspoint *pt;
- int i;
-
- /* Change selection status of all points, then make the stroke match */
- for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
- if (pt->flag & GP_SPOINT_SELECT) {
- calc_tw_center_with_matrix(tbounds, &pt->x, use_mat_local, diff_mat);
- totsel++;
- }
- }
- }
- }
- }
- }
-
-
- /* selection center */
- if (totsel) {
- mul_v3_fl(tbounds->center, 1.0f / (float)totsel); /* centroid! */
- }
- }
- else if (obedit) {
+ ScrArea *sa = CTX_wm_area(C);
+ ARegion *ar = CTX_wm_region(C);
+ Scene *scene = CTX_data_scene(C);
+ Depsgraph *depsgraph = CTX_data_depsgraph(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ View3D *v3d = sa->spacedata.first;
+ Object *obedit = CTX_data_edit_object(C);
+ RegionView3D *rv3d = ar->regiondata;
+ Base *base;
+ Object *ob = OBACT(view_layer);
+ bGPdata *gpd = CTX_data_gpencil_data(C);
+ const bool is_gp_edit = GPENCIL_ANY_MODE(gpd);
+ int a, totsel = 0;
+ const int pivot_point = scene->toolsettings->transform_pivot_point;
+
+ /* transform widget matrix */
+ unit_m4(rv3d->twmat);
+
+ unit_m3(rv3d->tw_axis_matrix);
+ zero_v3(rv3d->tw_axis_min);
+ zero_v3(rv3d->tw_axis_max);
+
+ rv3d->twdrawflag = 0xFFFF;
+
+ /* global, local or normal orientation?
+ * if we could check 'totsel' now, this should be skipped with no selection. */
+ if (ob) {
+ const short orientation_type = params->orientation_type ?
+ (params->orientation_type - 1) :
+ scene->orientation_slots[SCE_ORIENT_DEFAULT].type;
+ const short orientation_index_custom =
+ params->orientation_type ? params->orientation_index_custom :
+ scene->orientation_slots[SCE_ORIENT_DEFAULT].index_custom;
+ float mat[3][3];
+ ED_transform_calc_orientation_from_type_ex(
+ C, mat, scene, rv3d, ob, obedit, orientation_type, orientation_index_custom, pivot_point);
+ copy_m4_m3(rv3d->twmat, mat);
+ }
+
+ /* transform widget centroid/center */
+ reset_tw_center(tbounds);
+
+ copy_m3_m4(tbounds->axis, rv3d->twmat);
+ if (params->use_local_axis && (ob && ob->mode & OB_MODE_EDIT)) {
+ float diff_mat[3][3];
+ copy_m3_m4(diff_mat, ob->obmat);
+ normalize_m3(diff_mat);
+ invert_m3(diff_mat);
+ mul_m3_m3m3(tbounds->axis, tbounds->axis, diff_mat);
+ normalize_m3(tbounds->axis);
+ }
+
+ if (is_gp_edit) {
+ float diff_mat[4][4];
+ const bool use_mat_local = true;
+ for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
+ /* only editable and visible layers are considered */
+
+ if (gpencil_layer_is_editable(gpl) && (gpl->actframe != NULL)) {
+
+ /* calculate difference matrix */
+ ED_gpencil_parent_location(depsgraph, ob, gpd, gpl, diff_mat);
+
+ for (bGPDstroke *gps = gpl->actframe->strokes.first; gps; gps = gps->next) {
+ /* skip strokes that are invalid for current view */
+ if (ED_gpencil_stroke_can_use(C, gps) == false) {
+ continue;
+ }
+
+ /* we're only interested in selected points here... */
+ if (gps->flag & GP_STROKE_SELECT) {
+ bGPDspoint *pt;
+ int i;
+
+ /* Change selection status of all points, then make the stroke match */
+ for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
+ if (pt->flag & GP_SPOINT_SELECT) {
+ calc_tw_center_with_matrix(tbounds, &pt->x, use_mat_local, diff_mat);
+ totsel++;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /* selection center */
+ if (totsel) {
+ mul_v3_fl(tbounds->center, 1.0f / (float)totsel); /* centroid! */
+ }
+ }
+ else if (obedit) {
#define FOREACH_EDIT_OBJECT_BEGIN(ob_iter, use_mat_local) \
- { \
- invert_m4_m4(obedit->imat, obedit->obmat); \
- uint objects_len = 0; \
- Object **objects = BKE_view_layer_array_from_objects_in_edit_mode(view_layer, CTX_wm_view3d(C), &objects_len); \
- for (uint ob_index = 0; ob_index < objects_len; ob_index++) { \
- Object *ob_iter = objects[ob_index]; \
- const bool use_mat_local = (ob_iter != obedit);
+ { \
+ invert_m4_m4(obedit->imat, obedit->obmat); \
+ uint objects_len = 0; \
+ Object **objects = BKE_view_layer_array_from_objects_in_edit_mode( \
+ view_layer, CTX_wm_view3d(C), &objects_len); \
+ for (uint ob_index = 0; ob_index < objects_len; ob_index++) { \
+ Object *ob_iter = objects[ob_index]; \
+ const bool use_mat_local = (ob_iter != obedit);
#define FOREACH_EDIT_OBJECT_END() \
- } \
- MEM_freeN(objects); \
- } ((void)0)
-
- ob = obedit;
- if (obedit->type == OB_MESH) {
- FOREACH_EDIT_OBJECT_BEGIN(ob_iter, use_mat_local) {
- BMEditMesh *em_iter = BKE_editmesh_from_object(ob_iter);
- BMesh *bm = em_iter->bm;
-
- if (bm->totvertsel == 0) {
- continue;
- }
-
- BMVert *eve;
- BMIter iter;
-
- float mat_local[4][4];
- if (use_mat_local) {
- mul_m4_m4m4(mat_local, obedit->imat, ob_iter->obmat);
- }
-
- BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
- if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
- if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
- calc_tw_center_with_matrix(tbounds, eve->co, use_mat_local, mat_local);
- totsel++;
- }
- }
- }
- } FOREACH_EDIT_OBJECT_END();
- } /* end editmesh */
- else if (obedit->type == OB_ARMATURE) {
- FOREACH_EDIT_OBJECT_BEGIN(ob_iter, use_mat_local) {
- bArmature *arm = ob_iter->data;
-
- float mat_local[4][4];
- if (use_mat_local) {
- mul_m4_m4m4(mat_local, obedit->imat, ob_iter->obmat);
- }
- for (EditBone *ebo = arm->edbo->first; ebo; ebo = ebo->next) {
- if (EBONE_VISIBLE(arm, ebo)) {
- if (ebo->flag & BONE_TIPSEL) {
- calc_tw_center_with_matrix(tbounds, ebo->tail, use_mat_local, mat_local);
- totsel++;
- }
- if ((ebo->flag & BONE_ROOTSEL) &&
- /* don't include same point multiple times */
- ((ebo->flag & BONE_CONNECTED) &&
- (ebo->parent != NULL) &&
- (ebo->parent->flag & BONE_TIPSEL) &&
- EBONE_VISIBLE(arm, ebo->parent)) == 0)
- {
- calc_tw_center_with_matrix(tbounds, ebo->head, use_mat_local, mat_local);
- totsel++;
- }
- if (ebo->flag & BONE_SELECTED) {
- protectflag_to_drawflags_ebone(rv3d, ebo);
- }
- }
- }
- } FOREACH_EDIT_OBJECT_END();
- }
- else if (ELEM(obedit->type, OB_CURVE, OB_SURF)) {
- FOREACH_EDIT_OBJECT_BEGIN(ob_iter, use_mat_local) {
- Curve *cu = ob_iter->data;
- Nurb *nu;
- BezTriple *bezt;
- BPoint *bp;
- ListBase *nurbs = BKE_curve_editNurbs_get(cu);
-
- float mat_local[4][4];
- if (use_mat_local) {
- mul_m4_m4m4(mat_local, obedit->imat, ob_iter->obmat);
- }
-
- nu = nurbs->first;
- while (nu) {
- if (nu->type == CU_BEZIER) {
- bezt = nu->bezt;
- a = nu->pntsu;
- while (a--) {
- /* exceptions
- * if handles are hidden then only check the center points.
- * If the center knot is selected then only use this as the center point.
- */
- if ((v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_CU_HANDLES) == 0) {
- if (bezt->f2 & SELECT) {
- calc_tw_center_with_matrix(tbounds, bezt->vec[1], use_mat_local, mat_local);
- totsel++;
- }
- }
- else if (bezt->f2 & SELECT) {
- calc_tw_center_with_matrix(tbounds, bezt->vec[1], use_mat_local, mat_local);
- totsel++;
- }
- else {
- if (bezt->f1 & SELECT) {
- const float *co = bezt->vec[(pivot_point == V3D_AROUND_LOCAL_ORIGINS) ? 1 : 0];
- calc_tw_center_with_matrix(tbounds, co, use_mat_local, mat_local);
- totsel++;
- }
- if (bezt->f3 & SELECT) {
- const float *co = bezt->vec[(pivot_point == V3D_AROUND_LOCAL_ORIGINS) ? 1 : 2];
- calc_tw_center_with_matrix(tbounds, co, use_mat_local, mat_local);
- totsel++;
- }
- }
- bezt++;
- }
- }
- else {
- bp = nu->bp;
- a = nu->pntsu * nu->pntsv;
- while (a--) {
- if (bp->f1 & SELECT) {
- calc_tw_center_with_matrix(tbounds, bp->vec, use_mat_local, mat_local);
- totsel++;
- }
- bp++;
- }
- }
- nu = nu->next;
- }
- } FOREACH_EDIT_OBJECT_END();
- }
- else if (obedit->type == OB_MBALL) {
- FOREACH_EDIT_OBJECT_BEGIN(ob_iter, use_mat_local) {
- MetaBall *mb = (MetaBall *)ob_iter->data;
-
- float mat_local[4][4];
- if (use_mat_local) {
- mul_m4_m4m4(mat_local, obedit->imat, ob_iter->obmat);
- }
-
- for (MetaElem *ml = mb->editelems->first; ml; ml = ml->next) {
- if (ml->flag & SELECT) {
- calc_tw_center_with_matrix(tbounds, &ml->x, use_mat_local, mat_local);
- totsel++;
- }
- }
- } FOREACH_EDIT_OBJECT_END();
- }
- else if (obedit->type == OB_LATTICE) {
- FOREACH_EDIT_OBJECT_BEGIN(ob_iter, use_mat_local) {
- Lattice *lt = ((Lattice *)ob_iter->data)->editlatt->latt;
- BPoint *bp = lt->def;
- a = lt->pntsu * lt->pntsv * lt->pntsw;
-
- float mat_local[4][4];
- if (use_mat_local) {
- mul_m4_m4m4(mat_local, obedit->imat, ob_iter->obmat);
- }
-
- while (a--) {
- if (bp->f1 & SELECT) {
- calc_tw_center_with_matrix(tbounds, bp->vec, use_mat_local, mat_local);
- totsel++;
- }
- bp++;
- }
- } FOREACH_EDIT_OBJECT_END();
- }
+ } \
+ MEM_freeN(objects); \
+ } \
+ ((void)0)
+
+ ob = obedit;
+ if (obedit->type == OB_MESH) {
+ FOREACH_EDIT_OBJECT_BEGIN (ob_iter, use_mat_local) {
+ BMEditMesh *em_iter = BKE_editmesh_from_object(ob_iter);
+ BMesh *bm = em_iter->bm;
+
+ if (bm->totvertsel == 0) {
+ continue;
+ }
+
+ BMVert *eve;
+ BMIter iter;
+
+ float mat_local[4][4];
+ if (use_mat_local) {
+ mul_m4_m4m4(mat_local, obedit->imat, ob_iter->obmat);
+ }
+
+ BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
+ if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
+ if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
+ calc_tw_center_with_matrix(tbounds, eve->co, use_mat_local, mat_local);
+ totsel++;
+ }
+ }
+ }
+ }
+ FOREACH_EDIT_OBJECT_END();
+ } /* end editmesh */
+ else if (obedit->type == OB_ARMATURE) {
+ FOREACH_EDIT_OBJECT_BEGIN (ob_iter, use_mat_local) {
+ bArmature *arm = ob_iter->data;
+
+ float mat_local[4][4];
+ if (use_mat_local) {
+ mul_m4_m4m4(mat_local, obedit->imat, ob_iter->obmat);
+ }
+ for (EditBone *ebo = arm->edbo->first; ebo; ebo = ebo->next) {
+ if (EBONE_VISIBLE(arm, ebo)) {
+ if (ebo->flag & BONE_TIPSEL) {
+ calc_tw_center_with_matrix(tbounds, ebo->tail, use_mat_local, mat_local);
+ totsel++;
+ }
+ if ((ebo->flag & BONE_ROOTSEL) &&
+ /* don't include same point multiple times */
+ ((ebo->flag & BONE_CONNECTED) && (ebo->parent != NULL) &&
+ (ebo->parent->flag & BONE_TIPSEL) && EBONE_VISIBLE(arm, ebo->parent)) == 0) {
+ calc_tw_center_with_matrix(tbounds, ebo->head, use_mat_local, mat_local);
+ totsel++;
+ }
+ if (ebo->flag & BONE_SELECTED) {
+ protectflag_to_drawflags_ebone(rv3d, ebo);
+ }
+ }
+ }
+ }
+ FOREACH_EDIT_OBJECT_END();
+ }
+ else if (ELEM(obedit->type, OB_CURVE, OB_SURF)) {
+ FOREACH_EDIT_OBJECT_BEGIN (ob_iter, use_mat_local) {
+ Curve *cu = ob_iter->data;
+ Nurb *nu;
+ BezTriple *bezt;
+ BPoint *bp;
+ ListBase *nurbs = BKE_curve_editNurbs_get(cu);
+
+ float mat_local[4][4];
+ if (use_mat_local) {
+ mul_m4_m4m4(mat_local, obedit->imat, ob_iter->obmat);
+ }
+
+ nu = nurbs->first;
+ while (nu) {
+ if (nu->type == CU_BEZIER) {
+ bezt = nu->bezt;
+ a = nu->pntsu;
+ while (a--) {
+ /* exceptions
+ * if handles are hidden then only check the center points.
+ * If the center knot is selected then only use this as the center point.
+ */
+ if ((v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_CU_HANDLES) == 0) {
+ if (bezt->f2 & SELECT) {
+ calc_tw_center_with_matrix(tbounds, bezt->vec[1], use_mat_local, mat_local);
+ totsel++;
+ }
+ }
+ else if (bezt->f2 & SELECT) {
+ calc_tw_center_with_matrix(tbounds, bezt->vec[1], use_mat_local, mat_local);
+ totsel++;
+ }
+ else {
+ if (bezt->f1 & SELECT) {
+ const float *co = bezt->vec[(pivot_point == V3D_AROUND_LOCAL_ORIGINS) ? 1 : 0];
+ calc_tw_center_with_matrix(tbounds, co, use_mat_local, mat_local);
+ totsel++;
+ }
+ if (bezt->f3 & SELECT) {
+ const float *co = bezt->vec[(pivot_point == V3D_AROUND_LOCAL_ORIGINS) ? 1 : 2];
+ calc_tw_center_with_matrix(tbounds, co, use_mat_local, mat_local);
+ totsel++;
+ }
+ }
+ bezt++;
+ }
+ }
+ else {
+ bp = nu->bp;
+ a = nu->pntsu * nu->pntsv;
+ while (a--) {
+ if (bp->f1 & SELECT) {
+ calc_tw_center_with_matrix(tbounds, bp->vec, use_mat_local, mat_local);
+ totsel++;
+ }
+ bp++;
+ }
+ }
+ nu = nu->next;
+ }
+ }
+ FOREACH_EDIT_OBJECT_END();
+ }
+ else if (obedit->type == OB_MBALL) {
+ FOREACH_EDIT_OBJECT_BEGIN (ob_iter, use_mat_local) {
+ MetaBall *mb = (MetaBall *)ob_iter->data;
+
+ float mat_local[4][4];
+ if (use_mat_local) {
+ mul_m4_m4m4(mat_local, obedit->imat, ob_iter->obmat);
+ }
+
+ for (MetaElem *ml = mb->editelems->first; ml; ml = ml->next) {
+ if (ml->flag & SELECT) {
+ calc_tw_center_with_matrix(tbounds, &ml->x, use_mat_local, mat_local);
+ totsel++;
+ }
+ }
+ }
+ FOREACH_EDIT_OBJECT_END();
+ }
+ else if (obedit->type == OB_LATTICE) {
+ FOREACH_EDIT_OBJECT_BEGIN (ob_iter, use_mat_local) {
+ Lattice *lt = ((Lattice *)ob_iter->data)->editlatt->latt;
+ BPoint *bp = lt->def;
+ a = lt->pntsu * lt->pntsv * lt->pntsw;
+
+ float mat_local[4][4];
+ if (use_mat_local) {
+ mul_m4_m4m4(mat_local, obedit->imat, ob_iter->obmat);
+ }
+
+ while (a--) {
+ if (bp->f1 & SELECT) {
+ calc_tw_center_with_matrix(tbounds, bp->vec, use_mat_local, mat_local);
+ totsel++;
+ }
+ bp++;
+ }
+ }
+ FOREACH_EDIT_OBJECT_END();
+ }
#undef FOREACH_EDIT_OBJECT_BEGIN
#undef FOREACH_EDIT_OBJECT_END
- /* selection center */
- if (totsel) {
- mul_v3_fl(tbounds->center, 1.0f / (float)totsel); // centroid!
- mul_m4_v3(obedit->obmat, tbounds->center);
- mul_m4_v3(obedit->obmat, tbounds->min);
- mul_m4_v3(obedit->obmat, tbounds->max);
- }
- }
- else if (ob && (ob->mode & OB_MODE_POSE)) {
- invert_m4_m4(ob->imat, ob->obmat);
- uint objects_len = 0;
- Object **objects = BKE_view_layer_array_from_objects_in_mode(
- view_layer, v3d, &objects_len, {.object_mode = OB_MODE_POSE});
- for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
- Object *ob_iter = objects[ob_index];
- const bool use_mat_local = (ob_iter != ob);
- bPoseChannel *pchan;
-
- /* mislead counting bones... bah. We don't know the gizmo mode, could be mixed */
- const int mode = TFM_ROTATION;
-
- const int totsel_iter = count_set_pose_transflags(ob_iter, mode, V3D_AROUND_CENTER_BOUNDS, NULL);
-
- if (totsel_iter) {
- float mat_local[4][4];
- if (use_mat_local) {
- mul_m4_m4m4(mat_local, ob->imat, ob_iter->obmat);
- }
-
- /* use channels to get stats */
- for (pchan = ob_iter->pose->chanbase.first; pchan; pchan = pchan->next) {
- Bone *bone = pchan->bone;
- if (bone && (bone->flag & BONE_TRANSFORM)) {
- calc_tw_center_with_matrix(tbounds, pchan->pose_head, use_mat_local, mat_local);
- protectflag_to_drawflags_pchan(rv3d, pchan);
- }
- }
- totsel += totsel_iter;
- }
- }
- MEM_freeN(objects);
-
- if (totsel) {
- mul_v3_fl(tbounds->center, 1.0f / (float)totsel); // centroid!
- mul_m4_v3(ob->obmat, tbounds->center);
- mul_m4_v3(ob->obmat, tbounds->min);
- mul_m4_v3(ob->obmat, tbounds->max);
- }
- }
- else if (ob && (ob->mode & OB_MODE_ALL_PAINT)) {
- /* pass */
- }
- else if (ob && ob->mode & OB_MODE_PARTICLE_EDIT) {
- PTCacheEdit *edit = PE_get_current(scene, ob);
- PTCacheEditPoint *point;
- PTCacheEditKey *ek;
- int k;
-
- if (edit) {
- point = edit->points;
- for (a = 0; a < edit->totpoint; a++, point++) {
- if (point->flag & PEP_HIDE) continue;
-
- for (k = 0, ek = point->keys; k < point->totkey; k++, ek++) {
- if (ek->flag & PEK_SELECT) {
- calc_tw_center(tbounds, (ek->flag & PEK_USE_WCO) ? ek->world_co : ek->co);
- totsel++;
- }
- }
- }
-
- /* selection center */
- if (totsel)
- mul_v3_fl(tbounds->center, 1.0f / (float)totsel); // centroid!
- }
- }
- else {
-
- /* we need the one selected object, if its not active */
- base = BASACT(view_layer);
- ob = OBACT(view_layer);
- if (base && ((base->flag & BASE_SELECTED) == 0)) ob = NULL;
-
- for (base = view_layer->object_bases.first; base; base = base->next) {
- if (!BASE_SELECTED_EDITABLE(v3d, base)) {
- continue;
- }
- if (ob == NULL) {
- ob = base->object;
- }
-
- /* Get the boundbox out of the evaluated object. */
- const BoundBox *bb = NULL;
- if (params->use_only_center == false) {
- bb = BKE_object_boundbox_get(base->object);
- }
-
- if (params->use_only_center || (bb == NULL)) {
- calc_tw_center(tbounds, base->object->obmat[3]);
- }
- else {
- for (uint j = 0; j < 8; j++) {
- float co[3];
- mul_v3_m4v3(co, base->object->obmat, bb->vec[j]);
- calc_tw_center(tbounds, co);
- }
- }
- protectflag_to_drawflags(base->object->protectflag, &rv3d->twdrawflag);
- totsel++;
- }
-
- /* selection center */
- if (totsel) {
- mul_v3_fl(tbounds->center, 1.0f / (float)totsel); // centroid!
- }
- }
-
- if (totsel == 0) {
- unit_m4(rv3d->twmat);
- }
- else {
- copy_v3_v3(rv3d->tw_axis_min, tbounds->axis_min);
- copy_v3_v3(rv3d->tw_axis_max, tbounds->axis_max);
- copy_m3_m3(rv3d->tw_axis_matrix, tbounds->axis);
- }
-
- return totsel;
+ /* selection center */
+ if (totsel) {
+ mul_v3_fl(tbounds->center, 1.0f / (float)totsel); // centroid!
+ mul_m4_v3(obedit->obmat, tbounds->center);
+ mul_m4_v3(obedit->obmat, tbounds->min);
+ mul_m4_v3(obedit->obmat, tbounds->max);
+ }
+ }
+ else if (ob && (ob->mode & OB_MODE_POSE)) {
+ invert_m4_m4(ob->imat, ob->obmat);
+ uint objects_len = 0;
+ Object **objects = BKE_view_layer_array_from_objects_in_mode(
+ view_layer, v3d, &objects_len, {.object_mode = OB_MODE_POSE});
+ for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
+ Object *ob_iter = objects[ob_index];
+ const bool use_mat_local = (ob_iter != ob);
+ bPoseChannel *pchan;
+
+ /* mislead counting bones... bah. We don't know the gizmo mode, could be mixed */
+ const int mode = TFM_ROTATION;
+
+ const int totsel_iter = count_set_pose_transflags(
+ ob_iter, mode, V3D_AROUND_CENTER_BOUNDS, NULL);
+
+ if (totsel_iter) {
+ float mat_local[4][4];
+ if (use_mat_local) {
+ mul_m4_m4m4(mat_local, ob->imat, ob_iter->obmat);
+ }
+
+ /* use channels to get stats */
+ for (pchan = ob_iter->pose->chanbase.first; pchan; pchan = pchan->next) {
+ Bone *bone = pchan->bone;
+ if (bone && (bone->flag & BONE_TRANSFORM)) {
+ calc_tw_center_with_matrix(tbounds, pchan->pose_head, use_mat_local, mat_local);
+ protectflag_to_drawflags_pchan(rv3d, pchan);
+ }
+ }
+ totsel += totsel_iter;
+ }
+ }
+ MEM_freeN(objects);
+
+ if (totsel) {
+ mul_v3_fl(tbounds->center, 1.0f / (float)totsel); // centroid!
+ mul_m4_v3(ob->obmat, tbounds->center);
+ mul_m4_v3(ob->obmat, tbounds->min);
+ mul_m4_v3(ob->obmat, tbounds->max);
+ }
+ }
+ else if (ob && (ob->mode & OB_MODE_ALL_PAINT)) {
+ /* pass */
+ }
+ else if (ob && ob->mode & OB_MODE_PARTICLE_EDIT) {
+ PTCacheEdit *edit = PE_get_current(scene, ob);
+ PTCacheEditPoint *point;
+ PTCacheEditKey *ek;
+ int k;
+
+ if (edit) {
+ point = edit->points;
+ for (a = 0; a < edit->totpoint; a++, point++) {
+ if (point->flag & PEP_HIDE)
+ continue;
+
+ for (k = 0, ek = point->keys; k < point->totkey; k++, ek++) {
+ if (ek->flag & PEK_SELECT) {
+ calc_tw_center(tbounds, (ek->flag & PEK_USE_WCO) ? ek->world_co : ek->co);
+ totsel++;
+ }
+ }
+ }
+
+ /* selection center */
+ if (totsel)
+ mul_v3_fl(tbounds->center, 1.0f / (float)totsel); // centroid!
+ }
+ }
+ else {
+
+ /* we need the one selected object, if its not active */
+ base = BASACT(view_layer);
+ ob = OBACT(view_layer);
+ if (base && ((base->flag & BASE_SELECTED) == 0))
+ ob = NULL;
+
+ for (base = view_layer->object_bases.first; base; base = base->next) {
+ if (!BASE_SELECTED_EDITABLE(v3d, base)) {
+ continue;
+ }
+ if (ob == NULL) {
+ ob = base->object;
+ }
+
+ /* Get the boundbox out of the evaluated object. */
+ const BoundBox *bb = NULL;
+ if (params->use_only_center == false) {
+ bb = BKE_object_boundbox_get(base->object);
+ }
+
+ if (params->use_only_center || (bb == NULL)) {
+ calc_tw_center(tbounds, base->object->obmat[3]);
+ }
+ else {
+ for (uint j = 0; j < 8; j++) {
+ float co[3];
+ mul_v3_m4v3(co, base->object->obmat, bb->vec[j]);
+ calc_tw_center(tbounds, co);
+ }
+ }
+ protectflag_to_drawflags(base->object->protectflag, &rv3d->twdrawflag);
+ totsel++;
+ }
+
+ /* selection center */
+ if (totsel) {
+ mul_v3_fl(tbounds->center, 1.0f / (float)totsel); // centroid!
+ }
+ }
+
+ if (totsel == 0) {
+ unit_m4(rv3d->twmat);
+ }
+ else {
+ copy_v3_v3(rv3d->tw_axis_min, tbounds->axis_min);
+ copy_v3_v3(rv3d->tw_axis_max, tbounds->axis_max);
+ copy_m3_m3(rv3d->tw_axis_matrix, tbounds->axis);
+ }
+
+ return totsel;
}
static void gizmo_get_idot(RegionView3D *rv3d, float r_idot[3])
{
- float view_vec[3], axis_vec[3];
- ED_view3d_global_to_vector(rv3d, rv3d->twmat[3], view_vec);
- for (int i = 0; i < 3; i++) {
- normalize_v3_v3(axis_vec, rv3d->twmat[i]);
- r_idot[i] = 1.0f - fabsf(dot_v3v3(view_vec, axis_vec));
- }
+ float view_vec[3], axis_vec[3];
+ ED_view3d_global_to_vector(rv3d, rv3d->twmat[3], view_vec);
+ for (int i = 0; i < 3; i++) {
+ normalize_v3_v3(axis_vec, rv3d->twmat[i]);
+ r_idot[i] = 1.0f - fabsf(dot_v3v3(view_vec, axis_vec));
+ }
}
-static void gizmo_prepare_mat(
- const bContext *C, RegionView3D *rv3d, const struct TransformBounds *tbounds)
+static void gizmo_prepare_mat(const bContext *C,
+ RegionView3D *rv3d,
+ const struct TransformBounds *tbounds)
{
- Scene *scene = CTX_data_scene(C);
- ViewLayer *view_layer = CTX_data_view_layer(C);
-
- switch (scene->toolsettings->transform_pivot_point) {
- case V3D_AROUND_CENTER_BOUNDS:
- case V3D_AROUND_ACTIVE:
- {
- mid_v3_v3v3(rv3d->twmat[3], tbounds->min, tbounds->max);
-
- if (scene->toolsettings->transform_pivot_point == V3D_AROUND_ACTIVE) {
- bGPdata *gpd = CTX_data_gpencil_data(C);
- Object *ob = OBACT(view_layer);
- if (gpd && (gpd->flag & GP_DATA_STROKE_EDITMODE)) {
- /* pass */
- }
- else if (ob != NULL) {
- ED_object_calc_active_center(ob, false, rv3d->twmat[3]);
- }
- }
- break;
- }
- case V3D_AROUND_LOCAL_ORIGINS:
- case V3D_AROUND_CENTER_MEDIAN:
- copy_v3_v3(rv3d->twmat[3], tbounds->center);
- break;
- case V3D_AROUND_CURSOR:
- copy_v3_v3(rv3d->twmat[3], scene->cursor.location);
- break;
- }
+ Scene *scene = CTX_data_scene(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+
+ switch (scene->toolsettings->transform_pivot_point) {
+ case V3D_AROUND_CENTER_BOUNDS:
+ case V3D_AROUND_ACTIVE: {
+ mid_v3_v3v3(rv3d->twmat[3], tbounds->min, tbounds->max);
+
+ if (scene->toolsettings->transform_pivot_point == V3D_AROUND_ACTIVE) {
+ bGPdata *gpd = CTX_data_gpencil_data(C);
+ Object *ob = OBACT(view_layer);
+ if (gpd && (gpd->flag & GP_DATA_STROKE_EDITMODE)) {
+ /* pass */
+ }
+ else if (ob != NULL) {
+ ED_object_calc_active_center(ob, false, rv3d->twmat[3]);
+ }
+ }
+ break;
+ }
+ case V3D_AROUND_LOCAL_ORIGINS:
+ case V3D_AROUND_CENTER_MEDIAN:
+ copy_v3_v3(rv3d->twmat[3], tbounds->center);
+ break;
+ case V3D_AROUND_CURSOR:
+ copy_v3_v3(rv3d->twmat[3], scene->cursor.location);
+ break;
+ }
}
/**
@@ -1178,771 +1174,779 @@ static void gizmo_prepare_mat(
*/
static void gizmo_line_range(const int twtype, const short axis_type, float *r_start, float *r_len)
{
- const float ofs = 0.2f;
-
- *r_start = 0.2f;
- *r_len = 1.0f;
-
- switch (axis_type) {
- case MAN_AXES_TRANSLATE:
- if (twtype & V3D_GIZMO_SHOW_OBJECT_SCALE) {
- *r_start = *r_len - ofs + 0.075f;
- }
- if (twtype & V3D_GIZMO_SHOW_OBJECT_ROTATE) {
- *r_len += ofs;
- }
- break;
- case MAN_AXES_SCALE:
- if (twtype & (V3D_GIZMO_SHOW_OBJECT_TRANSLATE | V3D_GIZMO_SHOW_OBJECT_ROTATE)) {
- *r_len -= ofs + 0.025f;
- }
- break;
- }
-
- *r_len -= *r_start;
+ const float ofs = 0.2f;
+
+ *r_start = 0.2f;
+ *r_len = 1.0f;
+
+ switch (axis_type) {
+ case MAN_AXES_TRANSLATE:
+ if (twtype & V3D_GIZMO_SHOW_OBJECT_SCALE) {
+ *r_start = *r_len - ofs + 0.075f;
+ }
+ if (twtype & V3D_GIZMO_SHOW_OBJECT_ROTATE) {
+ *r_len += ofs;
+ }
+ break;
+ case MAN_AXES_SCALE:
+ if (twtype & (V3D_GIZMO_SHOW_OBJECT_TRANSLATE | V3D_GIZMO_SHOW_OBJECT_ROTATE)) {
+ *r_len -= ofs + 0.025f;
+ }
+ break;
+ }
+
+ *r_len -= *r_start;
}
-static void gizmo_xform_message_subscribe(
- wmGizmoGroup *gzgroup, struct wmMsgBus *mbus,
- Scene *scene, bScreen *screen, ScrArea *sa, ARegion *ar, const void *type_fn)
+static void gizmo_xform_message_subscribe(wmGizmoGroup *gzgroup,
+ struct wmMsgBus *mbus,
+ Scene *scene,
+ bScreen *screen,
+ ScrArea *sa,
+ ARegion *ar,
+ const void *type_fn)
{
- /* Subscribe to view properties */
- wmMsgSubscribeValue msg_sub_value_gz_tag_refresh = {
- .owner = ar,
- .user_data = gzgroup->parent_gzmap,
- .notify = WM_gizmo_do_msg_notify_tag_refresh,
- };
-
- int orient_flag = 0;
- if (type_fn == VIEW3D_GGT_xform_gizmo) {
- GizmoGroup *ggd = gzgroup->customdata;
- orient_flag = ggd->twtype_init;
- }
- else if (type_fn == VIEW3D_GGT_xform_cage) {
- orient_flag = V3D_GIZMO_SHOW_OBJECT_SCALE;
- /* pass */
- }
- else if (type_fn == VIEW3D_GGT_xform_shear) {
- orient_flag = V3D_GIZMO_SHOW_OBJECT_ROTATE;
- }
- TransformOrientationSlot *orient_slot = BKE_scene_orientation_slot_get_from_flag(scene, orient_flag);
- PointerRNA orient_ref_ptr;
- RNA_pointer_create(&scene->id, &RNA_TransformOrientationSlot, orient_slot, &orient_ref_ptr);
- const ToolSettings *ts = scene->toolsettings;
-
- PointerRNA scene_ptr;
- RNA_id_pointer_create(&scene->id, &scene_ptr);
- {
- extern PropertyRNA rna_Scene_transform_orientation_slots;
- const PropertyRNA *props[] = {
- &rna_Scene_transform_orientation_slots,
- };
- for (int i = 0; i < ARRAY_SIZE(props); i++) {
- WM_msg_subscribe_rna(mbus, &scene_ptr, props[i], &msg_sub_value_gz_tag_refresh, __func__);
- }
- }
-
- if ((ts->transform_pivot_point == V3D_AROUND_CURSOR) ||
- (orient_slot->type == V3D_ORIENT_CURSOR))
- {
- /* We could be more specific here, for now subscribe to any cursor change. */
- PointerRNA cursor_ptr;
- RNA_pointer_create(&scene->id, &RNA_View3DCursor, &scene->cursor, &cursor_ptr);
- WM_msg_subscribe_rna(mbus, &cursor_ptr, NULL, &msg_sub_value_gz_tag_refresh, __func__);
- }
-
- {
- extern PropertyRNA rna_TransformOrientationSlot_type;
- extern PropertyRNA rna_TransformOrientationSlot_use;
- const PropertyRNA *props[] = {
- &rna_TransformOrientationSlot_type,
- &rna_TransformOrientationSlot_use,
- };
- for (int i = 0; i < ARRAY_SIZE(props); i++) {
- if (props[i]) {
- WM_msg_subscribe_rna(mbus, &orient_ref_ptr, props[i], &msg_sub_value_gz_tag_refresh, __func__);
- }
- }
- }
-
- PointerRNA toolsettings_ptr;
- RNA_pointer_create(&scene->id, &RNA_ToolSettings, scene->toolsettings, &toolsettings_ptr);
-
- if (type_fn == VIEW3D_GGT_xform_gizmo) {
- extern PropertyRNA rna_ToolSettings_transform_pivot_point;
- const PropertyRNA *props[] = {
- &rna_ToolSettings_transform_pivot_point,
- };
- for (int i = 0; i < ARRAY_SIZE(props); i++) {
- WM_msg_subscribe_rna(mbus, &toolsettings_ptr, props[i], &msg_sub_value_gz_tag_refresh, __func__);
- }
- }
-
- PointerRNA view3d_ptr;
- RNA_pointer_create(&screen->id, &RNA_SpaceView3D, sa->spacedata.first, &view3d_ptr);
-
- if (type_fn == VIEW3D_GGT_xform_gizmo) {
- GizmoGroup *ggd = gzgroup->customdata;
- if (ggd->use_twtype_refresh) {
- extern PropertyRNA rna_SpaceView3D_show_gizmo_object_translate;
- extern PropertyRNA rna_SpaceView3D_show_gizmo_object_rotate;
- extern PropertyRNA rna_SpaceView3D_show_gizmo_object_scale;
- const PropertyRNA *props[] = {
- &rna_SpaceView3D_show_gizmo_object_translate,
- &rna_SpaceView3D_show_gizmo_object_rotate,
- &rna_SpaceView3D_show_gizmo_object_scale,
- };
- for (int i = 0; i < ARRAY_SIZE(props); i++) {
- WM_msg_subscribe_rna(mbus, &view3d_ptr, props[i], &msg_sub_value_gz_tag_refresh, __func__);
- }
- }
- }
- else if (type_fn == VIEW3D_GGT_xform_cage) {
- /* pass */
- }
- else if (type_fn == VIEW3D_GGT_xform_shear) {
- /* pass */
- }
- else {
- BLI_assert(0);
- }
-
- WM_msg_subscribe_rna_anon_prop(mbus, Window, view_layer, &msg_sub_value_gz_tag_refresh);
+ /* Subscribe to view properties */
+ wmMsgSubscribeValue msg_sub_value_gz_tag_refresh = {
+ .owner = ar,
+ .user_data = gzgroup->parent_gzmap,
+ .notify = WM_gizmo_do_msg_notify_tag_refresh,
+ };
+
+ int orient_flag = 0;
+ if (type_fn == VIEW3D_GGT_xform_gizmo) {
+ GizmoGroup *ggd = gzgroup->customdata;
+ orient_flag = ggd->twtype_init;
+ }
+ else if (type_fn == VIEW3D_GGT_xform_cage) {
+ orient_flag = V3D_GIZMO_SHOW_OBJECT_SCALE;
+ /* pass */
+ }
+ else if (type_fn == VIEW3D_GGT_xform_shear) {
+ orient_flag = V3D_GIZMO_SHOW_OBJECT_ROTATE;
+ }
+ TransformOrientationSlot *orient_slot = BKE_scene_orientation_slot_get_from_flag(scene,
+ orient_flag);
+ PointerRNA orient_ref_ptr;
+ RNA_pointer_create(&scene->id, &RNA_TransformOrientationSlot, orient_slot, &orient_ref_ptr);
+ const ToolSettings *ts = scene->toolsettings;
+
+ PointerRNA scene_ptr;
+ RNA_id_pointer_create(&scene->id, &scene_ptr);
+ {
+ extern PropertyRNA rna_Scene_transform_orientation_slots;
+ const PropertyRNA *props[] = {
+ &rna_Scene_transform_orientation_slots,
+ };
+ for (int i = 0; i < ARRAY_SIZE(props); i++) {
+ WM_msg_subscribe_rna(mbus, &scene_ptr, props[i], &msg_sub_value_gz_tag_refresh, __func__);
+ }
+ }
+
+ if ((ts->transform_pivot_point == V3D_AROUND_CURSOR) ||
+ (orient_slot->type == V3D_ORIENT_CURSOR)) {
+ /* We could be more specific here, for now subscribe to any cursor change. */
+ PointerRNA cursor_ptr;
+ RNA_pointer_create(&scene->id, &RNA_View3DCursor, &scene->cursor, &cursor_ptr);
+ WM_msg_subscribe_rna(mbus, &cursor_ptr, NULL, &msg_sub_value_gz_tag_refresh, __func__);
+ }
+
+ {
+ extern PropertyRNA rna_TransformOrientationSlot_type;
+ extern PropertyRNA rna_TransformOrientationSlot_use;
+ const PropertyRNA *props[] = {
+ &rna_TransformOrientationSlot_type,
+ &rna_TransformOrientationSlot_use,
+ };
+ for (int i = 0; i < ARRAY_SIZE(props); i++) {
+ if (props[i]) {
+ WM_msg_subscribe_rna(
+ mbus, &orient_ref_ptr, props[i], &msg_sub_value_gz_tag_refresh, __func__);
+ }
+ }
+ }
+
+ PointerRNA toolsettings_ptr;
+ RNA_pointer_create(&scene->id, &RNA_ToolSettings, scene->toolsettings, &toolsettings_ptr);
+
+ if (type_fn == VIEW3D_GGT_xform_gizmo) {
+ extern PropertyRNA rna_ToolSettings_transform_pivot_point;
+ const PropertyRNA *props[] = {
+ &rna_ToolSettings_transform_pivot_point,
+ };
+ for (int i = 0; i < ARRAY_SIZE(props); i++) {
+ WM_msg_subscribe_rna(
+ mbus, &toolsettings_ptr, props[i], &msg_sub_value_gz_tag_refresh, __func__);
+ }
+ }
+
+ PointerRNA view3d_ptr;
+ RNA_pointer_create(&screen->id, &RNA_SpaceView3D, sa->spacedata.first, &view3d_ptr);
+
+ if (type_fn == VIEW3D_GGT_xform_gizmo) {
+ GizmoGroup *ggd = gzgroup->customdata;
+ if (ggd->use_twtype_refresh) {
+ extern PropertyRNA rna_SpaceView3D_show_gizmo_object_translate;
+ extern PropertyRNA rna_SpaceView3D_show_gizmo_object_rotate;
+ extern PropertyRNA rna_SpaceView3D_show_gizmo_object_scale;
+ const PropertyRNA *props[] = {
+ &rna_SpaceView3D_show_gizmo_object_translate,
+ &rna_SpaceView3D_show_gizmo_object_rotate,
+ &rna_SpaceView3D_show_gizmo_object_scale,
+ };
+ for (int i = 0; i < ARRAY_SIZE(props); i++) {
+ WM_msg_subscribe_rna(mbus, &view3d_ptr, props[i], &msg_sub_value_gz_tag_refresh, __func__);
+ }
+ }
+ }
+ else if (type_fn == VIEW3D_GGT_xform_cage) {
+ /* pass */
+ }
+ else if (type_fn == VIEW3D_GGT_xform_shear) {
+ /* pass */
+ }
+ else {
+ BLI_assert(0);
+ }
+
+ WM_msg_subscribe_rna_anon_prop(mbus, Window, view_layer, &msg_sub_value_gz_tag_refresh);
}
-
void drawDial3d(const TransInfo *t)
{
- if (t->mode == TFM_ROTATION && t->spacetype == SPACE_VIEW3D) {
- wmGizmo *gz = wm_gizmomap_modal_get(t->ar->gizmo_map);
- if (gz == NULL) {
- /* We only draw Dial3d if the operator has been called by a gizmo. */
- return;
- }
-
- float mat_basis[4][4];
- float mat_final[4][4];
- float color[4];
- float increment;
- float line_with = GIZMO_AXIS_LINE_WIDTH + 1.0f;
- float scale = UI_DPI_FAC * U.gizmo_size;
-
- int axis_idx;
-
- const TransCon *tc = &(t->con);
- if (tc->mode & CON_APPLY) {
- if (tc->mode & CON_AXIS0) {
- axis_idx = MAN_AXIS_ROT_X;
- negate_v3_v3(mat_basis[2], tc->mtx[0]);
- }
- else if (tc->mode & CON_AXIS1) {
- axis_idx = MAN_AXIS_ROT_Y;
- negate_v3_v3(mat_basis[2], tc->mtx[1]);
- }
- else {
- BLI_assert((tc->mode & CON_AXIS2) != 0);
- axis_idx = MAN_AXIS_ROT_Z;
- negate_v3_v3(mat_basis[2], tc->mtx[2]);
- }
- }
- else {
- axis_idx = MAN_AXIS_ROT_C;
- negate_v3_v3(mat_basis[2], t->orient_matrix[t->orient_axis]);
- scale *= 1.2f;
- line_with -= 1.0f;
- }
-
- copy_v3_v3(mat_basis[3], t->center_global);
- mat_basis[2][3] = -dot_v3v3(mat_basis[2], mat_basis[3]);
-
- if (ED_view3d_win_to_3d_on_plane(
- t->ar, mat_basis[2], (float[2]){UNPACK2(t->mouse.imval)},
- false, mat_basis[1]))
- {
- sub_v3_v3(mat_basis[1], mat_basis[3]);
- normalize_v3(mat_basis[1]);
- cross_v3_v3v3(mat_basis[0], mat_basis[1], mat_basis[2]);
- }
- else {
- /* The plane and the mouse direction are parallel.
- * Calculate a matrix orthogonal to the axis. */
- ortho_basis_v3v3_v3(mat_basis[0], mat_basis[1], mat_basis[2]);
- }
-
- mat_basis[0][3] = 0.0f;
- mat_basis[1][3] = 0.0f;
- mat_basis[2][3] = 0.0f;
- mat_basis[3][3] = 1.0f;
-
- copy_m4_m4(mat_final, mat_basis);
- scale *= ED_view3d_pixel_size_no_ui_scale(t->ar->regiondata, mat_final[3]);
- mul_mat3_m4_fl(mat_final, scale);
-
- if ((t->tsnap.mode & (SCE_SNAP_MODE_INCREMENT | SCE_SNAP_MODE_GRID)) &&
- activeSnap(t))
- {
- increment = (t->modifiers & MOD_PRECISION) ? t->snap[2] : t->snap[1];
- }
- else {
- increment = t->snap[0];
- }
-
- BLI_assert(axis_idx >= MAN_AXIS_RANGE_ROT_START && axis_idx < MAN_AXIS_RANGE_ROT_END);
- gizmo_get_axis_color(axis_idx, NULL, color, color);
-
- GPU_depth_test(false);
- GPU_blend(true);
- GPU_line_smooth(true);
-
- ED_gizmotypes_dial_3d_draw_util(
- mat_basis, mat_final, line_with, color, false,
- &(struct Dial3dParams){
- .draw_options = ED_GIZMO_DIAL_DRAW_FLAG_ANGLE_VALUE,
- .angle_delta = t->values[0],
- .angle_increment = increment,
- });
-
- GPU_line_smooth(false);
- GPU_depth_test(true);
- GPU_blend(false);
- }
+ if (t->mode == TFM_ROTATION && t->spacetype == SPACE_VIEW3D) {
+ wmGizmo *gz = wm_gizmomap_modal_get(t->ar->gizmo_map);
+ if (gz == NULL) {
+ /* We only draw Dial3d if the operator has been called by a gizmo. */
+ return;
+ }
+
+ float mat_basis[4][4];
+ float mat_final[4][4];
+ float color[4];
+ float increment;
+ float line_with = GIZMO_AXIS_LINE_WIDTH + 1.0f;
+ float scale = UI_DPI_FAC * U.gizmo_size;
+
+ int axis_idx;
+
+ const TransCon *tc = &(t->con);
+ if (tc->mode & CON_APPLY) {
+ if (tc->mode & CON_AXIS0) {
+ axis_idx = MAN_AXIS_ROT_X;
+ negate_v3_v3(mat_basis[2], tc->mtx[0]);
+ }
+ else if (tc->mode & CON_AXIS1) {
+ axis_idx = MAN_AXIS_ROT_Y;
+ negate_v3_v3(mat_basis[2], tc->mtx[1]);
+ }
+ else {
+ BLI_assert((tc->mode & CON_AXIS2) != 0);
+ axis_idx = MAN_AXIS_ROT_Z;
+ negate_v3_v3(mat_basis[2], tc->mtx[2]);
+ }
+ }
+ else {
+ axis_idx = MAN_AXIS_ROT_C;
+ negate_v3_v3(mat_basis[2], t->orient_matrix[t->orient_axis]);
+ scale *= 1.2f;
+ line_with -= 1.0f;
+ }
+
+ copy_v3_v3(mat_basis[3], t->center_global);
+ mat_basis[2][3] = -dot_v3v3(mat_basis[2], mat_basis[3]);
+
+ if (ED_view3d_win_to_3d_on_plane(
+ t->ar, mat_basis[2], (float[2]){UNPACK2(t->mouse.imval)}, false, mat_basis[1])) {
+ sub_v3_v3(mat_basis[1], mat_basis[3]);
+ normalize_v3(mat_basis[1]);
+ cross_v3_v3v3(mat_basis[0], mat_basis[1], mat_basis[2]);
+ }
+ else {
+ /* The plane and the mouse direction are parallel.
+ * Calculate a matrix orthogonal to the axis. */
+ ortho_basis_v3v3_v3(mat_basis[0], mat_basis[1], mat_basis[2]);
+ }
+
+ mat_basis[0][3] = 0.0f;
+ mat_basis[1][3] = 0.0f;
+ mat_basis[2][3] = 0.0f;
+ mat_basis[3][3] = 1.0f;
+
+ copy_m4_m4(mat_final, mat_basis);
+ scale *= ED_view3d_pixel_size_no_ui_scale(t->ar->regiondata, mat_final[3]);
+ mul_mat3_m4_fl(mat_final, scale);
+
+ if ((t->tsnap.mode & (SCE_SNAP_MODE_INCREMENT | SCE_SNAP_MODE_GRID)) && activeSnap(t)) {
+ increment = (t->modifiers & MOD_PRECISION) ? t->snap[2] : t->snap[1];
+ }
+ else {
+ increment = t->snap[0];
+ }
+
+ BLI_assert(axis_idx >= MAN_AXIS_RANGE_ROT_START && axis_idx < MAN_AXIS_RANGE_ROT_END);
+ gizmo_get_axis_color(axis_idx, NULL, color, color);
+
+ GPU_depth_test(false);
+ GPU_blend(true);
+ GPU_line_smooth(true);
+
+ ED_gizmotypes_dial_3d_draw_util(mat_basis,
+ mat_final,
+ line_with,
+ color,
+ false,
+ &(struct Dial3dParams){
+ .draw_options = ED_GIZMO_DIAL_DRAW_FLAG_ANGLE_VALUE,
+ .angle_delta = t->values[0],
+ .angle_increment = increment,
+ });
+
+ GPU_line_smooth(false);
+ GPU_depth_test(true);
+ GPU_blend(false);
+ }
}
/** \} */
-
/* -------------------------------------------------------------------- */
/** \name Transform Gizmo
* \{ */
static GizmoGroup *gizmogroup_init(wmGizmoGroup *gzgroup)
{
- GizmoGroup *ggd;
-
- ggd = MEM_callocN(sizeof(GizmoGroup), "gizmo_data");
-
- const wmGizmoType *gzt_arrow = WM_gizmotype_find("GIZMO_GT_arrow_3d", true);
- const wmGizmoType *gzt_dial = WM_gizmotype_find("GIZMO_GT_dial_3d", true);
- const wmGizmoType *gzt_prim = WM_gizmotype_find("GIZMO_GT_primitive_3d", true);
-
-#define GIZMO_NEW_ARROW(v, draw_style) { \
- 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) { \
- ggd->gizmos[v] = WM_gizmo_new_ptr(gzt_dial, gzgroup, NULL); \
- RNA_enum_set(ggd->gizmos[v]->ptr, "draw_options", draw_options); \
-} ((void)0)
-#define GIZMO_NEW_PRIM(v, draw_style) { \
- 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_SCALE_C, ED_GIZMO_DIAL_DRAW_FLAG_FILL_SELECT);
-
- 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_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_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);
-
- /* 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_TRANS_C, ED_GIZMO_DIAL_DRAW_FLAG_FILL_SELECT);
-
- 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_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);
-
- ggd->gizmos[MAN_AXIS_ROT_T]->flag |= WM_GIZMO_SELECT_BACKGROUND;
-
- return ggd;
+ GizmoGroup *ggd;
+
+ ggd = MEM_callocN(sizeof(GizmoGroup), "gizmo_data");
+
+ const wmGizmoType *gzt_arrow = WM_gizmotype_find("GIZMO_GT_arrow_3d", true);
+ const wmGizmoType *gzt_dial = WM_gizmotype_find("GIZMO_GT_dial_3d", true);
+ const wmGizmoType *gzt_prim = WM_gizmotype_find("GIZMO_GT_primitive_3d", true);
+
+#define GIZMO_NEW_ARROW(v, draw_style) \
+ { \
+ 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) \
+ { \
+ ggd->gizmos[v] = WM_gizmo_new_ptr(gzt_dial, gzgroup, NULL); \
+ RNA_enum_set(ggd->gizmos[v]->ptr, "draw_options", draw_options); \
+ } \
+ ((void)0)
+#define GIZMO_NEW_PRIM(v, draw_style) \
+ { \
+ 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_SCALE_C, ED_GIZMO_DIAL_DRAW_FLAG_FILL_SELECT);
+
+ 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_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_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);
+
+ /* 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_TRANS_C, ED_GIZMO_DIAL_DRAW_FLAG_FILL_SELECT);
+
+ 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_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);
+
+ ggd->gizmos[MAN_AXIS_ROT_T]->flag |= WM_GIZMO_SELECT_BACKGROUND;
+
+ return ggd;
}
/**
* Custom handler for gizmo widgets
*/
-static int gizmo_modal(
- bContext *C, wmGizmo *widget, const wmEvent *event,
- eWM_GizmoFlagTweak UNUSED(tweak_flag))
+static int gizmo_modal(bContext *C,
+ wmGizmo *widget,
+ const wmEvent *event,
+ eWM_GizmoFlagTweak UNUSED(tweak_flag))
{
- /* Avoid unnecessary updates, partially address: T55458. */
- if (ELEM(event->type, TIMER, INBETWEEN_MOUSEMOVE)) {
- return OPERATOR_RUNNING_MODAL;
- }
-
- ARegion *ar = CTX_wm_region(C);
- RegionView3D *rv3d = ar->regiondata;
- struct TransformBounds tbounds;
-
-
- if (ED_transform_calc_gizmo_stats(
- C, &(struct TransformCalcParams){
- .use_only_center = true,
- }, &tbounds))
- {
- gizmo_prepare_mat(C, rv3d, &tbounds);
- WM_gizmo_set_matrix_location(widget, rv3d->twmat[3]);
- }
-
- ED_region_tag_redraw(ar);
-
- return OPERATOR_RUNNING_MODAL;
+ /* Avoid unnecessary updates, partially address: T55458. */
+ if (ELEM(event->type, TIMER, INBETWEEN_MOUSEMOVE)) {
+ return OPERATOR_RUNNING_MODAL;
+ }
+
+ ARegion *ar = CTX_wm_region(C);
+ RegionView3D *rv3d = ar->regiondata;
+ struct TransformBounds tbounds;
+
+ if (ED_transform_calc_gizmo_stats(C,
+ &(struct TransformCalcParams){
+ .use_only_center = true,
+ },
+ &tbounds)) {
+ gizmo_prepare_mat(C, rv3d, &tbounds);
+ WM_gizmo_set_matrix_location(widget, rv3d->twmat[3]);
+ }
+
+ ED_region_tag_redraw(ar);
+
+ return OPERATOR_RUNNING_MODAL;
}
static void gizmogroup_init_properties_from_twtype(wmGizmoGroup *gzgroup)
{
- struct {
- wmOperatorType *translate, *rotate, *trackball, *resize;
- } ot_store = {NULL};
- GizmoGroup *ggd = gzgroup->customdata;
-
- MAN_ITER_AXES_BEGIN(axis, axis_idx)
- {
- const short axis_type = gizmo_get_axis_type(axis_idx);
- bool constraint_axis[3] = {1, 0, 0};
- PointerRNA *ptr = NULL;
-
- gizmo_get_axis_constraint(axis_idx, constraint_axis);
-
- /* 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_ax = 7.0f;
- const float ofs[3] = {ofs_ax, ofs_ax, 0.0f};
- WM_gizmo_set_scale(axis, 0.07f);
- 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 {
- WM_gizmo_set_scale(axis, 0.2f);
- }
- break;
- }
-
- switch (axis_type) {
- case MAN_AXES_TRANSLATE:
- if (ot_store.translate == NULL) {
- ot_store.translate = WM_operatortype_find("TRANSFORM_OT_translate", true);
- }
- ptr = WM_gizmo_operator_set(axis, 0, ot_store.translate, NULL);
- break;
- case MAN_AXES_ROTATE:
- {
- wmOperatorType *ot_rotate;
- if (axis_idx == MAN_AXIS_ROT_T) {
- if (ot_store.trackball == NULL) {
- ot_store.trackball = WM_operatortype_find("TRANSFORM_OT_trackball", true);
- }
- ot_rotate = ot_store.trackball;
- }
- else {
- if (ot_store.rotate == NULL) {
- ot_store.rotate = WM_operatortype_find("TRANSFORM_OT_rotate", true);
- }
- ot_rotate = ot_store.rotate;
- }
- ptr = WM_gizmo_operator_set(axis, 0, ot_rotate, NULL);
- break;
- }
- case MAN_AXES_SCALE:
- {
- if (ot_store.resize == NULL) {
- ot_store.resize = WM_operatortype_find("TRANSFORM_OT_resize", true);
- }
- ptr = WM_gizmo_operator_set(axis, 0, ot_store.resize, NULL);
- break;
- }
- }
-
- if (ptr) {
- PropertyRNA *prop;
- if (ELEM(true, UNPACK3(constraint_axis))) {
- if ((prop = RNA_struct_find_property(ptr, "constraint_axis"))) {
- RNA_property_boolean_set_array(ptr, prop, constraint_axis);
- }
- }
-
- RNA_boolean_set(ptr, "release_confirm", 1);
- }
- }
- MAN_ITER_AXES_END;
+ struct {
+ wmOperatorType *translate, *rotate, *trackball, *resize;
+ } ot_store = {NULL};
+ GizmoGroup *ggd = gzgroup->customdata;
+
+ MAN_ITER_AXES_BEGIN (axis, axis_idx) {
+ const short axis_type = gizmo_get_axis_type(axis_idx);
+ bool constraint_axis[3] = {1, 0, 0};
+ PointerRNA *ptr = NULL;
+
+ gizmo_get_axis_constraint(axis_idx, constraint_axis);
+
+ /* 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_ax = 7.0f;
+ const float ofs[3] = {ofs_ax, ofs_ax, 0.0f};
+ WM_gizmo_set_scale(axis, 0.07f);
+ 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 {
+ WM_gizmo_set_scale(axis, 0.2f);
+ }
+ break;
+ }
+
+ switch (axis_type) {
+ case MAN_AXES_TRANSLATE:
+ if (ot_store.translate == NULL) {
+ ot_store.translate = WM_operatortype_find("TRANSFORM_OT_translate", true);
+ }
+ ptr = WM_gizmo_operator_set(axis, 0, ot_store.translate, NULL);
+ break;
+ case MAN_AXES_ROTATE: {
+ wmOperatorType *ot_rotate;
+ if (axis_idx == MAN_AXIS_ROT_T) {
+ if (ot_store.trackball == NULL) {
+ ot_store.trackball = WM_operatortype_find("TRANSFORM_OT_trackball", true);
+ }
+ ot_rotate = ot_store.trackball;
+ }
+ else {
+ if (ot_store.rotate == NULL) {
+ ot_store.rotate = WM_operatortype_find("TRANSFORM_OT_rotate", true);
+ }
+ ot_rotate = ot_store.rotate;
+ }
+ ptr = WM_gizmo_operator_set(axis, 0, ot_rotate, NULL);
+ break;
+ }
+ case MAN_AXES_SCALE: {
+ if (ot_store.resize == NULL) {
+ ot_store.resize = WM_operatortype_find("TRANSFORM_OT_resize", true);
+ }
+ ptr = WM_gizmo_operator_set(axis, 0, ot_store.resize, NULL);
+ break;
+ }
+ }
+
+ if (ptr) {
+ PropertyRNA *prop;
+ if (ELEM(true, UNPACK3(constraint_axis))) {
+ if ((prop = RNA_struct_find_property(ptr, "constraint_axis"))) {
+ RNA_property_boolean_set_array(ptr, prop, constraint_axis);
+ }
+ }
+
+ RNA_boolean_set(ptr, "release_confirm", 1);
+ }
+ }
+ MAN_ITER_AXES_END;
}
static void WIDGETGROUP_gizmo_setup(const bContext *C, wmGizmoGroup *gzgroup)
{
- GizmoGroup *ggd = gizmogroup_init(gzgroup);
-
- gzgroup->customdata = ggd;
-
- {
- ScrArea *sa = CTX_wm_area(C);
- const bToolRef *tref = sa->runtime.tool;
-
- ggd->twtype = 0;
- if (tref && STREQ(tref->idname, "builtin.move")) {
- ggd->twtype |= V3D_GIZMO_SHOW_OBJECT_TRANSLATE;
- }
- else if (tref && STREQ(tref->idname, "builtin.rotate")) {
- ggd->twtype |= V3D_GIZMO_SHOW_OBJECT_ROTATE;
- }
- else if (tref && STREQ(tref->idname, "builtin.scale")) {
- ggd->twtype |= V3D_GIZMO_SHOW_OBJECT_SCALE;
- }
- else {
- /* Setup all gizmos, they can be toggled via 'ToolSettings.gizmo_flag' */
- ggd->twtype = V3D_GIZMO_SHOW_OBJECT_TRANSLATE | V3D_GIZMO_SHOW_OBJECT_ROTATE | V3D_GIZMO_SHOW_OBJECT_SCALE;
- ggd->use_twtype_refresh = true;
- }
- BLI_assert(ggd->twtype != 0);
- ggd->twtype_init = ggd->twtype;
- }
-
- /* *** set properties for axes *** */
- gizmogroup_init_properties_from_twtype(gzgroup);
+ GizmoGroup *ggd = gizmogroup_init(gzgroup);
+
+ gzgroup->customdata = ggd;
+
+ {
+ ScrArea *sa = CTX_wm_area(C);
+ const bToolRef *tref = sa->runtime.tool;
+
+ ggd->twtype = 0;
+ if (tref && STREQ(tref->idname, "builtin.move")) {
+ ggd->twtype |= V3D_GIZMO_SHOW_OBJECT_TRANSLATE;
+ }
+ else if (tref && STREQ(tref->idname, "builtin.rotate")) {
+ ggd->twtype |= V3D_GIZMO_SHOW_OBJECT_ROTATE;
+ }
+ else if (tref && STREQ(tref->idname, "builtin.scale")) {
+ ggd->twtype |= V3D_GIZMO_SHOW_OBJECT_SCALE;
+ }
+ else {
+ /* Setup all gizmos, they can be toggled via 'ToolSettings.gizmo_flag' */
+ ggd->twtype = V3D_GIZMO_SHOW_OBJECT_TRANSLATE | V3D_GIZMO_SHOW_OBJECT_ROTATE |
+ V3D_GIZMO_SHOW_OBJECT_SCALE;
+ ggd->use_twtype_refresh = true;
+ }
+ BLI_assert(ggd->twtype != 0);
+ ggd->twtype_init = ggd->twtype;
+ }
+
+ /* *** set properties for axes *** */
+ gizmogroup_init_properties_from_twtype(gzgroup);
}
static void WIDGETGROUP_gizmo_refresh(const bContext *C, wmGizmoGroup *gzgroup)
{
- GizmoGroup *ggd = gzgroup->customdata;
- Scene *scene = CTX_data_scene(C);
- ScrArea *sa = CTX_wm_area(C);
- View3D *v3d = sa->spacedata.first;
- ARegion *ar = CTX_wm_region(C);
- RegionView3D *rv3d = ar->regiondata;
- struct TransformBounds tbounds;
-
- if (ggd->use_twtype_refresh) {
- ggd->twtype = v3d->gizmo_show_object & ggd->twtype_init;
- if (ggd->twtype != ggd->twtype_prev) {
- ggd->twtype_prev = ggd->twtype;
- gizmogroup_init_properties_from_twtype(gzgroup);
- }
- }
-
- const TransformOrientationSlot *orient_slot = BKE_scene_orientation_slot_get_from_flag(scene, ggd->twtype_init);
-
- /* skip, we don't draw anything anyway */
- if ((ggd->all_hidden =
- (ED_transform_calc_gizmo_stats(
- C, &(struct TransformCalcParams){
- .use_only_center = true,
- .orientation_type = orient_slot->type + 1,
- .orientation_index_custom = orient_slot->index_custom,
- }, &tbounds) == 0)))
- {
- return;
- }
-
- gizmo_prepare_mat(C, rv3d, &tbounds);
-
- /* *** set properties for axes *** */
-
- 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, rv3d->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);
-
- WM_gizmo_set_matrix_rotation_from_z_axis(axis, rv3d->twmat[aidx_norm]);
- 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) {
- /* Avoid rotate and translate arrows overlap. */
- start_co[2] += 0.215f;
- }
- }
- 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:
- WM_gizmo_set_matrix_rotation_from_z_axis(axis, rv3d->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 float *y_axis = rv3d->twmat[aidx_norm - 1 < 0 ? 2 : aidx_norm - 1];
- const float *z_axis = rv3d->twmat[aidx_norm];
- WM_gizmo_set_matrix_rotation_from_yz_axis(axis, y_axis, z_axis);
- break;
- }
- }
- }
- MAN_ITER_AXES_END;
+ GizmoGroup *ggd = gzgroup->customdata;
+ Scene *scene = CTX_data_scene(C);
+ ScrArea *sa = CTX_wm_area(C);
+ View3D *v3d = sa->spacedata.first;
+ ARegion *ar = CTX_wm_region(C);
+ RegionView3D *rv3d = ar->regiondata;
+ struct TransformBounds tbounds;
+
+ if (ggd->use_twtype_refresh) {
+ ggd->twtype = v3d->gizmo_show_object & ggd->twtype_init;
+ if (ggd->twtype != ggd->twtype_prev) {
+ ggd->twtype_prev = ggd->twtype;
+ gizmogroup_init_properties_from_twtype(gzgroup);
+ }
+ }
+
+ const TransformOrientationSlot *orient_slot = BKE_scene_orientation_slot_get_from_flag(
+ scene, ggd->twtype_init);
+
+ /* skip, we don't draw anything anyway */
+ if ((ggd->all_hidden = (ED_transform_calc_gizmo_stats(
+ C,
+ &(struct TransformCalcParams){
+ .use_only_center = true,
+ .orientation_type = orient_slot->type + 1,
+ .orientation_index_custom = orient_slot->index_custom,
+ },
+ &tbounds) == 0))) {
+ return;
+ }
+
+ gizmo_prepare_mat(C, rv3d, &tbounds);
+
+ /* *** set properties for axes *** */
+
+ 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, rv3d->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);
+
+ WM_gizmo_set_matrix_rotation_from_z_axis(axis, rv3d->twmat[aidx_norm]);
+ 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) {
+ /* Avoid rotate and translate arrows overlap. */
+ start_co[2] += 0.215f;
+ }
+ }
+ 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:
+ WM_gizmo_set_matrix_rotation_from_z_axis(axis, rv3d->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 float *y_axis = rv3d->twmat[aidx_norm - 1 < 0 ? 2 : aidx_norm - 1];
+ const float *z_axis = rv3d->twmat[aidx_norm];
+ WM_gizmo_set_matrix_rotation_from_yz_axis(axis, y_axis, z_axis);
+ break;
+ }
+ }
+ }
+ MAN_ITER_AXES_END;
}
-static void WIDGETGROUP_gizmo_message_subscribe(
- const bContext *C, wmGizmoGroup *gzgroup, struct wmMsgBus *mbus)
+static void WIDGETGROUP_gizmo_message_subscribe(const bContext *C,
+ wmGizmoGroup *gzgroup,
+ struct wmMsgBus *mbus)
{
- Scene *scene = CTX_data_scene(C);
- bScreen *screen = CTX_wm_screen(C);
- ScrArea *sa = CTX_wm_area(C);
- ARegion *ar = CTX_wm_region(C);
- gizmo_xform_message_subscribe(gzgroup, mbus, scene, screen, sa, ar, VIEW3D_GGT_xform_gizmo);
+ Scene *scene = CTX_data_scene(C);
+ bScreen *screen = CTX_wm_screen(C);
+ ScrArea *sa = CTX_wm_area(C);
+ ARegion *ar = CTX_wm_region(C);
+ gizmo_xform_message_subscribe(gzgroup, mbus, scene, screen, sa, ar, VIEW3D_GGT_xform_gizmo);
}
static void WIDGETGROUP_gizmo_draw_prepare(const bContext *C, wmGizmoGroup *gzgroup)
{
- GizmoGroup *ggd = gzgroup->customdata;
- // ScrArea *sa = CTX_wm_area(C);
- ARegion *ar = CTX_wm_region(C);
- // View3D *v3d = sa->spacedata.first;
- RegionView3D *rv3d = ar->regiondata;
- float viewinv_m3[3][3];
- copy_m3_m4(viewinv_m3, rv3d->viewinv);
- float idot[3];
-
- /* 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])) < 1e-6f) {
- MAN_ITER_AXES_BEGIN(axis, axis_idx)
- {
- WM_gizmo_set_flag(axis, WM_GIZMO_HIDDEN, true);
- }
- 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)) {
- WM_gizmo_set_flag(axis, WM_GIZMO_HIDDEN, false);
- }
- else {
- WM_gizmo_set_flag(axis, WM_GIZMO_HIDDEN, true);
- 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);
-
- switch (axis_idx) {
- case MAN_AXIS_TRANS_C:
- case MAN_AXIS_ROT_C:
- case MAN_AXIS_SCALE_C:
- case MAN_AXIS_ROT_T:
- WM_gizmo_set_matrix_rotation_from_z_axis(axis, rv3d->viewinv[2]);
- break;
- }
- } MAN_ITER_AXES_END;
-
- /* Refresh handled above when using view orientation. */
- if (!equals_m3m3(viewinv_m3, ggd->prev.viewinv_m3)) {
- {
- Scene *scene = CTX_data_scene(C);
- const TransformOrientationSlot *orient_slot = BKE_scene_orientation_slot_get_from_flag(scene, ggd->twtype_init);
- switch (orient_slot->type) {
- case V3D_ORIENT_VIEW:
- {
- WIDGETGROUP_gizmo_refresh(C, gzgroup);
- break;
- }
- }
- }
- copy_m3_m4(ggd->prev.viewinv_m3, rv3d->viewinv);
- }
-
+ GizmoGroup *ggd = gzgroup->customdata;
+ // ScrArea *sa = CTX_wm_area(C);
+ ARegion *ar = CTX_wm_region(C);
+ // View3D *v3d = sa->spacedata.first;
+ RegionView3D *rv3d = ar->regiondata;
+ float viewinv_m3[3][3];
+ copy_m3_m4(viewinv_m3, rv3d->viewinv);
+ float idot[3];
+
+ /* 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])) < 1e-6f) {
+ MAN_ITER_AXES_BEGIN (axis, axis_idx) {
+ WM_gizmo_set_flag(axis, WM_GIZMO_HIDDEN, true);
+ }
+ 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)) {
+ WM_gizmo_set_flag(axis, WM_GIZMO_HIDDEN, false);
+ }
+ else {
+ WM_gizmo_set_flag(axis, WM_GIZMO_HIDDEN, true);
+ 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);
+
+ switch (axis_idx) {
+ case MAN_AXIS_TRANS_C:
+ case MAN_AXIS_ROT_C:
+ case MAN_AXIS_SCALE_C:
+ case MAN_AXIS_ROT_T:
+ WM_gizmo_set_matrix_rotation_from_z_axis(axis, rv3d->viewinv[2]);
+ break;
+ }
+ }
+ MAN_ITER_AXES_END;
+
+ /* Refresh handled above when using view orientation. */
+ if (!equals_m3m3(viewinv_m3, ggd->prev.viewinv_m3)) {
+ {
+ Scene *scene = CTX_data_scene(C);
+ const TransformOrientationSlot *orient_slot = BKE_scene_orientation_slot_get_from_flag(
+ scene, ggd->twtype_init);
+ switch (orient_slot->type) {
+ case V3D_ORIENT_VIEW: {
+ WIDGETGROUP_gizmo_refresh(C, gzgroup);
+ break;
+ }
+ }
+ }
+ copy_m3_m4(ggd->prev.viewinv_m3, rv3d->viewinv);
+ }
}
-static void WIDGETGROUP_gizmo_invoke_prepare(
- const bContext *C, wmGizmoGroup *gzgroup, wmGizmo *gz)
+static void WIDGETGROUP_gizmo_invoke_prepare(const bContext *C, wmGizmoGroup *gzgroup, wmGizmo *gz)
{
- GizmoGroup *ggd = gzgroup->customdata;
-
- /* Support gizmo spesific orientation. */
- if (gz != ggd->gizmos[MAN_AXIS_ROT_T]) {
- Scene *scene = CTX_data_scene(C);
- wmGizmoOpElem *gzop = WM_gizmo_operator_get(gz, 0);
- PointerRNA *ptr = &gzop->ptr;
- PropertyRNA *prop_orient_type = RNA_struct_find_property(ptr, "orient_type");
- const TransformOrientationSlot *orient_slot = BKE_scene_orientation_slot_get_from_flag(scene, ggd->twtype_init);
- if (orient_slot == &scene->orientation_slots[SCE_ORIENT_DEFAULT]) {
- RNA_property_unset(ptr, prop_orient_type);
- }
- else {
- /* TODO: APIfunction */
- int index = BKE_scene_orientation_slot_get_index(orient_slot);
- RNA_property_enum_set(ptr, prop_orient_type, index);
- }
- }
-
- /* 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:
- case MAN_AXIS_TRANS_Y:
- case MAN_AXIS_TRANS_Z:
- axis = axis_idx - MAN_AXIS_TRANS_X; break;
- case MAN_AXIS_SCALE_X:
- case MAN_AXIS_SCALE_Y:
- case MAN_AXIS_SCALE_Z:
- axis = axis_idx - MAN_AXIS_SCALE_X; break;
- }
-
- if (axis != -1) {
- wmWindow *win = CTX_wm_window(C);
- /* Swap single axis for two-axis constraint. */
- bool flip = win->eventstate->shift;
- BLI_assert(axis_idx != -1);
- const short axis_type = gizmo_get_axis_type(axis_idx);
- if (axis_type != MAN_AXES_ROTATE) {
- wmGizmoOpElem *gzop = WM_gizmo_operator_get(gz, 0);
- PointerRNA *ptr = &gzop->ptr;
- PropertyRNA *prop_constraint_axis = RNA_struct_find_property(ptr, "constraint_axis");
- if (prop_constraint_axis) {
- bool constraint[3] = {false};
- constraint[axis] = true;
- if (flip) {
- for (int i = 0; i < ARRAY_SIZE(constraint); i++) {
- constraint[i] = !constraint[i];
- }
- }
- RNA_property_boolean_set_array(ptr, prop_constraint_axis, constraint);
- }
- }
- }
+ GizmoGroup *ggd = gzgroup->customdata;
+
+ /* Support gizmo spesific orientation. */
+ if (gz != ggd->gizmos[MAN_AXIS_ROT_T]) {
+ Scene *scene = CTX_data_scene(C);
+ wmGizmoOpElem *gzop = WM_gizmo_operator_get(gz, 0);
+ PointerRNA *ptr = &gzop->ptr;
+ PropertyRNA *prop_orient_type = RNA_struct_find_property(ptr, "orient_type");
+ const TransformOrientationSlot *orient_slot = BKE_scene_orientation_slot_get_from_flag(
+ scene, ggd->twtype_init);
+ if (orient_slot == &scene->orientation_slots[SCE_ORIENT_DEFAULT]) {
+ RNA_property_unset(ptr, prop_orient_type);
+ }
+ else {
+ /* TODO: APIfunction */
+ int index = BKE_scene_orientation_slot_get_index(orient_slot);
+ RNA_property_enum_set(ptr, prop_orient_type, index);
+ }
+ }
+
+ /* 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:
+ case MAN_AXIS_TRANS_Y:
+ case MAN_AXIS_TRANS_Z:
+ axis = axis_idx - MAN_AXIS_TRANS_X;
+ break;
+ case MAN_AXIS_SCALE_X:
+ case MAN_AXIS_SCALE_Y:
+ case MAN_AXIS_SCALE_Z:
+ axis = axis_idx - MAN_AXIS_SCALE_X;
+ break;
+ }
+
+ if (axis != -1) {
+ wmWindow *win = CTX_wm_window(C);
+ /* Swap single axis for two-axis constraint. */
+ bool flip = win->eventstate->shift;
+ BLI_assert(axis_idx != -1);
+ const short axis_type = gizmo_get_axis_type(axis_idx);
+ if (axis_type != MAN_AXES_ROTATE) {
+ wmGizmoOpElem *gzop = WM_gizmo_operator_get(gz, 0);
+ PointerRNA *ptr = &gzop->ptr;
+ PropertyRNA *prop_constraint_axis = RNA_struct_find_property(ptr, "constraint_axis");
+ if (prop_constraint_axis) {
+ bool constraint[3] = {false};
+ constraint[axis] = true;
+ if (flip) {
+ for (int i = 0; i < ARRAY_SIZE(constraint); i++) {
+ constraint[i] = !constraint[i];
+ }
+ }
+ RNA_property_boolean_set_array(ptr, prop_constraint_axis, constraint);
+ }
+ }
+ }
}
static bool WIDGETGROUP_gizmo_poll_generic(View3D *v3d)
{
- if (v3d->gizmo_flag & V3D_GIZMO_HIDE) {
- return false;
- }
- if (G.moving & (G_TRANSFORM_OBJ | G_TRANSFORM_EDIT)) {
- return false;
- }
- return true;
+ if (v3d->gizmo_flag & V3D_GIZMO_HIDE) {
+ return false;
+ }
+ if (G.moving & (G_TRANSFORM_OBJ | G_TRANSFORM_EDIT)) {
+ return false;
+ }
+ return true;
}
-static bool WIDGETGROUP_gizmo_poll_context(const struct bContext *C, struct wmGizmoGroupType *UNUSED(gzgt))
+static bool WIDGETGROUP_gizmo_poll_context(const struct bContext *C,
+ struct wmGizmoGroupType *UNUSED(gzgt))
{
- ScrArea *sa = CTX_wm_area(C);
- View3D *v3d = sa->spacedata.first;
- if (!WIDGETGROUP_gizmo_poll_generic(v3d)) {
- return false;
- }
-
- const bToolRef *tref = sa->runtime.tool;
- if (v3d->gizmo_flag & V3D_GIZMO_HIDE_CONTEXT) {
- return false;
- }
- if ((v3d->gizmo_show_object & (V3D_GIZMO_SHOW_OBJECT_TRANSLATE | V3D_GIZMO_SHOW_OBJECT_ROTATE | V3D_GIZMO_SHOW_OBJECT_SCALE)) == 0) {
- return false;
- }
-
- /* Don't show if the tool has a gizmo. */
- if (tref && tref->runtime && tref->runtime->gizmo_group[0]) {
- return false;
- }
- return true;
+ ScrArea *sa = CTX_wm_area(C);
+ View3D *v3d = sa->spacedata.first;
+ if (!WIDGETGROUP_gizmo_poll_generic(v3d)) {
+ return false;
+ }
+
+ const bToolRef *tref = sa->runtime.tool;
+ if (v3d->gizmo_flag & V3D_GIZMO_HIDE_CONTEXT) {
+ return false;
+ }
+ if ((v3d->gizmo_show_object & (V3D_GIZMO_SHOW_OBJECT_TRANSLATE | V3D_GIZMO_SHOW_OBJECT_ROTATE |
+ V3D_GIZMO_SHOW_OBJECT_SCALE)) == 0) {
+ return false;
+ }
+
+ /* Don't show if the tool has a gizmo. */
+ if (tref && tref->runtime && tref->runtime->gizmo_group[0]) {
+ return false;
+ }
+ return true;
}
static bool WIDGETGROUP_gizmo_poll_tool(const struct bContext *C, struct wmGizmoGroupType *gzgt)
{
- if (!ED_gizmo_poll_or_unlink_delayed_from_tool(C, gzgt)) {
- return false;
- }
-
- return true;
- ScrArea *sa = CTX_wm_area(C);
- View3D *v3d = sa->spacedata.first;
- if (!WIDGETGROUP_gizmo_poll_generic(v3d)) {
- return false;
- }
-
- if (v3d->gizmo_flag & V3D_GIZMO_HIDE_TOOL) {
- return false;
- }
-
- return true;
+ if (!ED_gizmo_poll_or_unlink_delayed_from_tool(C, gzgt)) {
+ return false;
+ }
+
+ return true;
+ ScrArea *sa = CTX_wm_area(C);
+ View3D *v3d = sa->spacedata.first;
+ if (!WIDGETGROUP_gizmo_poll_generic(v3d)) {
+ return false;
+ }
+
+ if (v3d->gizmo_flag & V3D_GIZMO_HIDE_TOOL) {
+ return false;
+ }
+
+ return true;
}
/* Expose as multiple gizmos so tools use one, persistant context another.
@@ -1950,236 +1954,238 @@ static bool WIDGETGROUP_gizmo_poll_tool(const struct bContext *C, struct wmGizmo
void VIEW3D_GGT_xform_gizmo(wmGizmoGroupType *gzgt)
{
- gzgt->name = "Transform Gizmo";
- gzgt->idname = "VIEW3D_GGT_xform_gizmo";
+ gzgt->name = "Transform Gizmo";
+ gzgt->idname = "VIEW3D_GGT_xform_gizmo";
- gzgt->flag = WM_GIZMOGROUPTYPE_3D;
+ gzgt->flag = WM_GIZMOGROUPTYPE_3D;
- gzgt->gzmap_params.spaceid = SPACE_VIEW3D;
- gzgt->gzmap_params.regionid = RGN_TYPE_WINDOW;
+ gzgt->gzmap_params.spaceid = SPACE_VIEW3D;
+ gzgt->gzmap_params.regionid = RGN_TYPE_WINDOW;
- gzgt->poll = WIDGETGROUP_gizmo_poll_tool;
- gzgt->setup = WIDGETGROUP_gizmo_setup;
- gzgt->refresh = WIDGETGROUP_gizmo_refresh;
- gzgt->message_subscribe = WIDGETGROUP_gizmo_message_subscribe;
- gzgt->draw_prepare = WIDGETGROUP_gizmo_draw_prepare;
- gzgt->invoke_prepare = WIDGETGROUP_gizmo_invoke_prepare;
+ gzgt->poll = WIDGETGROUP_gizmo_poll_tool;
+ gzgt->setup = WIDGETGROUP_gizmo_setup;
+ gzgt->refresh = WIDGETGROUP_gizmo_refresh;
+ gzgt->message_subscribe = WIDGETGROUP_gizmo_message_subscribe;
+ gzgt->draw_prepare = WIDGETGROUP_gizmo_draw_prepare;
+ gzgt->invoke_prepare = WIDGETGROUP_gizmo_invoke_prepare;
}
/** Only poll, flag & gzmap_params differ. */
void VIEW3D_GGT_xform_gizmo_context(wmGizmoGroupType *gzgt)
{
- gzgt->name = "Transform Gizmo Context";
- gzgt->idname = "VIEW3D_GGT_xform_gizmo_context";
+ gzgt->name = "Transform Gizmo Context";
+ gzgt->idname = "VIEW3D_GGT_xform_gizmo_context";
- gzgt->flag = WM_GIZMOGROUPTYPE_3D | WM_GIZMOGROUPTYPE_PERSISTENT;
+ gzgt->flag = WM_GIZMOGROUPTYPE_3D | WM_GIZMOGROUPTYPE_PERSISTENT;
- gzgt->poll = WIDGETGROUP_gizmo_poll_context;
- gzgt->setup = WIDGETGROUP_gizmo_setup;
- gzgt->refresh = WIDGETGROUP_gizmo_refresh;
- gzgt->message_subscribe = WIDGETGROUP_gizmo_message_subscribe;
- gzgt->draw_prepare = WIDGETGROUP_gizmo_draw_prepare;
- gzgt->invoke_prepare = WIDGETGROUP_gizmo_invoke_prepare;
+ gzgt->poll = WIDGETGROUP_gizmo_poll_context;
+ gzgt->setup = WIDGETGROUP_gizmo_setup;
+ gzgt->refresh = WIDGETGROUP_gizmo_refresh;
+ gzgt->message_subscribe = WIDGETGROUP_gizmo_message_subscribe;
+ gzgt->draw_prepare = WIDGETGROUP_gizmo_draw_prepare;
+ gzgt->invoke_prepare = WIDGETGROUP_gizmo_invoke_prepare;
}
/** \} */
-
/* -------------------------------------------------------------------- */
/** \name Scale Cage Gizmo
* \{ */
struct XFormCageWidgetGroup {
- wmGizmo *gizmo;
- /* Only for view orientation. */
- struct {
- float viewinv_m3[3][3];
- } prev;
+ wmGizmo *gizmo;
+ /* Only for view orientation. */
+ struct {
+ float viewinv_m3[3][3];
+ } prev;
};
static bool WIDGETGROUP_xform_cage_poll(const bContext *C, wmGizmoGroupType *gzgt)
{
- if (!ED_gizmo_poll_or_unlink_delayed_from_tool(C, gzgt)) {
- return false;
- }
- View3D *v3d = CTX_wm_view3d(C);
- if (v3d->gizmo_flag & (V3D_GIZMO_HIDE | V3D_GIZMO_HIDE_TOOL)) {
- return false;
- }
- if (G.moving & (G_TRANSFORM_OBJ | G_TRANSFORM_EDIT)) {
- return false;
- }
- return true;
+ if (!ED_gizmo_poll_or_unlink_delayed_from_tool(C, gzgt)) {
+ return false;
+ }
+ View3D *v3d = CTX_wm_view3d(C);
+ if (v3d->gizmo_flag & (V3D_GIZMO_HIDE | V3D_GIZMO_HIDE_TOOL)) {
+ return false;
+ }
+ if (G.moving & (G_TRANSFORM_OBJ | G_TRANSFORM_EDIT)) {
+ return false;
+ }
+ return true;
}
static void WIDGETGROUP_xform_cage_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup)
{
- struct XFormCageWidgetGroup *xgzgroup = MEM_mallocN(sizeof(struct XFormCageWidgetGroup), __func__);
- const wmGizmoType *gzt_cage = WM_gizmotype_find("GIZMO_GT_cage_3d", true);
- xgzgroup->gizmo = WM_gizmo_new_ptr(gzt_cage, gzgroup, NULL);
- wmGizmo *gz = xgzgroup->gizmo;
-
- RNA_enum_set(gz->ptr, "transform",
- ED_GIZMO_CAGE2D_XFORM_FLAG_SCALE |
- ED_GIZMO_CAGE2D_XFORM_FLAG_TRANSLATE);
-
- gz->color[0] = 1;
- gz->color_hi[0] = 1;
-
- gzgroup->customdata = xgzgroup;
-
- {
- wmOperatorType *ot_resize = WM_operatortype_find("TRANSFORM_OT_resize", true);
- PointerRNA *ptr;
-
- /* assign operator */
- PropertyRNA *prop_release_confirm = NULL;
- PropertyRNA *prop_constraint_axis = NULL;
-
- int i = ED_GIZMO_CAGE3D_PART_SCALE_MIN_X_MIN_Y_MIN_Z;
- for (int x = 0; x < 3; x++) {
- for (int y = 0; y < 3; y++) {
- for (int z = 0; z < 3; z++) {
- bool constraint[3] = {x != 1, y != 1, z != 1};
- ptr = WM_gizmo_operator_set(gz, i, ot_resize, NULL);
- if (prop_release_confirm == NULL) {
- prop_release_confirm = RNA_struct_find_property(ptr, "release_confirm");
- prop_constraint_axis = RNA_struct_find_property(ptr, "constraint_axis");
- }
- RNA_property_boolean_set(ptr, prop_release_confirm, true);
- RNA_property_boolean_set_array(ptr, prop_constraint_axis, constraint);
- i++;
- }
- }
- }
- }
+ struct XFormCageWidgetGroup *xgzgroup = MEM_mallocN(sizeof(struct XFormCageWidgetGroup),
+ __func__);
+ const wmGizmoType *gzt_cage = WM_gizmotype_find("GIZMO_GT_cage_3d", true);
+ xgzgroup->gizmo = WM_gizmo_new_ptr(gzt_cage, gzgroup, NULL);
+ wmGizmo *gz = xgzgroup->gizmo;
+
+ RNA_enum_set(gz->ptr,
+ "transform",
+ ED_GIZMO_CAGE2D_XFORM_FLAG_SCALE | ED_GIZMO_CAGE2D_XFORM_FLAG_TRANSLATE);
+
+ gz->color[0] = 1;
+ gz->color_hi[0] = 1;
+
+ gzgroup->customdata = xgzgroup;
+
+ {
+ wmOperatorType *ot_resize = WM_operatortype_find("TRANSFORM_OT_resize", true);
+ PointerRNA *ptr;
+
+ /* assign operator */
+ PropertyRNA *prop_release_confirm = NULL;
+ PropertyRNA *prop_constraint_axis = NULL;
+
+ int i = ED_GIZMO_CAGE3D_PART_SCALE_MIN_X_MIN_Y_MIN_Z;
+ for (int x = 0; x < 3; x++) {
+ for (int y = 0; y < 3; y++) {
+ for (int z = 0; z < 3; z++) {
+ bool constraint[3] = {x != 1, y != 1, z != 1};
+ ptr = WM_gizmo_operator_set(gz, i, ot_resize, NULL);
+ if (prop_release_confirm == NULL) {
+ prop_release_confirm = RNA_struct_find_property(ptr, "release_confirm");
+ prop_constraint_axis = RNA_struct_find_property(ptr, "constraint_axis");
+ }
+ RNA_property_boolean_set(ptr, prop_release_confirm, true);
+ RNA_property_boolean_set_array(ptr, prop_constraint_axis, constraint);
+ i++;
+ }
+ }
+ }
+ }
}
static void WIDGETGROUP_xform_cage_refresh(const bContext *C, wmGizmoGroup *gzgroup)
{
- ARegion *ar = CTX_wm_region(C);
- RegionView3D *rv3d = ar->regiondata;
- Scene *scene = CTX_data_scene(C);
-
- struct XFormCageWidgetGroup *xgzgroup = gzgroup->customdata;
- wmGizmo *gz = xgzgroup->gizmo;
-
- struct TransformBounds tbounds;
-
- const TransformOrientationSlot *orient_slot = BKE_scene_orientation_slot_get(scene, SCE_ORIENT_SCALE);
-
- if ((ED_transform_calc_gizmo_stats(
- C, &(struct TransformCalcParams) {
- .use_local_axis = true,
- .orientation_type = orient_slot->type + 1,
- .orientation_index_custom = orient_slot->index_custom,
- }, &tbounds) == 0) ||
- equals_v3v3(rv3d->tw_axis_min, rv3d->tw_axis_max))
- {
- WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, true);
- }
- else {
- gizmo_prepare_mat(C, rv3d, &tbounds);
-
- WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, false);
- WM_gizmo_set_flag(gz, WM_GIZMO_MOVE_CURSOR, true);
-
- float dims[3];
- sub_v3_v3v3(dims, rv3d->tw_axis_max, rv3d->tw_axis_min);
- RNA_float_set_array(gz->ptr, "dimensions", dims);
- mul_v3_fl(dims, 0.5f);
-
- copy_m4_m3(gz->matrix_offset, rv3d->tw_axis_matrix);
- mid_v3_v3v3(gz->matrix_offset[3], rv3d->tw_axis_max, rv3d->tw_axis_min);
- mul_m3_v3(rv3d->tw_axis_matrix, gz->matrix_offset[3]);
-
- float matrix_offset_global[4][4];
- mul_m4_m4m4(matrix_offset_global, gz->matrix_space, gz->matrix_offset);
-
- PropertyRNA *prop_center_override = NULL;
- float center[3];
- float center_global[3];
- int i = ED_GIZMO_CAGE3D_PART_SCALE_MIN_X_MIN_Y_MIN_Z;
- for (int x = 0; x < 3; x++) {
- center[0] = (float)(1 - x) * dims[0];
- for (int y = 0; y < 3; y++) {
- center[1] = (float)(1 - y) * dims[1];
- for (int z = 0; z < 3; z++) {
- center[2] = (float)(1 - z) * dims[2];
- struct wmGizmoOpElem *gzop = WM_gizmo_operator_get(gz, i);
- if (prop_center_override == NULL) {
- prop_center_override = RNA_struct_find_property(&gzop->ptr, "center_override");
- }
- mul_v3_m4v3(center_global, matrix_offset_global, center);
- RNA_property_float_set_array(&gzop->ptr, prop_center_override, center_global);
- i++;
- }
- }
- }
- }
-
- /* Needed to test view orientation changes. */
- copy_m3_m4(xgzgroup->prev.viewinv_m3, rv3d->viewinv);
+ ARegion *ar = CTX_wm_region(C);
+ RegionView3D *rv3d = ar->regiondata;
+ Scene *scene = CTX_data_scene(C);
+
+ struct XFormCageWidgetGroup *xgzgroup = gzgroup->customdata;
+ wmGizmo *gz = xgzgroup->gizmo;
+
+ struct TransformBounds tbounds;
+
+ const TransformOrientationSlot *orient_slot = BKE_scene_orientation_slot_get(scene,
+ SCE_ORIENT_SCALE);
+
+ if ((ED_transform_calc_gizmo_stats(C,
+ &(struct TransformCalcParams){
+ .use_local_axis = true,
+ .orientation_type = orient_slot->type + 1,
+ .orientation_index_custom = orient_slot->index_custom,
+ },
+ &tbounds) == 0) ||
+ equals_v3v3(rv3d->tw_axis_min, rv3d->tw_axis_max)) {
+ WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, true);
+ }
+ else {
+ gizmo_prepare_mat(C, rv3d, &tbounds);
+
+ WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, false);
+ WM_gizmo_set_flag(gz, WM_GIZMO_MOVE_CURSOR, true);
+
+ float dims[3];
+ sub_v3_v3v3(dims, rv3d->tw_axis_max, rv3d->tw_axis_min);
+ RNA_float_set_array(gz->ptr, "dimensions", dims);
+ mul_v3_fl(dims, 0.5f);
+
+ copy_m4_m3(gz->matrix_offset, rv3d->tw_axis_matrix);
+ mid_v3_v3v3(gz->matrix_offset[3], rv3d->tw_axis_max, rv3d->tw_axis_min);
+ mul_m3_v3(rv3d->tw_axis_matrix, gz->matrix_offset[3]);
+
+ float matrix_offset_global[4][4];
+ mul_m4_m4m4(matrix_offset_global, gz->matrix_space, gz->matrix_offset);
+
+ PropertyRNA *prop_center_override = NULL;
+ float center[3];
+ float center_global[3];
+ int i = ED_GIZMO_CAGE3D_PART_SCALE_MIN_X_MIN_Y_MIN_Z;
+ for (int x = 0; x < 3; x++) {
+ center[0] = (float)(1 - x) * dims[0];
+ for (int y = 0; y < 3; y++) {
+ center[1] = (float)(1 - y) * dims[1];
+ for (int z = 0; z < 3; z++) {
+ center[2] = (float)(1 - z) * dims[2];
+ struct wmGizmoOpElem *gzop = WM_gizmo_operator_get(gz, i);
+ if (prop_center_override == NULL) {
+ prop_center_override = RNA_struct_find_property(&gzop->ptr, "center_override");
+ }
+ mul_v3_m4v3(center_global, matrix_offset_global, center);
+ RNA_property_float_set_array(&gzop->ptr, prop_center_override, center_global);
+ i++;
+ }
+ }
+ }
+ }
+
+ /* Needed to test view orientation changes. */
+ copy_m3_m4(xgzgroup->prev.viewinv_m3, rv3d->viewinv);
}
-static void WIDGETGROUP_xform_cage_message_subscribe(
- const bContext *C, wmGizmoGroup *gzgroup, struct wmMsgBus *mbus)
+static void WIDGETGROUP_xform_cage_message_subscribe(const bContext *C,
+ wmGizmoGroup *gzgroup,
+ struct wmMsgBus *mbus)
{
- Scene *scene = CTX_data_scene(C);
- bScreen *screen = CTX_wm_screen(C);
- ScrArea *sa = CTX_wm_area(C);
- ARegion *ar = CTX_wm_region(C);
- gizmo_xform_message_subscribe(gzgroup, mbus, scene, screen, sa, ar, VIEW3D_GGT_xform_cage);
+ Scene *scene = CTX_data_scene(C);
+ bScreen *screen = CTX_wm_screen(C);
+ ScrArea *sa = CTX_wm_area(C);
+ ARegion *ar = CTX_wm_region(C);
+ gizmo_xform_message_subscribe(gzgroup, mbus, scene, screen, sa, ar, VIEW3D_GGT_xform_cage);
}
static void WIDGETGROUP_xform_cage_draw_prepare(const bContext *C, wmGizmoGroup *gzgroup)
{
- struct XFormCageWidgetGroup *xgzgroup = gzgroup->customdata;
- wmGizmo *gz = xgzgroup->gizmo;
- ViewLayer *view_layer = CTX_data_view_layer(C);
- Object *ob = OBACT(view_layer);
- if (ob && ob->mode & OB_MODE_EDIT) {
- copy_m4_m4(gz->matrix_space, ob->obmat);
- }
- else {
- unit_m4(gz->matrix_space);
- }
-
- RegionView3D *rv3d = CTX_wm_region_view3d(C);
- {
- Scene *scene = CTX_data_scene(C);
- const TransformOrientationSlot *orient_slot = BKE_scene_orientation_slot_get(scene, SCE_ORIENT_SCALE);
- switch (orient_slot->type) {
- case V3D_ORIENT_VIEW:
- {
- float viewinv_m3[3][3];
- copy_m3_m4(viewinv_m3, rv3d->viewinv);
- if (!equals_m3m3(viewinv_m3, xgzgroup->prev.viewinv_m3)) {
- /* Take care calling refresh from draw_prepare,
- * this should be OK because it's only adjusting the cage orientation. */
- WIDGETGROUP_xform_cage_refresh(C, gzgroup);
- }
- break;
- }
- }
- }
+ struct XFormCageWidgetGroup *xgzgroup = gzgroup->customdata;
+ wmGizmo *gz = xgzgroup->gizmo;
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ Object *ob = OBACT(view_layer);
+ if (ob && ob->mode & OB_MODE_EDIT) {
+ copy_m4_m4(gz->matrix_space, ob->obmat);
+ }
+ else {
+ unit_m4(gz->matrix_space);
+ }
+
+ RegionView3D *rv3d = CTX_wm_region_view3d(C);
+ {
+ Scene *scene = CTX_data_scene(C);
+ const TransformOrientationSlot *orient_slot = BKE_scene_orientation_slot_get(scene,
+ SCE_ORIENT_SCALE);
+ switch (orient_slot->type) {
+ case V3D_ORIENT_VIEW: {
+ float viewinv_m3[3][3];
+ copy_m3_m4(viewinv_m3, rv3d->viewinv);
+ if (!equals_m3m3(viewinv_m3, xgzgroup->prev.viewinv_m3)) {
+ /* Take care calling refresh from draw_prepare,
+ * this should be OK because it's only adjusting the cage orientation. */
+ WIDGETGROUP_xform_cage_refresh(C, gzgroup);
+ }
+ break;
+ }
+ }
+ }
}
void VIEW3D_GGT_xform_cage(wmGizmoGroupType *gzgt)
{
- gzgt->name = "Transform Cage";
- gzgt->idname = "VIEW3D_GGT_xform_cage";
+ gzgt->name = "Transform Cage";
+ gzgt->idname = "VIEW3D_GGT_xform_cage";
- gzgt->flag |= WM_GIZMOGROUPTYPE_3D;
+ gzgt->flag |= WM_GIZMOGROUPTYPE_3D;
- gzgt->gzmap_params.spaceid = SPACE_VIEW3D;
- gzgt->gzmap_params.regionid = RGN_TYPE_WINDOW;
+ gzgt->gzmap_params.spaceid = SPACE_VIEW3D;
+ gzgt->gzmap_params.regionid = RGN_TYPE_WINDOW;
- gzgt->poll = WIDGETGROUP_xform_cage_poll;
- gzgt->setup = WIDGETGROUP_xform_cage_setup;
- gzgt->refresh = WIDGETGROUP_xform_cage_refresh;
- gzgt->message_subscribe = WIDGETGROUP_xform_cage_message_subscribe;
- gzgt->draw_prepare = WIDGETGROUP_xform_cage_draw_prepare;
+ gzgt->poll = WIDGETGROUP_xform_cage_poll;
+ gzgt->setup = WIDGETGROUP_xform_cage_setup;
+ gzgt->refresh = WIDGETGROUP_xform_cage_refresh;
+ gzgt->message_subscribe = WIDGETGROUP_xform_cage_message_subscribe;
+ gzgt->draw_prepare = WIDGETGROUP_xform_cage_draw_prepare;
}
/** \} */
@@ -2189,177 +2195,180 @@ void VIEW3D_GGT_xform_cage(wmGizmoGroupType *gzgt)
* \{ */
struct XFormShearWidgetGroup {
- wmGizmo *gizmo[3][2];
- /* Only for view orientation. */
- struct {
- float viewinv_m3[3][3];
- } prev;
+ wmGizmo *gizmo[3][2];
+ /* Only for view orientation. */
+ struct {
+ float viewinv_m3[3][3];
+ } prev;
};
static bool WIDGETGROUP_xform_shear_poll(const bContext *C, wmGizmoGroupType *gzgt)
{
- if (!ED_gizmo_poll_or_unlink_delayed_from_tool(C, gzgt)) {
- return false;
- }
- View3D *v3d = CTX_wm_view3d(C);
- if (v3d->gizmo_flag & (V3D_GIZMO_HIDE | V3D_GIZMO_HIDE_TOOL)) {
- return false;
- }
- return true;
+ if (!ED_gizmo_poll_or_unlink_delayed_from_tool(C, gzgt)) {
+ return false;
+ }
+ View3D *v3d = CTX_wm_view3d(C);
+ if (v3d->gizmo_flag & (V3D_GIZMO_HIDE | V3D_GIZMO_HIDE_TOOL)) {
+ return false;
+ }
+ return true;
}
static void WIDGETGROUP_xform_shear_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup)
{
- struct XFormShearWidgetGroup *xgzgroup = MEM_mallocN(sizeof(struct XFormShearWidgetGroup), __func__);
- const wmGizmoType *gzt_arrow = WM_gizmotype_find("GIZMO_GT_arrow_3d", true);
- wmOperatorType *ot_shear = WM_operatortype_find("TRANSFORM_OT_shear", true);
-
- float axis_color[3][3];
- for (int i = 0; i < 3; i++) {
- UI_GetThemeColor3fv(TH_AXIS_X + i, axis_color[i]);
- }
-
- for (int i = 0; i < 3; i++) {
- for (int j = 0; j < 2; j++) {
- wmGizmo *gz = WM_gizmo_new_ptr(gzt_arrow, gzgroup, NULL);
- RNA_enum_set(gz->ptr, "draw_style", ED_GIZMO_ARROW_STYLE_BOX);
- const int i_ortho_a = (i + j + 1) % 3;
- const int i_ortho_b = (i + (1 - j) + 1) % 3;
- interp_v3_v3v3(gz->color, axis_color[i_ortho_a], axis_color[i_ortho_b], 0.75f);
- gz->color[3] = 0.5f;
- PointerRNA *ptr = WM_gizmo_operator_set(gz, 0, ot_shear, NULL);
- RNA_enum_set(ptr, "shear_axis", 0);
- RNA_boolean_set(ptr, "release_confirm", 1);
- xgzgroup->gizmo[i][j] = gz;
- }
- }
-
- gzgroup->customdata = xgzgroup;
+ struct XFormShearWidgetGroup *xgzgroup = MEM_mallocN(sizeof(struct XFormShearWidgetGroup),
+ __func__);
+ const wmGizmoType *gzt_arrow = WM_gizmotype_find("GIZMO_GT_arrow_3d", true);
+ wmOperatorType *ot_shear = WM_operatortype_find("TRANSFORM_OT_shear", true);
+
+ float axis_color[3][3];
+ for (int i = 0; i < 3; i++) {
+ UI_GetThemeColor3fv(TH_AXIS_X + i, axis_color[i]);
+ }
+
+ for (int i = 0; i < 3; i++) {
+ for (int j = 0; j < 2; j++) {
+ wmGizmo *gz = WM_gizmo_new_ptr(gzt_arrow, gzgroup, NULL);
+ RNA_enum_set(gz->ptr, "draw_style", ED_GIZMO_ARROW_STYLE_BOX);
+ const int i_ortho_a = (i + j + 1) % 3;
+ const int i_ortho_b = (i + (1 - j) + 1) % 3;
+ interp_v3_v3v3(gz->color, axis_color[i_ortho_a], axis_color[i_ortho_b], 0.75f);
+ gz->color[3] = 0.5f;
+ PointerRNA *ptr = WM_gizmo_operator_set(gz, 0, ot_shear, NULL);
+ RNA_enum_set(ptr, "shear_axis", 0);
+ RNA_boolean_set(ptr, "release_confirm", 1);
+ xgzgroup->gizmo[i][j] = gz;
+ }
+ }
+
+ gzgroup->customdata = xgzgroup;
}
static void WIDGETGROUP_xform_shear_refresh(const bContext *C, wmGizmoGroup *gzgroup)
{
- Scene *scene = CTX_data_scene(C);
- ARegion *ar = CTX_wm_region(C);
- RegionView3D *rv3d = ar->regiondata;
-
- struct XFormShearWidgetGroup *xgzgroup = gzgroup->customdata;
- struct TransformBounds tbounds;
-
- const TransformOrientationSlot *orient_slot = BKE_scene_orientation_slot_get(scene, SCE_ORIENT_ROTATE);
-
- if (ED_transform_calc_gizmo_stats(
- C, &(struct TransformCalcParams) {
- .use_local_axis = false,
- .orientation_type = orient_slot->type + 1,
- .orientation_index_custom = orient_slot->index_custom,
- }, &tbounds) == 0)
- {
- for (int i = 0; i < 3; i++) {
- for (int j = 0; j < 2; j++) {
- wmGizmo *gz = xgzgroup->gizmo[i][j];
- WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, true);
- }
- }
- }
- else {
- gizmo_prepare_mat(C, rv3d, &tbounds);
- for (int i = 0; i < 3; i++) {
- for (int j = 0; j < 2; j++) {
- wmGizmo *gz = xgzgroup->gizmo[i][j];
- WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, false);
- WM_gizmo_set_flag(gz, WM_GIZMO_MOVE_CURSOR, true);
-
- wmGizmoOpElem *gzop = WM_gizmo_operator_get(gz, 0);
- const int i_ortho_a = (i + j + 1) % 3;
- const int i_ortho_b = (i + (1 - j) + 1) % 3;
- WM_gizmo_set_matrix_rotation_from_yz_axis(gz, rv3d->twmat[i_ortho_a], rv3d->twmat[i]);
- WM_gizmo_set_matrix_location(gz, rv3d->twmat[3]);
-
- RNA_float_set_array(&gzop->ptr, "orient_matrix", &tbounds.axis[0][0]);
- RNA_enum_set(&gzop->ptr, "orient_type", orient_slot->type);
-
- RNA_enum_set(&gzop->ptr, "orient_axis", i_ortho_b);
- RNA_enum_set(&gzop->ptr, "orient_axis_ortho", i_ortho_a);
-
- mul_v3_fl(gz->matrix_basis[0], 0.5f);
- mul_v3_fl(gz->matrix_basis[1], 6.0f);
- }
- }
- }
-
- /* Needed to test view orientation changes. */
- copy_m3_m4(xgzgroup->prev.viewinv_m3, rv3d->viewinv);
+ Scene *scene = CTX_data_scene(C);
+ ARegion *ar = CTX_wm_region(C);
+ RegionView3D *rv3d = ar->regiondata;
+
+ struct XFormShearWidgetGroup *xgzgroup = gzgroup->customdata;
+ struct TransformBounds tbounds;
+
+ const TransformOrientationSlot *orient_slot = BKE_scene_orientation_slot_get(scene,
+ SCE_ORIENT_ROTATE);
+
+ if (ED_transform_calc_gizmo_stats(C,
+ &(struct TransformCalcParams){
+ .use_local_axis = false,
+ .orientation_type = orient_slot->type + 1,
+ .orientation_index_custom = orient_slot->index_custom,
+ },
+ &tbounds) == 0) {
+ for (int i = 0; i < 3; i++) {
+ for (int j = 0; j < 2; j++) {
+ wmGizmo *gz = xgzgroup->gizmo[i][j];
+ WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, true);
+ }
+ }
+ }
+ else {
+ gizmo_prepare_mat(C, rv3d, &tbounds);
+ for (int i = 0; i < 3; i++) {
+ for (int j = 0; j < 2; j++) {
+ wmGizmo *gz = xgzgroup->gizmo[i][j];
+ WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, false);
+ WM_gizmo_set_flag(gz, WM_GIZMO_MOVE_CURSOR, true);
+
+ wmGizmoOpElem *gzop = WM_gizmo_operator_get(gz, 0);
+ const int i_ortho_a = (i + j + 1) % 3;
+ const int i_ortho_b = (i + (1 - j) + 1) % 3;
+ WM_gizmo_set_matrix_rotation_from_yz_axis(gz, rv3d->twmat[i_ortho_a], rv3d->twmat[i]);
+ WM_gizmo_set_matrix_location(gz, rv3d->twmat[3]);
+
+ RNA_float_set_array(&gzop->ptr, "orient_matrix", &tbounds.axis[0][0]);
+ RNA_enum_set(&gzop->ptr, "orient_type", orient_slot->type);
+
+ RNA_enum_set(&gzop->ptr, "orient_axis", i_ortho_b);
+ RNA_enum_set(&gzop->ptr, "orient_axis_ortho", i_ortho_a);
+
+ mul_v3_fl(gz->matrix_basis[0], 0.5f);
+ mul_v3_fl(gz->matrix_basis[1], 6.0f);
+ }
+ }
+ }
+
+ /* Needed to test view orientation changes. */
+ copy_m3_m4(xgzgroup->prev.viewinv_m3, rv3d->viewinv);
}
-static void WIDGETGROUP_xform_shear_message_subscribe(
- const bContext *C, wmGizmoGroup *gzgroup, struct wmMsgBus *mbus)
+static void WIDGETGROUP_xform_shear_message_subscribe(const bContext *C,
+ wmGizmoGroup *gzgroup,
+ struct wmMsgBus *mbus)
{
- Scene *scene = CTX_data_scene(C);
- bScreen *screen = CTX_wm_screen(C);
- ScrArea *sa = CTX_wm_area(C);
- ARegion *ar = CTX_wm_region(C);
- gizmo_xform_message_subscribe(gzgroup, mbus, scene, screen, sa, ar, VIEW3D_GGT_xform_shear);
+ Scene *scene = CTX_data_scene(C);
+ bScreen *screen = CTX_wm_screen(C);
+ ScrArea *sa = CTX_wm_area(C);
+ ARegion *ar = CTX_wm_region(C);
+ gizmo_xform_message_subscribe(gzgroup, mbus, scene, screen, sa, ar, VIEW3D_GGT_xform_shear);
}
static void WIDGETGROUP_xform_shear_draw_prepare(const bContext *C, wmGizmoGroup *gzgroup)
{
- struct XFormShearWidgetGroup *xgzgroup = gzgroup->customdata;
- RegionView3D *rv3d = CTX_wm_region_view3d(C);
- {
- Scene *scene = CTX_data_scene(C);
- /* Shear is like rotate, use the rotate setting. */
- const TransformOrientationSlot *orient_slot = BKE_scene_orientation_slot_get(scene, SCE_ORIENT_ROTATE);
- switch (orient_slot->type) {
- case V3D_ORIENT_VIEW:
- {
- float viewinv_m3[3][3];
- copy_m3_m4(viewinv_m3, rv3d->viewinv);
- if (!equals_m3m3(viewinv_m3, xgzgroup->prev.viewinv_m3)) {
- /* Take care calling refresh from draw_prepare,
- * this should be OK because it's only adjusting the cage orientation. */
- WIDGETGROUP_xform_shear_refresh(C, gzgroup);
- }
- break;
- }
- }
- }
-
- /* Basic ordering for drawing only. */
- {
- LISTBASE_FOREACH (wmGizmo *, gz, &gzgroup->gizmos) {
- /* Since we have two pairs of each axis,
- * bias the values so gizmos that are orthogonal to the view get priority.
- * This means we never default to shearing along
- * the view axis in the case of an overlap. */
- float axis_order[3], axis_bias[3];
- copy_v3_v3(axis_order, gz->matrix_basis[2]);
- copy_v3_v3(axis_bias, gz->matrix_basis[1]);
- if (dot_v3v3(axis_bias, rv3d->viewinv[2]) < 0.0f) {
- negate_v3(axis_bias);
- }
- madd_v3_v3fl(axis_order, axis_bias, 0.01f);
- gz->temp.f = dot_v3v3(rv3d->viewinv[2], axis_order);
- }
- BLI_listbase_sort(&gzgroup->gizmos, WM_gizmo_cmp_temp_fl_reverse);
- }
+ struct XFormShearWidgetGroup *xgzgroup = gzgroup->customdata;
+ RegionView3D *rv3d = CTX_wm_region_view3d(C);
+ {
+ Scene *scene = CTX_data_scene(C);
+ /* Shear is like rotate, use the rotate setting. */
+ const TransformOrientationSlot *orient_slot = BKE_scene_orientation_slot_get(
+ scene, SCE_ORIENT_ROTATE);
+ switch (orient_slot->type) {
+ case V3D_ORIENT_VIEW: {
+ float viewinv_m3[3][3];
+ copy_m3_m4(viewinv_m3, rv3d->viewinv);
+ if (!equals_m3m3(viewinv_m3, xgzgroup->prev.viewinv_m3)) {
+ /* Take care calling refresh from draw_prepare,
+ * this should be OK because it's only adjusting the cage orientation. */
+ WIDGETGROUP_xform_shear_refresh(C, gzgroup);
+ }
+ break;
+ }
+ }
+ }
+
+ /* Basic ordering for drawing only. */
+ {
+ LISTBASE_FOREACH (wmGizmo *, gz, &gzgroup->gizmos) {
+ /* Since we have two pairs of each axis,
+ * bias the values so gizmos that are orthogonal to the view get priority.
+ * This means we never default to shearing along
+ * the view axis in the case of an overlap. */
+ float axis_order[3], axis_bias[3];
+ copy_v3_v3(axis_order, gz->matrix_basis[2]);
+ copy_v3_v3(axis_bias, gz->matrix_basis[1]);
+ if (dot_v3v3(axis_bias, rv3d->viewinv[2]) < 0.0f) {
+ negate_v3(axis_bias);
+ }
+ madd_v3_v3fl(axis_order, axis_bias, 0.01f);
+ gz->temp.f = dot_v3v3(rv3d->viewinv[2], axis_order);
+ }
+ BLI_listbase_sort(&gzgroup->gizmos, WM_gizmo_cmp_temp_fl_reverse);
+ }
}
void VIEW3D_GGT_xform_shear(wmGizmoGroupType *gzgt)
{
- gzgt->name = "Transform Shear";
- gzgt->idname = "VIEW3D_GGT_xform_shear";
+ gzgt->name = "Transform Shear";
+ gzgt->idname = "VIEW3D_GGT_xform_shear";
- gzgt->flag |= WM_GIZMOGROUPTYPE_3D;
+ gzgt->flag |= WM_GIZMOGROUPTYPE_3D;
- gzgt->gzmap_params.spaceid = SPACE_VIEW3D;
- gzgt->gzmap_params.regionid = RGN_TYPE_WINDOW;
+ gzgt->gzmap_params.spaceid = SPACE_VIEW3D;
+ gzgt->gzmap_params.regionid = RGN_TYPE_WINDOW;
- gzgt->poll = WIDGETGROUP_xform_shear_poll;
- gzgt->setup = WIDGETGROUP_xform_shear_setup;
- gzgt->refresh = WIDGETGROUP_xform_shear_refresh;
- gzgt->message_subscribe = WIDGETGROUP_xform_shear_message_subscribe;
- gzgt->draw_prepare = WIDGETGROUP_xform_shear_draw_prepare;
+ gzgt->poll = WIDGETGROUP_xform_shear_poll;
+ gzgt->setup = WIDGETGROUP_xform_shear_setup;
+ gzgt->refresh = WIDGETGROUP_xform_shear_refresh;
+ gzgt->message_subscribe = WIDGETGROUP_xform_shear_message_subscribe;
+ gzgt->draw_prepare = WIDGETGROUP_xform_shear_draw_prepare;
}
/** \} */