[Bf-blender-cvs] [23f256b24be] blender2.8: DwM: Armature: add solid envelope bone drawing.

Bastien Montagne noreply at git.blender.org
Thu May 18 12:14:53 CEST 2017


Commit: 23f256b24bed34bb25d1d66ec9ba0726f7a71659
Author: Bastien Montagne
Date:   Thu May 18 11:41:59 2017 +0200
Branches: blender2.8
https://developer.blender.org/rB23f256b24bed34bb25d1d66ec9ba0726f7a71659

DwM: Armature: add solid envelope bone drawing.

Envelope bones are now pretty much identical to old drawing code.

Note that currently new DwM drawing code does not seem to care about
wire/solid drawing modes at all, guess this is still TODO... For now we
hence just get both wire and solid for envelope bones, this can be
refined later.

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

M	source/blender/draw/intern/draw_armature.c
M	source/blender/draw/intern/draw_cache.c
M	source/blender/draw/intern/draw_cache.h
M	source/blender/draw/intern/draw_common.c
M	source/blender/draw/intern/draw_common.h
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_instance_bone_envelope_solid_vert.glsl

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

diff --git a/source/blender/draw/intern/draw_armature.c b/source/blender/draw/intern/draw_armature.c
index 3d320465935..c4be82a223b 100644
--- a/source/blender/draw/intern/draw_armature.c
+++ b/source/blender/draw/intern/draw_armature.c
@@ -78,6 +78,7 @@ static struct {
 	DRWShadingGroup *bone_box_solid;
 	DRWShadingGroup *bone_box_wire;
 	DRWShadingGroup *bone_wire_wire;
+	DRWShadingGroup *bone_envelope_solid;
 	DRWShadingGroup *bone_envelope_distance;
 	DRWShadingGroup *bone_envelope_wire;
 	DRWShadingGroup *bone_envelope_head_wire;
@@ -165,6 +166,18 @@ static void DRW_shgroup_bone_envelope_distance(
 	}
 }
 
+static void DRW_shgroup_bone_envelope_solid(
+        const float (*bone_mat)[4], const float color[4],
+        const float *radius_head, const float *radius_tail)
+{
+	if (g_data.bone_envelope_solid == NULL) {
+		struct Batch *geom = DRW_cache_bone_envelope_get();
+		g_data.bone_envelope_solid = shgroup_instance_bone_envelope_solid(g_data.pass_bone_solid, geom, g_data.ob->obmat);
+	}
+
+	DRW_shgroup_call_dynamic_add(g_data.bone_envelope_solid, bone_mat, color, radius_head, radius_tail);
+}
+
 static void DRW_shgroup_bone_envelope_wire(
         const float (*bone_mat)[4], const float color[4],
         const float *radius_head, const float *radius_tail, const float *distance)
@@ -591,7 +604,31 @@ static const float *get_bone_solid_color(
 		}
 	}
 #else
-	UNUSED_VARS(eBone, pchan, arm);
+	if (arm->drawtype == ARM_ENVELOPE) {
+		/* Edit Mode */
+		if (eBone) {
+			bool is_active = (arm->act_edbone == eBone);
+			if (eBone->flag & BONE_SELECTED) {
+				if (is_active) {
+					return g_theme.edge_select_color;
+				}
+				else {
+					return g_theme.bone_select_color;
+				}
+			}
+		}
+		else if (arm->flag & ARM_POSEMODE) {
+			bool is_active = (arm->act_bone == pchan->bone);
+			if (pchan->bone->flag & BONE_SELECTED) {
+				if (is_active) {
+					return g_theme.bone_pose_active_color;
+				}
+				else {
+					return g_theme.bone_pose_color;
+				}
+			}
+		}
+	}
 #endif
 
 	if (arm->flag & ARM_POSEMODE) {
@@ -895,18 +932,27 @@ static void draw_points(
 	const float *col_wire_tail = (g_theme.const_color) ? g_theme.const_color : g_theme.vertex_color;
 
 	const bool is_envelope_draw = (arm->drawtype == ARM_ENVELOPE);
+	static const float envelope_ignore = -1.0f;
 
 	/* Edit bone points can be selected */
 	if (eBone) {
 		if (eBone->flag & BONE_ROOTSEL) {
 #ifdef USE_SOLID_COLOR
 			col_solid_root = g_theme.vertex_select_color;
+#else
+			if (is_envelope_draw) {
+				col_solid_root = g_theme.vertex_select_color;
+			}
 #endif
 			col_wire_root = g_theme.vertex_select_color;
 		}
 		if (eBone->flag & BONE_TIPSEL) {
 #ifdef USE_SOLID_COLOR
 			col_solid_tail = g_theme.vertex_select_color;
+#else
+			if (is_envelope_draw) {
+				col_solid_tail = g_theme.vertex_select_color;
+			}
 #endif
 			col_wire_tail = g_theme.vertex_select_color;
 		}
@@ -925,6 +971,8 @@ static void draw_points(
 		if (eBone) {
 			if (!((eBone->parent) && !EBONE_VISIBLE(arm, eBone->parent))) {
 				if (is_envelope_draw) {
+					DRW_shgroup_bone_envelope_solid(eBone->disp_mat, col_solid_root,
+					                                &eBone->rad_head, &envelope_ignore);
 					DRW_shgroup_bone_envelope_head_wire(eBone->disp_mat, col_wire_root,
 					                                    &eBone->rad_head, &eBone->rad_tail, &eBone->dist);
 				}
@@ -938,6 +986,8 @@ static void draw_points(
 			Bone *bone = pchan->bone;
 			if (!((bone->parent) && (bone->parent->flag & (BONE_HIDDEN_P | BONE_HIDDEN_PG)))) {
 				if (is_envelope_draw) {
+					DRW_shgroup_bone_envelope_solid(pchan->disp_mat, col_solid_root,
+					                                &bone->rad_head, &envelope_ignore);
 					DRW_shgroup_bone_envelope_head_wire(pchan->disp_mat, col_wire_root,
 					                                    &bone->rad_head, &bone->rad_tail, &bone->dist);
 				}
@@ -964,6 +1014,8 @@ static void draw_points(
 			rad_tail = &pchan->bone->rad_tail;
 			dist = &pchan->bone->dist;
 		}
+		DRW_shgroup_bone_envelope_solid(
+		            BONE_VAR(eBone, pchan, disp_mat), col_solid_tail, &envelope_ignore, rad_tail);
 		DRW_shgroup_bone_envelope_head_wire(
 		            BONE_VAR(eBone, pchan, disp_tail_mat), col_wire_tail, rad_tail, rad_tail, dist);
 	}
@@ -1011,7 +1063,7 @@ static void draw_bone_envelope(
         const int boneflag, const short constflag,
         const int select_id)
 {
-//	const float *col_solid = get_bone_solid_color(eBone, pchan, arm, boneflag, constflag);
+	const float *col_solid = get_bone_solid_color(eBone, pchan, arm, boneflag, constflag);
 	const float *col_wire = get_bone_wire_color(eBone, pchan, arm, boneflag, constflag);
 
 	static const float col_white[4] = {1.0f, 1.0f, 1.0f, 0.2f};
@@ -1038,6 +1090,7 @@ static void draw_bone_envelope(
 		DRW_select_load_id(select_id | BONESEL_BONE);
 	}
 
+	DRW_shgroup_bone_envelope_solid(BONE_VAR(eBone, pchan, disp_mat), col_solid, rad_head, rad_tail);
 	DRW_shgroup_bone_envelope_wire(BONE_VAR(eBone, pchan, disp_mat), col_wire, rad_head, rad_tail, distance);
 
 	if (select_id != -1) {
diff --git a/source/blender/draw/intern/draw_cache.c b/source/blender/draw/intern/draw_cache.c
index 5b9247c1024..18e64a86fa9 100644
--- a/source/blender/draw/intern/draw_cache.c
+++ b/source/blender/draw/intern/draw_cache.c
@@ -70,6 +70,7 @@ static struct DRWShapeCache {
 	Batch *drw_bone_box;
 	Batch *drw_bone_box_wire;
 	Batch *drw_bone_wire_wire;
+	Batch *drw_bone_envelope;
 	Batch *drw_bone_envelope_distance;
 	Batch *drw_bone_envelope_wire;
 	Batch *drw_bone_envelope_head_wire;
@@ -113,6 +114,7 @@ void DRW_shape_cache_free(void)
 	BATCH_DISCARD_ALL_SAFE(SHC.drw_bone_box);
 	BATCH_DISCARD_ALL_SAFE(SHC.drw_bone_box_wire);
 	BATCH_DISCARD_ALL_SAFE(SHC.drw_bone_wire_wire);
+	BATCH_DISCARD_ALL_SAFE(SHC.drw_bone_envelope);
 	BATCH_DISCARD_ALL_SAFE(SHC.drw_bone_envelope_distance);
 	BATCH_DISCARD_ALL_SAFE(SHC.drw_bone_envelope_wire);
 	BATCH_DISCARD_ALL_SAFE(SHC.drw_bone_envelope_head_wire);
@@ -1530,9 +1532,101 @@ Batch *DRW_cache_bone_wire_wire_outline_get(void)
 }
 
 
+/* Helpers for envelope bone's solid sphere-with-hidden-equatorial-cylinder.
+ * Note that here we only encode head/tail in forth component of the vector. */
+static void benv_lat_lon_to_co(const float lat, const float lon, float r_nor[3])
+{
+	/* Poles are along Y axis. */
+	r_nor[0] = sinf(lat) * cosf(lon);
+	r_nor[1] = cosf(lat);
+	r_nor[2] = sinf(lat) * sinf(lon);
+}
+
+static void benv_add_tri(VertexBuffer *vbo, uint pos_id, uint *v_idx, float *co1, float *co2, float *co3)
+{
+	/* Given tri and its seven other mirrors along X/Y/Z axes. */
+	for (int x = -1; x <= 1; x += 2) {
+		for (int y = -1; y <= 1; y += 2) {
+			const float head_tail = (y == -1) ? 0.0f : 1.0f;
+			for (int z = -1; z <= 1; z += 2) {
+				VertexBuffer_set_attrib(vbo, pos_id, (*v_idx)++,
+				                        (const float[4]){co1[0] * x, co1[1] * y, co1[2] * z, head_tail});
+				VertexBuffer_set_attrib(vbo, pos_id, (*v_idx)++,
+				                        (const float[4]){co2[0] * x, co2[1] * y, co2[2] * z, head_tail});
+				VertexBuffer_set_attrib(vbo, pos_id, (*v_idx)++,
+				                        (const float[4]){co3[0] * x, co3[1] * y, co3[2] * z, head_tail});
+			}
+		}
+	}
+}
+
+Batch *DRW_cache_bone_envelope_get(void)
+{
+#define CIRCLE_RESOL 32  /* Must be multiple of 4 */
+	if (!SHC.drw_bone_envelope) {
+		const int lon_res = CIRCLE_RESOL / 4;
+		const int lat_res = CIRCLE_RESOL / 4;
+		const float lon_inc = M_PI_2 / lon_res;
+		const float lat_inc = M_PI_2 / lat_res;
+		unsigned int v_idx = 0;
+
+		static VertexFormat format = { 0 };
+		static struct { uint pos; } attr_id;
+		if (format.attrib_ct == 0) {
+			attr_id.pos = VertexFormat_add_attrib(&format, "pos", COMP_F32, 4, KEEP_FLOAT);
+		}
+
+		/* Vertices */
+		VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
+		VertexBuffer_allocate_data(vbo, lat_res * lon_res * 8 * 6);
+
+		float lon = 0.0f;
+		for (int i = 0; i < lon_res; i++, lon += lon_inc) {
+			float lat = 0.0f;
+			float co1[3], co2[3], co3[3], co4[3];
+
+			for (int j = 0; j < lat_res; j++, lat += lat_inc) {
+				benv_lat_lon_to_co(lat          , lon          , co1);
+				benv_lat_lon_to_co(lat          , lon + lon_inc, co2);
+				benv_lat_lon_to_co(lat + lat_inc, lon + lon_inc, co3);
+				benv_lat_lon_to_co(lat + lat_inc, lon          , co4);
+
+				if (j != 0) {  /* At pole, n1 and n2 are identical. */
+					benv_add_tri(vbo, attr_id.pos, &v_idx, co1, co2, co3);
+				}
+				benv_add_tri(vbo, attr_id.pos, &v_idx, co1, co3, co4);
+			}
+
+			/* lat is at equator (i.e. lat == pi / 2). */
+			/* We need to add 'cylinder' part between the equators (along XZ plane). */
+			for (int x = -1; x <= 1; x += 2) {
+				for (int z = -1; z <= 1; z += 2) {
+					VertexBuffer_set_attrib(vbo, attr_id.pos, v_idx++,
+					                        (const float[4]){co3[0] * x, co3[1], co3[2] * z, 0.0f});
+					VertexBuffer_set_attrib(vbo, attr_id.pos, v_idx++,
+					                        (const float[4]){co4[0] * x, co4[1], co4[2] * z, 0.0f});
+					VertexBuffer_set_attrib(vbo, attr_id.pos, v_idx++,
+					                        (const float[4]){co4[0] * x, co4[1], co4[2] * z, 1.0f});
+
+					VertexBuffer_set_attrib(vbo, attr_id.pos, v_idx++,
+					                        (const float[4]){co3[0] * x, co3[1], co3[2] * z, 0.0f});
+					VertexBuffer_set_attrib(vbo, attr_id.pos, v_idx++,
+					                        (const float[4]){co4[0] * x, co4[1], co4[2] * z, 1.0f});
+					VertexBuffer_set_attrib(vbo, attr_id.pos, v_idx++,
+					                        (const float[4]){co3[0] * x, co3[1], co3[2] * z, 1.0f});
+				}
+			}
+		}
+
+		SHC.drw_bone_envelope = Batch_create(PRIM_TRIANGLES, vbo, NULL);
+	}
+	return SHC.drw_bone_envelope;
+}
+
+
 Batch *DRW_cache_bone_envelope_distance_outline_get(void)
 {
-#define CIRCLE_RESOL 32
+#define CIRCLE_RESOL 32  /* Must be multiple of 2 */
 	if (!SHC.drw_bone_envelope_distance) {
 		unsigned int v_idx = 0;
 
@@ -1570,7 +1664,7 @@ Batch *DRW_cache_bone_envelope_distance_outline_get(void)
 }
 
 
-/* Bone body and tail. */
+/* Bone body. */
 Batch *DRW_cache_bone_envelope_wire_outline_get(void)
 {
 	if (!SHC.drw_bone_envelope_wire) {
@@ -1600,10 +1694,10 @@ Ba

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list