2011-10-23 17:52:20 +00:00
|
|
|
/*
|
2011-05-24 07:52:29 +00:00
|
|
|
* ***** 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.
|
|
|
|
*
|
2011-07-04 21:21:49 +00:00
|
|
|
* Contributor(s): Mitchell Stokes.
|
2011-05-24 07:52:29 +00:00
|
|
|
*
|
|
|
|
* ***** END GPL LICENSE BLOCK *****
|
|
|
|
*/
|
|
|
|
|
2011-07-07 03:53:24 +00:00
|
|
|
/** \file BL_Action.cpp
|
|
|
|
* \ingroup ketsji
|
|
|
|
*/
|
|
|
|
|
2011-06-01 07:42:40 +00:00
|
|
|
#include <cstdlib>
|
2012-03-08 03:05:57 +00:00
|
|
|
#include <stdio.h>
|
2011-06-01 07:42:40 +00:00
|
|
|
|
2011-05-24 07:52:29 +00:00
|
|
|
#include "BL_Action.h"
|
|
|
|
#include "BL_ArmatureObject.h"
|
2011-06-23 19:49:53 +00:00
|
|
|
#include "BL_DeformableGameObject.h"
|
|
|
|
#include "BL_ShapeDeformer.h"
|
2011-05-28 07:15:27 +00:00
|
|
|
#include "KX_IpoConvert.h"
|
2011-05-24 07:52:29 +00:00
|
|
|
#include "KX_GameObject.h"
|
|
|
|
|
|
|
|
// These three are for getting the action from the logic manager
|
|
|
|
#include "KX_Scene.h"
|
|
|
|
#include "SCA_LogicManager.h"
|
|
|
|
|
|
|
|
extern "C" {
|
|
|
|
#include "BKE_animsys.h"
|
|
|
|
#include "BKE_action.h"
|
|
|
|
#include "RNA_access.h"
|
|
|
|
#include "RNA_define.h"
|
2013-02-23 02:47:22 +00:00
|
|
|
|
|
|
|
// Needed for material IPOs
|
|
|
|
#include "BKE_material.h"
|
|
|
|
#include "DNA_material_types.h"
|
2011-05-24 07:52:29 +00:00
|
|
|
}
|
|
|
|
|
2011-06-11 00:14:47 +00:00
|
|
|
BL_Action::BL_Action(class KX_GameObject* gameobj)
|
2011-05-24 07:52:29 +00:00
|
|
|
:
|
2011-07-29 21:58:31 +00:00
|
|
|
m_action(NULL),
|
|
|
|
m_pose(NULL),
|
|
|
|
m_blendpose(NULL),
|
|
|
|
m_blendinpose(NULL),
|
2011-05-24 07:52:29 +00:00
|
|
|
m_obj(gameobj),
|
2011-06-11 00:14:47 +00:00
|
|
|
m_startframe(0.f),
|
|
|
|
m_endframe(0.f),
|
2011-05-24 07:52:29 +00:00
|
|
|
m_endtime(0.f),
|
2011-06-11 00:14:47 +00:00
|
|
|
m_localtime(0.f),
|
2011-07-29 21:58:31 +00:00
|
|
|
m_blendin(0.f),
|
2011-05-24 07:52:29 +00:00
|
|
|
m_blendframe(0.f),
|
|
|
|
m_blendstart(0.f),
|
2011-06-11 00:14:47 +00:00
|
|
|
m_speed(0.f),
|
2011-06-23 22:12:49 +00:00
|
|
|
m_priority(0),
|
2013-08-14 23:31:49 +00:00
|
|
|
m_playmode(ACT_MODE_PLAY),
|
|
|
|
m_blendmode(ACT_BLEND_BLEND),
|
2011-06-16 01:18:52 +00:00
|
|
|
m_ipo_flags(0),
|
2011-08-08 04:28:30 +00:00
|
|
|
m_done(true),
|
|
|
|
m_calc_localtime(true)
|
2011-05-24 07:52:29 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
BL_Action::~BL_Action()
|
|
|
|
{
|
|
|
|
if (m_pose)
|
|
|
|
game_free_pose(m_pose);
|
|
|
|
if (m_blendpose)
|
|
|
|
game_free_pose(m_blendpose);
|
2011-07-04 21:19:11 +00:00
|
|
|
if (m_blendinpose)
|
|
|
|
game_free_pose(m_blendinpose);
|
2011-08-17 09:38:50 +00:00
|
|
|
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();
|
2011-05-28 07:15:27 +00:00
|
|
|
}
|
|
|
|
|
2011-06-29 01:53:17 +00:00
|
|
|
bool BL_Action::Play(const char* name,
|
2011-06-11 00:14:47 +00:00
|
|
|
float start,
|
|
|
|
float end,
|
2011-06-23 22:12:49 +00:00
|
|
|
short priority,
|
2011-06-11 00:14:47 +00:00
|
|
|
float blendin,
|
|
|
|
short play_mode,
|
2011-07-03 01:59:17 +00:00
|
|
|
float layer_weight,
|
2011-06-16 01:18:52 +00:00
|
|
|
short ipo_flags,
|
2013-08-14 23:31:49 +00:00
|
|
|
float playback_speed,
|
|
|
|
short blend_mode)
|
2011-06-11 00:14:47 +00:00
|
|
|
{
|
2011-06-23 22:12:49 +00:00
|
|
|
|
|
|
|
// Only start playing a new action if we're done, or if
|
|
|
|
// the new action has a higher priority
|
2012-05-23 04:01:05 +00:00
|
|
|
if (!IsDone() && priority > m_priority)
|
2011-06-29 01:53:17 +00:00
|
|
|
return false;
|
2011-06-23 22:12:49 +00:00
|
|
|
m_priority = priority;
|
2011-06-11 00:14:47 +00:00
|
|
|
bAction* prev_action = m_action;
|
|
|
|
|
2013-02-23 00:28:25 +00:00
|
|
|
KX_Scene* kxscene = m_obj->GetScene();
|
|
|
|
|
2011-06-11 00:14:47 +00:00
|
|
|
// First try to load the action
|
2013-02-23 00:28:25 +00:00
|
|
|
m_action = (bAction*)kxscene->GetLogicManager()->GetActionByName(name);
|
2011-06-11 00:14:47 +00:00
|
|
|
if (!m_action)
|
|
|
|
{
|
|
|
|
printf("Failed to load action: %s\n", name);
|
|
|
|
m_done = true;
|
2011-06-29 01:53:17 +00:00
|
|
|
return false;
|
2011-06-11 00:14:47 +00:00
|
|
|
}
|
|
|
|
|
2012-06-23 03:39:03 +00:00
|
|
|
// If we have the same settings, don't play again
|
|
|
|
// This is to resolve potential issues with pulses on sensors such as the ones
|
|
|
|
// reported in bug #29412. The fix is here so it works for both logic bricks and Python.
|
|
|
|
// However, this may eventually lead to issues where a user wants to override an already
|
|
|
|
// playing action with the same action and settings. If this becomes an issue,
|
|
|
|
// then this fix may have to be re-evaluated.
|
|
|
|
if (!IsDone() && m_action == prev_action && m_startframe == start && m_endframe == end
|
|
|
|
&& m_priority == priority && m_speed == playback_speed)
|
|
|
|
return false;
|
|
|
|
|
2013-02-23 00:46:58 +00:00
|
|
|
// First get rid of any old controllers
|
|
|
|
ClearControllerList();
|
2011-08-17 09:38:50 +00:00
|
|
|
|
2013-02-23 00:46:58 +00:00
|
|
|
// Create an SG_Controller
|
|
|
|
SG_Controller *sg_contr = BL_CreateIPO(m_action, m_obj, kxscene->GetSceneConverter());
|
|
|
|
m_sg_contr_list.push_back(sg_contr);
|
|
|
|
m_obj->GetSGNode()->AddSGController(sg_contr);
|
|
|
|
sg_contr->SetObject(m_obj->GetSGNode());
|
|
|
|
|
|
|
|
// Try obcolor
|
|
|
|
sg_contr = BL_CreateObColorIPO(m_action, m_obj, kxscene->GetSceneConverter());
|
|
|
|
if (sg_contr) {
|
2011-08-17 09:38:50 +00:00
|
|
|
m_sg_contr_list.push_back(sg_contr);
|
|
|
|
m_obj->GetSGNode()->AddSGController(sg_contr);
|
|
|
|
sg_contr->SetObject(m_obj->GetSGNode());
|
2013-02-23 00:46:58 +00:00
|
|
|
}
|
2011-08-17 09:38:50 +00:00
|
|
|
|
2013-02-23 02:47:22 +00:00
|
|
|
// Now try materials
|
|
|
|
if (m_obj->GetBlenderObject()->totcol==1) {
|
|
|
|
Material *mat = give_current_material(m_obj->GetBlenderObject(), 1);
|
2013-02-25 05:55:37 +00:00
|
|
|
if (mat) {
|
|
|
|
sg_contr = BL_CreateMaterialIpo(m_action, mat, 0, m_obj, kxscene->GetSceneConverter());
|
|
|
|
if (sg_contr) {
|
|
|
|
m_sg_contr_list.push_back(sg_contr);
|
|
|
|
m_obj->GetSGNode()->AddSGController(sg_contr);
|
|
|
|
sg_contr->SetObject(m_obj->GetSGNode());
|
|
|
|
}
|
2013-02-23 02:47:22 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
Material *mat;
|
|
|
|
STR_HashedString matname;
|
|
|
|
|
|
|
|
for (int matidx = 1; matidx <= m_obj->GetBlenderObject()->totcol; ++matidx) {
|
|
|
|
mat = give_current_material(m_obj->GetBlenderObject(), matidx);
|
2013-02-25 05:55:37 +00:00
|
|
|
if (mat) {
|
|
|
|
matname = mat->id.name;
|
|
|
|
sg_contr = BL_CreateMaterialIpo(m_action, mat, matname.hash(), m_obj, kxscene->GetSceneConverter());
|
|
|
|
if (sg_contr) {
|
|
|
|
m_sg_contr_list.push_back(sg_contr);
|
|
|
|
m_obj->GetSGNode()->AddSGController(sg_contr);
|
|
|
|
sg_contr->SetObject(m_obj->GetSGNode());
|
|
|
|
}
|
2013-02-23 02:47:22 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-02-23 00:46:58 +00:00
|
|
|
// Extra controllers
|
|
|
|
if (m_obj->GetGameObjectType() == SCA_IObject::OBJ_LIGHT)
|
|
|
|
{
|
|
|
|
sg_contr = BL_CreateLampIPO(m_action, m_obj, kxscene->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, kxscene->GetSceneConverter());
|
|
|
|
m_sg_contr_list.push_back(sg_contr);
|
|
|
|
m_obj->GetSGNode()->AddSGController(sg_contr);
|
|
|
|
sg_contr->SetObject(m_obj->GetSGNode());
|
2011-06-11 00:14:47 +00:00
|
|
|
}
|
2011-06-16 01:18:52 +00:00
|
|
|
|
|
|
|
m_ipo_flags = ipo_flags;
|
|
|
|
InitIPO();
|
2011-06-11 00:14:47 +00:00
|
|
|
|
2011-06-29 01:05:12 +00:00
|
|
|
// Setup blendin shapes/poses
|
|
|
|
if (m_obj->GetGameObjectType() == SCA_IObject::OBJ_ARMATURE)
|
|
|
|
{
|
2011-07-04 21:19:11 +00:00
|
|
|
BL_ArmatureObject *obj = (BL_ArmatureObject*)m_obj;
|
|
|
|
obj->GetMRDPose(&m_blendinpose);
|
2011-06-29 01:05:12 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
BL_DeformableGameObject *obj = (BL_DeformableGameObject*)m_obj;
|
|
|
|
BL_ShapeDeformer *shape_deformer = dynamic_cast<BL_ShapeDeformer*>(obj->GetDeformer());
|
|
|
|
|
2011-07-20 06:20:49 +00:00
|
|
|
if (shape_deformer && shape_deformer->GetKey())
|
2011-07-08 07:31:40 +00:00
|
|
|
{
|
|
|
|
obj->GetShape(m_blendinshape);
|
2011-06-29 01:05:12 +00:00
|
|
|
|
2011-07-08 07:31:40 +00:00
|
|
|
// Now that we have the previous blend shape saved, we can clear out the key to avoid any
|
|
|
|
// further interference.
|
|
|
|
KeyBlock *kb;
|
2013-03-18 11:44:56 +00:00
|
|
|
for (kb=(KeyBlock *)shape_deformer->GetKey()->block.first; kb; kb=(KeyBlock *)kb->next)
|
2011-07-08 07:31:40 +00:00
|
|
|
kb->curval = 0.f;
|
|
|
|
}
|
2011-06-29 01:05:12 +00:00
|
|
|
}
|
|
|
|
|
2011-06-11 00:14:47 +00:00
|
|
|
// Now that we have an action, we have something we can play
|
2012-08-06 00:53:26 +00:00
|
|
|
m_starttime = -1.f; // We get the start time on our first update
|
2011-06-11 00:14:47 +00:00
|
|
|
m_startframe = m_localtime = start;
|
|
|
|
m_endframe = end;
|
|
|
|
m_blendin = blendin;
|
|
|
|
m_playmode = play_mode;
|
2013-08-14 23:31:49 +00:00
|
|
|
m_blendmode = blend_mode;
|
2011-06-11 00:14:47 +00:00
|
|
|
m_endtime = 0.f;
|
|
|
|
m_blendframe = 0.f;
|
|
|
|
m_blendstart = 0.f;
|
|
|
|
m_speed = playback_speed;
|
2011-07-03 01:59:17 +00:00
|
|
|
m_layer_weight = layer_weight;
|
2011-06-11 00:14:47 +00:00
|
|
|
|
|
|
|
m_done = false;
|
2011-06-29 01:53:17 +00:00
|
|
|
|
|
|
|
return true;
|
2011-06-11 00:14:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void BL_Action::Stop()
|
|
|
|
{
|
|
|
|
m_done = true;
|
|
|
|
}
|
|
|
|
|
2011-06-29 02:45:08 +00:00
|
|
|
bool BL_Action::IsDone()
|
|
|
|
{
|
|
|
|
return m_done;
|
|
|
|
}
|
|
|
|
|
2011-05-28 07:15:27 +00:00
|
|
|
void BL_Action::InitIPO()
|
|
|
|
{
|
2011-08-17 09:38:50 +00:00
|
|
|
// 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);
|
|
|
|
}
|
2011-05-24 07:52:29 +00:00
|
|
|
}
|
|
|
|
|
2011-07-05 05:22:02 +00:00
|
|
|
bAction *BL_Action::GetAction()
|
|
|
|
{
|
|
|
|
return (IsDone()) ? NULL : m_action;
|
|
|
|
}
|
|
|
|
|
2011-06-01 07:42:40 +00:00
|
|
|
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);
|
2011-07-05 05:22:02 +00:00
|
|
|
|
2011-08-08 04:28:30 +00:00
|
|
|
m_localtime = frame;
|
|
|
|
m_calc_localtime = false;
|
|
|
|
}
|
2011-07-05 05:22:02 +00:00
|
|
|
|
2011-08-08 04:28:30 +00:00
|
|
|
void BL_Action::SetPlayMode(short play_mode)
|
|
|
|
{
|
|
|
|
m_playmode = play_mode;
|
|
|
|
}
|
2011-06-01 07:42:40 +00:00
|
|
|
|
2011-08-08 04:28:30 +00:00
|
|
|
void BL_Action::SetTimes(float start, float end)
|
|
|
|
{
|
|
|
|
m_startframe = start;
|
|
|
|
m_endframe = end;
|
2011-06-01 07:42:40 +00:00
|
|
|
}
|
|
|
|
|
2011-05-24 07:52:29 +00:00
|
|
|
void BL_Action::SetLocalTime(float curtime)
|
|
|
|
{
|
2011-05-28 07:15:27 +00:00
|
|
|
float dt = (curtime-m_starttime)*KX_KetsjiEngine::GetAnimFrameRate()*m_speed;
|
2011-05-24 07:52:29 +00:00
|
|
|
|
|
|
|
if (m_endframe < m_startframe)
|
|
|
|
dt = -dt;
|
|
|
|
|
|
|
|
m_localtime = m_startframe + dt;
|
|
|
|
}
|
|
|
|
|
2011-08-08 04:28:30 +00:00
|
|
|
void BL_Action::ResetStartTime(float curtime)
|
|
|
|
{
|
2011-10-23 17:52:20 +00:00
|
|
|
float dt = (m_localtime > m_startframe) ? m_localtime - m_startframe : m_startframe - m_localtime;
|
2011-08-08 04:28:30 +00:00
|
|
|
|
|
|
|
m_starttime = curtime - dt / (KX_KetsjiEngine::GetAnimFrameRate()*m_speed);
|
|
|
|
SetLocalTime(curtime);
|
|
|
|
}
|
|
|
|
|
2011-06-29 01:05:12 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-07-04 21:19:11 +00:00
|
|
|
void BL_Action::BlendShape(Key* key, float srcweight, std::vector<float>& blendshape)
|
2011-06-29 01:05:12 +00:00
|
|
|
{
|
|
|
|
vector<float>::const_iterator it;
|
|
|
|
float dstweight;
|
|
|
|
KeyBlock *kb;
|
|
|
|
|
|
|
|
dstweight = 1.0F - srcweight;
|
|
|
|
//printf("Dst: %f\tSrc: %f\n", srcweight, dstweight);
|
2013-03-18 11:44:56 +00:00
|
|
|
for (it=blendshape.begin(), kb = (KeyBlock *)key->block.first;
|
2011-11-11 13:09:14 +00:00
|
|
|
kb && it != blendshape.end();
|
2013-03-18 11:44:56 +00:00
|
|
|
kb = (KeyBlock *)kb->next, it++)
|
2011-11-11 13:09:14 +00:00
|
|
|
{
|
2011-06-29 01:05:12 +00:00
|
|
|
//printf("OirgKeys: %f\t%f\n", kb->curval, (*it));
|
|
|
|
kb->curval = kb->curval * dstweight + (*it) * srcweight;
|
|
|
|
//printf("NewKey: %f\n", kb->curval);
|
|
|
|
}
|
|
|
|
//printf("\n");
|
|
|
|
}
|
|
|
|
|
2011-05-24 07:52:29 +00:00
|
|
|
void BL_Action::Update(float curtime)
|
|
|
|
{
|
2011-05-28 07:15:27 +00:00
|
|
|
// Don't bother if we're done with the animation
|
|
|
|
if (m_done)
|
|
|
|
return;
|
|
|
|
|
2011-07-05 05:22:02 +00:00
|
|
|
curtime -= KX_KetsjiEngine::GetSuspendedDelta();
|
2011-08-08 04:28:30 +00:00
|
|
|
|
2012-08-06 00:53:26 +00:00
|
|
|
// Grab the start time here so we don't end up with a negative m_localtime when
|
|
|
|
// suspending and resuming scenes.
|
|
|
|
if (m_starttime < 0)
|
|
|
|
m_starttime = curtime;
|
|
|
|
|
2011-08-08 04:28:30 +00:00
|
|
|
if (m_calc_localtime)
|
|
|
|
SetLocalTime(curtime);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ResetStartTime(curtime);
|
|
|
|
m_calc_localtime = true;
|
|
|
|
}
|
2011-05-24 07:52:29 +00:00
|
|
|
|
|
|
|
// Handle wrap around
|
2012-10-21 07:58:38 +00:00
|
|
|
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;
|
2011-05-24 07:52:29 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
2013-05-13 10:54:57 +00:00
|
|
|
|
|
|
|
PointerRNA ptrrna;
|
|
|
|
RNA_id_pointer_create(&arm->id, &ptrrna);
|
|
|
|
|
|
|
|
animsys_evaluate_action(&ptrrna, m_action, NULL, m_localtime);
|
2011-05-24 07:52:29 +00:00
|
|
|
|
|
|
|
arm->pose = temp;
|
|
|
|
}
|
|
|
|
|
2011-06-29 01:05:12 +00:00
|
|
|
// Handle blending between armature actions
|
2011-05-24 07:52:29 +00:00
|
|
|
if (m_blendin && m_blendframe<m_blendin)
|
|
|
|
{
|
2011-06-29 01:05:12 +00:00
|
|
|
IncrementBlending(curtime);
|
2011-05-24 07:52:29 +00:00
|
|
|
|
|
|
|
// Calculate weight
|
|
|
|
float weight = 1.f - (m_blendframe/m_blendin);
|
|
|
|
|
2011-06-29 01:05:12 +00:00
|
|
|
// Blend the poses
|
2013-08-14 23:31:49 +00:00
|
|
|
game_blend_poses(m_pose, m_blendinpose, weight, ACT_BLEND_BLEND);
|
2011-05-24 07:52:29 +00:00
|
|
|
}
|
|
|
|
|
2011-06-29 01:53:17 +00:00
|
|
|
|
|
|
|
// Handle layer blending
|
2011-07-03 01:59:17 +00:00
|
|
|
if (m_layer_weight >= 0)
|
2011-06-29 02:42:46 +00:00
|
|
|
{
|
|
|
|
obj->GetMRDPose(&m_blendpose);
|
2013-08-14 23:31:49 +00:00
|
|
|
game_blend_poses(m_pose, m_blendpose, m_layer_weight, m_blendmode);
|
2011-06-29 02:42:46 +00:00
|
|
|
}
|
|
|
|
|
2011-05-24 07:52:29 +00:00
|
|
|
obj->SetPose(m_pose);
|
|
|
|
|
|
|
|
obj->SetActiveAction(NULL, 0, curtime);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2011-06-23 19:49:53 +00:00
|
|
|
BL_DeformableGameObject *obj = (BL_DeformableGameObject*)m_obj;
|
|
|
|
BL_ShapeDeformer *shape_deformer = dynamic_cast<BL_ShapeDeformer*>(obj->GetDeformer());
|
|
|
|
|
|
|
|
// Handle shape actions if we have any
|
2011-07-20 06:20:49 +00:00
|
|
|
if (shape_deformer && shape_deformer->GetKey())
|
2011-06-23 19:49:53 +00:00
|
|
|
{
|
|
|
|
Key *key = shape_deformer->GetKey();
|
|
|
|
|
2013-05-13 10:54:57 +00:00
|
|
|
PointerRNA ptrrna;
|
|
|
|
RNA_id_pointer_create(&key->id, &ptrrna);
|
2011-06-23 19:49:53 +00:00
|
|
|
|
2013-05-13 10:54:57 +00:00
|
|
|
animsys_evaluate_action(&ptrrna, m_action, NULL, m_localtime);
|
2011-06-23 19:49:53 +00:00
|
|
|
|
2011-06-29 01:05:12 +00:00
|
|
|
// 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;
|
2013-03-18 11:44:56 +00:00
|
|
|
for (kb=(KeyBlock *)key->block.first; kb; kb=(KeyBlock *)kb->next)
|
2011-06-29 01:05:12 +00:00
|
|
|
kb->curval = 0.f;
|
|
|
|
|
|
|
|
// Now blend the shape
|
2011-07-04 21:19:11 +00:00
|
|
|
BlendShape(key, weight, m_blendinshape);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Handle layer blending
|
|
|
|
if (m_layer_weight >= 0)
|
|
|
|
{
|
|
|
|
obj->GetShape(m_blendshape);
|
|
|
|
BlendShape(key, m_layer_weight, m_blendshape);
|
2011-06-29 01:05:12 +00:00
|
|
|
}
|
2011-06-23 19:49:53 +00:00
|
|
|
|
2011-07-04 21:19:11 +00:00
|
|
|
obj->SetActiveAction(NULL, 0, curtime);
|
2011-06-23 19:49:53 +00:00
|
|
|
}
|
2011-05-24 07:52:29 +00:00
|
|
|
}
|
2013-02-23 00:46:58 +00:00
|
|
|
|
2013-06-24 09:37:37 +00:00
|
|
|
m_obj->UpdateIPO(m_localtime, m_ipo_flags & ACT_IPOFLAG_CHILD);
|
|
|
|
|
2013-02-23 00:46:58 +00:00
|
|
|
if (m_done)
|
|
|
|
ClearControllerList();
|
2011-05-24 07:52:29 +00:00
|
|
|
}
|