Changeset View
Changeset View
Standalone View
Standalone View
source/graphics/Model.cpp
Show First 20 Lines • Show All 107 Lines • ▼ Show 20 Lines | void CModel::CalcBounds() | ||||
// Need to calculate the object bounds first, if that hasn't already been done | // Need to calculate the object bounds first, if that hasn't already been done | ||||
if (! (m_Anim && m_Anim->m_AnimDef)) | if (! (m_Anim && m_Anim->m_AnimDef)) | ||||
{ | { | ||||
if (m_ObjectBounds.IsEmpty()) | if (m_ObjectBounds.IsEmpty()) | ||||
CalcStaticObjectBounds(); | CalcStaticObjectBounds(); | ||||
} | } | ||||
else | else | ||||
{ | { | ||||
if (m_Anim->m_ObjectBounds.IsEmpty()) | if (!m_Anim->m_ObjectBounds) | ||||
CalcAnimatedObjectBounds(m_Anim->m_AnimDef, m_Anim->m_ObjectBounds); | { | ||||
ENSURE(! m_Anim->m_ObjectBounds.IsEmpty()); // (if this happens, it'll be recalculating the bounds every time) | m_Anim->m_ObjectBounds = std::make_unique<CBoundingBoxAligned>(); | ||||
m_ObjectBounds = m_Anim->m_ObjectBounds; | CalcAnimatedObjectBounds(m_Anim->m_AnimDef, *m_Anim->m_ObjectBounds); | ||||
} | |||||
ENSURE(!m_Anim->m_ObjectBounds->IsEmpty()); // (if this happens, it'll be recalculating the bounds every time) | |||||
m_ObjectBounds = *m_Anim->m_ObjectBounds; | |||||
} | } | ||||
// Ensure the transform is set correctly before we use it | // Ensure the transform is set correctly before we use it | ||||
ValidatePosition(); | ValidatePosition(); | ||||
// Now transform the object-space bounds to world-space bounds | // Now transform the object-space bounds to world-space bounds | ||||
m_ObjectBounds.Transform(GetTransform(), m_WorldBounds); | m_ObjectBounds.Transform(GetTransform(), m_WorldBounds); | ||||
} | } | ||||
Show All 11 Lines | for (size_t i=0;i<numverts;i++) { | ||||
m_ObjectBounds+=verts[i].m_Coords; | m_ObjectBounds+=verts[i].m_Coords; | ||||
} | } | ||||
} | } | ||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////// | ///////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
// CalcAnimatedObjectBound: calculate bounds encompassing all vertex positions for given animation | // CalcAnimatedObjectBound: calculate bounds encompassing all vertex positions for given animation | ||||
void CModel::CalcAnimatedObjectBounds(CSkeletonAnimDef* anim, CBoundingBoxAligned& result) | void CModel::CalcAnimatedObjectBounds(CSkeletonAnimDef* anim, CBoundingBoxAligned& result) | ||||
{ | { | ||||
PROFILE2("CalcAnimatedObjectBounds"); | |||||
PROFILE2_ATTR("Tex %s", anim->m_Pathname.c_str()); | |||||
LOGWARNING("calculating bounds for %s %s", m_pModelDef->GetName().string8().c_str(), anim->m_Pathname.c_str()); | |||||
result.SetEmpty(); | result.SetEmpty(); | ||||
// Set the current animation on which to perform calculations (if it's necessary) | // Set the current animation on which to perform calculations (if it's necessary) | ||||
if (anim != m_Anim->m_AnimDef) | if (anim != m_Anim->m_AnimDef) | ||||
{ | { | ||||
CSkeletonAnim dummyanim; | SkeletonAnim dummyanim; | ||||
dummyanim.m_AnimDef=anim; | dummyanim.m_AnimDef=anim; | ||||
if (!SetAnimation(&dummyanim)) return; | if (!SetAnimation(&dummyanim)) return; | ||||
} | } | ||||
size_t numverts=m_pModelDef->GetNumVertices(); | size_t numverts=m_pModelDef->GetNumVertices(); | ||||
SModelVertex* verts=m_pModelDef->GetVertices(); | SModelVertex* verts=m_pModelDef->GetVertices(); | ||||
// Remove any transformations, so that we calculate the bounding box | // Remove any transformations, so that we calculate the bounding box | ||||
▲ Show 20 Lines • Show All 88 Lines • ▼ Show 20 Lines | for (size_t i = 0; i < m_Props.size(); ++i) | ||||
objBounds += transformedPropSelectionBounds; | objBounds += transformedPropSelectionBounds; | ||||
} | } | ||||
return objBounds; | return objBounds; | ||||
} | } | ||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////// | ///////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
// BuildAnimation: load raw animation frame animation from given file, and build a | |||||
// animation specific to this model | |||||
CSkeletonAnim* CModel::BuildAnimation(const VfsPath& pathname, const CStr& name, const CStr& ID, int frequency, float speed, float actionpos, float actionpos2, float soundpos) | |||||
{ | |||||
CSkeletonAnimDef* def = m_SkeletonAnimManager.GetAnimation(pathname); | |||||
if (!def) | |||||
return NULL; | |||||
CSkeletonAnim* anim = new CSkeletonAnim(); | |||||
anim->m_Name = name; | |||||
anim->m_ID = ID; | |||||
anim->m_Frequency = frequency; | |||||
anim->m_AnimDef = def; | |||||
anim->m_Speed = speed; | |||||
if (actionpos == -1.f) | |||||
anim->m_ActionPos = -1.f; | |||||
else | |||||
anim->m_ActionPos = actionpos * anim->m_AnimDef->GetDuration(); | |||||
if (actionpos2 == -1.f) | |||||
anim->m_ActionPos2 = -1.f; | |||||
else | |||||
anim->m_ActionPos2 = actionpos2 * anim->m_AnimDef->GetDuration(); | |||||
if (soundpos == -1.f) | |||||
anim->m_SoundPos = -1.f; | |||||
else | |||||
anim->m_SoundPos = soundpos * anim->m_AnimDef->GetDuration(); | |||||
anim->m_ObjectBounds.SetEmpty(); | |||||
InvalidateBounds(); | |||||
return anim; | |||||
} | |||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||||
// Update: update this model to the given time, in msec | // Update: update this model to the given time, in msec | ||||
void CModel::UpdateTo(float time) | void CModel::UpdateTo(float time) | ||||
{ | { | ||||
// update animation time, but don't calculate bone matrices - do that (lazily) when | // update animation time, but don't calculate bone matrices - do that (lazily) when | ||||
// something requests them; that saves some calculation work for offscreen models, | // something requests them; that saves some calculation work for offscreen models, | ||||
// and also assures the world space, inverted bone matrices (required for normal | // and also assures the world space, inverted bone matrices (required for normal | ||||
// skinning) are up to date with respect to m_Transform | // skinning) are up to date with respect to m_Transform | ||||
m_AnimTime = time; | m_AnimTime = time; | ||||
▲ Show 20 Lines • Show All 147 Lines • ▼ Show 20 Lines | if (computeBlendMatrices) | ||||
m_pModelDef->BlendBoneMatrices(m_BoneMatrices); | m_pModelDef->BlendBoneMatrices(m_BoneMatrices); | ||||
} | } | ||||
} | } | ||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////// | ///////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
// SetAnimation: set the given animation as the current animation on this model; | // SetAnimation: set the given animation as the current animation on this model; | ||||
// return false on error, else true | // return false on error, else true | ||||
bool CModel::SetAnimation(CSkeletonAnim* anim, bool once) | bool CModel::SetAnimation(SkeletonAnim* anim, bool once) | ||||
{ | { | ||||
m_Anim = nullptr; // in case something fails | m_Anim = nullptr; // in case something fails | ||||
if (anim) | if (anim) | ||||
{ | { | ||||
m_Flags &= ~MODELFLAG_NOLOOPANIMATION; | m_Flags &= ~MODELFLAG_NOLOOPANIMATION; | ||||
if (once) | if (once) | ||||
▲ Show 20 Lines • Show All 211 Lines • Show Last 20 Lines |
Wildfire Games · Phabricator