DragonNest/Common/EternityEngine/EtBone.cpp
Cussrro 47f7895977 Revert "修复编码问题"
This reverts commit 9e69c01767.
2024-12-21 10:04:04 +08:00

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 );
}
}