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
path: root/source
diff options
context:
space:
mode:
authorBenoit Bolsee <benoit.bolsee@online.be>2008-06-25 02:19:00 +0400
committerBenoit Bolsee <benoit.bolsee@online.be>2008-06-25 02:19:00 +0400
commit820c2df12c9d1ba7479c0a924f90f79a33028db9 (patch)
treea83e89982a63186795ac44ca0ad1038ef6f76ded /source
parent4d478cbe8629bed1d32205f85e3583f73a5c16a7 (diff)
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.
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/BKE_ipo.h8
-rw-r--r--source/gameengine/Converter/BL_BlenderDataConversion.cpp2
-rw-r--r--source/gameengine/Converter/BL_ShapeDeformer.cpp47
-rw-r--r--source/gameengine/Converter/BL_ShapeDeformer.h9
-rw-r--r--source/gameengine/Converter/BL_SkinDeformer.cpp5
-rw-r--r--source/gameengine/Converter/BL_SkinDeformer.h8
-rw-r--r--source/gameengine/Ketsji/KX_Scene.cpp1
7 files changed, 76 insertions, 4 deletions
diff --git a/source/blender/blenkernel/BKE_ipo.h b/source/blender/blenkernel/BKE_ipo.h
index 922f3201345..5b209cb8f5b 100644
--- a/source/blender/blenkernel/BKE_ipo.h
+++ b/source/blender/blenkernel/BKE_ipo.h
@@ -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 @@ float IPO_GetFloatValue(struct Ipo *ipo,
short c,
float ctime);
+#ifdef __cplusplus
+};
+#endif
+
#endif
diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
index 1bde5ad3450..665783a1ba5 100644
--- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp
+++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
@@ -1668,6 +1668,8 @@ static KX_GameObject *gameobject_from_blenderobject(
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;
diff --git a/source/gameengine/Converter/BL_ShapeDeformer.cpp b/source/gameengine/Converter/BL_ShapeDeformer.cpp
index 3ae634905b9..eb5c1467ea5 100644
--- a/source/gameengine/Converter/BL_ShapeDeformer.cpp
+++ b/source/gameengine/Converter/BL_ShapeDeformer.cpp
@@ -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 @@ void BL_ShapeDeformer::ProcessReplica()
{
}
+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 */
diff --git a/source/gameengine/Converter/BL_ShapeDeformer.h b/source/gameengine/Converter/BL_ShapeDeformer.h
index 9bbdde3fb2c..9f8361dbaca 100644
--- a/source/gameengine/Converter/BL_ShapeDeformer.h
+++ b/source/gameengine/Converter/BL_ShapeDeformer.h
@@ -38,6 +38,7 @@
#include "BL_DeformableGameObject.h"
#include <vector>
+struct IpoCurve;
class BL_ShapeDeformer : public BL_SkinDeformer
{
@@ -82,8 +83,16 @@ public:
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;
diff --git a/source/gameengine/Converter/BL_SkinDeformer.cpp b/source/gameengine/Converter/BL_SkinDeformer.cpp
index 1015221c392..dd7119b1031 100644
--- a/source/gameengine/Converter/BL_SkinDeformer.cpp
+++ b/source/gameengine/Converter/BL_SkinDeformer.cpp
@@ -149,12 +149,9 @@ void BL_SkinDeformer::ProcessReplica()
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... */
diff --git a/source/gameengine/Converter/BL_SkinDeformer.h b/source/gameengine/Converter/BL_SkinDeformer.h
index 603e716fb1e..c5568c049cb 100644
--- a/source/gameengine/Converter/BL_SkinDeformer.h
+++ b/source/gameengine/Converter/BL_SkinDeformer.h
@@ -79,6 +79,14 @@ public:
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()
{
diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp
index 1526709f425..a7e91e27df3 100644
--- a/source/gameengine/Ketsji/KX_Scene.cpp
+++ b/source/gameengine/Ketsji/KX_Scene.cpp
@@ -866,6 +866,7 @@ void KX_Scene::ReplaceMesh(class CValue* obj,void* meshobj)
static_cast<BL_ArmatureObject*>( parentobj )
);
releaseParent= false;
+ shapeDeformer->LoadShapeDrivers(blendobj->parent);
}
else
{