[Bf-blender-cvs] [8e0c18f] wiggly-widgets: Support and use custom arrow line drawing verts

Julian Eisel noreply at git.blender.org
Tue Aug 18 23:24:14 CEST 2015


Commit: 8e0c18f8ca8152ec761fe04dfa794f401b976b40
Author: Julian Eisel
Date:   Tue Aug 18 23:10:17 2015 +0200
Branches: wiggly-widgets
https://developer.blender.org/rB8e0c18f8ca8152ec761fe04dfa794f401b976b40

Support and use custom arrow line drawing verts

This gives us enough flexibility for some special manipulator drawing with combined axis types (like translate, rotate, scale manipulators enabled all together)
Now we also don't have to use immediate mode drawing.

It might also be interesting to support custom drawing callbacks, but for now this isn't really needed. Let's see!

Based on feedback by @psy-fi

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

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

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

diff --git a/source/blender/editors/transform/manipulator_widget.c b/source/blender/editors/transform/manipulator_widget.c
index 6ce2277..e1ec041 100644
--- a/source/blender/editors/transform/manipulator_widget.c
+++ b/source/blender/editors/transform/manipulator_widget.c
@@ -889,6 +889,35 @@ static void manipulator_prepare_mat(Scene *scene, View3D *v3d, RegionView3D *rv3
 	mul_mat3_m4_fl(rv3d->twmat, ED_view3d_pixel_size(rv3d, rv3d->twmat[3]) * U.tw_size);
 }
 
+/**
+ * Sets up \a r_vec for custom arrow widget line drawing. Needed to
+ * adjust line drawing for combined manipulator axis types.
+ */
+static void manipulator_line_vec(const View3D *v3d, float r_vec[2][3], const short axis_type)
+{
+	const float ofs = 0.2f;
+	float start[3] = {0.0f, 0.0f, 0.2f};
+	float end[3] = {0.0f, 0.0f, 1.0f};
+
+	switch (axis_type) {
+		case MAN_AXES_TRANSLATE:
+			if (v3d->twtype & V3D_MANIP_SCALE) {
+				start[2] = end[2] - ofs;
+			}
+			if (v3d->twtype & V3D_MANIP_ROTATE) {
+				end[2] += ofs;
+			}
+			break;
+		case MAN_AXES_SCALE:
+			if (v3d->twtype & (V3D_MANIP_TRANSLATE | V3D_MANIP_ROTATE)) {
+				end[2] -= ofs;
+			}
+			break;
+	}
+	copy_v3_v3(r_vec[0], start);
+	copy_v3_v3(r_vec[1], end);
+}
+
 
 /* **************** Actual Widget Stuff **************** */
 
@@ -984,13 +1013,14 @@ void WIDGETGROUP_manipulator_draw(const struct bContext *C, struct wmWidgetGroup
 					WIDGET_dial_set_color(axis, col);
 				}
 				else {
-					/* scale for combined use */
-					if (v3d->twtype & V3D_MANIP_ROTATE) {
-						WM_widget_set_scale(axis, 1.15f);
-					}
+					float line_vec[2][3];
+
+					manipulator_line_vec(v3d, line_vec, atype);
+
 					WM_widget_set_line_width(axis, MAN_AXIS_LINE_WIDTH);
 					WIDGET_arrow_set_direction(axis, rv3d->twmat[aidx_norm]);
 					WIDGET_arrow_set_color(axis, col);
+					WIDGET_arrow_set_line_vec(axis, (const float (*)[3])line_vec, ARRAY_SIZE(line_vec));
 				}
 				WM_widget_operator(axis, "TRANSFORM_OT_translate");
 				break;
@@ -1007,7 +1037,7 @@ void WIDGETGROUP_manipulator_draw(const struct bContext *C, struct wmWidgetGroup
 				break;
 			case MAN_AXES_SCALE:
 				if (axis_idx == MAN_AXIS_SCALE_C) {
-					/* only draw  */
+					/* only draw if there isn't already a circle for translate */
 					if ((v3d->twtype & V3D_MANIP_TRANSLATE)) {
 						WM_widget_flag_set(axis, WM_WIDGET_HIDDEN, true);
 					}
@@ -1018,13 +1048,14 @@ void WIDGETGROUP_manipulator_draw(const struct bContext *C, struct wmWidgetGroup
 					}
 				}
 				else {
-					/* scale for combined use */
-					if (v3d->twtype & (V3D_MANIP_TRANSLATE | V3D_MANIP_ROTATE)) {
-						WM_widget_set_scale(axis, 0.85f);
-					}
+					float line_vec[2][3];
+
+					manipulator_line_vec(v3d, line_vec, atype);
+
 					WM_widget_set_line_width(axis, MAN_AXIS_LINE_WIDTH);
 					WIDGET_arrow_set_direction(axis, rv3d->twmat[aidx_norm]);
 					WIDGET_arrow_set_color(axis, col);
+					WIDGET_arrow_set_line_vec(axis, (const float (*)[3])line_vec, ARRAY_SIZE(line_vec));
 				}
 				WM_widget_operator(axis, "TRANSFORM_OT_resize");
 				break;
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index c14efc4..c354de4 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -577,6 +577,7 @@ struct wmWidget *WIDGET_arrow_new(struct wmWidgetGroup *wgroup, const char *name
 void WIDGET_arrow_set_color(struct wmWidget *widget, const float color[4]);
 void WIDGET_arrow_set_direction(struct wmWidget *widget, const float direction[3]);
 void WIDGET_arrow_set_up_vector(struct wmWidget *widget, const float direction[3]);
+void WIDGET_arrow_set_line_vec(struct wmWidget *widget, const float (*vec)[3], const int tot_points);
 void WIDGET_arrow_set_scale(struct wmWidget *widget, const float scale);
 
 struct wmWidget *WIDGET_dial_new(struct wmWidgetGroup *wgroup, const char *name, const int style);
diff --git a/source/blender/windowmanager/intern/wm_generic_widgets.c b/source/blender/windowmanager/intern/wm_generic_widgets.c
index e5d095d..9c75f00 100644
--- a/source/blender/windowmanager/intern/wm_generic_widgets.c
+++ b/source/blender/windowmanager/intern/wm_generic_widgets.c
@@ -160,6 +160,8 @@ typedef struct ArrowWidget {
 	float direction[3];
 	float up[3];
 	float color[4];
+	float (*line)[3];    /* custom coords for arrow line drawing */
+	int tot_line_points; /* amount of points for arrow line drawing */
 	float offset;
 	/* property range and minimum for constrained arrows */
 	float range, min;
@@ -205,15 +207,15 @@ static void arrow_draw_geom(const ArrowWidget *arrow, const bool select)
 		widget_draw_intern(&arraw_head_draw_info, select);
 #else
 		glLineWidth(arrow->widget.line_width);
-		glBegin(GL_LINES);
-		glVertex3f(0.0, 0.0, 0.0);
-		glVertex3f(0.0, 0.0, 1.0);
-		glEnd();
+		glEnableClientState(GL_VERTEX_ARRAY);
+		glVertexPointer(3, GL_FLOAT, 0, arrow->line);
+		glDrawArrays(GL_LINES, 0, arrow->tot_line_points);
+		glDisableClientState(GL_VERTEX_ARRAY);
 		glLineWidth(1.0);
 
 		/* draw arrow head */
 
-		glTranslatef(0.0, 0.0, 1.0);
+		glTranslatef(UNPACK3(arrow->line[arrow->tot_line_points - 1]));
 
 		if (arrow->style & WIDGET_ARROW_STYLE_BOX) {
 			const float size = 0.05;
@@ -253,7 +255,7 @@ static void arrow_draw_geom(const ArrowWidget *arrow, const bool select)
 			glEnableClientState(GL_VERTEX_ARRAY);
 			glScalef(size, size, size);
 			glVertexPointer(3, GL_FLOAT, 0, box);
-			glDrawArrays(GL_QUADS, 0, 24);
+			glDrawArrays(GL_QUADS, 0, ARRAY_SIZE(box));
 			glDisableClientState(GL_VERTEX_ARRAY);
 		}
 		else {
@@ -525,6 +527,10 @@ wmWidget *WIDGET_arrow_new(wmWidgetGroup *wgroup, const char *name, const int st
 {
 	ArrowWidget *arrow;
 	const float dir_default[3] = {0.0f, 0.0f, 1.0f};
+	const float line_default[2][3] = {
+		{0.0f, 0.0f, 0.0f},
+		{0.0f, 0.0f, 1.0f}
+	};
 	int real_style = style;
 
 #ifdef WIDGET_USE_CUSTOM_ARROWS
@@ -542,9 +548,9 @@ wmWidget *WIDGET_arrow_new(wmWidgetGroup *wgroup, const char *name, const int st
 	if (real_style & WIDGET_ARROW_STYLE_INVERTED) {
 		real_style |= WIDGET_ARROW_STYLE_CONSTRAINED;
 	}
-	
+
+
 	arrow = MEM_callocN(sizeof(ArrowWidget), name);
-	
 
 	arrow->widget.draw = widget_arrow_draw;
 	arrow->widget.get_final_position = 	widget_arrow_get_final_pos;
@@ -556,9 +562,12 @@ wmWidget *WIDGET_arrow_new(wmWidgetGroup *wgroup, const char *name, const int st
 	arrow->widget.flag |= WM_WIDGET_SCALE_3D;
 	arrow->style = real_style;
 	copy_v3_v3(arrow->direction, dir_default);
-	
+	arrow->tot_line_points = ARRAY_SIZE(line_default);
+	arrow->line = MEM_mallocN(sizeof(line_default), __func__);
+	memcpy(arrow->line, line_default, sizeof(line_default));
+
 	wm_widget_register(wgroup, &arrow->widget, name);
-	
+
 	return (wmWidget *)arrow;
 }
 
@@ -591,6 +600,19 @@ void WIDGET_arrow_set_up_vector(wmWidget *widget, const float direction[3])
 	}
 }
 
+/**
+ * Define a custom coord vec for arrow line drawing
+ */
+void WIDGET_arrow_set_line_vec(wmWidget *widget, const float (*vec)[3], const int tot_points)
+{
+	ArrowWidget *arrow = (ArrowWidget *)widget;
+	const size_t vec_size = 3 * tot_points * sizeof(float);
+
+	arrow->tot_line_points = tot_points;
+	arrow->line = MEM_reallocN(arrow->line, vec_size);
+	memcpy(arrow->line, vec, vec_size);
+}
+
 
 /********* Dial widget ************/




More information about the Bf-blender-cvs mailing list