BGE Animations: Making shape actions work again:
authorMitchell Stokes <mogurijin@gmail.com>
Thu, 23 Jun 2011 19:09:09 +0000 (19:09 +0000)
committerMitchell Stokes <mogurijin@gmail.com>
Thu, 23 Jun 2011 19:09:09 +0000 (19:09 +0000)
  * BL_DeformableGameObject is no longer responsible for handling keys, BL_ShapeDeformer is
  * BL_ShapeDeformer also creates a copy of the key on construction and puts it back on the mesh when destructed. This avoids us permanently modifying Blender data.
  * I'm not too fond of clearing out the key every frame, but this works and I can't think of another alternative at the moment (something may be possible with some key juggling)

source/gameengine/Converter/BL_DeformableGameObject.h
source/gameengine/Converter/BL_ShapeActionActuator.cpp
source/gameengine/Converter/BL_ShapeActionActuator.h
source/gameengine/Converter/BL_ShapeDeformer.cpp
source/gameengine/Converter/BL_ShapeDeformer.h

index 615bb84ac2b9b554e36dedb02c91b1438db5ac90..3ba55664007b5a84cf2157406b708960ee8caf9a 100644 (file)
@@ -82,23 +82,6 @@ public:
        bool SetActiveAction(class BL_ShapeActionActuator *act, short priority, double curtime);
 
        bool GetShape(vector<float> &shape);
-       Key* GetKey()
-       {
-               if(m_pDeformer) {
-                       BL_MeshDeformer *deformer= dynamic_cast<BL_MeshDeformer *>(m_pDeformer); // incase its not a MeshDeformer
-                       if(deformer) {
-                               return deformer->GetMesh()->key;
-                       }
-
-#if 0          // TODO. shape keys for softbody, currently they dont store a mesh.
-                       KX_SoftBodyDeformer *deformer_soft= dynamic_cast<KX_SoftBodyDeformer *>(m_pDeformer);   
-                       if(deformer) {
-                               return deformer->GetMesh()->key;
-                       }
-#endif
-               }
-               return NULL;
-       }
        
        virtual void    SetDeformer(class RAS_Deformer* deformer);
        virtual class RAS_Deformer* GetDeformer()
index bb53c2d6fe6f68a69a9fc8832838423c5bc8ce6c..ac377cdb7cab85683b0f816531f1743ffbbd8362 100644 (file)
 
 extern "C" {
        #include "BKE_animsys.h"
+       #include "BKE_key.h"
+       #include "RNA_access.h"
 }
 
+BL_ShapeActionActuator::BL_ShapeActionActuator(SCA_IObject* gameobj,
+                                       const STR_String& propname,
+                                       const STR_String& framepropname,
+                                       float starttime,
+                                       float endtime,
+                                       struct bAction *action,
+                                       short   playtype,
+                                       short   blendin,
+                                       short   priority,
+                                       float   stride) 
+       : SCA_IActuator(gameobj, KX_ACT_SHAPEACTION),
+               
+       m_lastpos(0, 0, 0),
+       m_blendframe(0),
+       m_flag(0),
+       m_startframe (starttime),
+       m_endframe(endtime) ,
+       m_starttime(0),
+       m_localtime(starttime),
+       m_lastUpdate(-1),
+       m_blendin(blendin),
+       m_blendstart(0),
+       m_stridelength(stride),
+       m_playtype(playtype),
+       m_priority(priority),
+       m_action(action),
+       m_framepropname(framepropname), 
+       m_propname(propname)
+{
+       m_idptr = new PointerRNA();
+       BL_DeformableGameObject *obj = (BL_DeformableGameObject*)GetParent();
+       BL_ShapeDeformer *shape_deformer = dynamic_cast<BL_ShapeDeformer*>(obj->GetDeformer());
+       RNA_id_pointer_create(&shape_deformer->GetKey()->id, m_idptr);
+};
+
 BL_ShapeActionActuator::~BL_ShapeActionActuator()
 {
+       if (m_idptr)
+               delete m_idptr;
 }
 
 void BL_ShapeActionActuator::ProcessReplica()
@@ -382,7 +421,11 @@ bool BL_ShapeActionActuator::Update(double curtime, bool frame)
 
                /* Priority test */
                if (obj->SetActiveAction(this, priority, curtime)){
-                       Key *key = obj->GetKey();
+                       BL_ShapeDeformer *shape_deformer = dynamic_cast<BL_ShapeDeformer*>(obj->GetDeformer());
+                       Key *key = NULL;
+
+                       if (shape_deformer)
+                               key = shape_deformer->GetKey();
 
                        if (!key) {
                                // this could happen if the mesh was changed in the middle of an action
@@ -397,10 +440,14 @@ bool BL_ShapeActionActuator::Update(double curtime, bool frame)
                                        obj->GetShape(m_blendshape);
                                        m_blendstart = curtime;
                                }
-                               // only interested in shape channel
 
-                               // in 2.4x was // extract_ipochannels_from_action(&tchanbase, &key->id, m_action, "Shape", m_localtime);
-                               BKE_animsys_evaluate_animdata(&key->id, key->adt, m_localtime, ADT_RECALC_ANIM);
+                               KeyBlock *kb;
+                               // We go through and clear out the keyblocks so there isn't any interference
+                               // from other shape actions
+                               for (kb=(KeyBlock*)key->block.first; kb; kb=(KeyBlock*)kb->next)
+                                       kb->curval = 0.f;
+
+                               animsys_evaluate_action(m_idptr, m_action, NULL, m_localtime);
 
                                // XXX - in 2.5 theres no way to do this. possibly not that important to support - Campbell
                                if (0) { // XXX !execute_ipochannels(&tchanbase)) {
index 7a4523d45541e06e3198edd96394ed754c63c8e2..efd24fc305fce07c97e2ddb262e18c2b62161fce 100644 (file)
@@ -54,27 +54,7 @@ public:
                                                short   playtype,
                                                short   blendin,
                                                short   priority,
-                                               float   stride) 
-               : SCA_IActuator(gameobj, KX_ACT_SHAPEACTION),
-               
-               m_lastpos(0, 0, 0),
-               m_blendframe(0),
-               m_flag(0),
-               m_startframe (starttime),
-               m_endframe(endtime) ,
-               m_starttime(0),
-               m_localtime(starttime),
-               m_lastUpdate(-1),
-               m_blendin(blendin),
-               m_blendstart(0),
-               m_stridelength(stride),
-               m_playtype(playtype),
-               m_priority(priority),
-               m_action(action),
-               m_framepropname(framepropname), 
-               m_propname(propname)
-       {
-       };
+                                               float   stride);
        virtual ~BL_ShapeActionActuator();
        virtual bool Update(double curtime, bool frame);
        virtual CValue* GetReplica();
@@ -160,6 +140,7 @@ protected:
        STR_String      m_framepropname;
        STR_String      m_propname;
        vector<float> m_blendshape;
+       struct PointerRNA *m_idptr;
 };
 
 #endif
index 8d8f149bb6c2ee90bf8dc25fd158361694ba8a9a..c651d457cd9869ecf9456020cb4b50ce6947b42d 100644 (file)
@@ -68,9 +68,40 @@ extern "C"{
 #define __NLA_DEFNORMALS
 //#undef __NLA_DEFNORMALS
 
+BL_ShapeDeformer::BL_ShapeDeformer(BL_DeformableGameObject *gameobj,
+                    Object *bmeshobj,
+                    RAS_MeshObject *mesh)
+                               :       
+                                       BL_SkinDeformer(gameobj,bmeshobj, mesh),
+                                       m_lastShapeUpdate(-1)
+{
+       m_key = m_bmesh->key;
+       m_bmesh->key = copy_key(m_key);
+};
+
+/* this second constructor is needed for making a mesh deformable on the fly. */
+BL_ShapeDeformer::BL_ShapeDeformer(BL_DeformableGameObject *gameobj,
+                               Object *bmeshobj_old,
+                               Object *bmeshobj_new,
+                               RAS_MeshObject *mesh,
+                               bool release_object,
+                               bool recalc_normal,
+                               BL_ArmatureObject* arma)
+                               :
+                                       BL_SkinDeformer(gameobj, bmeshobj_old, bmeshobj_new, mesh, release_object, recalc_normal, arma),
+                                       m_lastShapeUpdate(-1)
+{
+       m_key = m_bmesh->key;
+       m_bmesh->key = copy_key(m_key);
+};
 
 BL_ShapeDeformer::~BL_ShapeDeformer()
 {
+       if (m_key && m_bmesh->key)
+       {
+               free_key(m_bmesh->key);
+               m_bmesh->key = m_key;
+       }
 };
 
 RAS_Deformer *BL_ShapeDeformer::GetReplica()
@@ -190,3 +221,13 @@ bool BL_ShapeDeformer::Update(void)
        }
        return bSkinUpdate;
 }
+
+Key *BL_ShapeDeformer::GetKey()
+{
+       return m_bmesh->key;
+}
+
+void BL_ShapeDeformer::SetKey(Key *key)
+{
+       m_bmesh->key = key;
+}
index 8115af59d27999f8ce840bd2370c9f85720d59d1..7d33204fd4c82fc862b33ff5eb28873dd33362c0 100644 (file)
@@ -49,12 +49,7 @@ class BL_ShapeDeformer : public BL_SkinDeformer
 public:
        BL_ShapeDeformer(BL_DeformableGameObject *gameobj,
                      Object *bmeshobj,
-                     RAS_MeshObject *mesh)
-                                       :       
-                                               BL_SkinDeformer(gameobj,bmeshobj, mesh),
-                                               m_lastShapeUpdate(-1)
-       {
-       };
+                     RAS_MeshObject *mesh);
 
        /* this second constructor is needed for making a mesh deformable on the fly. */
        BL_ShapeDeformer(BL_DeformableGameObject *gameobj,
@@ -63,12 +58,7 @@ public:
                                        class RAS_MeshObject *mesh,
                                        bool release_object,
                                        bool recalc_normal,
-                                       BL_ArmatureObject* arma = NULL)
-                                       :
-                                               BL_SkinDeformer(gameobj, bmeshobj_old, bmeshobj_new, mesh, release_object, recalc_normal, arma),
-                                               m_lastShapeUpdate(-1)
-       {
-       };
+                                       BL_ArmatureObject* arma = NULL);
 
        virtual RAS_Deformer *GetReplica();
        virtual void ProcessReplica();
@@ -78,6 +68,9 @@ public:
        bool LoadShapeDrivers(Object* arma);
        bool ExecuteShapeDrivers(void);
 
+       struct Key *GetKey();
+       void SetKey(struct Key *key);
+
        void ForceUpdate()
        {
                m_lastShapeUpdate = -1.0;
@@ -86,6 +79,7 @@ public:
 protected:
        vector<IpoCurve*>                m_shapeDrivers;
        double                                   m_lastShapeUpdate;
+       struct Key*                              m_key;
 
 
 #ifdef WITH_CXX_GUARDEDALLOC