123
This commit is contained in:
499
CryMovie/AnimNode.cpp
Normal file
499
CryMovie/AnimNode.cpp
Normal file
@@ -0,0 +1,499 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2001.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: animnode.cpp
|
||||
// Version: v1.00
|
||||
// Created: 23/4/2002 by Timur.
|
||||
// Compilers: Visual C++ 7.0
|
||||
// Description:
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "AnimNode.h"
|
||||
#include "Animtrack.h"
|
||||
#include "CharacterTrack.h"
|
||||
#include "AnimSplineTrack.h"
|
||||
#include "BoolTrack.h"
|
||||
#include "SelectTrack.h"
|
||||
#include "EventTrack.h"
|
||||
#include "SoundTrack.h"
|
||||
#include "ExprTrack.h"
|
||||
#include "ConsoleTrack.h"
|
||||
#include "MusicTrack.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// CAnimBlock
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
int CAnimBlock::GetTrackCount() const
|
||||
{
|
||||
return m_tracks.size();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool CAnimBlock::GetTrackInfo( int index,int ¶mId,IAnimTrack **pTrack ) const
|
||||
{
|
||||
if (index < 0 && index >= m_tracks.size())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
paramId = m_tracks[index].paramId;
|
||||
if (pTrack)
|
||||
*pTrack = m_tracks[index].track;
|
||||
return true;
|
||||
}
|
||||
|
||||
const char* CAnimBlock::GetParamName( AnimParamType param ) const
|
||||
{
|
||||
switch (param)
|
||||
{
|
||||
case APARAM_FOV:
|
||||
return "FOV";
|
||||
case APARAM_POS:
|
||||
return "Position";
|
||||
case APARAM_ROT:
|
||||
return "Rotation";
|
||||
case APARAM_SCL:
|
||||
return "Scale";
|
||||
case APARAM_VISIBLE:
|
||||
return "Visiblity";
|
||||
case APARAM_EVENT:
|
||||
return "Events";
|
||||
case APARAM_CAMERA:
|
||||
return "Camera";
|
||||
|
||||
// Sound tracks.
|
||||
case APARAM_SOUND1:
|
||||
return "Sound1";
|
||||
case APARAM_SOUND2:
|
||||
return "Sound2";
|
||||
case APARAM_SOUND3:
|
||||
return "Sound3";
|
||||
|
||||
// Character tracks.
|
||||
case APARAM_CHARACTER1:
|
||||
return "Animation1";
|
||||
case APARAM_CHARACTER2:
|
||||
return "Animation2";
|
||||
case APARAM_CHARACTER3:
|
||||
return "Animation3";
|
||||
|
||||
case APARAM_EXPRESSION1:
|
||||
return "Expression1";
|
||||
case APARAM_EXPRESSION2:
|
||||
return "Expression2";
|
||||
case APARAM_EXPRESSION3:
|
||||
return "Expression3";
|
||||
|
||||
case APARAM_SEQUENCE:
|
||||
return "Sequence";
|
||||
case APARAM_CONSOLE:
|
||||
return "Console";
|
||||
case APARAM_MUSIC:
|
||||
return "Music";
|
||||
|
||||
case APARAM_FLOAT_1:
|
||||
return "Value";
|
||||
}
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
IAnimTrack* CAnimBlock::GetTrack( int param ) const
|
||||
{
|
||||
for (int i = 0; i < m_tracks.size(); i++)
|
||||
{
|
||||
if (m_tracks[i].paramId == param)
|
||||
return m_tracks[i].track;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CAnimBlock::SetTrack( int param,IAnimTrack *track )
|
||||
{
|
||||
if (track)
|
||||
{
|
||||
for (int i = 0; i < m_tracks.size(); i++)
|
||||
{
|
||||
if (m_tracks[i].paramId == param)
|
||||
{
|
||||
m_tracks[i].track = track;
|
||||
return;
|
||||
}
|
||||
}
|
||||
AddTrack( param,track );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Remove track at this id.
|
||||
for (int i = 0; i < m_tracks.size(); i++)
|
||||
{
|
||||
if (m_tracks[i].paramId == param)
|
||||
{
|
||||
m_tracks.erase( m_tracks.begin() + i );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CAnimBlock::AddTrack( int param,IAnimTrack *track )
|
||||
{
|
||||
TrackDesc td;
|
||||
td.paramId = param;
|
||||
td.track = track;
|
||||
m_tracks.push_back(td);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool CAnimBlock::RemoveTrack( IAnimTrack *pTrack )
|
||||
{
|
||||
for (int i = 0; i < m_tracks.size(); i++)
|
||||
{
|
||||
if (m_tracks[i].track == pTrack)
|
||||
{
|
||||
m_tracks.erase( m_tracks.begin() + i );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
IAnimTrack* CAnimBlock::CreateTrack( int paramId,EAnimValue valueType )
|
||||
{
|
||||
IAnimTrack *pTrack = NULL;
|
||||
switch (valueType)
|
||||
{
|
||||
case AVALUE_FLOAT: pTrack=new CTcbFloatTrack; break;
|
||||
case AVALUE_VECTOR: pTrack=new CTcbVectorTrack; break;
|
||||
case AVALUE_QUAT: pTrack=new CTcbQuatTrack; break;
|
||||
case AVALUE_EVENT: pTrack=new CEventTrack; break;
|
||||
case AVALUE_BOOL: pTrack=new CBoolTrack; break;
|
||||
case AVALUE_SELECT: pTrack=new CSelectTrack; break;
|
||||
case AVALUE_SOUND: pTrack=new CSoundTrack; break;
|
||||
case AVALUE_CHARACTER: pTrack=new CCharacterTrack; break;
|
||||
case AVALUE_EXPRESSION:pTrack=new CExprTrack; break;
|
||||
case AVALUE_CONSOLE: pTrack=new CConsoleTrack; break;
|
||||
case AVALUE_MUSIC: pTrack=new CMusicTrack; break;
|
||||
}
|
||||
if (pTrack)
|
||||
AddTrack( paramId,pTrack );
|
||||
return pTrack;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CAnimBlock::Serialize( IAnimNode *pNode,XmlNodeRef &xmlNode,bool bLoading, bool bLoadEmptyTracks )
|
||||
{
|
||||
if (bLoading)
|
||||
{
|
||||
// Delete all tracks.
|
||||
m_tracks.clear();
|
||||
|
||||
IAnimNode::SParamInfo info;
|
||||
// Loading.
|
||||
int paramId = -1;
|
||||
int num = xmlNode->getChildCount();
|
||||
for (int i = 0; i < num; i++)
|
||||
{
|
||||
XmlNodeRef trackNode = xmlNode->getChild(i);
|
||||
trackNode->getAttr( "ParamId",paramId );
|
||||
if (!pNode->GetParamInfoFromId( paramId,info ))
|
||||
continue;
|
||||
|
||||
IAnimTrack *track = CreateTrack( paramId,info.valueType );
|
||||
if (track)
|
||||
{
|
||||
if (!track->Serialize( trackNode,bLoading,bLoadEmptyTracks ))
|
||||
{
|
||||
// Boolean tracks must always be loaded even if empty.
|
||||
if (track->GetType() != ATRACK_BOOL)
|
||||
{
|
||||
RemoveTrack(track);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Saving.
|
||||
for (int i = 0; i < m_tracks.size(); i++)
|
||||
{
|
||||
IAnimTrack *track = m_tracks[i].track;
|
||||
if (track)
|
||||
{
|
||||
int paramid = m_tracks[i].paramId;
|
||||
XmlNodeRef trackNode = xmlNode->newChild( "Track" );
|
||||
trackNode->setAttr( "ParamId",m_tracks[i].paramId );
|
||||
track->Serialize( trackNode,bLoading );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CAnimBlock::SetTimeRange( Range timeRange )
|
||||
{
|
||||
for (int i = 0; i < m_tracks.size(); i++)
|
||||
{
|
||||
if (m_tracks[i].track)
|
||||
{
|
||||
m_tracks[i].track->SetTimeRange( timeRange );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// CAnimNode.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CAnimNode::CAnimNode( IMovieSystem *sys )
|
||||
{
|
||||
m_dwSupportedTracks=0;
|
||||
m_id = 0;
|
||||
m_animBlock = 0;
|
||||
m_callback = 0;
|
||||
m_parent = 0;
|
||||
m_pMovieSystem = sys;
|
||||
m_pMovieSystem->Callback(CBR_ADDNODE);
|
||||
m_flags = 0;
|
||||
strcpy(m_name,"");
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CAnimNode::~CAnimNode()
|
||||
{
|
||||
m_pMovieSystem->Callback(CBR_REMOVENODE);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CAnimNode::SetFlags( int flags )
|
||||
{
|
||||
m_flags = flags;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
int CAnimNode::GetFlags() const
|
||||
{
|
||||
return m_flags;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
int CAnimNode::FindTrack(IAnimTrack *pInTrack)
|
||||
{
|
||||
if (!m_animBlock)
|
||||
return -1;
|
||||
|
||||
int paramCount = m_animBlock->GetTrackCount();
|
||||
for (int paramIndex = 0; paramIndex < paramCount; paramIndex++)
|
||||
{
|
||||
int paramId;
|
||||
IAnimTrack *pTrack;
|
||||
if (!m_animBlock->GetTrackInfo( paramIndex,paramId,&pTrack ))
|
||||
continue;
|
||||
if (pTrack == pInTrack)
|
||||
return paramId;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
IAnimTrack* CAnimNode::CreateTrack( int paramId )
|
||||
{
|
||||
if (!m_animBlock)
|
||||
return 0;
|
||||
|
||||
SParamInfo info;
|
||||
if (GetParamInfoFromId(paramId,info))
|
||||
{
|
||||
IAnimTrack *pTrack = m_animBlock->CreateTrack( paramId,info.valueType );
|
||||
if (pTrack)
|
||||
m_pMovieSystem->Callback(CBR_CHANGENODE);
|
||||
return pTrack;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool CAnimNode::RemoveTrack( IAnimTrack *pTrack )
|
||||
{
|
||||
if (!m_animBlock)
|
||||
return false;
|
||||
if (m_animBlock->RemoveTrack( pTrack ))
|
||||
{
|
||||
m_pMovieSystem->Callback(CBR_CHANGENODE);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
IAnimNode* CAnimNode::GetChild( int i ) const
|
||||
{
|
||||
assert( i >= 0 && i < (int)m_childs.size() );
|
||||
return m_childs[i];
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool CAnimNode::IsChildOf( IAnimNode *node )
|
||||
{
|
||||
CAnimNode *p = m_parent;
|
||||
while (p && p != node) {
|
||||
p = p->m_parent;
|
||||
}
|
||||
if (p == node)
|
||||
return true;
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CAnimNode::AttachChild( IAnimNode* child )
|
||||
{
|
||||
assert( child );
|
||||
if (!child)
|
||||
return;
|
||||
|
||||
CAnimNode *childNode = (CAnimNode*)child;
|
||||
|
||||
// If not already attached to this node.
|
||||
if (childNode->m_parent == this)
|
||||
return;
|
||||
|
||||
// Add to child list first to make sure node not get deleted while reattaching.
|
||||
m_childs.push_back( childNode );
|
||||
if (childNode->m_parent)
|
||||
childNode->DetachThis(); // Detach node if attached to other parent.
|
||||
childNode->m_parent = this; // Assign this node as parent to child node.
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CAnimNode::DetachAll()
|
||||
{
|
||||
for (Childs::iterator c = m_childs.begin(); c != m_childs.end(); c++)
|
||||
{
|
||||
(*c)->m_parent = 0;
|
||||
}
|
||||
m_childs.clear();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CAnimNode::DetachThis()
|
||||
{
|
||||
if (m_parent)
|
||||
{
|
||||
// Copy parent to temp var, erasing child from parent may delete this node if child referenced only from parent.
|
||||
CAnimNode* parent = m_parent;
|
||||
m_parent = 0;
|
||||
parent->RemoveChild( this );
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CAnimNode::RemoveChild( CAnimNode *node )
|
||||
{
|
||||
Childs::iterator it = std::find( m_childs.begin(),m_childs.end(),node );
|
||||
if (it != m_childs.end())
|
||||
m_childs.erase( it );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CAnimNode::Animate( SAnimContext &ec )
|
||||
{
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool CAnimNode::IsParamValid( int paramId ) const
|
||||
{
|
||||
SParamInfo info;
|
||||
if (GetParamInfoFromId(paramId,info))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool CAnimNode::SetParamValue( float time,AnimParamType param,float value )
|
||||
{
|
||||
IAnimBlock *anim = GetAnimBlock();
|
||||
if (anim)
|
||||
{
|
||||
IAnimTrack *track = anim->GetTrack(param);
|
||||
if (track && track->GetValueType() == AVALUE_FLOAT)
|
||||
{
|
||||
// Float track.
|
||||
bool bDefault = !(m_pMovieSystem->IsRecording() && (m_flags&ANODE_FLAG_SELECTED)); // Only selected nodes can be recorded
|
||||
track->SetValue( time,value,bDefault );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool CAnimNode::GetParamValue( float time,AnimParamType param,float &value )
|
||||
{
|
||||
IAnimBlock *anim = GetAnimBlock();
|
||||
if (anim)
|
||||
{
|
||||
IAnimTrack *track = anim->GetTrack(param);
|
||||
if (track && track->GetValueType() == AVALUE_FLOAT)
|
||||
{
|
||||
// Float track.
|
||||
track->GetValue( time,value );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
IAnimTrack* CAnimNode::GetTrack( int nParamId ) const
|
||||
{
|
||||
if (!m_animBlock)
|
||||
return 0;
|
||||
return m_animBlock->GetTrack( nParamId );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CAnimNode::SetTrack( int nParamId,IAnimTrack *track )
|
||||
{
|
||||
if (!m_animBlock)
|
||||
return;
|
||||
m_animBlock->SetTrack( nParamId,track );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CAnimNode::Serialize( XmlNodeRef &xmlNode,bool bLoading )
|
||||
{
|
||||
if (bLoading)
|
||||
{
|
||||
xmlNode->getAttr( "Id",m_id );
|
||||
const char *name = xmlNode->getAttr("Name");
|
||||
if (name)
|
||||
SetName(name);
|
||||
}
|
||||
else
|
||||
{
|
||||
xmlNode->setAttr( "Id",m_id );
|
||||
xmlNode->setAttr("Type", GetType() );
|
||||
xmlNode->setAttr("Name", GetName() );
|
||||
IAnimNode *pTgt = GetTarget();
|
||||
if (pTgt)
|
||||
{
|
||||
xmlNode->setAttr("TargetId", pTgt->GetId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CAnimNode::SetAnimBlock( IAnimBlock *block )
|
||||
{
|
||||
m_animBlock = block;
|
||||
if (m_animBlock)
|
||||
m_animBlock->SetId( m_id );
|
||||
};
|
||||
Reference in New Issue
Block a user