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
diff options
context:
space:
mode:
authorXiao Xiangquan <xiaoxiangquan@gmail.com>2011-09-05 18:44:11 +0400
committerXiao Xiangquan <xiaoxiangquan@gmail.com>2011-09-05 18:44:11 +0400
commit034cda72d36711c725862f89eddefa3e277e2ce2 (patch)
treeb2ce911bc59714b4c47f9dd4bdd59a372f4d7afe /source/gameengine
parentd31d7fd4875ac81c8e41572390b51cd14f5682be (diff)
add missing files after merging
Diffstat (limited to 'source/gameengine')
-rwxr-xr-xsource/gameengine/Ketsji/BL_Action.cpp453
-rwxr-xr-xsource/gameengine/Ketsji/BL_Action.h144
-rwxr-xr-xsource/gameengine/Ketsji/BL_ActionManager.cpp110
-rwxr-xr-xsource/gameengine/Ketsji/BL_ActionManager.h106
4 files changed, 813 insertions, 0 deletions
diff --git a/source/gameengine/Ketsji/BL_Action.cpp b/source/gameengine/Ketsji/BL_Action.cpp
new file mode 100755
index 00000000000..5bc86264f9c
--- /dev/null
+++ b/source/gameengine/Ketsji/BL_Action.cpp
@@ -0,0 +1,453 @@
+/**
+ * $Id: BL_Action.cpp 39792 2011-08-30 09:15:55Z nexyon $
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Mitchell Stokes.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file BL_Action.cpp
+ * \ingroup ketsji
+ */
+
+#include <cstdlib>
+
+#include "BL_Action.h"
+#include "BL_ArmatureObject.h"
+#include "BL_DeformableGameObject.h"
+#include "BL_ShapeDeformer.h"
+#include "KX_IpoConvert.h"
+#include "KX_GameObject.h"
+
+// These three are for getting the action from the logic manager
+#include "KX_Scene.h"
+#include "KX_PythonInit.h"
+#include "SCA_LogicManager.h"
+
+extern "C" {
+#include "BKE_animsys.h"
+#include "BKE_action.h"
+#include "RNA_access.h"
+#include "RNA_define.h"
+}
+
+BL_Action::BL_Action(class KX_GameObject* gameobj)
+:
+ m_action(NULL),
+ m_pose(NULL),
+ m_blendpose(NULL),
+ m_blendinpose(NULL),
+ m_ptrrna(NULL),
+ m_obj(gameobj),
+ m_startframe(0.f),
+ m_endframe(0.f),
+ m_endtime(0.f),
+ m_localtime(0.f),
+ m_blendin(0.f),
+ m_blendframe(0.f),
+ m_blendstart(0.f),
+ m_speed(0.f),
+ m_priority(0),
+ m_playmode(0),
+ m_ipo_flags(0),
+ m_done(true),
+ m_calc_localtime(true)
+{
+ if (m_obj->GetGameObjectType() == SCA_IObject::OBJ_ARMATURE)
+ {
+ BL_ArmatureObject *obj = (BL_ArmatureObject*)m_obj;
+
+ m_ptrrna = new PointerRNA();
+ RNA_id_pointer_create(&obj->GetArmatureObject()->id, m_ptrrna);
+ }
+ else
+ {
+ BL_DeformableGameObject *obj = (BL_DeformableGameObject*)m_obj;
+ BL_ShapeDeformer *shape_deformer = dynamic_cast<BL_ShapeDeformer*>(obj->GetDeformer());
+
+ if (shape_deformer)
+ {
+ m_ptrrna = new PointerRNA();
+ RNA_id_pointer_create(&shape_deformer->GetKey()->id, m_ptrrna);
+ }
+ }
+}
+
+BL_Action::~BL_Action()
+{
+ if (m_pose)
+ game_free_pose(m_pose);
+ if (m_blendpose)
+ game_free_pose(m_blendpose);
+ if (m_blendinpose)
+ game_free_pose(m_blendinpose);
+ if (m_ptrrna)
+ delete m_ptrrna;
+ ClearControllerList();
+}
+
+void BL_Action::ClearControllerList()
+{
+ // Clear out the controller list
+ std::vector<SG_Controller*>::iterator it;
+ for (it = m_sg_contr_list.begin(); it != m_sg_contr_list.end(); it++)
+ {
+ m_obj->GetSGNode()->RemoveSGController((*it));
+ delete *it;
+ }
+
+ m_sg_contr_list.clear();
+}
+
+bool BL_Action::Play(const char* name,
+ float start,
+ float end,
+ short priority,
+ float blendin,
+ short play_mode,
+ float layer_weight,
+ short ipo_flags,
+ float playback_speed)
+{
+
+ // Only start playing a new action if we're done, or if
+ // the new action has a higher priority
+ if (priority != 0 && !IsDone() && priority >= m_priority)
+ return false;
+ m_priority = priority;
+ bAction* prev_action = m_action;
+
+ // First try to load the action
+ m_action = (bAction*)KX_GetActiveScene()->GetLogicManager()->GetActionByName(name);
+ if (!m_action)
+ {
+ printf("Failed to load action: %s\n", name);
+ m_done = true;
+ return false;
+ }
+
+ if (prev_action != m_action)
+ {
+ // First get rid of any old controllers
+ ClearControllerList();
+
+ // Create an SG_Controller
+ SG_Controller *sg_contr = BL_CreateIPO(m_action, m_obj, KX_GetActiveScene()->GetSceneConverter());
+ m_sg_contr_list.push_back(sg_contr);
+ m_obj->GetSGNode()->AddSGController(sg_contr);
+ sg_contr->SetObject(m_obj->GetSGNode());
+
+ // Extra controllers
+ if (m_obj->GetGameObjectType() == SCA_IObject::OBJ_LIGHT)
+ {
+ sg_contr = BL_CreateLampIPO(m_action, m_obj, KX_GetActiveScene()->GetSceneConverter());
+ m_sg_contr_list.push_back(sg_contr);
+ m_obj->GetSGNode()->AddSGController(sg_contr);
+ sg_contr->SetObject(m_obj->GetSGNode());
+ }
+ else if (m_obj->GetGameObjectType() == SCA_IObject::OBJ_CAMERA)
+ {
+ sg_contr = BL_CreateCameraIPO(m_action, m_obj, KX_GetActiveScene()->GetSceneConverter());
+ m_sg_contr_list.push_back(sg_contr);
+ m_obj->GetSGNode()->AddSGController(sg_contr);
+ sg_contr->SetObject(m_obj->GetSGNode());
+ }
+ }
+
+ m_ipo_flags = ipo_flags;
+ InitIPO();
+
+ // Setup blendin shapes/poses
+ if (m_obj->GetGameObjectType() == SCA_IObject::OBJ_ARMATURE)
+ {
+ BL_ArmatureObject *obj = (BL_ArmatureObject*)m_obj;
+ obj->GetMRDPose(&m_blendinpose);
+ }
+ else
+ {
+ BL_DeformableGameObject *obj = (BL_DeformableGameObject*)m_obj;
+ BL_ShapeDeformer *shape_deformer = dynamic_cast<BL_ShapeDeformer*>(obj->GetDeformer());
+
+ if (shape_deformer && shape_deformer->GetKey())
+ {
+ obj->GetShape(m_blendinshape);
+
+ // Now that we have the previous blend shape saved, we can clear out the key to avoid any
+ // further interference.
+ KeyBlock *kb;
+ for (kb=(KeyBlock*)shape_deformer->GetKey()->block.first; kb; kb=(KeyBlock*)kb->next)
+ kb->curval = 0.f;
+ }
+ }
+
+ // Now that we have an action, we have something we can play
+ m_starttime = KX_GetActiveEngine()->GetFrameTime();
+ m_startframe = m_localtime = start;
+ m_endframe = end;
+ m_blendin = blendin;
+ m_playmode = play_mode;
+ m_endtime = 0.f;
+ m_blendframe = 0.f;
+ m_blendstart = 0.f;
+ m_speed = playback_speed;
+ m_layer_weight = layer_weight;
+
+ m_done = false;
+
+ return true;
+}
+
+void BL_Action::Stop()
+{
+ m_done = true;
+}
+
+bool BL_Action::IsDone()
+{
+ return m_done;
+}
+
+void BL_Action::InitIPO()
+{
+ // Initialize the IPOs
+ std::vector<SG_Controller*>::iterator it;
+ for (it = m_sg_contr_list.begin(); it != m_sg_contr_list.end(); it++)
+ {
+ (*it)->SetOption(SG_Controller::SG_CONTR_IPO_RESET, true);
+ (*it)->SetOption(SG_Controller::SG_CONTR_IPO_IPO_AS_FORCE, m_ipo_flags & ACT_IPOFLAG_FORCE);
+ (*it)->SetOption(SG_Controller::SG_CONTR_IPO_IPO_ADD, m_ipo_flags & ACT_IPOFLAG_ADD);
+ (*it)->SetOption(SG_Controller::SG_CONTR_IPO_LOCAL, m_ipo_flags & ACT_IPOFLAG_LOCAL);
+ }
+}
+
+bAction *BL_Action::GetAction()
+{
+ return (IsDone()) ? NULL : m_action;
+}
+
+float BL_Action::GetFrame()
+{
+ return m_localtime;
+}
+
+void BL_Action::SetFrame(float frame)
+{
+ // Clamp the frame to the start and end frame
+ if (frame < min(m_startframe, m_endframe))
+ frame = min(m_startframe, m_endframe);
+ else if (frame > max(m_startframe, m_endframe))
+ frame = max(m_startframe, m_endframe);
+
+ m_localtime = frame;
+ m_calc_localtime = false;
+}
+
+void BL_Action::SetPlayMode(short play_mode)
+{
+ m_playmode = play_mode;
+}
+
+void BL_Action::SetTimes(float start, float end)
+{
+ m_startframe = start;
+ m_endframe = end;
+}
+
+void BL_Action::SetLocalTime(float curtime)
+{
+ float dt = (curtime-m_starttime)*KX_KetsjiEngine::GetAnimFrameRate()*m_speed;
+
+ if (m_endframe < m_startframe)
+ dt = -dt;
+
+ m_localtime = m_startframe + dt;
+}
+
+void BL_Action::ResetStartTime(float curtime)
+{
+ float dt = m_localtime - m_startframe;
+
+ m_starttime = curtime - dt / (KX_KetsjiEngine::GetAnimFrameRate()*m_speed);
+ SetLocalTime(curtime);
+}
+
+void BL_Action::IncrementBlending(float curtime)
+{
+ // Setup m_blendstart if we need to
+ if (m_blendstart == 0.f)
+ m_blendstart = curtime;
+
+ // Bump the blend frame
+ m_blendframe = (curtime - m_blendstart)*KX_KetsjiEngine::GetAnimFrameRate();
+
+ // Clamp
+ if (m_blendframe>m_blendin)
+ m_blendframe = m_blendin;
+}
+
+
+void BL_Action::BlendShape(Key* key, float srcweight, std::vector<float>& blendshape)
+{
+ vector<float>::const_iterator it;
+ float dstweight;
+ KeyBlock *kb;
+
+ dstweight = 1.0F - srcweight;
+ //printf("Dst: %f\tSrc: %f\n", srcweight, dstweight);
+ for (it=blendshape.begin(), kb = (KeyBlock*)key->block.first;
+ kb && it != blendshape.end();
+ kb = (KeyBlock*)kb->next, it++) {
+ //printf("OirgKeys: %f\t%f\n", kb->curval, (*it));
+ kb->curval = kb->curval * dstweight + (*it) * srcweight;
+ //printf("NewKey: %f\n", kb->curval);
+ }
+ //printf("\n");
+}
+
+void BL_Action::Update(float curtime)
+{
+ // Don't bother if we're done with the animation
+ if (m_done)
+ return;
+
+ curtime -= KX_KetsjiEngine::GetSuspendedDelta();
+
+ if (m_calc_localtime)
+ SetLocalTime(curtime);
+ else
+ {
+ ResetStartTime(curtime);
+ m_calc_localtime = true;
+ }
+
+ // Handle wrap around
+ if (m_localtime < min(m_startframe, m_endframe) || m_localtime > max(m_startframe, m_endframe))
+ {
+ switch(m_playmode)
+ {
+ case ACT_MODE_PLAY:
+ // Clamp
+ m_localtime = m_endframe;
+ m_done = true;
+ break;
+ case ACT_MODE_LOOP:
+ // Put the time back to the beginning
+ m_localtime = m_startframe;
+ m_starttime = curtime;
+ break;
+ case ACT_MODE_PING_PONG:
+ // Swap the start and end frames
+ float temp = m_startframe;
+ m_startframe = m_endframe;
+ m_endframe = temp;
+
+ m_starttime = curtime;
+
+ break;
+ }
+
+ if (!m_done)
+ InitIPO();
+ }
+
+ if (m_obj->GetGameObjectType() == SCA_IObject::OBJ_ARMATURE)
+ {
+ BL_ArmatureObject *obj = (BL_ArmatureObject*)m_obj;
+ obj->GetPose(&m_pose);
+
+ // Extract the pose from the action
+ {
+ Object *arm = obj->GetArmatureObject();
+ bPose *temp = arm->pose;
+
+ arm->pose = m_pose;
+ animsys_evaluate_action(m_ptrrna, m_action, NULL, m_localtime);
+
+ arm->pose = temp;
+ }
+
+ // Handle blending between armature actions
+ if (m_blendin && m_blendframe<m_blendin)
+ {
+ IncrementBlending(curtime);
+
+ // Calculate weight
+ float weight = 1.f - (m_blendframe/m_blendin);
+
+ // Blend the poses
+ game_blend_poses(m_pose, m_blendinpose, weight);
+ }
+
+
+ // Handle layer blending
+ if (m_layer_weight >= 0)
+ {
+ obj->GetMRDPose(&m_blendpose);
+ game_blend_poses(m_pose, m_blendpose, m_layer_weight);
+ }
+
+ obj->SetPose(m_pose);
+
+ obj->SetActiveAction(NULL, 0, curtime);
+ }
+ else
+ {
+ BL_DeformableGameObject *obj = (BL_DeformableGameObject*)m_obj;
+ BL_ShapeDeformer *shape_deformer = dynamic_cast<BL_ShapeDeformer*>(obj->GetDeformer());
+
+ // Handle shape actions if we have any
+ if (shape_deformer && shape_deformer->GetKey())
+ {
+ Key *key = shape_deformer->GetKey();
+
+
+ animsys_evaluate_action(m_ptrrna, m_action, NULL, m_localtime);
+
+ // Handle blending between shape actions
+ if (m_blendin && m_blendframe < m_blendin)
+ {
+ IncrementBlending(curtime);
+
+ float weight = 1.f - (m_blendframe/m_blendin);
+
+ // We go through and clear out the keyblocks so there isn't any interference
+ // from other shape actions
+ KeyBlock *kb;
+ for (kb=(KeyBlock*)key->block.first; kb; kb=(KeyBlock*)kb->next)
+ kb->curval = 0.f;
+
+ // Now blend the shape
+ BlendShape(key, weight, m_blendinshape);
+ }
+
+ // Handle layer blending
+ if (m_layer_weight >= 0)
+ {
+ obj->GetShape(m_blendshape);
+ BlendShape(key, m_layer_weight, m_blendshape);
+ }
+
+ obj->SetActiveAction(NULL, 0, curtime);
+ }
+
+
+ InitIPO();
+ m_obj->UpdateIPO(m_localtime, m_ipo_flags & ACT_IPOFLAG_CHILD);
+ }
+}
diff --git a/source/gameengine/Ketsji/BL_Action.h b/source/gameengine/Ketsji/BL_Action.h
new file mode 100755
index 00000000000..de2bedb7062
--- /dev/null
+++ b/source/gameengine/Ketsji/BL_Action.h
@@ -0,0 +1,144 @@
+/**
+ * $Id: BL_Action.h 39792 2011-08-30 09:15:55Z nexyon $
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Mitchell Stokes.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file BL_Action.h
+ * \ingroup ketsji
+ */
+
+#ifndef __BL_ACTION
+#define __BL_ACTION
+
+
+#include <vector>
+
+#ifdef WITH_CXX_GUARDEDALLOC
+#include "MEM_guardedalloc.h"
+#endif
+
+
+class BL_Action
+{
+private:
+ struct bAction* m_action;
+ struct bPose* m_pose;
+ struct bPose* m_blendpose;
+ struct bPose* m_blendinpose;
+ struct PointerRNA *m_ptrrna;
+ std::vector<class SG_Controller*> m_sg_contr_list;
+ class KX_GameObject* m_obj;
+ std::vector<float> m_blendshape;
+ std::vector<float> m_blendinshape;
+
+ float m_startframe;
+ float m_endframe;
+ float m_starttime;
+ float m_endtime;
+ float m_localtime;
+
+ float m_blendin;
+ float m_blendframe;
+ float m_blendstart;
+
+ float m_layer_weight;
+
+ float m_speed;
+
+ short m_priority;
+
+ short m_playmode;
+
+ short m_ipo_flags;
+
+ bool m_done;
+ bool m_calc_localtime;
+
+ void ClearControllerList();
+ void InitIPO();
+ void SetLocalTime(float curtime);
+ void ResetStartTime(float curtime);
+ void IncrementBlending(float curtime);
+ void BlendShape(struct Key* key, float srcweight, std::vector<float>& blendshape);
+public:
+ BL_Action(class KX_GameObject* gameobj);
+ ~BL_Action();
+
+ /**
+ * Play an action
+ */
+ bool Play(const char* name,
+ float start,
+ float end,
+ short priority,
+ float blendin,
+ short play_mode,
+ float layer_weight,
+ short ipo_flags,
+ float playback_speed);
+ /**
+ * Stop playing the action
+ */
+ void Stop();
+ /**
+ * Whether or not the action is still playing
+ */
+ bool IsDone();
+ /**
+ * Update the action's frame, etc.
+ */
+ void Update(float curtime);
+
+ // Accessors
+ float GetFrame();
+ struct bAction *GetAction();
+
+ // Mutators
+ void SetFrame(float frame);
+ void SetPlayMode(short play_mode);
+ void SetTimes(float start, float end);
+
+ enum
+ {
+ ACT_MODE_PLAY = 0,
+ ACT_MODE_LOOP,
+ ACT_MODE_PING_PONG,
+ ACT_MODE_MAX,
+ };
+
+ enum
+ {
+ ACT_IPOFLAG_FORCE = 1,
+ ACT_IPOFLAG_LOCAL = 2,
+ ACT_IPOFLAG_ADD = 4,
+ ACT_IPOFLAG_CHILD = 8,
+ };
+
+#ifdef WITH_CXX_GUARDEDALLOC
+public:
+ void *operator new(size_t num_bytes) { return MEM_mallocN(num_bytes, "GE:BL_Action"); }
+ void operator delete( void *mem ) { MEM_freeN(mem); }
+#endif
+};
+
+#endif //BL_ACTION
+
diff --git a/source/gameengine/Ketsji/BL_ActionManager.cpp b/source/gameengine/Ketsji/BL_ActionManager.cpp
new file mode 100755
index 00000000000..2b7719a46ff
--- /dev/null
+++ b/source/gameengine/Ketsji/BL_ActionManager.cpp
@@ -0,0 +1,110 @@
+/**
+ * $Id: BL_ActionManager.cpp 39792 2011-08-30 09:15:55Z nexyon $
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Mitchell Stokes.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file BL_ActionManager.cpp
+ * \ingroup ketsji
+ */
+
+#include "BL_ActionManager.h"
+
+BL_ActionManager::BL_ActionManager(class KX_GameObject *obj)
+{
+ for (int i=0; i<MAX_ACTION_LAYERS; ++i)
+ m_layers[i] = new BL_Action(obj);
+}
+
+BL_ActionManager::~BL_ActionManager()
+{
+ for (int i=0; i<MAX_ACTION_LAYERS; ++i)
+ delete m_layers[i];
+}
+
+float BL_ActionManager::GetActionFrame(short layer)
+{
+ return m_layers[layer]->GetFrame();
+
+ return 0.f;
+}
+
+void BL_ActionManager::SetActionFrame(short layer, float frame)
+{
+ m_layers[layer]->SetFrame(frame);
+}
+
+struct bAction *BL_ActionManager::GetCurrentAction(short layer)
+{
+ return m_layers[layer]->GetAction();
+
+ return 0;
+}
+
+void BL_ActionManager::SetPlayMode(short layer, short mode)
+{
+ m_layers[layer]->SetPlayMode(mode);
+}
+
+void BL_ActionManager::SetTimes(short layer, float start, float end)
+{
+ m_layers[layer]->SetTimes(start, end);
+}
+
+bool BL_ActionManager::PlayAction(const char* name,
+ float start,
+ float end,
+ short layer,
+ short priority,
+ float blendin,
+ short play_mode,
+ float layer_weight,
+ short ipo_flags,
+ float playback_speed)
+{
+ // Disable layer blending on the first layer
+ if (layer == 0) layer_weight = -1.f;
+
+ return m_layers[layer]->Play(name, start, end, priority, blendin, play_mode, layer_weight, ipo_flags, playback_speed);
+}
+
+void BL_ActionManager::StopAction(short layer)
+{
+ m_layers[layer]->Stop();
+}
+
+bool BL_ActionManager::IsActionDone(short layer)
+{
+ return m_layers[layer]->IsDone();
+
+ return true;
+}
+
+void BL_ActionManager::Update(float curtime)
+{
+ for (int i=0; i<MAX_ACTION_LAYERS; ++i)
+ {
+ if (!m_layers[i]->IsDone())
+ {
+ m_layers[i]->Update(curtime);
+ }
+ }
+}
diff --git a/source/gameengine/Ketsji/BL_ActionManager.h b/source/gameengine/Ketsji/BL_ActionManager.h
new file mode 100755
index 00000000000..96a37756124
--- /dev/null
+++ b/source/gameengine/Ketsji/BL_ActionManager.h
@@ -0,0 +1,106 @@
+/**
+ * $Id: BL_ActionManager.h 39792 2011-08-30 09:15:55Z nexyon $
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Mitchell Stokes.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file BL_ActionManager.cpp
+ * \ingroup ketsji
+ */
+
+#ifndef __BL_ACTIONMANAGER
+#define __BL_ACTIONMANAGER
+
+#include "BL_Action.h"
+
+#define MAX_ACTION_LAYERS 8
+
+/**
+ * BL_ActionManager is responsible for handling a KX_GameObject's actions.
+ */
+class BL_ActionManager
+{
+private:
+ BL_Action* m_layers[MAX_ACTION_LAYERS];
+
+public:
+ BL_ActionManager(class KX_GameObject* obj);
+ ~BL_ActionManager();
+
+ bool PlayAction(const char* name,
+ float start,
+ float end,
+ short layer=0,
+ short priority=0,
+ float blendin=0.f,
+ short play_mode=0,
+ float layer_weight=0.f,
+ short ipo_flags=0,
+ float playback_speed=1.f);
+ /**
+ * Gets the current frame of an action
+ */
+ float GetActionFrame(short layer);
+
+ /**
+ * Sets the current frame of an action
+ */
+ void SetActionFrame(short layer, float frame);
+
+ /**
+ * Gets the currently running action on the given layer
+ */
+ struct bAction *GetCurrentAction(short layer);
+
+ /**
+ * Sets play mode of the action on the given layer
+ */
+ void SetPlayMode(short layer, short mode);
+
+ /**
+ * Sets the start and end times of the action on the given layer
+ */
+ void SetTimes(short layer, float start, float end);
+
+ /**
+ * Stop playing the action on the given layer
+ */
+ void StopAction(short layer);
+
+ /**
+ * Check if an action has finished playing
+ */
+ bool IsActionDone(short layer);
+
+ /**
+ * Update any running actions
+ */
+ void Update(float);
+
+#ifdef WITH_CXX_GUARDEDALLOC
+public:
+ void *operator new(size_t num_bytes) { return MEM_mallocN(num_bytes, "GE:BL_ActionManager"); }
+ void operator delete( void *mem ) { MEM_freeN(mem); }
+#endif
+};
+
+#endif //BL_ACTIONMANAGER
+