#include "stdafx.h" #include "IResourceFactory.h" #include "TransformationAnimation.h" TransformationAnimation::TransformationAnimation(IEngine& argEngine) : m_Engine(argEngine) { } TransformationAnimation::~TransformationAnimation() { //m_Engine.get_ResourceFactory().DeleteTransformationAnimation(*const_cast(this), true); } string16 TransformationAnimation::get_Name() const { return m_Name; } void TransformationAnimation::AddKeyFrame(const KeyFrame& argKeyFrame) { m_Keys[argKeyFrame.m_Target][argKeyFrame.m_Time] = argKeyFrame; } float TransformationAnimation::get_Duration() const { float duration = 0.0f; if (!m_Keys[0].empty()) duration = max(duration, m_Keys[0].rbegin()->first); if (!m_Keys[1].empty()) duration = max(duration, m_Keys[1].rbegin()->first); if (!m_Keys[2].empty()) duration = max(duration, m_Keys[2].rbegin()->first); return duration; } D3DXMATRIX TransformationAnimation::GetTransformationAtTime(float argTime) { float lf_Time = /*this->get_Duration() * */argTime; D3DXMATRIX lk_Rot; D3DXMATRIX lk_Trans; D3DXMATRIX lk_Scale; // Rotation std::map::const_iterator lk_LowerR = this->FindLowerBoundKey(lf_Time, KeyFrameTarget::Rotation); std::map::const_iterator lk_UpperR = this->FindUpperBoundKey(lf_Time, KeyFrameTarget::Rotation); if (lk_LowerR != m_Keys[KeyFrameTarget::Rotation].end()) { float t = 0.0f; if ((lk_UpperR->first - lk_LowerR->first) > 0) t = (lf_Time - lk_LowerR->first) / (lk_UpperR->first - lk_LowerR->first); D3DXVECTOR3 lk_A = lk_LowerR->second.m_Value; D3DXVECTOR3 lk_B = lk_UpperR->second.m_Value; D3DXVECTOR3 lk_TmpResult = lk_A * (1.0f - t) + lk_B * t; D3DXMATRIX tempMat; D3DXMatrixRotationX(&lk_Rot, (float)D3DXToRadian(lk_TmpResult.x)); D3DXMatrixRotationY(&tempMat, (float)D3DXToRadian(lk_TmpResult.y)); D3DXMatrixMultiply(&lk_Rot, &lk_Rot, &tempMat); D3DXMatrixRotationZ(&tempMat, (float)D3DXToRadian(lk_TmpResult.z)); D3DXMatrixMultiply(&lk_Rot, &lk_Rot, &tempMat); } // Translation std::map::const_iterator lk_LowerT = this->FindLowerBoundKey(lf_Time, KeyFrameTarget::Position); std::map::const_iterator lk_UpperT = this->FindUpperBoundKey(lf_Time, KeyFrameTarget::Position); if (lk_LowerT != m_Keys[KeyFrameTarget::Position].end()) { float t = 0.0f; if ((lk_UpperT->first - lk_LowerT->first) > 0) t = (lf_Time - lk_LowerT->first) / (lk_UpperT->first - lk_LowerT->first); D3DXVECTOR3 lk_A = lk_LowerT->second.m_Value; D3DXVECTOR3 lk_B = lk_UpperT->second.m_Value; D3DXVECTOR3 lk_TmpResult = lk_A * (1.0f - t) + lk_B * t; D3DXMatrixTranslation(&lk_Trans, lk_TmpResult.x, lk_TmpResult.y, lk_TmpResult.z); } // Scale std::map::const_iterator lk_LowerS = this->FindLowerBoundKey(lf_Time, KeyFrameTarget::Scale); std::map::const_iterator lk_UpperS = this->FindUpperBoundKey(lf_Time, KeyFrameTarget::Scale); if (lk_LowerS != m_Keys[KeyFrameTarget::Scale].end()) { float t = 0.0f; if ((lk_UpperS->first - lk_LowerS->first) > 0) t = (lf_Time - lk_LowerS->first) / (lk_UpperS->first - lk_LowerS->first); D3DXVECTOR3 lk_A = lk_LowerS->second.m_Value; D3DXVECTOR3 lk_B = lk_UpperS->second.m_Value; D3DXVECTOR3 lk_TmpResult = lk_A * (1.0f - t) + lk_B * t; D3DXMatrixScaling(&lk_Scale, lk_TmpResult.x, lk_TmpResult.y, lk_TmpResult.z); } D3DXMATRIXA16 comboMatrix; ::D3DXMatrixMultiply(&comboMatrix, &lk_Rot, &lk_Trans); ::D3DXMatrixMultiply(&comboMatrix, &lk_Scale, &comboMatrix); return comboMatrix; } std::map::const_iterator TransformationAnimation::FindLowerBoundKey(float argTimeime, KeyFrameTarget::Enumeration ae_Target) const { std::map::const_iterator lk_Iter = m_Keys[ae_Target].begin(); for (; lk_Iter != m_Keys[ae_Target].end(); ++lk_Iter) if (lk_Iter->first >= argTimeime) break; if (lk_Iter != m_Keys[ae_Target].begin()) --lk_Iter; return lk_Iter; } std::map::const_iterator TransformationAnimation::FindUpperBoundKey(float argTimeime, KeyFrameTarget::Enumeration ae_Target) const { std::map::const_iterator lk_Iter = m_Keys[ae_Target].begin(); for (; lk_Iter != m_Keys[ae_Target].end(); ++lk_Iter) if (lk_Iter->first >= argTimeime) break; if (lk_Iter == m_Keys[ae_Target].end() && m_Keys[ae_Target].size() > 0) --lk_Iter; return lk_Iter; }