Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/blender/blenkernel/intern/armature.c101
-rw-r--r--source/blender/makesdna/DNA_action_types.h13
2 files changed, 64 insertions, 50 deletions
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c
index b44bf751a8a..3bec79eb352 100644
--- a/source/blender/blenkernel/intern/armature.c
+++ b/source/blender/blenkernel/intern/armature.c
@@ -577,7 +577,13 @@ Mat4 *b_bone_spline_setup(bPoseChannel *pchan, int rest)
/* ************ Armature Deform ******************* */
-static void pchan_b_bone_defmats(bPoseChannel *pchan, int use_quaternion)
+typedef struct bPoseChanDeform {
+ Mat4 *b_bone_mats;
+ DualQuat *dual_quat;
+ DualQuat *b_bone_dual_quats;
+} bPoseChanDeform;
+
+static void pchan_b_bone_defmats(bPoseChannel *pchan, bPoseChanDeform *pdef_info, int use_quaternion)
{
Bone *bone= pchan->bone;
Mat4 *b_bone= b_bone_spline_setup(pchan, 0);
@@ -589,11 +595,11 @@ static void pchan_b_bone_defmats(bPoseChannel *pchan, int use_quaternion)
/* allocate b_bone matrices and dual quats */
b_bone_mats= MEM_mallocN((1+bone->segments)*sizeof(Mat4), "BBone defmats");
- pchan->b_bone_mats= b_bone_mats;
+ pdef_info->b_bone_mats= b_bone_mats;
if(use_quaternion) {
b_bone_dual_quats= MEM_mallocN((bone->segments)*sizeof(DualQuat), "BBone dqs");
- pchan->b_bone_dual_quats= b_bone_dual_quats;
+ pdef_info->b_bone_dual_quats= b_bone_dual_quats;
}
/* first matrix is the inverse arm_mat, to bring points in local bone space
@@ -618,9 +624,9 @@ static void pchan_b_bone_defmats(bPoseChannel *pchan, int use_quaternion)
}
}
-static void b_bone_deform(bPoseChannel *pchan, Bone *bone, float *co, DualQuat *dq, float defmat[][3])
+static void b_bone_deform(bPoseChanDeform *pdef_info, Bone *bone, float *co, DualQuat *dq, float defmat[][3])
{
- Mat4 *b_bone= pchan->b_bone_mats;
+ Mat4 *b_bone= pdef_info->b_bone_mats;
float (*mat)[4]= b_bone[0].mat;
float segment, y;
int a;
@@ -637,7 +643,7 @@ static void b_bone_deform(bPoseChannel *pchan, Bone *bone, float *co, DualQuat *
CLAMP(a, 0, bone->segments-1);
if(dq) {
- copy_dq_dq(dq, &((DualQuat*)pchan->b_bone_dual_quats)[a]);
+ copy_dq_dq(dq, &(pdef_info->b_bone_dual_quats)[a]);
}
else {
mul_m4_v3(b_bone[a+1].mat, co);
@@ -711,7 +717,7 @@ static void pchan_deform_mat_add(bPoseChannel *pchan, float weight, float bbonem
add_m3_m3m3(mat, mat, wmat);
}
-static float dist_bone_deform(bPoseChannel *pchan, float *vec, DualQuat *dq, float mat[][3], float *co)
+static float dist_bone_deform(bPoseChannel *pchan, bPoseChanDeform *pdef_info, float *vec, DualQuat *dq, float mat[][3], float *co)
{
Bone *bone= pchan->bone;
float fac, contrib=0.0;
@@ -732,7 +738,7 @@ static float dist_bone_deform(bPoseChannel *pchan, float *vec, DualQuat *dq, flo
if(vec) {
if(bone->segments>1)
// applies on cop and bbonemat
- b_bone_deform(pchan, bone, cop, NULL, (mat)?bbonemat:NULL);
+ b_bone_deform(pdef_info, bone, cop, NULL, (mat)?bbonemat:NULL);
else
mul_m4_v3(pchan->chan_mat, cop);
@@ -745,11 +751,11 @@ static float dist_bone_deform(bPoseChannel *pchan, float *vec, DualQuat *dq, flo
}
else {
if(bone->segments>1) {
- b_bone_deform(pchan, bone, cop, &bbonedq, NULL);
+ b_bone_deform(pdef_info, bone, cop, &bbonedq, NULL);
add_weighted_dq_dq(dq, &bbonedq, fac);
}
else
- add_weighted_dq_dq(dq, pchan->dual_quat, fac);
+ add_weighted_dq_dq(dq, pdef_info->dual_quat, fac);
}
}
}
@@ -757,7 +763,7 @@ static float dist_bone_deform(bPoseChannel *pchan, float *vec, DualQuat *dq, flo
return contrib;
}
-static void pchan_bone_deform(bPoseChannel *pchan, float weight, float *vec, DualQuat *dq, float mat[][3], float *co, float *contrib)
+static void pchan_bone_deform(bPoseChannel *pchan, bPoseChanDeform *pdef_info, float weight, float *vec, DualQuat *dq, float mat[][3], float *co, float *contrib)
{
float cop[3], bbonemat[3][3];
DualQuat bbonedq;
@@ -770,7 +776,7 @@ static void pchan_bone_deform(bPoseChannel *pchan, float weight, float *vec, Dua
if(vec) {
if(pchan->bone->segments>1)
// applies on cop and bbonemat
- b_bone_deform(pchan, pchan->bone, cop, NULL, (mat)?bbonemat:NULL);
+ b_bone_deform(pdef_info, pchan->bone, cop, NULL, (mat)?bbonemat:NULL);
else
mul_m4_v3(pchan->chan_mat, cop);
@@ -783,11 +789,11 @@ static void pchan_bone_deform(bPoseChannel *pchan, float weight, float *vec, Dua
}
else {
if(pchan->bone->segments>1) {
- b_bone_deform(pchan, pchan->bone, cop, &bbonedq, NULL);
+ b_bone_deform(pdef_info, pchan->bone, cop, &bbonedq, NULL);
add_weighted_dq_dq(dq, &bbonedq, weight);
}
else
- add_weighted_dq_dq(dq, pchan->dual_quat, weight);
+ add_weighted_dq_dq(dq, pdef_info->dual_quat, weight);
}
(*contrib)+=weight;
@@ -798,8 +804,11 @@ void armature_deform_verts(Object *armOb, Object *target, DerivedMesh *dm,
int numVerts, int deformflag,
float (*prevCos)[3], const char *defgrp_name)
{
+ bPoseChanDeform *pdef_info_array;
+ bPoseChanDeform *pdef_info= NULL;
bArmature *arm= armOb->data;
bPoseChannel *pchan, **defnrToPC = NULL;
+ int *defnrToPCIndex= NULL;
MDeformVert *dverts = NULL;
bDeformGroup *dg;
DualQuat *dualquats= NULL;
@@ -823,20 +832,24 @@ void armature_deform_verts(Object *armOb, Object *target, DerivedMesh *dm,
/* bone defmats are already in the channels, chan_mat */
/* initialize B_bone matrices and dual quaternions */
+ totchan= BLI_countlist(&armOb->pose->chanbase);
+
if(use_quaternion) {
- totchan= BLI_countlist(&armOb->pose->chanbase);
dualquats= MEM_callocN(sizeof(DualQuat)*totchan, "dualquats");
}
+
+ pdef_info_array= MEM_callocN(sizeof(bPoseChanDeform)*totchan, "bPoseChanDeform");
totchan= 0;
- for(pchan = armOb->pose->chanbase.first; pchan; pchan = pchan->next) {
+ pdef_info= pdef_info_array;
+ for(pchan= armOb->pose->chanbase.first; pchan; pchan= pchan->next, pdef_info++) {
if(!(pchan->bone->flag & BONE_NO_DEFORM)) {
if(pchan->bone->segments > 1)
- pchan_b_bone_defmats(pchan, use_quaternion);
+ pchan_b_bone_defmats(pchan, pdef_info, use_quaternion);
if(use_quaternion) {
- pchan->dual_quat= &dualquats[totchan++];
- mat4_to_dquat( pchan->dual_quat,pchan->bone->arm_mat, pchan->chan_mat);
+ pdef_info->dual_quat= &dualquats[totchan++];
+ mat4_to_dquat( pdef_info->dual_quat,pchan->bone->arm_mat, pchan->chan_mat);
}
}
}
@@ -872,15 +885,19 @@ void armature_deform_verts(Object *armOb, Object *target, DerivedMesh *dm,
else if(dverts) use_dverts = 1;
if(use_dverts) {
- defnrToPC = MEM_callocN(sizeof(*defnrToPC) * numGroups,
- "defnrToBone");
+ defnrToPC = MEM_callocN(sizeof(*defnrToPC) * numGroups, "defnrToBone");
+ defnrToPCIndex = MEM_callocN(sizeof(*defnrToPCIndex) * numGroups, "defnrToIndex");
for(i = 0, dg = target->defbase.first; dg;
i++, dg = dg->next) {
defnrToPC[i] = get_pose_channel(armOb->pose, dg->name);
/* exclude non-deforming bones */
if(defnrToPC[i]) {
- if(defnrToPC[i]->bone->flag & BONE_NO_DEFORM)
+ if(defnrToPC[i]->bone->flag & BONE_NO_DEFORM) {
defnrToPC[i]= NULL;
+ }
+ else {
+ defnrToPCIndex[i]= BLI_findindex(&armOb->pose->chanbase, defnrToPC[i]);
+ }
}
}
}
@@ -951,10 +968,10 @@ void armature_deform_verts(Object *armOb, Object *target, DerivedMesh *dm,
for(j = 0; j < dvert->totweight; j++){
int index = dvert->dw[j].def_nr;
- pchan = index < numGroups?defnrToPC[index]:NULL;
- if(pchan) {
+ if(index < numGroups && (pchan= defnrToPC[index])) {
float weight = dvert->dw[j].weight;
- Bone *bone = pchan->bone;
+ Bone *bone= pchan->bone;
+ pdef_info= pdef_info_array + defnrToPCIndex[index];
deformed = 1;
@@ -965,25 +982,27 @@ void armature_deform_verts(Object *armOb, Object *target, DerivedMesh *dm,
bone->rad_tail,
bone->dist);
}
- pchan_bone_deform(pchan, weight, vec, dq, smat, co, &contrib);
+ pchan_bone_deform(pchan, pdef_info, weight, vec, dq, smat, co, &contrib);
}
}
/* if there are vertexgroups but not groups with bones
* (like for softbody groups)
*/
if(deformed == 0 && use_envelope) {
- for(pchan = armOb->pose->chanbase.first; pchan;
- pchan = pchan->next) {
+ pdef_info= pdef_info_array;
+ for(pchan= armOb->pose->chanbase.first; pchan;
+ pchan= pchan->next, pdef_info++) {
if(!(pchan->bone->flag & BONE_NO_DEFORM))
- contrib += dist_bone_deform(pchan, vec, dq, smat, co);
+ contrib += dist_bone_deform(pchan, pdef_info, vec, dq, smat, co);
}
}
}
else if(use_envelope) {
+ pdef_info= pdef_info_array;
for(pchan = armOb->pose->chanbase.first; pchan;
- pchan = pchan->next) {
+ pchan = pchan->next, pdef_info++) {
if(!(pchan->bone->flag & BONE_NO_DEFORM))
- contrib += dist_bone_deform(pchan, vec, dq, smat, co);
+ contrib += dist_bone_deform(pchan, pdef_info, vec, dq, smat, co);
}
}
@@ -1039,20 +1058,20 @@ void armature_deform_verts(Object *armOb, Object *target, DerivedMesh *dm,
if(dualquats) MEM_freeN(dualquats);
if(defnrToPC) MEM_freeN(defnrToPC);
-
+ if(defnrToPCIndex) MEM_freeN(defnrToPCIndex);
+
/* free B_bone matrices */
- for(pchan = armOb->pose->chanbase.first; pchan; pchan = pchan->next) {
- if(pchan->b_bone_mats) {
- MEM_freeN(pchan->b_bone_mats);
- pchan->b_bone_mats = NULL;
+ pdef_info= pdef_info_array;
+ for(pchan = armOb->pose->chanbase.first; pchan; pchan = pchan->next, pdef_info++) {
+ if(pdef_info->b_bone_mats) {
+ MEM_freeN(pdef_info->b_bone_mats);
}
- if(pchan->b_bone_dual_quats) {
- MEM_freeN(pchan->b_bone_dual_quats);
- pchan->b_bone_dual_quats = NULL;
+ if(pdef_info->b_bone_dual_quats) {
+ MEM_freeN(pdef_info->b_bone_dual_quats);
}
-
- pchan->dual_quat = NULL;
}
+
+ MEM_freeN(pdef_info_array);
}
/* ************ END Armature Deform ******************* */
diff --git a/source/blender/makesdna/DNA_action_types.h b/source/blender/makesdna/DNA_action_types.h
index f7bbf9235ab..6f6e4978cfc 100644
--- a/source/blender/makesdna/DNA_action_types.h
+++ b/source/blender/makesdna/DNA_action_types.h
@@ -203,12 +203,10 @@ typedef struct bPoseChannel {
struct bPoseChannel *child; /* set on read file or rebuild pose, the 'ik' child, for b-bones */
struct ListBase iktree; /* only while evaluating pose */
- /* only while deform, stores precalculated b_bone deform mats,
- dual quaternions */
- void *b_bone_mats;
- void *dual_quat;
- void *b_bone_dual_quats;
-
+ bMotionPath *mpath; /* motion path cache for this bone */
+ struct Object *custom; /* draws custom object instead of default bone shape */
+ struct bPoseChannel *custom_tx; /* odd feature, display with another bones transform. needed in rare cases for advanced rigs, since the alternative is highly complicated - campbell */
+
/* transforms - written in by actions or transform */
float loc[3];
float size[3];
@@ -234,9 +232,6 @@ typedef struct bPoseChannel {
float iklinweight; /* weight of joint stretch constraint */
float *path; /* totpath x 3 x float */ // XXX depreceated... old animation system (armature only viz)
- bMotionPath *mpath; /* motion path cache for this bone */
- struct Object *custom; /* draws custom object instead of default bone shape */
- struct bPoseChannel *custom_tx; /* odd feature, display with another bones transform. needed in rare cases for advanced rigs, since the alternative is highly complicated - campbell */
} bPoseChannel;