Revision: 15348
          
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=15348
Author:   ben2610
Date:     2008-06-25 00:19:00 +0200 (Wed, 25 Jun 2008)

Log Message:
-----------
BGE patch: Add automatic support for armature driven shape keys.

To take advantage of this feature, you must have a mesh with 
relative shape keys and shape Ipo curves with drivers referring
to bones of the mesh's parent armature. 
The BGE will automatically detect the dependency between the 
shape keys and the armature and execute the Ipo drivers during
the rendering of the armature actions.
This technique is used to make the armature action more natural: 
the shape keys compensate in places where the armature deformation 
is uggly and the drivers make sure that the shape correction
is synchronized with the bone position.

Note: This is not compatible with shape actions; BLender does 
not allow to have Shape Ipo Curves and Shape actions at the same
time.

Modified Paths:
--------------
    trunk/blender/source/blender/blenkernel/BKE_ipo.h
    trunk/blender/source/gameengine/Converter/BL_BlenderDataConversion.cpp
    trunk/blender/source/gameengine/Converter/BL_ShapeDeformer.cpp
    trunk/blender/source/gameengine/Converter/BL_ShapeDeformer.h
    trunk/blender/source/gameengine/Converter/BL_SkinDeformer.cpp
    trunk/blender/source/gameengine/Converter/BL_SkinDeformer.h
    trunk/blender/source/gameengine/Ketsji/KX_Scene.cpp

Modified: trunk/blender/source/blender/blenkernel/BKE_ipo.h
===================================================================
--- trunk/blender/source/blender/blenkernel/BKE_ipo.h   2008-06-24 21:39:45 UTC 
(rev 15347)
+++ trunk/blender/source/blender/blenkernel/BKE_ipo.h   2008-06-24 22:19:00 UTC 
(rev 15348)
@@ -31,6 +31,10 @@
 #ifndef BKE_IPO_H
 #define BKE_IPO_H
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 typedef struct CfraElem {
        struct CfraElem *next, *prev;
        float cfra;
@@ -111,5 +115,9 @@
                                                short c,
                                                float ctime);
 
+#ifdef __cplusplus
+};
 #endif
 
+#endif
+

Modified: trunk/blender/source/gameengine/Converter/BL_BlenderDataConversion.cpp
===================================================================
--- trunk/blender/source/gameengine/Converter/BL_BlenderDataConversion.cpp      
2008-06-24 21:39:45 UTC (rev 15347)
+++ trunk/blender/source/gameengine/Converter/BL_BlenderDataConversion.cpp      
2008-06-24 22:19:00 UTC (rev 15348)
@@ -1668,6 +1668,8 @@
                        BL_ShapeDeformer *dcont = new 
BL_ShapeDeformer((BL_DeformableGameObject*)gameobj, 
                                                                                
                                        ob, (BL_SkinMeshObject*)meshobj);
                        ((BL_DeformableGameObject*)gameobj)->m_pDeformer = 
dcont;
+                       if (bHasArmature)
+                               dcont->LoadShapeDrivers(ob->parent);
                } else if (bHasArmature) {
                        BL_SkinDeformer *dcont = new BL_SkinDeformer(ob, 
(BL_SkinMeshObject*)meshobj );                         
                        ((BL_DeformableGameObject*)gameobj)->m_pDeformer = 
dcont;

Modified: trunk/blender/source/gameengine/Converter/BL_ShapeDeformer.cpp
===================================================================
--- trunk/blender/source/gameengine/Converter/BL_ShapeDeformer.cpp      
2008-06-24 21:39:45 UTC (rev 15347)
+++ trunk/blender/source/gameengine/Converter/BL_ShapeDeformer.cpp      
2008-06-24 22:19:00 UTC (rev 15348)
@@ -44,9 +44,12 @@
 #include "DNA_key_types.h"
 #include "DNA_mesh_types.h"
 #include "DNA_meshdata_types.h"
+#include "DNA_ipo_types.h"
+#include "DNA_curve_types.h"
 #include "BKE_armature.h"
 #include "BKE_action.h"
 #include "BKE_key.h"
+#include "BKE_ipo.h"
 #include "MT_Point3.h"
 
 extern "C"{
@@ -78,11 +81,55 @@
 {
 }
 
+bool BL_ShapeDeformer::LoadShapeDrivers(Object* arma)
+{
+       IpoCurve *icu;
+
+       m_shapeDrivers.clear();
+       // check if this mesh has armature driven shape keys
+       if (m_bmesh->key->ipo) {
+               for(icu= (IpoCurve*)m_bmesh->key->ipo->curve.first; icu; icu= 
(IpoCurve*)icu->next) {
+                       if(icu->driver && 
+                               (icu->flag & IPO_MUTE) == 0 &&
+                               icu->driver->type == IPO_DRIVER_TYPE_NORMAL &&
+                               icu->driver->ob == arma &&
+                               icu->driver->blocktype == ID_AR) {
+                               // this shape key ipo curve has a driver on the 
parent armature
+                               // record this curve in the shape deformer so 
that the corresponding
+                               m_shapeDrivers.push_back(icu);
+                       }
+               }
+       }
+       return !m_shapeDrivers.empty();
+}
+
+bool BL_ShapeDeformer::ExecuteShapeDrivers(void)
+{
+       if (!m_shapeDrivers.empty() && PoseUpdated()) {
+               vector<IpoCurve*>::iterator it;
+               void *poin;
+               int type;
+               for (it=m_shapeDrivers.begin(); it!=m_shapeDrivers.end(); it++) 
{
+                       // no need to set a specific time: this curve has a 
driver
+                       IpoCurve *icu = *it;
+                       calc_icu(icu, 1.0f);
+                       poin = get_ipo_poin((ID*)m_bmesh->key, icu, &type);
+                       if (poin) 
+                               write_ipo_poin(poin, type, icu->curval);
+               }
+               ForceUpdate();
+               return true;
+       }
+       return false;
+}
+
 bool BL_ShapeDeformer::Update(void)
 {
        bool bShapeUpdate = false;
        bool bSkinUpdate = false;
 
+       ExecuteShapeDrivers();
+
        /* See if the object shape has changed */
        if (m_lastShapeUpdate != m_gameobj->GetLastFrame()) {
                /* the key coefficient have been set already, we just need to 
blend the keys */

Modified: trunk/blender/source/gameengine/Converter/BL_ShapeDeformer.h
===================================================================
--- trunk/blender/source/gameengine/Converter/BL_ShapeDeformer.h        
2008-06-24 21:39:45 UTC (rev 15347)
+++ trunk/blender/source/gameengine/Converter/BL_ShapeDeformer.h        
2008-06-24 22:19:00 UTC (rev 15348)
@@ -38,6 +38,7 @@
 #include "BL_DeformableGameObject.h"
 #include <vector>
 
+struct IpoCurve;
 
 class BL_ShapeDeformer : public BL_SkinDeformer  
 {
@@ -82,8 +83,16 @@
        virtual ~BL_ShapeDeformer();
 
        bool Update (void);
+       bool LoadShapeDrivers(Object* arma);
+       bool ExecuteShapeDrivers(void);
 
+       void ForceUpdate()
+       {
+               m_lastShapeUpdate = -1.0;
+       };
+
 protected:
+       vector<IpoCurve*>                m_shapeDrivers;
        double                                   m_lastShapeUpdate;
        BL_DeformableGameObject* m_gameobj;
 

Modified: trunk/blender/source/gameengine/Converter/BL_SkinDeformer.cpp
===================================================================
--- trunk/blender/source/gameengine/Converter/BL_SkinDeformer.cpp       
2008-06-24 21:39:45 UTC (rev 15347)
+++ trunk/blender/source/gameengine/Converter/BL_SkinDeformer.cpp       
2008-06-24 22:19:00 UTC (rev 15348)
@@ -149,12 +149,9 @@
 bool BL_SkinDeformer::Update(void)
 {
        /* See if the armature has been updated for this frame */
-       if (m_armobj && m_lastArmaUpdate!=m_armobj->GetLastFrame()){    
+       if (PoseUpdated()){     
                float obmat[4][4];      // the original object matrice 
                
-               /* Do all of the posing necessary */
-               m_armobj->ApplyPose();
-               
                /* XXX note: where_is_pose() (from BKE_armature.h) calculates 
all matrices needed to start deforming */
                /* but it requires the blender object pointer... */
 

Modified: trunk/blender/source/gameengine/Converter/BL_SkinDeformer.h
===================================================================
--- trunk/blender/source/gameengine/Converter/BL_SkinDeformer.h 2008-06-24 
21:39:45 UTC (rev 15347)
+++ trunk/blender/source/gameengine/Converter/BL_SkinDeformer.h 2008-06-24 
22:19:00 UTC (rev 15348)
@@ -79,6 +79,14 @@
        virtual ~BL_SkinDeformer();
        bool Update (void);
        bool Apply (class RAS_IPolyMaterial *polymat);
+       bool PoseUpdated(void)
+               { 
+                       if (m_armobj && 
m_lastArmaUpdate!=m_armobj->GetLastFrame()) {
+                               m_armobj->ApplyPose();
+                               return true;
+                       }
+                       return false;
+               }
 
        void ForceUpdate()
        {

Modified: trunk/blender/source/gameengine/Ketsji/KX_Scene.cpp
===================================================================
--- trunk/blender/source/gameengine/Ketsji/KX_Scene.cpp 2008-06-24 21:39:45 UTC 
(rev 15347)
+++ trunk/blender/source/gameengine/Ketsji/KX_Scene.cpp 2008-06-24 22:19:00 UTC 
(rev 15348)
@@ -866,6 +866,7 @@
                                                
static_cast<BL_ArmatureObject*>( parentobj )
                                        );
                                        releaseParent= false;
+                                       
shapeDeformer->LoadShapeDrivers(blendobj->parent);
                                }
                                else
                                {


_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to