Files
Client/Engine/Zalla3D Scene Class/Z3DAniMixer.cpp
LGram16 e067522598 Initial commit: ROW Client source code
Game client codebase including:
- CharacterActionControl: Character and creature management
- GlobalScript: Network, items, skills, quests, utilities
- RYLClient: Main client application with GUI and event handlers
- Engine: 3D rendering engine (RYLGL)
- MemoryManager: Custom memory allocation
- Library: Third-party dependencies (DirectX, boost, etc.)
- Tools: Development utilities

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 16:24:34 +09:00

194 lines
4.9 KiB
C++
Raw Blame History

// Z3DAniMixer.cpp: implementation of the CZ3DAniMixer class.
//
//////////////////////////////////////////////////////////////////////
#include "Z3DAniMixer.h"
#include "GMMemory.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CZ3DAniMixer::CZ3DAniMixer()
{
m_apOperand[0] = NULL;
m_apOperand[1] = NULL;
m_pActiveIndex = NULL;
m_pTransitFlag = NULL;
m_lSkelCount = 0;
m_lAniHolderCount = 0;
m_rpSkeleton = NULL;
m_rpAniHolder = NULL;
m_rpAddonAniHolder = NULL;
m_fAddonFactorPeak = 0.5f;
m_bSustainLast = false;
}
CZ3DAniMixer::~CZ3DAniMixer()
{
SAFE_DELETEA( m_apOperand[0] );
SAFE_DELETEA( m_apOperand[1] );
SAFE_DELETEA( m_pActiveIndex );
SAFE_DELETEA( m_pTransitFlag );
}
bool CZ3DAniMixer::Init( CZ3DSkeletonObject* pSkel, const matrix* pLocalizer, Z3DAniHolder* pAniHolder, Z3DAniHolder* pAddonAniHolder, long lSkelCount, long lAniHolderCount )
{
int i;
if( NULL == pSkel || NULL == pAniHolder )
{
return false;
}
m_rpSkeleton = pSkel;
m_rpAniHolder = pAniHolder;
m_rpAddonAniHolder = pAddonAniHolder;
m_lSkelCount = lSkelCount;
m_lAniHolderCount = lAniHolderCount;
m_apOperand[0] = new Z3D_POSNDIR[m_lSkelCount];
m_apOperand[1] = new Z3D_POSNDIR[m_lSkelCount];
matrix matInitialTM;
for( i = 0; i < m_lSkelCount; ++i )
{
matInitialTM.Inverse(pLocalizer[i]);
// m_apOperand[0][i].pos.Identity();
// m_apOperand[0][i].dir.Identity();
//
// m_apOperand[1][i].pos.Identity();
// m_apOperand[1][i].dir.Identity();
m_apOperand[0][i].pos = matInitialTM.GetLoc();
z3d::QuaternionRotationMatrix( m_apOperand[0][i].dir, matInitialTM );
m_apOperand[1][i] = m_apOperand[0][i];
}
m_pActiveIndex = new long[m_lAniHolderCount];
m_pTransitFlag = new bool[m_lAniHolderCount];
for( i = 0; i < m_lAniHolderCount; ++i )
{
m_pActiveIndex[i] = 0;
m_pTransitFlag[i] = true;
}
return true;
}
void CZ3DAniMixer::Swap( long lAniHolderIndex, bool bTransitFlag )
{
if( lAniHolderIndex >= m_lAniHolderCount )
{
return;
}
m_pActiveIndex[lAniHolderIndex] = (m_pActiveIndex[lAniHolderIndex] + 1) % 2;
m_pTransitFlag[lAniHolderIndex] = bTransitFlag;
}
float CZ3DAniMixer::GetAddFactorCurve( float fCurrent, float fAniLength )
{
float fInterval = min( 10.0f, (fAniLength) * 0.3f );
if( fCurrent < fInterval )
{
return (fCurrent / fInterval) * m_fAddonFactorPeak;
}
else if( (fAniLength - fCurrent) < fInterval && m_bSustainLast )
{
return ( (fAniLength-fCurrent) / fInterval) * m_fAddonFactorPeak;
}
return m_fAddonFactorPeak;
}
void CZ3DAniMixer::Mix()
{
int i;
int nAniHolderIndex, nPartInHolderIndex;
float fDuration, fAniLength, fCurrent, fTmp;
vector3 posAdd;
quaternion dirAdd;
for( i = 0; i < m_lSkelCount; i++ )
{
nAniHolderIndex = m_rpSkeleton[i].GetAniHolderIndex();
nPartInHolderIndex = m_rpSkeleton[i].GetPartInHolderIndex();
// anikeypack <20><> null<6C≯<EFBFBD> pos<6F><73> dir<69><72> identity<74><79><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>
m_rpAniHolder[nAniHolderIndex].GetControllerData(
nPartInHolderIndex,
m_apOperand[m_pActiveIndex[nAniHolderIndex]][i].pos,
m_apOperand[m_pActiveIndex[nAniHolderIndex]][i].dir );
if( !m_rpAniHolder[nAniHolderIndex].IsOverflow() )
{
fAniLength = m_rpAniHolder[nAniHolderIndex].GetAniKeyPackInterface()->GetAniLength();
fCurrent = m_rpAniHolder[nAniHolderIndex].GetCurrentFrame();
fDuration = min( 6.0f, (fAniLength) * 0.2f );
if( fCurrent < fDuration && m_pTransitFlag[nAniHolderIndex] )
{
fTmp = fCurrent / fDuration;
z3d::VectorLerp(
m_apOperand[m_pActiveIndex[nAniHolderIndex]][i].pos,
m_apOperand[((m_pActiveIndex[nAniHolderIndex]+1)%2)][i].pos,
m_apOperand[m_pActiveIndex[nAniHolderIndex]][i].pos, fTmp );
z3d::QuaternionSlerp(
m_apOperand[m_pActiveIndex[nAniHolderIndex]][i].dir,
m_apOperand[((m_pActiveIndex[nAniHolderIndex]+1)%2)][i].dir,
m_apOperand[m_pActiveIndex[nAniHolderIndex]][i].dir, fTmp );
}
// else
// do nothing
}
if( !m_rpAddonAniHolder[nAniHolderIndex].IsOverflow() )
{
fAniLength = m_rpAddonAniHolder[nAniHolderIndex].GetAniKeyPackInterface()->GetAniLength();
fCurrent = m_rpAddonAniHolder[nAniHolderIndex].GetCurrentFrame();
m_rpAddonAniHolder[nAniHolderIndex].GetControllerData(
nPartInHolderIndex, posAdd, dirAdd );
fTmp = GetAddFactorCurve( fCurrent, fAniLength );
z3d::VectorLerp(
m_apOperand[m_pActiveIndex[nAniHolderIndex]][i].pos,
m_apOperand[m_pActiveIndex[nAniHolderIndex]][i].pos,
posAdd, fTmp );
z3d::QuaternionSlerp(
m_apOperand[m_pActiveIndex[nAniHolderIndex]][i].dir,
m_apOperand[m_pActiveIndex[nAniHolderIndex]][i].dir,
dirAdd, fTmp );
}
}
for( i = 0; i < m_lSkelCount; i++ )
{
nAniHolderIndex = m_rpSkeleton[i].GetAniHolderIndex();
m_rpSkeleton[i].SetPositionLocal(
m_apOperand[m_pActiveIndex[nAniHolderIndex]][i].pos );
m_rpSkeleton[i].SetDirectionLocal(
m_apOperand[m_pActiveIndex[nAniHolderIndex]][i].dir );
}
}