[Bf-blender-cvs] [dd8dcf2] wiggly-widgets: Transform manipulator: New widget for trackball rotation

Julian Eisel noreply at git.blender.org
Sun Feb 7 13:58:18 CET 2016


Commit: dd8dcf2d7f0764ad37a6c69d4e5af285737bbfc5
Author: Julian Eisel
Date:   Sun Feb 7 13:52:02 2016 +0100
Branches: wiggly-widgets
https://developer.blender.org/rBdd8dcf2d7f0764ad37a6c69d4e5af285737bbfc5

Transform manipulator: New widget for trackball rotation

Adds a new (partially invisible) widget to the rotation transform manipulator that triggers trackball rotation. It is activated by clicking inside the outer white circle, but not on any other axis. For better feedback, a slight white overlay is drawn on mouse hover.

===================================================================

M	source/blender/editors/transform/transform_manipulator.c
M	source/blender/windowmanager/WM_api.h
M	source/blender/windowmanager/intern/wm_generic_widgets.c

===================================================================

diff --git a/source/blender/editors/transform/transform_manipulator.c b/source/blender/editors/transform/transform_manipulator.c
index c3b2628..6b12538 100644
--- a/source/blender/editors/transform/transform_manipulator.c
+++ b/source/blender/editors/transform/transform_manipulator.c
@@ -118,6 +118,7 @@ enum {
 	MAN_AXIS_ROT_Y,
 	MAN_AXIS_ROT_Z,
 	MAN_AXIS_ROT_C,
+	MAN_AXIS_ROT_T, /* trackball rotation */
 
 	MAN_AXIS_SCALE_X,
 	MAN_AXIS_SCALE_Y,
@@ -157,6 +158,7 @@ typedef struct ManipulatorGroup {
 	                *rotate_y,
 	                *rotate_z,
 	                *rotate_c,
+	                *rotate_t, /* trackball rotation */
 
 	                *scale_x,
 	                *scale_y,
@@ -210,6 +212,8 @@ static wmWidget *manipulator_get_axis_from_index(const ManipulatorGroup *man, co
 			return man->rotate_z;
 		case MAN_AXIS_ROT_C:
 			return man->rotate_c;
+		case MAN_AXIS_ROT_T:
+			return man->rotate_t;
 		case MAN_AXIS_SCALE_X:
 			return man->scale_x;
 		case MAN_AXIS_SCALE_Y:
@@ -236,7 +240,7 @@ static short manipulator_get_axis_type(const ManipulatorGroup *man, const wmWidg
 	{
 		return MAN_AXES_TRANSLATE;
 	}
-	else if (ELEM(axis, man->rotate_x, man->rotate_y, man->rotate_z, man->rotate_c)) {
+	else if (ELEM(axis, man->rotate_x, man->rotate_y, man->rotate_z, man->rotate_c, man->rotate_t)) {
 		return MAN_AXES_ROTATE;
 	}
 	else {
@@ -248,13 +252,13 @@ static short manipulator_get_axis_type(const ManipulatorGroup *man, const wmWidg
 static int manipulator_index_normalize(const int axis_idx)
 {
 	if (axis_idx > MAN_AXIS_TRANS_ZX) {
-		return axis_idx - 15;
+		return axis_idx - 16;
 	}
 	else if (axis_idx > MAN_AXIS_SCALE_C) {
-		return axis_idx - 12;
+		return axis_idx - 13;
 	}
-	else if (axis_idx > MAN_AXIS_ROT_C) {
-		return axis_idx - 8;
+	else if (axis_idx > MAN_AXIS_ROT_T) {
+		return axis_idx - 9;
 	}
 	else if (axis_idx > MAN_AXIS_TRANS_C) {
 		return axis_idx - 4;
@@ -281,6 +285,7 @@ static bool manipulator_is_axis_visible(const View3D *v3d, const RegionView3D *r
 		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);
@@ -326,18 +331,19 @@ static void manipulator_get_axis_color(const RegionView3D *rv3d, const int axis_
 	/* alpha values for normal/highlighted states */
 	const float alpha = 0.6f;
 	const float alpha_hi = 1.0f;
-	/* get alpha fac based on axis angle, to fade axis out when hiding it because it points towards view */
-	float alpha_fac_view;
+	float alpha_fac;
 
 	const int axis_idx_norm = manipulator_index_normalize(axis_idx);
+	/* 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 = rv3d->tw_idot[axis_idx_norm];
-		alpha_fac_view = (idot > TW_AXIS_DOT_MAX) ?
+		alpha_fac = (idot > TW_AXIS_DOT_MAX) ?
 		        1.0f : (idot < TW_AXIS_DOT_MIN) ?
 		        0.0f : ((idot - TW_AXIS_DOT_MIN) / (TW_AXIS_DOT_MAX - TW_AXIS_DOT_MIN));
 	}
 	else {
-		alpha_fac_view = 1.0f;
+		/* 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;
 	}
 
 	switch (axis_idx) {
@@ -365,14 +371,15 @@ static void manipulator_get_axis_color(const RegionView3D *rv3d, const int axis_
 		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_view;
-	r_col_hi[3] = alpha_hi * alpha_fac_view;
+	r_col[3] = alpha * alpha_fac;
+	r_col_hi[3] = alpha_hi * alpha_fac;
 }
 
 static void manipulator_get_axis_constraint(const int axis_idx, int r_axis[3])
@@ -395,10 +402,6 @@ static void manipulator_get_axis_constraint(const int axis_idx, int r_axis[3])
 		case MAN_AXIS_SCALE_Z:
 			r_axis[2] = 1;
 			break;
-		case MAN_AXIS_TRANS_C:
-		case MAN_AXIS_ROT_C:
-		case MAN_AXIS_SCALE_C:
-			break;
 		case MAN_AXIS_TRANS_XY:
 		case MAN_AXIS_SCALE_XY:
 			r_axis[0] = r_axis[1] = 1;
@@ -411,6 +414,8 @@ static void manipulator_get_axis_constraint(const int axis_idx, int r_axis[3])
 		case MAN_AXIS_SCALE_ZX:
 			r_axis[2] = r_axis[0] = 1;
 			break;
+		default:
+			break;
 	}
 }
 
@@ -1054,6 +1059,9 @@ static ManipulatorGroup *manipulatorgroup_init(
 	man = MEM_callocN(sizeof(ManipulatorGroup), "manipulator_data");
 
 	/* add/init widgets - order matters! */
+	if (init_rot) {
+		man->rotate_t = WIDGET_dial_new(wgroup, "rotate_c", WIDGET_DIAL_STYLE_RING_FILLED);
+	}
 	if (init_scale) {
 		man->scale_c = WIDGET_dial_new(wgroup, "scale_c", WIDGET_DIAL_STYLE_RING);
 		man->scale_x = WIDGET_arrow_new(wgroup, "scale_x", WIDGET_ARROW_STYLE_BOX);
@@ -1210,8 +1218,12 @@ void WIDGETGROUP_manipulator_create(const struct bContext *C, struct wmWidgetGro
 			case MAN_AXIS_TRANS_C:
 			case MAN_AXIS_ROT_C:
 			case MAN_AXIS_SCALE_C:
+			case MAN_AXIS_ROT_T:
 				WIDGET_dial_set_up_vector(axis, rv3d->viewinv[2]);
-				if (axis_idx != MAN_AXIS_ROT_C) {
+				if (axis_idx == MAN_AXIS_ROT_T) {
+					WM_widget_set_flag(axis, WM_WIDGET_DRAW_HOVER, true);
+				}
+				else if (axis_idx != MAN_AXIS_ROT_C) {
 					WM_widget_set_scale(axis, 0.2f);
 				}
 				break;
@@ -1222,13 +1234,16 @@ void WIDGETGROUP_manipulator_create(const struct bContext *C, struct wmWidgetGro
 				ptr = WM_widget_set_operator(axis, "TRANSFORM_OT_translate");
 				break;
 			case MAN_AXES_ROTATE:
-				ptr = WM_widget_set_operator(axis, "TRANSFORM_OT_rotate");
+				ptr = WM_widget_set_operator(
+				          axis, (axis_idx == MAN_AXIS_ROT_T) ?
+				          "TRANSFORM_OT_trackball" : "TRANSFORM_OT_rotate");
 				break;
 			case MAN_AXES_SCALE:
 				ptr = WM_widget_set_operator(axis, "TRANSFORM_OT_resize");
 				break;
 		}
-		RNA_boolean_set_array(ptr, "constraint_axis", constraint_axis);
+		if (RNA_struct_find_property(ptr, "constraint_axis"))
+			RNA_boolean_set_array(ptr, "constraint_axis", constraint_axis);
 		RNA_boolean_set(ptr, "release_confirm", 1);
 	}
 	MAN_ITER_AXES_END;
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index 223c8ef..da0369a 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -615,6 +615,7 @@ enum {
 enum {
 	WIDGET_DIAL_STYLE_RING = 0,
 	WIDGET_DIAL_STYLE_RING_CLIPPED = 1,
+	WIDGET_DIAL_STYLE_RING_FILLED = 2,
 };
 
 enum {
diff --git a/source/blender/windowmanager/intern/wm_generic_widgets.c b/source/blender/windowmanager/intern/wm_generic_widgets.c
index 169b911..81c1915 100644
--- a/source/blender/windowmanager/intern/wm_generic_widgets.c
+++ b/source/blender/windowmanager/intern/wm_generic_widgets.c
@@ -773,12 +773,14 @@ static void dial_draw_geom(const DialWidget *dial, const bool select)
 #else
 	const float width = 1.0f;
 	const int resol = 32;
+	const bool filled = (dial->style == WIDGET_DIAL_STYLE_RING_FILLED);
 
 	glLineWidth(dial->widget.line_width);
 
 	GLUquadricObj *qobj = gluNewQuadric();
-	gluQuadricDrawStyle(qobj, GLU_SILHOUETTE);
-	gluDisk(qobj, 0.0, width, resol, 1);
+	gluQuadricDrawStyle(qobj, filled ? GLU_FILL : GLU_SILHOUETTE);
+	/* inner at 0.0 with silhouette drawing confuses OGL selection, so draw it at width */
+	gluDisk(qobj, filled ? 0.0 : width, width, resol, 1);
 	gluDeleteQuadric(qobj);
 
 	glLineWidth(1.0);




More information about the Bf-blender-cvs mailing list