[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [12272] trunk/blender/source/blender/ blenkernel/intern/armature.c:
Brecht Van Lommel
brechtvanlommel at pandora.be
Wed Oct 17 19:53:59 CEST 2007
Revision: 12272
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=12272
Author: blendix
Date: 2007-10-17 19:53:59 +0200 (Wed, 17 Oct 2007)
Log Message:
-----------
Bugfix:
The roll of a B-Bone relative to a previous regular bone was not matched
correctly.
Modified Paths:
--------------
trunk/blender/source/blender/blenkernel/intern/armature.c
Modified: trunk/blender/source/blender/blenkernel/intern/armature.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/armature.c 2007-10-17 15:48:59 UTC (rev 12271)
+++ trunk/blender/source/blender/blenkernel/intern/armature.c 2007-10-17 17:53:59 UTC (rev 12272)
@@ -411,7 +411,7 @@
Mat4 *result_array= (rest)? bbone_rest_array: bbone_array;
bPoseChannel *next, *prev;
Bone *bone= pchan->bone;
- float h1[3], h2[3], length, hlength1, hlength2, roll;
+ float h1[3], h2[3], length, hlength1, hlength2, roll1, roll2;
float mat3[3][3], imat[4][4];
float data[MAX_BBONE_SUBDIV+1][4], *fp;
int a;
@@ -438,19 +438,43 @@
Mat4Invert(imat, pchan->pose_mat);
if(prev) {
+ float difmat[4][4], result[3][3], imat3[3][3];
+
/* transform previous point inside this bone space */
if(rest)
VECCOPY(h1, prev->bone->arm_head)
else
VECCOPY(h1, prev->pose_head)
Mat4MulVecfl(imat, h1);
- /* if previous bone is B-bone too, use average handle direction */
- if(prev->bone->segments>1) h1[1]-= length;
+
+ if(prev->bone->segments>1) {
+ /* if previous bone is B-bone too, use average handle direction */
+ h1[1]-= length;
+ roll1= 0.0f;
+ }
+
Normalize(h1);
VecMulf(h1, -hlength1);
+
+ if(prev->bone->segments==1) {
+ /* find the previous roll to interpolate */
+ if(rest)
+ Mat4MulMat4(difmat, prev->bone->arm_mat, imat);
+ else
+ Mat4MulMat4(difmat, prev->pose_mat, imat);
+ Mat3CpyMat4(result, difmat); // the desired rotation at beginning of next bone
+
+ vec_roll_to_mat3(h1, 0.0f, mat3); // the result of vec_roll without roll
+
+ Mat3Inv(imat3, mat3);
+ Mat3MulMat3(mat3, result, imat3); // the matrix transforming vec_roll to desired roll
+
+ roll1= atan2(mat3[2][0], mat3[2][2]);
+ }
}
else {
h1[0]= 0.0f; h1[1]= hlength1; h1[2]= 0.0f;
+ roll1= 0.0f;
}
if(next) {
float difmat[4][4], result[3][3], imat3[3][3];
@@ -464,6 +488,7 @@
/* if next bone is B-bone too, use average handle direction */
if(next->bone->segments>1);
else h2[1]-= length;
+ Normalize(h2);
/* find the next roll to interpolate as well */
if(rest)
@@ -477,18 +502,16 @@
Mat3Inv(imat3, mat3);
Mat3MulMat3(mat3, imat3, result); // the matrix transforming vec_roll to desired roll
- roll= atan2(mat3[2][0], mat3[2][2]);
+ roll2= atan2(mat3[2][0], mat3[2][2]);
/* and only now negate handle */
- Normalize(h2);
VecMulf(h2, -hlength2);
-
}
else {
h2[0]= 0.0f; h2[1]= -hlength2; h2[2]= 0.0f;
- roll= 0.0;
+ roll2= 0.0;
}
-
+
/* make curve */
if(bone->segments > MAX_BBONE_SUBDIV)
bone->segments= MAX_BBONE_SUBDIV;
@@ -496,7 +519,7 @@
forward_diff_bezier(0.0, h1[0], h2[0], 0.0, data[0], MAX_BBONE_SUBDIV, 4);
forward_diff_bezier(0.0, h1[1], length + h2[1], length, data[0]+1, MAX_BBONE_SUBDIV, 4);
forward_diff_bezier(0.0, h1[2], h2[2], 0.0, data[0]+2, MAX_BBONE_SUBDIV, 4);
- forward_diff_bezier(0.0, 0.390464f*roll, (1.0f-0.390464f)*roll, roll, data[0]+3, MAX_BBONE_SUBDIV, 4);
+ forward_diff_bezier(roll1, roll1 + 0.390464f*(roll2-roll1), roll2 - 0.390464f*(roll2-roll1), roll2, data[0]+3, MAX_BBONE_SUBDIV, 4);
equalize_bezier(data[0], bone->segments); // note: does stride 4!
More information about the Bf-blender-cvs
mailing list