// Z3DAniMixer.cpp: implementation of the CZ3DAniMixer class. // ////////////////////////////////////////////////////////////////////// #include "Z3DAniMixer.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, 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]; for( i = 0; i < m_lSkelCount; ++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_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 ÀÌ nullÀ̸é pos¿Í dir´Â identity¼³Á¤ÀÌ µÊ 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 ); } }