#include "stdafx.h" #include "IResourceFactory.h" #include "BoneController.h" #include "../ShaderParameterCollection/Types/Types.h" BoneController::BoneController(IEngine& argEngine) : ShaderParameterCollection(argEngine) , m_StartTime(0.0) , m_LastMatrixArray(NULL) { } BoneController::~BoneController() { m_Engine.get_ResourceFactory().DeleteBoneController(*const_cast(this), true); } void BoneController::Initialize(IBone& argRootBone) { m_RootBone = &argRootBone; m_Bones = m_RootBone->get_BoneIndexList(); } void BoneController::Initialize(const IBoneController& argOther) { m_RootBone = &argOther.get_RootBone(); m_Bones = m_RootBone->get_BoneIndexList(); m_CurrentSequence = argOther.get_CurrentSequence(); m_Sequences = argOther.get_Sequences(); this->PlaySequence(m_CurrentSequence); } void BoneController::Apply() { float lf_Time = 0.0f; if (!m_CurrentSequence.empty()) lf_Time = get_CurrentTime(); int i = 0; D3DXMATRIX* lr_MatrixArray_ = m_RootBone->get_MatrixArray(); for (std::map::const_iterator lk_Iter = m_Bones.begin(); lk_Iter != m_Bones.end(); ++lk_Iter, ++i) lr_MatrixArray_[i] = lk_Iter->second->GetTransformationAtTime(lf_Time, D3DXMATRIX()); if (m_LastMatrixArray != lr_MatrixArray_) { m_LastMatrixArray = lr_MatrixArray_; this->SetParameter("BoneMatrix", new Matrix4x4ShaderParameter(m_LastMatrixArray, m_RootBone->get_MatrixArraySize(), ParameterBindType::BindBySemantic)); } } void BoneController::RegisterSequence(const string16& argName, float argStart, float argEnd, bool argLoop) { Sequence lr_NewSequence; lr_NewSequence.m_Start = argStart; lr_NewSequence.m_End = argEnd; lr_NewSequence.m_Loop = argLoop; m_Sequences[argName] = lr_NewSequence; } void BoneController::PlaySequence(const string16& argName) { m_StartTime = m_Engine.get_Timeline().get_DemoTime(); std::map::iterator lk_Iter = m_Sequences.find(argName); if (lk_Iter != m_Sequences.end()) { m_CurrentSequenceInfo = lk_Iter->second; m_CurrentSequence = argName; } else m_CurrentSequence = string16(); } const string16& BoneController::get_CurrentSequence() const { return m_CurrentSequence; } float BoneController::get_CurrentTime() { float lf_CurrentTime = static_cast(m_Engine.get_Timeline().get_DemoTime() - m_StartTime); lf_CurrentTime = lf_CurrentTime / (m_CurrentSequenceInfo.m_End - m_CurrentSequenceInfo.m_Start); lf_CurrentTime = (m_CurrentSequenceInfo.m_End - m_CurrentSequenceInfo.m_Start) * lf_CurrentTime + m_CurrentSequenceInfo.m_Start; if (lf_CurrentTime >= m_CurrentSequenceInfo.m_End) { while (m_CurrentSequenceInfo.m_Loop && lf_CurrentTime >= m_CurrentSequenceInfo.m_End) { lf_CurrentTime -= m_CurrentSequenceInfo.m_End; m_StartTime += m_CurrentSequenceInfo.m_End; } if (!m_CurrentSequenceInfo.m_Loop) lf_CurrentTime = m_CurrentSequenceInfo.m_End; } else if (lf_CurrentTime < m_CurrentSequenceInfo.m_Start) { while (m_CurrentSequenceInfo.m_Loop && lf_CurrentTime < m_CurrentSequenceInfo.m_Start) { lf_CurrentTime += m_CurrentSequenceInfo.m_Start; m_StartTime -= m_CurrentSequenceInfo.m_Start; } if (!m_CurrentSequenceInfo.m_Loop) lf_CurrentTime = m_CurrentSequenceInfo.m_Start; } return lf_CurrentTime; }