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
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/intern/armature.c42
1 files changed, 37 insertions, 5 deletions
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c
index e362bdbd2dd..40f4ae7298e 100644
--- a/source/blender/blenkernel/intern/armature.c
+++ b/source/blender/blenkernel/intern/armature.c
@@ -411,12 +411,31 @@ Mat4 *b_bone_spline_setup(bPoseChannel *pchan, int rest)
Mat4 *result_array= (rest)? bbone_rest_array: bbone_array;
bPoseChannel *next, *prev;
Bone *bone= pchan->bone;
- float h1[3], h2[3], length, hlength1, hlength2, roll1=0.0f, roll2;
- float mat3[3][3], imat[4][4];
+ float h1[3], h2[3], scale[3], length, hlength1, hlength2, roll1=0.0f, roll2;
+ float mat3[3][3], imat[4][4], posemat[4][4], scalemat[4][4], iscalemat[4][4];
float data[MAX_BBONE_SUBDIV+1][4], *fp;
- int a;
-
+ int a, doscale= 0;
+
length= bone->length;
+
+ if(!rest) {
+ /* check if we need to take non-uniform bone scaling into account */
+ scale[0]= VecLength(pchan->pose_mat[0]);
+ scale[1]= VecLength(pchan->pose_mat[1]);
+ scale[2]= VecLength(pchan->pose_mat[2]);
+
+ if(fabs(scale[0] - scale[1]) > 1e-6f || fabs(scale[1] - scale[2]) > 1e-6f) {
+ Mat4One(scalemat);
+ scalemat[0][0]= scale[0];
+ scalemat[1][1]= scale[1];
+ scalemat[2][2]= scale[2];
+ Mat4Invert(iscalemat, scalemat);
+
+ length *= scale[1];
+ doscale = 1;
+ }
+ }
+
hlength1= bone->ease1*length*0.390464f; // 0.5*sqrt(2)*kappa, the handle length for near-perfect circles
hlength2= bone->ease2*length*0.390464f;
@@ -432,8 +451,14 @@ Mat4 *b_bone_spline_setup(bPoseChannel *pchan, int rest)
first point = (0,0,0)
last point = (0, length, 0) */
- if(rest)
+ if(rest) {
Mat4Invert(imat, pchan->bone->arm_mat);
+ }
+ else if(doscale) {
+ Mat4CpyMat4(posemat, pchan->pose_mat);
+ Mat4Ortho(posemat);
+ Mat4Invert(imat, posemat);
+ }
else
Mat4Invert(imat, pchan->pose_mat);
@@ -527,8 +552,15 @@ Mat4 *b_bone_spline_setup(bPoseChannel *pchan, int rest)
for(a=0, fp= data[0]; a<bone->segments; a++, fp+=4) {
VecSubf(h1, fp+4, fp);
vec_roll_to_mat3(h1, fp[3], mat3); // fp[3] is roll
+
Mat4CpyMat3(result_array[a].mat, mat3);
VECCOPY(result_array[a].mat[3], fp);
+
+ if(doscale) {
+ /* correct for scaling when this matrix is used in scaled space */
+ Mat4MulSerie(result_array[a].mat, iscalemat, result_array[a].mat,
+ scalemat, NULL, NULL, NULL, NULL, NULL);
+ }
}
return result_array;