/////////////////////////////////////////////////////////////////////////////// // // Name: Model.cpp // Author: Rich Cross // Contact: rich@wildfiregames.com // /////////////////////////////////////////////////////////////////////////////// #include "Model.h" #include "Quaternion.h" #include "Bound.h" /////////////////////////////////////////////////////////////////////////////// // Constructor CModel::CModel() : m_pModelDef(0), m_Anim(0), m_AnimTime(0), m_BoneMatrices(0), m_InvBoneMatrices(0) { } /////////////////////////////////////////////////////////////////////////////// // Destructor CModel::~CModel() { ReleaseData(); } /////////////////////////////////////////////////////////////////////////////// // ReleaseData: delete anything allocated by the model void CModel::ReleaseData() { delete[] m_BoneMatrices; delete[] m_InvBoneMatrices; } /////////////////////////////////////////////////////////////////////////////// // InitModel: setup model from given geometry bool CModel::InitModel(CModelDef* modeldef) { // clean up any existing data first ReleaseData(); m_pModelDef = modeldef; u32 numBones=modeldef->GetNumBones(); if (numBones>0) { // allocate matrices for bone transformations m_BoneMatrices=new CMatrix3D[numBones]; m_InvBoneMatrices=new CMatrix3D[numBones]; // store default pose until animation assigned CBoneState* defpose=modeldef->GetBones(); for (uint i=0;iGetNumVertices(); SModelVertex* verts=m_pModelDef->GetVertices(); u32 numbones=m_pModelDef->GetNumBones(); if (numbones>0) { // Boned object: tricky to get an ideal bound - for the minute, just use the bound of // the reference pose. There's no guarantee that when animations are applied to the // model, the bounds will be within this bound - ideally, we want the bound of the // object to be the union of the bounds of the model for each animation for (int i=0;iGetBones()); m_Bounds+=m_Transform.Transform(tmp); } } else { for (int i=0;iGetDuration(); if (m_AnimTime>duration) { m_AnimTime=(float) fmod(m_AnimTime,duration); } m_Anim->BuildBoneMatrices(m_AnimTime,m_BoneMatrices); for (int i=0;iGetNumBones();i++) { m_BoneMatrices[i].GetInverse(m_InvBoneMatrices[i]); } if (m_RenderData) m_RenderData->m_UpdateFlags|=RENDERDATA_UPDATE_VERTICES; } } ///////////////////////////////////////////////////////////////////////////////////// // SetAnimation: set the given animation as the current animation on this model; // return false on error, else true bool CModel::SetAnimation(CSkeletonAnim* anim) { if (anim) { if (!m_BoneMatrices) { // not boned, can't animate return false; } if (anim->GetNumKeys()!=m_pModelDef->GetNumBones()) { // mismatch between models skeleton and animations skeleton return false; } } m_AnimTime=0; m_Anim=anim; return true; } ///////////////////////////////////////////////////////////////////////////////////// // Clone: return a clone of this model CModel* CModel::Clone() const { CModel* clone=new CModel; clone->InitModel(m_pModelDef); clone->SetTexture(m_Texture); clone->SetAnimation(m_Anim); return clone; }