138 lines
4.3 KiB
C++
138 lines
4.3 KiB
C++
#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<TransformationAnimation*>(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<float, KeyFrame>::const_iterator lk_LowerR = this->FindLowerBoundKey(lf_Time, KeyFrameTarget::Rotation);
|
|
std::map<float, KeyFrame>::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<float, KeyFrame>::const_iterator lk_LowerT = this->FindLowerBoundKey(lf_Time, KeyFrameTarget::Position);
|
|
std::map<float, KeyFrame>::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<float, KeyFrame>::const_iterator lk_LowerS = this->FindLowerBoundKey(lf_Time, KeyFrameTarget::Scale);
|
|
std::map<float, KeyFrame>::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<float, KeyFrame>::const_iterator TransformationAnimation::FindLowerBoundKey(float argTimeime, KeyFrameTarget::Enumeration ae_Target) const
|
|
{
|
|
std::map<float, KeyFrame>::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<float, KeyFrame>::const_iterator TransformationAnimation::FindUpperBoundKey(float argTimeime, KeyFrameTarget::Enumeration ae_Target) const
|
|
{
|
|
std::map<float, KeyFrame>::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;
|
|
} |