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:
authorTon Roosendaal <ton@blender.org>2004-11-11 16:17:32 +0300
committerTon Roosendaal <ton@blender.org>2004-11-11 16:17:32 +0300
commit2e4a10253b8f96b631eee8af5e1e711f372612ae (patch)
treef7ac4c363e22d2085397ca9410acdceb424c5476
parent11fe49227b8b3dbcc6dbafbde16ee84c1a2e5af7 (diff)
Fix for bug #1756
This was caused by a very primitive method of interpolating quaternions. It was converting quats to mat and back to quat, and then just doing a linear interpolation. That whilst quaternions are renowned for having good interpolation possible. I've experimented with 2 quaternion interpolation methods, and can only get one to work correctly... the "official" version from Watt brothers I can't get working, both are in arithb.c now. Will arrange *close* review with experienced NLAers for it! But testing here gives fully predictable results. Also changed; - added pointer check in drawaction - changed puldown menu for correct hotkeys for move NLA strips up/down
-rw-r--r--source/blender/blenkernel/intern/action.c32
-rw-r--r--source/blender/blenlib/BLI_arithb.h5
-rw-r--r--source/blender/blenlib/intern/arithb.c86
-rw-r--r--source/blender/src/drawaction.c17
-rw-r--r--source/blender/src/header_nla.c4
5 files changed, 124 insertions, 20 deletions
diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c
index 673c5080f2e..1740fe70247 100644
--- a/source/blender/blenkernel/intern/action.c
+++ b/source/blender/blenkernel/intern/action.c
@@ -178,26 +178,38 @@ void blend_poses(bPose *dst, const bPose *src, float srcweight, short mode)
* This sucks because it is slow and stupid
*/
- QuatToMat3(dchan->quat, mat);
- Mat3ToQuat(mat, dquat);
- QuatToMat3(schan->quat, mat);
- Mat3ToQuat(mat, squat);
+ //QuatToMat3(dchan->quat, mat);
+ //Mat3ToQuat(mat, dquat);
+ //QuatToMat3(schan->quat, mat);
+ //Mat3ToQuat(mat, squat);
+ /* replaced quat->matrix->quat conversion with decent quaternion interpol (ton) */
/* Do the transformation blend */
+ if (schan->flag & POSE_ROT) {
+ QUATCOPY(dquat, dchan->quat);
+ QUATCOPY(squat, schan->quat);
+ if(mode==POSE_BLEND)
+ QuatInterpol(dchan->quat, dquat, squat, srcweight);
+ else
+ QuatAdd(dchan->quat, dquat, squat, srcweight);
+ NormalQuat (dchan->quat);
+ }
+
for (i=0; i<3; i++){
if (schan->flag & POSE_LOC)
dchan->loc[i] = (dchan->loc[i]*dstweight) + (schan->loc[i]*srcweight);
if (schan->flag & POSE_SIZE)
dchan->size[i] = 1.0f + ((dchan->size[i]-1.0f)*dstweight) + ((schan->size[i]-1.0f)*srcweight);
- if (schan->flag & POSE_ROT)
- dchan->quat[i+1] = (dquat[i+1]*dstweight) + (squat[i+1]*srcweight);
+ //if (schan->flag & POSE_ROT)
+ // dchan->quat[i+1] = (dquat[i+1]*dstweight) + (squat[i+1]*srcweight);
}
/* Do one more iteration for the quaternions only and normalize the quaternion if needed */
- if (schan->flag & POSE_ROT)
- dchan->quat[0] = 1.0f + ((dquat[0]-1.0f)*dstweight) + ((squat[0]-1.0f)*srcweight);
- if (mode==POSE_BLEND)
- NormalQuat (dchan->quat);
+ //if (schan->flag & POSE_ROT)
+ // dchan->quat[0] = 1.0f + ((dquat[0]-1.0f)*dstweight) + ((squat[0]-1.0f)*srcweight);
+ //if (mode==POSE_BLEND)
+ // NormalQuat (dchan->quat);
+
dchan->flag |= schan->flag;
}
}
diff --git a/source/blender/blenlib/BLI_arithb.h b/source/blender/blenlib/BLI_arithb.h
index 9935932ca31..77081f99246 100644
--- a/source/blender/blenlib/BLI_arithb.h
+++ b/source/blender/blenlib/BLI_arithb.h
@@ -178,6 +178,11 @@ QuatSub(
float *q2
);
+
+void QuatInterpol(float *result, float *quat1, float *quat2, float t);
+void QuatAdd(float *result, float *quat1, float *quat2, float t);
+
+
/**
* @section matrix multiplication can copying routines
*/
diff --git a/source/blender/blenlib/intern/arithb.c b/source/blender/blenlib/intern/arithb.c
index 08a26821ccd..caa4771ff4b 100644
--- a/source/blender/blenlib/intern/arithb.c
+++ b/source/blender/blenlib/intern/arithb.c
@@ -1386,6 +1386,92 @@ void VecUpMat3(float *vec, float mat[][3], short axis)
}
+/* A & M Watt, Advanced animation and rendering techniques, 1992 ACM press */
+
+void QuatInterpolW(float *result, float *quat1, float *quat2, float t)
+{
+ float omega, cosom, sinom, sc1, sc2;
+
+ cosom = quat1[0]*quat2[0] + quat1[1]*quat2[1] + quat1[2]*quat2[2] + quat1[3]*quat2[3] ;
+
+ /* rotate around shortest angle */
+ if ((1.0 + cosom) > 0.0001) {
+
+ if ((1.0 - cosom) > 0.0001) {
+ omega = acos(cosom);
+ sinom = sin(omega);
+ sc1 = sin((1.0 - t) * omega) / sinom;
+ sc2 = sin(t * omega) / sinom;
+ }
+ else {
+ sc1 = 1.0 - t;
+ sc2 = t;
+ }
+ result[0] = sc1*quat1[0] + sc2*quat2[0];
+ result[1] = sc1*quat1[1] + sc2*quat2[1];
+ result[2] = sc1*quat1[2] + sc2*quat2[2];
+ result[3] = sc1*quat1[3] + sc2*quat2[3];
+ }
+ else {
+ result[0] = quat2[3];
+ result[1] = -quat2[2];
+ result[2] = quat2[1];
+ result[3] = -quat2[0];
+
+ sc1 = sin((1.0 - t)*M_PI_2);
+ sc2 = sin(t*M_PI_2);
+
+ result[0] = sc1*quat1[0] + sc2*result[0];
+ result[1] = sc1*quat1[1] + sc2*result[1];
+ result[2] = sc1*quat1[2] + sc2*result[2];
+ result[3] = sc1*quat1[3] + sc2*result[3];
+ }
+}
+
+void QuatInterpol(float *result, float *quat1, float *quat2, float t)
+{
+ float quat[4], omega, cosom, sinom, sc1, sc2;
+
+ cosom = quat1[0]*quat2[0] + quat1[1]*quat2[1] + quat1[2]*quat2[2] + quat1[3]*quat2[3] ;
+
+ /* rotate around shortest angle */
+ if (cosom < 0.0) {
+ cosom = -cosom;
+ quat[0]= -quat1[0];
+ quat[1]= -quat1[1];
+ quat[2]= -quat1[2];
+ quat[3]= -quat1[3];
+ }
+ else {
+ quat[0]= quat1[0];
+ quat[1]= quat1[1];
+ quat[2]= quat1[2];
+ quat[3]= quat1[3];
+ }
+
+ if ((1.0 - cosom) > 0.0001) {
+ omega = acos(cosom);
+ sinom = sin(omega);
+ sc1 = sin((1 - t) * omega) / sinom;
+ sc2 = sin(t * omega) / sinom;
+ } else {
+ sc1= 1.0 - t;
+ sc2= t;
+ }
+
+ result[0] = sc1 * quat[0] + sc2 * quat2[0];
+ result[1] = sc1 * quat[1] + sc2 * quat2[1];
+ result[2] = sc1 * quat[2] + sc2 * quat2[2];
+ result[3] = sc1 * quat[3] + sc2 * quat2[3];
+}
+
+void QuatAdd(float *result, float *quat1, float *quat2, float t)
+{
+ result[0]= quat1[0] + t*quat2[0];
+ result[1]= quat1[1] + t*quat2[1];
+ result[2]= quat1[2] + t*quat2[2];
+ result[3]= quat1[3] + t*quat2[3];
+}
/* **************** VIEW / PROJECTION ******************************** */
diff --git a/source/blender/src/drawaction.c b/source/blender/src/drawaction.c
index 402f7684215..278be07b65b 100644
--- a/source/blender/src/drawaction.c
+++ b/source/blender/src/drawaction.c
@@ -877,15 +877,16 @@ static BezTriple **action_to_keylist(bAction *act, int flags, int *totvert)
/* Count required keys */
for (achan=act->chanbase.first; achan; achan=achan->next){
/* Count transformation keys */
- for (icu=achan->ipo->curve.first; icu; icu=icu->next)
- count+=icu->totvert;
-
- /* Count constraint keys */
- for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next)
- for (icu=conchan->ipo->curve.first; icu; icu=icu->next)
+ if(achan->ipo) {
+ for (icu=achan->ipo->curve.first; icu; icu=icu->next)
count+=icu->totvert;
-
-
+
+ /* Count constraint keys */
+ for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next)
+ for (icu=conchan->ipo->curve.first; icu; icu=icu->next)
+ count+=icu->totvert;
+
+ }
}
/* Build the list */
diff --git a/source/blender/src/header_nla.c b/source/blender/src/header_nla.c
index 332c0bece86..cdf2763eeab 100644
--- a/source/blender/src/header_nla.c
+++ b/source/blender/src/header_nla.c
@@ -289,8 +289,8 @@ static uiBlock *nla_stripmenu(void *arg_unused)
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Move Up|NumPad -", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 6, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Move Down|NumPad +", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 7, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Move Up|Page Down", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 6, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Move Down|Page Up", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 7, "");
// uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Convert Action to NLA Strip|C", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 5, "");