Pose Mode: Add back IK Degrees of freedom display

This commit is contained in:
Clément Foucault 2018-10-03 15:42:05 +02:00
parent 34a627f345
commit 89c30ff746
7 changed files with 244 additions and 0 deletions

View File

@ -263,6 +263,7 @@ data_to_c_simple(modes/shaders/armature_shape_outline_vert.glsl SRC)
data_to_c_simple(modes/shaders/armature_shape_outline_geom.glsl SRC)
data_to_c_simple(modes/shaders/armature_stick_vert.glsl SRC)
data_to_c_simple(modes/shaders/armature_stick_frag.glsl SRC)
data_to_c_simple(modes/shaders/armature_dof_vert.glsl SRC)
data_to_c_simple(modes/shaders/edit_mesh_overlay_common_lib.glsl SRC)
data_to_c_simple(modes/shaders/edit_mesh_overlay_frag.glsl SRC)
data_to_c_simple(modes/shaders/edit_mesh_overlay_vert.glsl SRC)

View File

@ -83,6 +83,8 @@ static struct {
DRWShadingGroup *bone_box_outline;
DRWShadingGroup *bone_wire;
DRWShadingGroup *bone_stick;
DRWShadingGroup *bone_dof_sphere;
DRWShadingGroup *bone_dof_lines;
DRWShadingGroup *bone_envelope_solid;
DRWShadingGroup *bone_envelope_distance;
DRWShadingGroup *bone_envelope_wire;
@ -1413,6 +1415,83 @@ static void draw_bone_octahedral(
/** \} */
/* -------------------------------------------------------------------- */
/** \name Draw Degrees of Freedom
* \{ */
static void draw_bone_dofs(bPoseChannel *pchan)
{
float final_bonemat[4][4], posetrans[4][4], mat[4][4];
float amin[2], amax[2], xminmax[2], zminmax[2];
float col_sphere[4] = {0.25f, 0.25f, 0.25f, 0.25f};
float col_lines[4] = {0.0f, 0.0f, 0.0f, 1.0f};
float col_xaxis[4] = {1.0f, 0.0f, 0.0f, 1.0f};
float col_zaxis[4] = {0.0f, 0.0f, 1.0f, 1.0f};
if (g_data.passes.bone_envelope == NULL) {
return;
}
if (g_data.bone_dof_sphere == NULL) {
g_data.bone_dof_lines = shgroup_instance_bone_dof(g_data.passes.bone_wire, DRW_cache_bone_dof_lines_get());
g_data.bone_dof_sphere = shgroup_instance_bone_dof(g_data.passes.bone_envelope, DRW_cache_bone_dof_sphere_get());
DRW_shgroup_state_enable(g_data.bone_dof_sphere, DRW_STATE_BLEND);
DRW_shgroup_state_disable(g_data.bone_dof_sphere, DRW_STATE_CULL_FRONT);
}
/* *0.5f here comes from M_PI/360.0f when rotations were still in degrees */
xminmax[0] = sinf(pchan->limitmin[0] * 0.5f);
xminmax[1] = sinf(pchan->limitmax[0] * 0.5f);
zminmax[0] = sinf(pchan->limitmin[2] * 0.5f);
zminmax[1] = sinf(pchan->limitmax[2] * 0.5f);
unit_m4(posetrans);
translate_m4(posetrans, pchan->pose_mat[3][0], pchan->pose_mat[3][1], pchan->pose_mat[3][2]);
/* in parent-bone pose space... */
if (pchan->parent) {
copy_m4_m4(mat, pchan->parent->pose_mat);
mat[3][0] = mat[3][1] = mat[3][2] = 0.0f;
mul_m4_m4m4(posetrans, posetrans, mat);
}
/* ... but own restspace */
mul_m4_m4m3(posetrans, posetrans, pchan->bone->bone_mat);
float scale = pchan->bone->length * pchan->size[1];
scale_m4_fl(mat, scale);
mat[1][1] = -mat[1][1];
mul_m4_m4m4(posetrans, posetrans, mat);
/* into world space. */
mul_m4_m4m4(final_bonemat, g_data.ob->obmat, posetrans);
if ((pchan->ikflag & BONE_IK_XLIMIT) &&
(pchan->ikflag & BONE_IK_ZLIMIT))
{
amin[0] = xminmax[0];
amax[0] = xminmax[1];
amin[1] = zminmax[0];
amax[1] = zminmax[1];
DRW_shgroup_call_dynamic_add(g_data.bone_dof_sphere, final_bonemat, col_sphere, amin, amax);
DRW_shgroup_call_dynamic_add(g_data.bone_dof_lines, final_bonemat, col_lines, amin, amax);
}
if (pchan->ikflag & BONE_IK_XLIMIT) {
amin[0] = xminmax[0];
amax[0] = xminmax[1];
amin[1] = amax[1] = 0.0f;
DRW_shgroup_call_dynamic_add(g_data.bone_dof_lines, final_bonemat, col_xaxis, amin, amax);
}
if (pchan->ikflag & BONE_IK_ZLIMIT) {
amin[1] = zminmax[0];
amax[1] = zminmax[1];
amin[0] = amax[0] = 0.0f;
DRW_shgroup_call_dynamic_add(g_data.bone_dof_lines, final_bonemat, col_zaxis, amin, amax);
}
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Draw Relationships
@ -1704,6 +1783,15 @@ static void draw_armature_pose(Object *ob, const float const_color[4])
draw_bone_octahedral(NULL, pchan, arm, boneflag, constflag, select_id);
}
if (!is_pose_select && show_relations &&
(arm->flag & ARM_POSEMODE) &&
(bone->flag & BONE_SELECTED) &&
((ob->base_flag & BASE_FROMDUPLI) == 0) &&
(pchan->ikflag & (BONE_IK_XLIMIT | BONE_IK_ZLIMIT)))
{
draw_bone_dofs(pchan);
}
/* Draw names of bone */
if (show_text && (arm->flag & ARM_DRAWNAMES)) {
uchar color[4];

View File

@ -108,6 +108,8 @@ static struct DRWShapeCache {
GPUBatch *drw_bone_point_wire;
GPUBatch *drw_bone_stick;
GPUBatch *drw_bone_arrows;
GPUBatch *drw_bone_dof_sphere;
GPUBatch *drw_bone_dof_lines;
GPUBatch *drw_camera;
GPUBatch *drw_camera_frame;
GPUBatch *drw_camera_tria;
@ -2698,6 +2700,100 @@ GPUBatch *DRW_cache_bone_arrows_get(void)
return SHC.drw_bone_arrows;
}
const float staticSine[16] = {
0.0f, 0.104528463268f, 0.207911690818f, 0.309016994375f,
0.406736643076f, 0.5f, 0.587785252292f, 0.669130606359f,
0.743144825477f, 0.809016994375f, 0.866025403784f,
0.913545457643f, 0.951056516295f, 0.978147600734f,
0.994521895368f, 1.0f
};
#define set_vert(a, b, quarter) \
copy_v2_fl2(pos, (quarter % 2 == 0) ? -(a) : (a), (quarter < 2) ? -(b) : (b)); \
GPU_vertbuf_attr_set(vbo, attr_id.pos, v++, pos);
GPUBatch *DRW_cache_bone_dof_sphere_get(void)
{
if (!SHC.drw_bone_dof_sphere) {
int i, j, q, n = ARRAY_SIZE(staticSine);
float x, z, px, pz, pos[2];
/* Position Only 3D format */
static GPUVertFormat format = { 0 };
static struct { uint pos; } attr_id;
if (format.attr_len == 0) {
attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
}
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
GPU_vertbuf_data_alloc(vbo, n * n * 6 * 4);
uint v = 0;
for (q = 0; q < 4; ++q) {
pz = 0.0f;
for (i = 1; i < n; ++i) {
z = staticSine[i];
px = 0.0f;
for (j = 1; j <= (n - i); ++j) {
x = staticSine[j];
if (j == n - i) {
set_vert(px, z, q);
set_vert(px, pz, q);
set_vert(x, pz, q);
}
else {
set_vert(x, z, q);
set_vert(x, pz, q);
set_vert(px, z, q);
set_vert(x, pz, q);
set_vert(px, pz, q);
set_vert(px, z, q);
}
px = x;
}
pz = z;
}
}
/* TODO alloc right count from the begining. */
GPU_vertbuf_data_resize(vbo, v);
SHC.drw_bone_dof_sphere = GPU_batch_create_ex(GPU_PRIM_TRIS, vbo, NULL, GPU_BATCH_OWNS_VBO);
}
return SHC.drw_bone_dof_sphere;
}
GPUBatch *DRW_cache_bone_dof_lines_get(void)
{
if (!SHC.drw_bone_dof_lines) {
int i, n = ARRAY_SIZE(staticSine);
float pos[2];
/* Position Only 3D format */
static GPUVertFormat format = { 0 };
static struct { uint pos; } attr_id;
if (format.attr_len == 0) {
attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
}
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
GPU_vertbuf_data_alloc(vbo, n * 4);
uint v = 0;
for (i = 0; i < n * 4; i++) {
float a = (1.0f - (i / (float)(n * 4))) * 2.0f * M_PI;
float x = cosf(a);
float y = sinf(a);
set_vert(x, y, 0);
}
SHC.drw_bone_dof_lines = GPU_batch_create_ex(GPU_PRIM_LINE_LOOP, vbo, NULL, GPU_BATCH_OWNS_VBO);
}
return SHC.drw_bone_dof_lines;
}
#undef set_vert
/** \} */
/* -------------------------------------------------------------------- */

View File

@ -121,6 +121,8 @@ struct GPUBatch *DRW_cache_bone_point_get(void);
struct GPUBatch *DRW_cache_bone_point_wire_outline_get(void);
struct GPUBatch *DRW_cache_bone_stick_get(void);
struct GPUBatch *DRW_cache_bone_arrows_get(void);
struct GPUBatch *DRW_cache_bone_dof_sphere_get(void);
struct GPUBatch *DRW_cache_bone_dof_lines_get(void);
/* Meshes */
struct GPUBatch *DRW_cache_mesh_surface_overlay_get(struct Object *ob);

View File

@ -222,6 +222,7 @@ extern char datatoc_armature_shape_outline_vert_glsl[];
extern char datatoc_armature_shape_outline_geom_glsl[];
extern char datatoc_armature_stick_vert_glsl[];
extern char datatoc_armature_stick_frag_glsl[];
extern char datatoc_armature_dof_vert_glsl[];
extern char datatoc_common_globals_lib_glsl[];
@ -242,6 +243,7 @@ static struct {
struct GPUShader *bone_sphere;
struct GPUShader *bone_sphere_outline;
struct GPUShader *bone_stick;
struct GPUShader *bone_dofs;
struct GPUShader *mpath_line_sh;
struct GPUShader *mpath_points_sh;
@ -265,6 +267,7 @@ static struct {
struct GPUVertFormat *instance_distance_lines;
struct GPUVertFormat *instance_spot;
struct GPUVertFormat *instance_bone;
struct GPUVertFormat *instance_bone_dof;
struct GPUVertFormat *instance_bone_stick;
struct GPUVertFormat *instance_bone_outline;
struct GPUVertFormat *instance_bone_envelope;
@ -784,6 +787,29 @@ DRWShadingGroup *shgroup_instance_bone_stick(DRWPass *pass)
return grp;
}
struct DRWShadingGroup *shgroup_instance_bone_dof(struct DRWPass *pass, struct GPUBatch *geom)
{
if (g_shaders.bone_dofs == NULL) {
g_shaders.bone_dofs = DRW_shader_create(
datatoc_armature_dof_vert_glsl, NULL,
datatoc_gpu_shader_flat_color_frag_glsl, NULL);
}
DRW_shgroup_instance_format(g_formats.instance_bone_dof, {
{"InstanceModelMatrix", DRW_ATTRIB_FLOAT, 16},
{"color", DRW_ATTRIB_FLOAT, 4},
{"amin", DRW_ATTRIB_FLOAT, 2},
{"amax", DRW_ATTRIB_FLOAT, 2},
});
DRWShadingGroup *grp = DRW_shgroup_instance_create(
g_shaders.bone_dofs,
pass, geom,
g_formats.instance_bone_dof);
return grp;
}
struct GPUShader *mpath_line_shader_get(void)
{
if (g_shaders.mpath_line_sh == NULL) {

View File

@ -150,6 +150,7 @@ struct DRWShadingGroup *shgroup_instance_bone_shape_solid(struct DRWPass *pass,
struct DRWShadingGroup *shgroup_instance_bone_sphere_outline(struct DRWPass *pass);
struct DRWShadingGroup *shgroup_instance_bone_sphere_solid(struct DRWPass *pass, bool transp);
struct DRWShadingGroup *shgroup_instance_bone_stick(struct DRWPass *pass);
struct DRWShadingGroup *shgroup_instance_bone_dof(struct DRWPass *pass, struct GPUBatch *geom);
struct GPUShader *mpath_line_shader_get(void);
struct GPUShader *mpath_points_shader_get(void);

View File

@ -0,0 +1,30 @@
uniform mat4 ViewProjectionMatrix;
/* ---- Instantiated Attribs ---- */
in vec2 pos;
/* ---- Per instance Attribs ---- */
/* Assumed to be in world coordinate already. */
in mat4 InstanceModelMatrix;
in vec4 color;
in vec2 amin;
in vec2 amax;
flat out vec4 finalColor;
vec3 sphere_project(float ax, float az)
{
float sine = 1.0 - ax * ax - az * az;
float q3 = sqrt(max(0.0, sine));
return vec3(-az * q3, 0.5 - sine, ax * q3) * 2.0;
}
void main()
{
vec3 final_pos = sphere_project(pos.x * abs((pos.x > 0.0) ? amax.x : amin.x),
pos.y * abs((pos.y > 0.0) ? amax.y : amin.y));
gl_Position = ViewProjectionMatrix * (InstanceModelMatrix * vec4(final_pos, 1.0));
finalColor = color;
}