[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