249 lines
5.6 KiB
C++
249 lines
5.6 KiB
C++
#include "StdAfx.h"
|
|
#include "EtBone.h"
|
|
#include "EtAniKey.h"
|
|
|
|
#ifdef _DEBUG
|
|
#define new new(_NORMAL_BLOCK,__FILE__,__LINE__)
|
|
#endif
|
|
|
|
int CEtBone::s_CalcPositionFlag = CALC_POSITION_Y;
|
|
|
|
CEtBone::CEtBone(void)
|
|
{
|
|
m_bRootBone = false;
|
|
m_bEnableBlend = true;
|
|
m_pParent = NULL;
|
|
m_pBoneRotation = NULL;
|
|
m_fScale = 1.0f;
|
|
|
|
memset( &m_BoneHeader, 0, sizeof( m_BoneHeader ) );
|
|
memset( &m_AniInfo, 0, sizeof( m_AniInfo ) );
|
|
}
|
|
|
|
CEtBone::~CEtBone(void)
|
|
{
|
|
Clear();
|
|
}
|
|
|
|
void CEtBone::Clear()
|
|
{
|
|
SAFE_DELETE_PVEC( m_vecAniKey );
|
|
}
|
|
|
|
void CEtBone::LoadBone( CStream *pStream, int nAniCount, int nAniVersion )
|
|
{
|
|
int i;
|
|
CEtAniKey *pAniKey;
|
|
|
|
Clear();
|
|
pStream->Read( &m_BoneHeader, sizeof( SBoneHeader ) );
|
|
pStream->Seek( BONE_HEADER_RESERVED, SEEK_CUR );
|
|
|
|
for( i = 0; i < nAniCount; i++ )
|
|
{
|
|
pAniKey = new CEtAniKey();
|
|
pAniKey->LoadKey( pStream, nAniVersion );
|
|
m_vecAniKey.push_back( pAniKey );
|
|
}
|
|
}
|
|
|
|
void CEtBone::SaveBone( CStream *pStream, int nAniCount )
|
|
{
|
|
int i;
|
|
char cReserved[ BONE_HEADER_RESERVED ];
|
|
|
|
pStream->Write( &m_BoneHeader, sizeof( SBoneHeader ) );
|
|
memset( cReserved, 0, BONE_HEADER_RESERVED );
|
|
pStream->Write( cReserved, BONE_HEADER_RESERVED );
|
|
|
|
for( i = 0; i < ( int )m_vecAniKey.size(); i++ )
|
|
{
|
|
m_vecAniKey[ i ]->SaveKey( pStream );
|
|
}
|
|
}
|
|
|
|
void CEtBone::MergeBone( CEtBone *pMergeBone, int nAniCount )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < nAniCount; i++ )
|
|
{
|
|
CEtAniKey *pAniKey, *pMergeKey;
|
|
|
|
pAniKey = new CEtAniKey();
|
|
pMergeKey = pMergeBone->GetAniKey( i );
|
|
pAniKey->CopyKey( pMergeKey );
|
|
m_vecAniKey.push_back( pAniKey );
|
|
}
|
|
}
|
|
|
|
void CEtBone::Reset()
|
|
{
|
|
m_AniInfo.fFrame = 0.0f;
|
|
m_AniInfo.nAni = 0;
|
|
m_vecBlendAniInfo.clear();
|
|
}
|
|
|
|
void CEtBone::SetAni( SBoneAniInfo *pInfo )
|
|
{
|
|
if( IsValidAniIndex( pInfo->nAni ) )
|
|
{
|
|
int i;
|
|
|
|
m_AniInfo = *pInfo;
|
|
for( i = 0; i < ( int )m_vecChild.size(); i++ )
|
|
{
|
|
m_vecChild[ i ]->SetAni( pInfo );
|
|
}
|
|
}
|
|
}
|
|
|
|
void CEtBone::BlendAni( SBoneAniInfo *pInfo )
|
|
{
|
|
if( IsValidAniIndex( pInfo->nAni ) )
|
|
{
|
|
int i;
|
|
|
|
if( !m_bEnableBlend )
|
|
{
|
|
return;
|
|
}
|
|
m_vecBlendAniInfo.push_back( *pInfo );
|
|
for( i = 0; i < ( int )m_vecChild.size(); i++ )
|
|
{
|
|
m_vecChild[ i ]->BlendAni( pInfo );
|
|
}
|
|
}
|
|
}
|
|
|
|
void CEtBone::EnableBlend( bool bEnable )
|
|
{
|
|
m_bEnableBlend = bEnable;
|
|
int i;
|
|
for( i = 0; i < ( int )m_vecChild.size(); i++ )
|
|
{
|
|
m_vecChild[ i ]->EnableBlend( bEnable );
|
|
}
|
|
}
|
|
|
|
void CEtBone::CalcAni()
|
|
{
|
|
if( m_pParent )
|
|
{
|
|
EtMatrix AniMat;
|
|
|
|
GetAniMatrix( &AniMat );
|
|
if( m_fScale != 1.0f )
|
|
{
|
|
EtMatrix ScaleMat;
|
|
EtMatrixScaling( &ScaleMat, m_fScale, m_fScale, m_fScale );
|
|
EtMatrixMultiply( &AniMat, &ScaleMat, &AniMat );
|
|
}
|
|
EtMatrixMultiply( &m_TransMat, &AniMat, m_pParent->GetTransMat() );
|
|
if( m_pBoneRotation )
|
|
{
|
|
EtMatrix RotationMat;
|
|
EtVector3 Save;
|
|
|
|
memcpy( &Save, &m_TransMat._41, sizeof( EtVector3 ) );
|
|
EtMatrixRotationYawPitchRoll( &RotationMat, EtToRadian( m_pBoneRotation->y ), EtToRadian( m_pBoneRotation->x ), EtToRadian( m_pBoneRotation->z ) );
|
|
EtMatrixMultiply( &m_TransMat, &m_TransMat, &RotationMat );
|
|
memcpy( &m_TransMat._41, &Save, sizeof( EtVector3 ) );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
GetAniMatrix( &m_TransMat );
|
|
}
|
|
}
|
|
|
|
void CEtBone::GetAniMatrix( EtMatrix *pOutMat )
|
|
{
|
|
int i;
|
|
EtVector3 Position1, Position2;
|
|
EtQuat Rotation1, Rotation2;
|
|
EtVector3 Scale;
|
|
|
|
if( m_bRootBone )
|
|
{
|
|
m_vecAniKey[ m_AniInfo.nAni ]->CalcPosition( Position1, 0.0f );
|
|
m_vecAniKey[ m_AniInfo.nAni ]->CalcPosition( Position2, m_AniInfo.fFrame );
|
|
if( s_CalcPositionFlag & CALC_POSITION_X )
|
|
{
|
|
Position1.x = Position2.x;
|
|
}
|
|
if( s_CalcPositionFlag & CALC_POSITION_Y )
|
|
{
|
|
Position1.y = Position2.y;
|
|
}
|
|
if( s_CalcPositionFlag & CALC_POSITION_Z )
|
|
{
|
|
Position1.z = Position2.z;
|
|
}
|
|
for( i = 0; i < ( int )m_vecBlendAniInfo.size(); i++ )
|
|
{
|
|
m_vecAniKey[ m_vecBlendAniInfo[ i ].nAni ]->CalcPosition( Position2, m_vecBlendAniInfo[ i ].fFrame );
|
|
if( !( s_CalcPositionFlag & CALC_POSITION_X ) )
|
|
{
|
|
Position2.x = Position1.x;
|
|
}
|
|
if( !( s_CalcPositionFlag & CALC_POSITION_Y ) )
|
|
{
|
|
Position2.y = Position1.y;
|
|
}
|
|
if( !( s_CalcPositionFlag & CALC_POSITION_Z ) )
|
|
{
|
|
Position2.z = Position1.z;
|
|
}
|
|
EtVec3Lerp( &Position1, &Position1, &Position2, m_vecBlendAniInfo[ i ].fWeight );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
m_vecAniKey[ m_AniInfo.nAni ]->CalcPosition( Position1, m_AniInfo.fFrame );
|
|
for( i = 0; i < ( int )m_vecBlendAniInfo.size(); i++ )
|
|
{
|
|
m_vecAniKey[ m_vecBlendAniInfo[ i ].nAni ]->CalcPosition( Position2, m_vecBlendAniInfo[ i ].fFrame );
|
|
EtVec3Lerp( &Position1, &Position1, &Position2, m_vecBlendAniInfo[ i ].fWeight );
|
|
}
|
|
}
|
|
|
|
m_vecAniKey[ m_AniInfo.nAni ]->CalcRotation( Rotation1, m_AniInfo.fFrame );
|
|
for( i = 0; i < ( int )m_vecBlendAniInfo.size(); i++ )
|
|
{
|
|
m_vecAniKey[ m_vecBlendAniInfo[ i ].nAni ]->CalcRotation( Rotation2, m_vecBlendAniInfo[ i ].fFrame );
|
|
EtQuaternionSlerp( &Rotation1, &Rotation1, &Rotation2, m_vecBlendAniInfo[ i ].fWeight );
|
|
}
|
|
|
|
m_vecAniKey[ m_AniInfo.nAni ]->CalcScale( Scale, m_AniInfo.fFrame );
|
|
|
|
EtMatrixTransformation( pOutMat, NULL, NULL, &Scale, NULL, &Rotation1, &Position1 );
|
|
}
|
|
|
|
void CEtBone::GetAniRotationMatrix( int nAni, float fFrame, EtMatrix &AniMat )
|
|
{
|
|
if( IsValidAniIndex( nAni ) )
|
|
{
|
|
EtQuat Rotation;
|
|
|
|
m_vecAniKey[ nAni ]->CalcRotation( Rotation, fFrame );
|
|
EtMatrixRotationQuaternion( &AniMat, &Rotation );
|
|
}
|
|
}
|
|
|
|
void CEtBone::CalcAniDistance( int nAni, float fCurFrame, float fPrevFrame, EtVector3 &DistVec )
|
|
{
|
|
if( IsValidAniIndex( nAni ) )
|
|
{
|
|
EtVector3 Position1, Position2;
|
|
|
|
m_vecAniKey[ nAni ]->CalcPosition( Position1, fPrevFrame );
|
|
m_vecAniKey[ nAni ]->CalcPosition( Position2, fCurFrame );
|
|
DistVec = Position2 - Position1;
|
|
}
|
|
else
|
|
{
|
|
DistVec = EtVector3( 0.0f, 0.0f, 0.0f );
|
|
}
|
|
}
|
|
|