BGE: allow action blending by bringing back blend_poses() as game_blend_poses, the...
authorCampbell Barton <ideasman42@gmail.com>
Fri, 19 Jun 2009 16:27:01 +0000 (16:27 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Fri, 19 Jun 2009 16:27:01 +0000 (16:27 +0000)
source/blender/blenkernel/BKE_action.h
source/blender/blenkernel/intern/action.c
source/gameengine/Converter/BL_ActionActuator.cpp
source/gameengine/Converter/KX_BlenderScalarInterpolator.cpp

index 67eb2ed58bf2cc972850cf16865c8498fc5d1fc9..f0796697670a86ed8ce7f584f4aeb9806b616285 100644 (file)
@@ -137,7 +137,7 @@ void framechange_poses_clear_unkeyed(void);
 void what_does_obaction(struct Scene *scene, struct Object *ob, struct Object *workob, struct bPose *pose, struct bAction *act, char groupname[], float cframe);
 
 /* exported for game engine */
-void blend_poses(struct bPose *dst, struct bPose *src, float srcweight, short mode);
+void game_blend_poses(struct bPose *dst, struct bPose *src, float srcweight/*, short mode*/); /* was blend_poses */
 void extract_pose_from_pose(struct bPose *pose, const struct bPose *src);
 
 /* for proxy */
index fb1b2e9cf70d75b82e0805c6519ad75ed8fbbcd6..f7e15cef4c4137ab158f2198c75f1f60dc3807ab 100644 (file)
@@ -581,6 +581,77 @@ void game_copy_pose(bPose **dst, bPose *src)
        *dst=out;
 }
 
+
+/* Only allowed for Poses with identical channels */
+void game_blend_poses(bPose *dst, bPose *src, float srcweight/*, short mode*/)
+{
+       short mode= ACTSTRIPMODE_BLEND;
+       
+       bPoseChannel *dchan;
+       const bPoseChannel *schan;
+       bConstraint *dcon, *scon;
+       float dstweight;
+       int i;
+
+       switch (mode){
+       case ACTSTRIPMODE_BLEND:
+               dstweight = 1.0F - srcweight;
+               break;
+       case ACTSTRIPMODE_ADD:
+               dstweight = 1.0F;
+               break;
+       default :
+               dstweight = 1.0F;
+       }
+       
+       schan= src->chanbase.first;
+       for (dchan = dst->chanbase.first; dchan; dchan=dchan->next, schan= schan->next){
+               if (schan->flag & (POSE_ROT|POSE_LOC|POSE_SIZE)) {
+                       /* replaced quat->matrix->quat conversion with decent quaternion interpol (ton) */
+                       
+                       /* Do the transformation blend */
+                       if (schan->flag & POSE_ROT) {
+                               /* quat interpolation done separate */
+                               if (schan->rotmode == PCHAN_ROT_QUAT) {
+                                       float dquat[4], squat[4];
+                                       
+                                       QUATCOPY(dquat, dchan->quat);
+                                       QUATCOPY(squat, schan->quat);
+                                       if (mode==ACTSTRIPMODE_BLEND)
+                                               QuatInterpol(dchan->quat, dquat, squat, srcweight);
+                                       else {
+                                               QuatMulFac(squat, srcweight);
+                                               QuatMul(dchan->quat, dquat, squat);
+                                       }
+                                       
+                                       NormalQuat(dchan->quat);
+                               }
+                       }
+
+                       for (i=0; i<3; i++) {
+                               /* blending for loc and scale are pretty self-explanatory... */
+                               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);
+                               
+                               /* euler-rotation interpolation done here instead... */
+                               // FIXME: are these results decent?
+                               if ((schan->flag & POSE_ROT) && (schan->rotmode))
+                                       dchan->eul[i] = (dchan->eul[i]*dstweight) + (schan->eul[i]*srcweight);
+                       }
+                       dchan->flag |= schan->flag;
+               }
+               for(dcon= dchan->constraints.first, scon= schan->constraints.first; dcon && scon; dcon= dcon->next, scon= scon->next) {
+                       /* no 'add' option for constraint blending */
+                       dcon->enforce= dcon->enforce*(1.0f-srcweight) + scon->enforce*srcweight;
+               }
+       }
+       
+       /* this pose is now in src time */
+       dst->ctime= src->ctime;
+}
+
 void game_free_pose(bPose *pose)
 {
        if (pose) {
@@ -1039,75 +1110,6 @@ static void blend_pose_offset_bone(bActionStrip *strip, bPose *dst, bPose *src,
        VecAddf(dst->cyclic_offset, dst->cyclic_offset, src->cyclic_offset);
 }
 
-
-/* Only allowed for Poses with identical channels */
-void blend_poses(bPose *dst, bPose *src, float srcweight, short mode)
-{
-       bPoseChannel *dchan;
-       const bPoseChannel *schan;
-       bConstraint *dcon, *scon;
-       float dstweight;
-       int i;
-       
-       switch (mode){
-       case ACTSTRIPMODE_BLEND:
-               dstweight = 1.0F - srcweight;
-               break;
-       case ACTSTRIPMODE_ADD:
-               dstweight = 1.0F;
-               break;
-       default :
-               dstweight = 1.0F;
-       }
-       
-       schan= src->chanbase.first;
-       for (dchan = dst->chanbase.first; dchan; dchan=dchan->next, schan= schan->next){
-               if (schan->flag & (POSE_ROT|POSE_LOC|POSE_SIZE)) {
-                       /* replaced quat->matrix->quat conversion with decent quaternion interpol (ton) */
-                       
-                       /* Do the transformation blend */
-                       if (schan->flag & POSE_ROT) {
-                               /* quat interpolation done separate */
-                               if (schan->rotmode == PCHAN_ROT_QUAT) {
-                                       float dquat[4], squat[4];
-                                       
-                                       QUATCOPY(dquat, dchan->quat);
-                                       QUATCOPY(squat, schan->quat);
-                                       if (mode==ACTSTRIPMODE_BLEND)
-                                               QuatInterpol(dchan->quat, dquat, squat, srcweight);
-                                       else {
-                                               QuatMulFac(squat, srcweight);
-                                               QuatMul(dchan->quat, dquat, squat);
-                                       }
-                                       
-                                       NormalQuat(dchan->quat);
-                               }
-                       }
-
-                       for (i=0; i<3; i++) {
-                               /* blending for loc and scale are pretty self-explanatory... */
-                               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);
-                               
-                               /* euler-rotation interpolation done here instead... */
-                               // FIXME: are these results decent?
-                               if ((schan->flag & POSE_ROT) && (schan->rotmode))
-                                       dchan->eul[i] = (dchan->eul[i]*dstweight) + (schan->eul[i]*srcweight);
-                       }
-                       dchan->flag |= schan->flag;
-               }
-               for(dcon= dchan->constraints.first, scon= schan->constraints.first; dcon && scon; dcon= dcon->next, scon= scon->next) {
-                       /* no 'add' option for constraint blending */
-                       dcon->enforce= dcon->enforce*(1.0f-srcweight) + scon->enforce*srcweight;
-               }
-       }
-       
-       /* this pose is now in src time */
-       dst->ctime= src->ctime;
-}
-
 typedef struct NlaIpoChannel {
        struct NlaIpoChannel *next, *prev;
        float val;
index 131d48aed4f3ba8781eb0a2b3b9c19bd2af63e25..c0d28d28bda4323071f4cb0a2d5b98f25410d23c 100644 (file)
@@ -409,7 +409,7 @@ bool BL_ActionActuator::Update(double curtime, bool frame)
                                
                                /* Find percentages */
                                newweight = (m_blendframe/(float)m_blendin);
-                               // XXX blend_poses(m_pose, m_blendpose, 1.0 - newweight, ACTSTRIPMODE_BLEND);
+                               game_blend_poses(m_pose, m_blendpose, 1.0 - newweight);
 
                                /* Increment current blending percentage */
                                m_blendframe = (curtime - m_blendstart)*KX_KetsjiEngine::GetAnimFrameRate();
index 20829524558ec8e180b594d186b243b66fbea22e..c3264a2bc37403667483772f57ffd9d1a0ba4ec4 100644 (file)
@@ -43,6 +43,9 @@ float BL_ScalarInterpolator::GetValue(float currentTime) const {
 }
 
 BL_InterpolatorList::BL_InterpolatorList(struct AnimData *adt) {
+       if(adt->action==NULL)
+               return;
+       
        for(FCurve *fcu= (FCurve *)adt->action->curves.first; fcu; fcu= (FCurve *)fcu->next) {
                if(fcu->rna_path) {
                        BL_ScalarInterpolator *new_ipo = new BL_ScalarInterpolator(fcu);