New option for roll correction.
Calculate new roll based on the angle to the normal of the joint (cross produce of the two bones). This works best in some cases but not in others, so it's an option for now. I'll have to see if I can iron the left over kinks, then it can be made the default (with Align to view an added option).
This commit is contained in:
@@ -7999,7 +7999,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
|
||||
|
||||
/* Skeleton Sketching */
|
||||
sce->toolsettings->bone_sketching = 0;
|
||||
sce->toolsettings->skgen_retarget_options |= SK_RETARGET_ROLL;
|
||||
sce->toolsettings->skgen_retarget_roll = SK_RETARGET_ROLL_VIEW;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -107,7 +107,8 @@ typedef struct RigEdge {
|
||||
struct RigEdge *next, *prev;
|
||||
float head[3], tail[3];
|
||||
float length;
|
||||
float angle;
|
||||
float angle; /* angle to next edge */
|
||||
float up_angle; /* angle between up_axis and the joint normal (defined as Previous edge CrossProduct Current edge */
|
||||
EditBone *bone;
|
||||
float up_axis[3];
|
||||
} RigEdge;
|
||||
|
||||
@@ -448,12 +448,13 @@ typedef struct ToolSettings {
|
||||
char bone_sketching_convert;
|
||||
char skgen_subdivision_number;
|
||||
char skgen_retarget_options;
|
||||
char skgen_retarget_roll;
|
||||
char skgen_side_string[8];
|
||||
char skgen_num_string[8];
|
||||
|
||||
/* Alt+RMB option */
|
||||
char edge_mode;
|
||||
char pad3[3];
|
||||
char pad3[2];
|
||||
} ToolSettings;
|
||||
|
||||
/* Used by all brushes to store their properties, which can be directly set
|
||||
@@ -887,8 +888,11 @@ typedef struct Scene {
|
||||
#define SK_CONVERT_RETARGET 4
|
||||
|
||||
/* toolsettings->skgen_retarget_options */
|
||||
#define SK_RETARGET_ROLL 1
|
||||
#define SK_RETARGET_AUTONAME 2
|
||||
#define SK_RETARGET_AUTONAME 1
|
||||
|
||||
/* toolsettings->skgen_retarget_roll */
|
||||
#define SK_RETARGET_ROLL_VIEW 1
|
||||
#define SK_RETARGET_ROLL_JOINT 2
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -2310,15 +2310,14 @@ static void view3d_panel_bonesketch_spaces(short cntrl)
|
||||
uiBlockBeginAlign(block);
|
||||
|
||||
/* use real flag instead of 1 */
|
||||
uiDefButBitC(block, TOG, BONE_SKETCHING, B_REDR, "Use Bone Sketching", 10, yco, 130, 20, &G.scene->toolsettings->bone_sketching, 0, 0, 0, 0, "Use sketching to create and edit bones");
|
||||
uiDefButBitC(block, TOG, BONE_SKETCHING_QUICK, B_REDR, "Q", 140, yco, 20, 20, &G.scene->toolsettings->bone_sketching, 0, 0, 0, 0, "Automatically convert and delete on stroke end");
|
||||
uiDefButBitC(block, TOG, BONE_SKETCHING, B_REDR, "Use Bone Sketching", 10, yco, 180, 20, &G.scene->toolsettings->bone_sketching, 0, 0, 0, 0, "Use sketching to create and edit bones");
|
||||
uiDefButBitC(block, TOG, BONE_SKETCHING_QUICK, B_REDR, "Q", 190, yco, 20, 20, &G.scene->toolsettings->bone_sketching, 0, 0, 0, 0, "Automatically convert and delete on stroke end");
|
||||
yco -= 20;
|
||||
|
||||
but = uiDefBut(block, BUT, B_REDR, "Convert", 10,yco,150,20, 0, 0, 0, 0, 0, "Convert sketch to armature");
|
||||
but = uiDefBut(block, BUT, B_REDR, "Convert", 10,yco,100,20, 0, 0, 0, 0, 0, "Convert sketch to armature");
|
||||
uiButSetFunc(but, convert_sketch_armature, NULL, NULL);
|
||||
yco -= 20;
|
||||
|
||||
but = uiDefBut(block, BUT, B_REDR, "Delete", 10,yco,150,20, 0, 0, 0, 0, 0, "Delete sketch");
|
||||
but = uiDefBut(block, BUT, B_REDR, "Delete", 110,yco,100,20, 0, 0, 0, 0, 0, "Delete sketch");
|
||||
uiButSetFunc(but, delete_sketch_armature, NULL, NULL);
|
||||
yco -= 20;
|
||||
|
||||
@@ -2327,20 +2326,21 @@ static void view3d_panel_bonesketch_spaces(short cntrl)
|
||||
uiBlockBeginAlign(block);
|
||||
|
||||
uiDefButC(block, ROW, B_REDR, "Length", 10, yco, 60, 19, &G.scene->toolsettings->bone_sketching_convert, 0, SK_CONVERT_CUT_LENGTH, 0, 0, "Subdivide arcs in bones of equal length");
|
||||
uiDefButF(block, NUM, B_REDR, "L:", 70, yco, 90, 19, &G.scene->toolsettings->skgen_length_limit,0.1,50.0, 10, 0, "Maximum length of the subdivided bones");
|
||||
uiDefButF(block, NUM, B_REDR, "Lim:", 70, yco, 140, 19, &G.scene->toolsettings->skgen_length_limit,0.1,50.0, 10, 0, "Maximum length of the subdivided bones");
|
||||
yco -= 20;
|
||||
|
||||
uiDefButC(block, ROW, B_REDR, "Correlation", 10, yco, 60, 19, &G.scene->toolsettings->bone_sketching_convert, 0, SK_CONVERT_CUT_CORRELATION, 0, 0, "Subdivide arcs based on correlation");
|
||||
uiDefButF(block, NUM, B_REDR, "T:", 70, yco, 90, 19, &G.scene->toolsettings->skgen_correlation_limit,0.0, 1.0, 0.01, 0, "Correlation threshold for subdivision");
|
||||
uiDefButF(block, NUM, B_REDR, "Thres:", 70, yco, 140, 19, &G.scene->toolsettings->skgen_correlation_limit,0.0, 1.0, 0.01, 0, "Correlation threshold for subdivision");
|
||||
yco -= 20;
|
||||
|
||||
uiDefButC(block, ROW, B_REDR, "Fixed", 10, yco, 60, 19, &G.scene->toolsettings->bone_sketching_convert, 0, SK_CONVERT_CUT_FIXED, 0, 0, "Subdivide arcs based on a fixed number of bones");
|
||||
uiDefButC(block, NUM, B_REDR, "N:", 70, yco, 90, 19, &G.scene->toolsettings->skgen_subdivision_number,1, 100, 1, 5, "Number of subdivided bones");
|
||||
uiDefButC(block, NUM, B_REDR, "Num:", 70, yco, 140, 19, &G.scene->toolsettings->skgen_subdivision_number,1, 100, 1, 5, "Number of subdivided bones");
|
||||
yco -= 20;
|
||||
|
||||
uiDefButC(block, ROW, B_REDR, "Retarget", 10, yco,80, 19, &G.scene->toolsettings->bone_sketching_convert, 0, SK_CONVERT_RETARGET, 0, 0, "Retarget selected bones to stroke");
|
||||
uiDefButBitC(block, TOG, SK_RETARGET_ROLL, B_DIFF, "Roll", 90, yco, 70,19, &G.scene->toolsettings->skgen_retarget_options, 0, 0, 0, 0, "Roll bones perpendicular to view");
|
||||
/* button here to select what to do (copy or not), template, ...*/
|
||||
uiDefButC(block, ROW, B_REDR, "Retarget", 10, yco,80, 19, &G.scene->toolsettings->bone_sketching_convert, 0, SK_CONVERT_RETARGET, 0, 0, "Retarget selected bones to stroke");
|
||||
uiDefButC(block, ROW, B_DIFF, "No", 90, yco, 40,19, &G.scene->toolsettings->skgen_retarget_roll, 0, 0, 0, 0, "No special roll treatment");
|
||||
uiDefButC(block, ROW, B_DIFF, "View", 130, yco, 40,19, &G.scene->toolsettings->skgen_retarget_roll, 0, SK_RETARGET_ROLL_VIEW, 0, 0, "Roll bones perpendicular to view");
|
||||
uiDefButC(block, ROW, B_DIFF, "Joint", 170, yco, 40,19, &G.scene->toolsettings->skgen_retarget_roll, 0, SK_RETARGET_ROLL_JOINT, 0, 0, "Roll bones relative to joint bend");
|
||||
yco -= 20;
|
||||
|
||||
uiBlockEndAlign(block);
|
||||
@@ -2348,22 +2348,24 @@ static void view3d_panel_bonesketch_spaces(short cntrl)
|
||||
yco -= 10;
|
||||
uiBlockBeginAlign(block);
|
||||
|
||||
/* button here to select what to do (copy or not), template, ...*/
|
||||
|
||||
BIF_makeListTemplates();
|
||||
template_index = BIF_currentTemplate();
|
||||
|
||||
but = uiDefButI(block, MENU, B_REDR, BIF_listTemplates(), 10,yco,150,19, &template_index, 0, 0, 0, 0, "Template");
|
||||
but = uiDefButI(block, MENU, B_REDR, BIF_listTemplates(), 10,yco,200,19, &template_index, 0, 0, 0, 0, "Template");
|
||||
uiButSetFunc(but, assign_template_sketch_armature, &template_index, NULL);
|
||||
|
||||
yco -= 20;
|
||||
|
||||
uiDefButF(block, NUM, B_DIFF, "Ang:", 10, yco, 50,19, &G.scene->toolsettings->skgen_retarget_angle_weight, 0, 10, 1, 0, "Angle Weight");
|
||||
uiDefButF(block, NUM, B_DIFF, "Len:", 60, yco, 50,19, &G.scene->toolsettings->skgen_retarget_length_weight, 0, 10, 1, 0, "Length Weight");
|
||||
uiDefButF(block, NUM, B_DIFF, "Dist:", 110,yco, 50,19, &G.scene->toolsettings->skgen_retarget_distance_weight, 0, 10, 1, 0, "Distance Weight");
|
||||
uiDefButF(block, NUM, B_DIFF, "A:", 10, yco, 66,19, &G.scene->toolsettings->skgen_retarget_angle_weight, 0, 10, 1, 0, "Angle Weight");
|
||||
uiDefButF(block, NUM, B_DIFF, "L:", 76, yco, 67,19, &G.scene->toolsettings->skgen_retarget_length_weight, 0, 10, 1, 0, "Length Weight");
|
||||
uiDefButF(block, NUM, B_DIFF, "D:", 143,yco, 67,19, &G.scene->toolsettings->skgen_retarget_distance_weight, 0, 10, 1, 0, "Distance Weight");
|
||||
yco -= 20;
|
||||
|
||||
uiDefBut(block, TEX,0,"S:", 10, yco, 65, 20, G.scene->toolsettings->skgen_side_string, 0.0, 8.0, 0, 0, "Text to replace %S with");
|
||||
uiDefBut(block, TEX,0,"N:", 75, yco, 65, 20, G.scene->toolsettings->skgen_num_string, 0.0, 8.0, 0, 0, "Text to replace %N with");
|
||||
uiDefIconButBitC(block, TOG, SK_RETARGET_AUTONAME, B_DIFF, ICON_AUTO,140,yco,20,20, &G.scene->toolsettings->skgen_retarget_options, 0, 0, 0, 0, "Use Auto Naming");
|
||||
uiDefBut(block, TEX,0,"S:", 10, yco, 90, 20, G.scene->toolsettings->skgen_side_string, 0.0, 8.0, 0, 0, "Text to replace %S with");
|
||||
uiDefBut(block, TEX,0,"N:", 100, yco, 90, 20, G.scene->toolsettings->skgen_num_string, 0.0, 8.0, 0, 0, "Text to replace %N with");
|
||||
uiDefIconButBitC(block, TOG, SK_RETARGET_AUTONAME, B_DIFF, ICON_AUTO,190,yco,20,20, &G.scene->toolsettings->skgen_retarget_options, 0, 0, 0, 0, "Use Auto Naming");
|
||||
|
||||
/* auto renaming magic */
|
||||
|
||||
|
||||
@@ -110,7 +110,8 @@ RigGraph *GLOBAL_RIGG = NULL;
|
||||
|
||||
void *exec_retargetArctoArc(void *param);
|
||||
|
||||
static void RIG_calculateEdgeAngle(RigEdge *edge_first, RigEdge *edge_second);
|
||||
static void RIG_calculateEdgeAngles(RigEdge *edge_first, RigEdge *edge_second);
|
||||
float rollBoneByQuat(EditBone *bone, float old_up_axis[3], float qrot[4]);
|
||||
|
||||
/* two levels */
|
||||
#define SHAPE_LEVELS (SHAPE_RADIX * SHAPE_RADIX)
|
||||
@@ -200,12 +201,63 @@ float rollBoneByQuatAligned(EditBone *bone, float old_up_axis[3], float qrot[4],
|
||||
}
|
||||
}
|
||||
|
||||
float rollBoneByQuat(EditBone *bone, float old_up_axis[3], float quat[4])
|
||||
float rollBoneByQuatJoint(RigEdge *edge, RigEdge *previous, float qrot[4], float qroll[4])
|
||||
{
|
||||
if (previous == NULL)
|
||||
{
|
||||
QuatOne(qroll);
|
||||
return rollBoneByQuat(edge->bone, edge->up_axis, qrot);
|
||||
}
|
||||
else
|
||||
{
|
||||
float new_up_axis[3];
|
||||
float vec_first[3], vec_second[3], normal[3];
|
||||
|
||||
if (previous->bone)
|
||||
{
|
||||
VecSubf(vec_first, previous->bone->tail, previous->bone->head);
|
||||
}
|
||||
else if (previous->prev->bone)
|
||||
{
|
||||
VecSubf(vec_first, edge->bone->head, previous->prev->bone->tail);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* SHOULDN'T BE HERE */
|
||||
QuatOne(qroll);
|
||||
return rollBoneByQuat(edge->bone, edge->up_axis, qrot);
|
||||
}
|
||||
|
||||
VecSubf(vec_second, edge->bone->tail, edge->bone->head);
|
||||
|
||||
Normalize(vec_first);
|
||||
Normalize(vec_second);
|
||||
|
||||
Crossf(normal, vec_first, vec_second);
|
||||
Normalize(normal);
|
||||
|
||||
AxisAngleToQuat(qroll, vec_second, edge->up_angle);
|
||||
|
||||
QuatMulVecf(qroll, normal);
|
||||
|
||||
VECCOPY(new_up_axis, edge->up_axis);
|
||||
QuatMulVecf(qrot, new_up_axis);
|
||||
|
||||
Normalize(new_up_axis);
|
||||
|
||||
/* real qroll between normal and up_axis */
|
||||
RotationBetweenVectorsToQuat(qroll, new_up_axis, normal);
|
||||
|
||||
return rollBoneToVector(edge->bone, normal);
|
||||
}
|
||||
}
|
||||
|
||||
float rollBoneByQuat(EditBone *bone, float old_up_axis[3], float qrot[4])
|
||||
{
|
||||
float new_up_axis[3];
|
||||
|
||||
VECCOPY(new_up_axis, old_up_axis);
|
||||
QuatMulVecf(quat, new_up_axis);
|
||||
QuatMulVecf(qrot, new_up_axis);
|
||||
|
||||
Normalize(new_up_axis);
|
||||
|
||||
@@ -372,7 +424,7 @@ static void RIG_appendEdgeToArc(RigArc *arc, RigEdge *edge)
|
||||
{
|
||||
RigEdge *last_edge = edge->prev;
|
||||
VECCOPY(edge->head, last_edge->tail);
|
||||
RIG_calculateEdgeAngle(last_edge, edge);
|
||||
RIG_calculateEdgeAngles(last_edge, edge);
|
||||
}
|
||||
|
||||
edge->length = VecLenf(edge->head, edge->tail);
|
||||
@@ -493,6 +545,7 @@ static RigArc *cloneArc(RigGraph *rg, RigGraph *src_rg, RigArc *src_arc, GHash *
|
||||
|
||||
edge->length = src_edge->length;
|
||||
edge->angle = src_edge->angle;
|
||||
edge->up_angle = src_edge->up_angle;
|
||||
|
||||
if (src_edge->bone != NULL)
|
||||
{
|
||||
@@ -596,7 +649,7 @@ static RigGraph *cloneRigGraph(RigGraph *src, ListBase *editbones, Object *ob)
|
||||
|
||||
/*******************************************************************************************************/
|
||||
|
||||
static void RIG_calculateEdgeAngle(RigEdge *edge_first, RigEdge *edge_second)
|
||||
static void RIG_calculateEdgeAngles(RigEdge *edge_first, RigEdge *edge_second)
|
||||
{
|
||||
float vec_first[3], vec_second[3];
|
||||
|
||||
@@ -606,7 +659,17 @@ static void RIG_calculateEdgeAngle(RigEdge *edge_first, RigEdge *edge_second)
|
||||
Normalize(vec_first);
|
||||
Normalize(vec_second);
|
||||
|
||||
edge_first->angle = saacos(Inpf(vec_first, vec_second));
|
||||
edge_first->angle = NormalizedVecAngle2(vec_first, vec_second);
|
||||
|
||||
if (edge_second->bone != NULL)
|
||||
{
|
||||
float normal[3];
|
||||
|
||||
Crossf(normal, vec_first, vec_second);
|
||||
Normalize(normal);
|
||||
|
||||
edge_second->up_angle = NormalizedVecAngle2(normal, edge_second->up_axis);
|
||||
}
|
||||
}
|
||||
|
||||
/************************************ CONTROL BONES ****************************************************/
|
||||
@@ -1831,7 +1894,18 @@ static void repositionBone(RigGraph *rigg, RigEdge *edge, float vec0[3], float v
|
||||
{
|
||||
float qroll[4];
|
||||
|
||||
bone->roll = rollBoneByQuatAligned(bone, edge->up_axis, qrot, qroll, up_axis);
|
||||
if (G.scene->toolsettings->skgen_retarget_roll == SK_RETARGET_ROLL_VIEW)
|
||||
{
|
||||
bone->roll = rollBoneByQuatAligned(bone, edge->up_axis, qrot, qroll, up_axis);
|
||||
}
|
||||
else if (G.scene->toolsettings->skgen_retarget_roll == SK_RETARGET_ROLL_JOINT)
|
||||
{
|
||||
bone->roll = rollBoneByQuatJoint(edge, edge->next, qrot, qroll);
|
||||
}
|
||||
else
|
||||
{
|
||||
QuatOne(qroll);
|
||||
}
|
||||
|
||||
QuatMul(qrot, qroll, qrot);
|
||||
}
|
||||
|
||||
@@ -529,11 +529,8 @@ ReebNode *sk_pointToNode(SK_Point *pt, float imat[][4], float tmat[][3])
|
||||
VECCOPY(node->p, pt->p);
|
||||
Mat4MulVecfl(imat, node->p);
|
||||
|
||||
if (G.scene->toolsettings->skgen_retarget_options & SK_RETARGET_ROLL)
|
||||
{
|
||||
VECCOPY(node->no, pt->no);
|
||||
Mat3MulVecfl(tmat, node->no);
|
||||
}
|
||||
VECCOPY(node->no, pt->no);
|
||||
Mat3MulVecfl(tmat, node->no);
|
||||
|
||||
return node;
|
||||
}
|
||||
@@ -555,11 +552,8 @@ ReebArc *sk_strokeToArc(SK_Stroke *stk, float imat[][4], float tmat[][3])
|
||||
VECCOPY(arc->buckets[i].p, stk->points[i + 1].p);
|
||||
Mat4MulVecfl(imat, arc->buckets[i].p);
|
||||
|
||||
if (G.scene->toolsettings->skgen_retarget_options & SK_RETARGET_ROLL)
|
||||
{
|
||||
VECCOPY(arc->buckets[i].no, stk->points[i + 1].no);
|
||||
Mat3MulVecfl(tmat, arc->buckets[i].no);
|
||||
}
|
||||
VECCOPY(arc->buckets[i].no, stk->points[i + 1].no);
|
||||
Mat3MulVecfl(tmat, arc->buckets[i].no);
|
||||
}
|
||||
|
||||
return arc;
|
||||
|
||||
Reference in New Issue
Block a user