[Bf-blender-cvs] [ebe1b4f11f6] blender2.8: Fix rotation manipulators not clipping

Julian Eisel noreply at git.blender.org
Wed Apr 5 01:34:46 CEST 2017


Commit: ebe1b4f11f6240811da407bcf5ce8176cb635d26
Author: Julian Eisel
Date:   Wed Apr 5 01:28:48 2017 +0200
Branches: blender2.8
https://developer.blender.org/rBebe1b4f11f6240811da407bcf5ce8176cb635d26

Fix rotation manipulators not clipping

Added new shader for clipping, also cleaned up rotation manipulator
drawing code a bit.
This code should be replaced by new transform manipulators soon, just
keeping this working in the meanwhile.

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

M	source/blender/editors/transform/transform_manipulator.c
M	source/blender/gpu/CMakeLists.txt
M	source/blender/gpu/GPU_shader.h
M	source/blender/gpu/intern/gpu_shader.c
A	source/blender/gpu/shaders/gpu_shader_3D_clipped_uniform_color_vert.glsl

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

diff --git a/source/blender/editors/transform/transform_manipulator.c b/source/blender/editors/transform/transform_manipulator.c
index a9b3363e0c8..ab5494ff39f 100644
--- a/source/blender/editors/transform/transform_manipulator.c
+++ b/source/blender/editors/transform/transform_manipulator.c
@@ -960,6 +960,22 @@ static void postOrtho(const bool ortho)
 	}
 }
 
+static void twmat_to_rotation_axis_mat(
+        const float twmat[4][4], const int axis, const bool ortho,
+        float r_axis_mat[4][4])
+{
+	copy_m4_m4(r_axis_mat, twmat);
+	if (!ortho) {
+		orthogonalize_m4(r_axis_mat, axis); /* for gimbal */
+	}
+
+	if (ELEM(axis, 0, 1)) {
+		const char rot_axis = (axis == 0) ? 'Y' : 'X';
+		const float angle = (axis == 0) ? M_PI_2 : -M_PI_2;
+		rotate_m4(r_axis_mat, rot_axis, angle);
+	}
+}
+
 BLI_INLINE bool manipulator_rotate_is_visible(const int drawflags)
 {
 	return (drawflags & (MAN_ROT_X | MAN_ROT_Y | MAN_ROT_Z));
@@ -969,12 +985,11 @@ static void draw_manipulator_rotate(
         View3D *v3d, RegionView3D *rv3d, const int drawflags, const int combo,
         const bool is_moving, const bool is_picksel)
 {
-	double plane[4];
 	float matt[4][4];
 	float size, unitmat[4][4];
 	float cywid = 0.33f * 0.01f * (float)U.tw_handlesize;
 	float cusize = cywid * 0.65f;
-	int arcs = (G.debug_value != 2);
+	bool arcs = (G.debug_value != 2);
 	const int colcode = (is_moving) ? MAN_MOVECOL : MAN_RGB;
 	bool ortho;
 
@@ -994,17 +1009,9 @@ static void draw_manipulator_rotate(
 
 	const unsigned pos = add_attrib(immVertexFormat(), "pos", GL_FLOAT, 3, KEEP_FLOAT);
 
-	immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
-
-
-	if (arcs) {
-		/* clipplane makes nice handles, calc here because of multmatrix but with translate! */
-		copy_v3db_v3fl(plane, rv3d->viewinv[2]);
-		plane[3] = -0.02f * size; // clip just a bit more
-		glClipPlane(GL_CLIP_PLANE0, plane);
-	}
 	/* sets view screen aligned */
 	gpuRotate3f(-360.0f * saacos(rv3d->viewquat[0]) / (float)M_PI, rv3d->viewquat[1], rv3d->viewquat[2], rv3d->viewquat[3]);
+	immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
 
 	/* Screen aligned help circle */
 	if (arcs) {
@@ -1063,7 +1070,7 @@ static void draw_manipulator_rotate(
 	}
 
 	/* axes */
-	if (arcs == 0) {
+	if (arcs == false) {
 		if (!is_picksel) {
 			if ((combo & V3D_MANIP_SCALE) == 0) {
 				/* axis */
@@ -1098,7 +1105,7 @@ static void draw_manipulator_rotate(
 		}
 	}
 
-	if (arcs == 0 && is_moving) {
+	if (arcs == false && is_moving) {
 
 		/* Z circle */
 		if (drawflags & MAN_ROT_Z) {
@@ -1133,43 +1140,63 @@ static void draw_manipulator_rotate(
 	}
 	// donut arcs
 	if (arcs) {
-		glEnable(GL_CLIP_PLANE0);
+		float axis_model_mat[4][4];
+		float clip_plane[4];
+
+		copy_v3_v3(clip_plane, rv3d->viewinv[2]);
+		clip_plane[3] = -dot_v3v3(rv3d->viewinv[2], rv3d->twmat[3]);
+		clip_plane[3] -= 0.02f * size; /* clip just a bit more so view aligned arcs are not visible */
+
+		gpuPopMatrix(); /* we setup our own matrix, pop previously set twmat */
+		immUnbindProgram();
+		immBindBuiltinProgram(GPU_SHADER_3D_CLIPPED_UNIFORM_COLOR);
+		immUniform4fv("ClipPlane", clip_plane);
+
+		glEnable(GL_CLIP_DISTANCE0);
 
 		/* Z circle */
 		if (drawflags & MAN_ROT_Z) {
-			preOrthoFront(ortho, rv3d->twmat, 2);
 			if (is_picksel) GPU_select_load_id(MAN_ROT_Z);
 			else manipulator_setcolor(v3d, 'Z', colcode, 255);
+
+			twmat_to_rotation_axis_mat(rv3d->twmat, 2, ortho, axis_model_mat);
+			immUniformMatrix4fv("ModelMatrix", axis_model_mat);
+			gpuPushMatrix();
+			gpuMultMatrix3D(axis_model_mat);
+
 			partial_doughnut(pos, cusize / 4.0f, 1.0f, 0, 48, 8, 48);
-			postOrtho(ortho);
+			gpuPopMatrix();
 		}
 		/* X circle */
 		if (drawflags & MAN_ROT_X) {
-			preOrthoFront(ortho, rv3d->twmat, 0);
 			if (is_picksel) GPU_select_load_id(MAN_ROT_X);
 			else manipulator_setcolor(v3d, 'X', colcode, 255);
+
+			twmat_to_rotation_axis_mat(rv3d->twmat, 0, ortho, axis_model_mat);
+			immUniformMatrix4fv("ModelMatrix", axis_model_mat);
 			gpuPushMatrix();
-			gpuRotateAxis(90.0, 'Y');
+			gpuMultMatrix3D(axis_model_mat);
+
 			partial_doughnut(pos, cusize / 4.0f, 1.0f, 0, 48, 8, 48);
 			gpuPopMatrix();
-			postOrtho(ortho);
 		}
 		/* Y circle */
 		if (drawflags & MAN_ROT_Y) {
-			preOrthoFront(ortho, rv3d->twmat, 1);
 			if (is_picksel) GPU_select_load_id(MAN_ROT_Y);
 			else manipulator_setcolor(v3d, 'Y', colcode, 255);
+
+			twmat_to_rotation_axis_mat(rv3d->twmat, 1, ortho, axis_model_mat);
+			immUniformMatrix4fv("ModelMatrix", axis_model_mat);
 			gpuPushMatrix();
-			gpuRotateAxis(-90.0, 'X');
+			gpuMultMatrix3D(axis_model_mat);
+
 			partial_doughnut(pos, cusize / 4.0f, 1.0f, 0, 48, 8, 48);
 			gpuPopMatrix();
-			postOrtho(ortho);
 		}
 
-		glDisable(GL_CLIP_PLANE0);
+		glDisable(GL_CLIP_DISTANCE0);
 	}
-
-	if (arcs == 0) {
+	else {
 
 		/* Z handle on X axis */
 		if (drawflags & MAN_ROT_Z) {
@@ -1213,8 +1240,8 @@ static void draw_manipulator_rotate(
 			gpuPopMatrix();
 			postOrtho(ortho);
 		}
-
 	}
+	/* Note: Shader is not ensured to be GPU_SHADER_3D_UNIFORM_COLOR from here on, twmat might have been popped too! */
 
 	/* restore */
 	gpuPopMatrix();
diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt
index 049ee3d3f64..f0ef87c5f28 100644
--- a/source/blender/gpu/CMakeLists.txt
+++ b/source/blender/gpu/CMakeLists.txt
@@ -148,6 +148,7 @@ data_to_c_simple(shaders/gpu_shader_3D_flat_color_vert.glsl SRC)
 data_to_c_simple(shaders/gpu_shader_3D_smooth_color_vert.glsl SRC)
 data_to_c_simple(shaders/gpu_shader_3D_smooth_color_frag.glsl SRC)
 data_to_c_simple(shaders/gpu_shader_3D_passthrough_vert.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_3D_clipped_uniform_color_vert.glsl SRC)
 
 data_to_c_simple(shaders/gpu_shader_instance_vert.glsl SRC)
 data_to_c_simple(shaders/gpu_shader_instance_variying_size_variying_color_vert.glsl SRC)
diff --git a/source/blender/gpu/GPU_shader.h b/source/blender/gpu/GPU_shader.h
index 19a3430c629..71a1e3a6591 100644
--- a/source/blender/gpu/GPU_shader.h
+++ b/source/blender/gpu/GPU_shader.h
@@ -121,6 +121,7 @@ typedef enum GPUBuiltinShader {
 	GPU_SHADER_3D_FLAT_COLOR,
 	GPU_SHADER_3D_SMOOTH_COLOR,
 	GPU_SHADER_3D_DEPTH_ONLY,
+	GPU_SHADER_3D_CLIPPED_UNIFORM_COLOR,
 	/* basic image drawing */
 	GPU_SHADER_2D_IMAGE_SHUFFLE_COLOR,
 	GPU_SHADER_2D_IMAGE_MASK_UNIFORM_COLOR,
diff --git a/source/blender/gpu/intern/gpu_shader.c b/source/blender/gpu/intern/gpu_shader.c
index 89607008ed2..7e705662ac5 100644
--- a/source/blender/gpu/intern/gpu_shader.c
+++ b/source/blender/gpu/intern/gpu_shader.c
@@ -74,6 +74,7 @@ extern char datatoc_gpu_shader_3D_flat_color_vert_glsl[];
 extern char datatoc_gpu_shader_3D_smooth_color_vert_glsl[];
 extern char datatoc_gpu_shader_3D_smooth_color_frag_glsl[];
 extern char datatoc_gpu_shader_3D_passthrough_vert_glsl[];
+extern char datatoc_gpu_shader_3D_clipped_uniform_color_vert_glsl[];
 
 extern char datatoc_gpu_shader_instance_vert_glsl[];
 extern char datatoc_gpu_shader_instance_variying_size_variying_color_vert_glsl[];
@@ -719,6 +720,8 @@ GPUShader *GPU_shader_get_builtin_shader(GPUBuiltinShader shader)
 		[GPU_SHADER_3D_SMOOTH_COLOR] = { datatoc_gpu_shader_3D_smooth_color_vert_glsl,
 		                                 datatoc_gpu_shader_3D_smooth_color_frag_glsl },
 		[GPU_SHADER_3D_DEPTH_ONLY] = { datatoc_gpu_shader_3D_vert_glsl, datatoc_gpu_shader_depth_only_frag_glsl },
+		[GPU_SHADER_3D_CLIPPED_UNIFORM_COLOR] = { datatoc_gpu_shader_3D_clipped_uniform_color_vert_glsl,
+		                                          datatoc_gpu_shader_uniform_color_frag_glsl },
 
 		[GPU_SHADER_3D_GROUNDPOINT] = { datatoc_gpu_shader_3D_groundpoint_vert_glsl, datatoc_gpu_shader_point_uniform_color_frag_glsl },
 		[GPU_SHADER_3D_GROUNDLINE] = { datatoc_gpu_shader_3D_passthrough_vert_glsl,
diff --git a/source/blender/gpu/shaders/gpu_shader_3D_clipped_uniform_color_vert.glsl b/source/blender/gpu/shaders/gpu_shader_3D_clipped_uniform_color_vert.glsl
new file mode 100644
index 00000000000..2988bb3b682
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_3D_clipped_uniform_color_vert.glsl
@@ -0,0 +1,16 @@
+
+uniform mat4 ModelViewProjectionMatrix;
+uniform mat4 ModelMatrix;
+uniform vec4 ClipPlane;
+
+#if __VERSION__ == 120
+  attribute vec3 pos;
+#else
+  in vec3 pos;
+#endif
+
+void main()
+{
+	gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
+	gl_ClipDistance[0] = dot(ModelMatrix * vec4(pos, 1.0), ClipPlane);
+}




More information about the Bf-blender-cvs mailing list