BGE Animations: Making shape actions work again:

* 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)
This commit is contained in:
Mitchell Stokes 2011-06-23 19:09:09 +00:00
parent 413bc87e4f
commit 2d2aa95227
5 changed files with 100 additions and 54 deletions

@ -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()

@ -59,10 +59,49 @@
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)) {

@ -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

@ -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;
}

@ -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