多动画多动作基本控制的CAnimation类
//需要包含我之前写的SkinnedMesh.h
#ifndef __AnimationH__
#define __AnimationH__
#include "SkinnedMesh.h"
#include <d3d9.h>
#include <d3dx9.h>
#include <vector>
using namespace std;
struct SAnimationTime
{
float fStartTime, fEndTime;
};
struct SAnimation
{
LPD3DXFRAME pFrameRoot;
ID3DXAnimationController* pAnimController;
D3DXMATRIX matTrans;
vector<SAnimationTime> vAnimationTime;
float fPeriodTime;
int nAnimationIndex;
bool bUpdate;
};
class CAnimation
{
private:
IDirect3DDevice9* m_pDevice;
vector<SAnimation> m_vAnimation;
public:
void Init(IDirect3DDevice9* pDevice);
void Add(WCHAR* wsFileName, D3DXMATRIX matTrans, float fPeriodTime, vector<SAnimationTime>& vAnimationTime);
void Logic(float fElapsedTime);
void Render(float fElapsedTime);
void Start(int nRoleIndex, int nAnimIndex);
void Stop(int nRoleIndex);
};
void CAnimation::Init(IDirect3DDevice9* pDevice)
{
m_pDevice = pDevice;
}
void CAnimation::Add(WCHAR* wsFileName, D3DXMATRIX matTrans, float fPeriodTime, vector<SAnimationTime>& vAnimationTime)
{
CAllocateHierarchy Alloc;
SAnimation Animation;
D3DXLoadMeshHierarchyFromX( wsFileName, D3DXMESH_MANAGED, m_pDevice, &Alloc, NULL, &Animation.pFrameRoot, &Animation.pAnimController );
SetupBoneMatrixPointers(Animation.pFrameRoot, Animation.pFrameRoot);
Animation.matTrans = matTrans;
Animation.bUpdate = false;
Animation.fPeriodTime = fPeriodTime;
Animation.vAnimationTime = vAnimationTime;
m_vAnimation.push_back(Animation);
}
void CAnimation::Start(int nRoleIndex, int nAnimIndex)
{
float fCurrentTime = m_vAnimation[nRoleIndex].pAnimController->GetTime();
float fDestinationTime = m_vAnimation[nRoleIndex].vAnimationTime[nAnimIndex].fStartTime;
float fDeltaTime = fDestinationTime - fCurrentTime;
while(fDeltaTime < 0.0f) fDeltaTime += m_vAnimation[nRoleIndex].fPeriodTime;
m_vAnimation[nRoleIndex].pAnimController->AdvanceTime(fDeltaTime, 0);
UpdateFrameMatrices(m_vAnimation[nRoleIndex].pFrameRoot, &m_vAnimation[nRoleIndex].matTrans);
m_vAnimation[nRoleIndex].nAnimationIndex = nAnimIndex;
m_vAnimation[nRoleIndex].bUpdate = true;
}
void CAnimation::Logic(float fElapsedTime)
{
float fCurrentTime, fDestinationTime, fDeltaTime;
int i;
for(i = 0; i < m_vAnimation.size(); i ++)
{
if(m_vAnimation[i].bUpdate)
{
fCurrentTime = m_vAnimation[i].pAnimController->GetTime();
fDestinationTime = fCurrentTime + fElapsedTime;
while(fDestinationTime > m_vAnimation[i].fPeriodTime) fDestinationTime -= m_vAnimation[i].fPeriodTime;
if(fDestinationTime > m_vAnimation[i].vAnimationTime[m_vAnimation[i].nAnimationIndex].fEndTime ||
fDestinationTime < m_vAnimation[i].vAnimationTime[m_vAnimation[i].nAnimationIndex].fStartTime)
{
fDeltaTime = m_vAnimation[i].vAnimationTime[m_vAnimation[i].nAnimationIndex].fStartTime - fCurrentTime;
while(fDeltaTime < 0.0f) fDeltaTime += m_vAnimation[i].fPeriodTime;
}
else fDeltaTime = fElapsedTime;
m_vAnimation[i].pAnimController->AdvanceTime(fDeltaTime, 0);
UpdateFrameMatrices(m_vAnimation[i].pFrameRoot, &m_vAnimation[i].matTrans);
}
}
}
void CAnimation::Render(float fElapsedTime)
{
int i;
for(i = 0; i < m_vAnimation.size(); i ++)
{
DrawFrame(m_pDevice, m_vAnimation[i].pFrameRoot);
}
}
void CAnimation::Stop(int nRoleIndex)
{
float fCurrentTime = m_vAnimation[nRoleIndex].pAnimController->GetTime();
float fDestinationTime = 0.0f;
float fDeltaTime = fDestinationTime - fCurrentTime;
while(fDeltaTime < 0.0f) fDeltaTime += m_vAnimation[nRoleIndex].fPeriodTime;
m_vAnimation[nRoleIndex].pAnimController->AdvanceTime(fDeltaTime, 0);
UpdateFrameMatrices(m_vAnimation[nRoleIndex].pFrameRoot, &m_vAnimation[nRoleIndex].matTrans);
m_vAnimation[nRoleIndex].bUpdate = false;
}
#endif