Improved KeyframeMesh AABB support

When you use KeyframeMesh::SetPosition(frame, vertex, pos), it will now
invalidate the frame AABB.
Finish() method will now generate automatically invalid AABBs before
interpolating


Former-commit-id: aa4695cee635da73e4a3b70ce22e83b1c3f443f9
This commit is contained in:
Lynix 2013-01-03 15:10:06 +01:00
parent 41fb7f7ae5
commit 81e95ecddf
3 changed files with 37 additions and 12 deletions

View File

@ -26,6 +26,8 @@ class NAZARA_API NzKeyframeMesh final : public NzSubMesh
void Finish();
void GenerateAABBs();
const NzAxisAlignedBox& GetAABB() const override;
nzAnimationType GetAnimationType() const override;
unsigned int GetFrameCount() const;

View File

@ -106,9 +106,34 @@ void NzKeyframeMesh::Finish()
}
#endif
GenerateAABBs();
InterpolateImpl(0, 0, 0.f);
}
void NzKeyframeMesh::GenerateAABBs()
{
#if NAZARA_UTILITY_SAFE
if (!m_impl)
{
NazaraError("Keyframe mesh not created");
return;
}
#endif
unsigned int vertexCount = m_impl->vertexBuffer->GetVertexCount();
for (unsigned int i = 0; i < m_impl->frameCount; ++i)
{
NzAxisAlignedBox& aabb = m_impl->aabb[i+1]; // l'AABB 0 est celle qui est interpolée
if (aabb.IsNull())
{
// Génération de l'AABB selon la position
unsigned int index = i*vertexCount;
for (unsigned int j = 0; j < vertexCount; ++j)
aabb.ExtendTo(m_impl->positions[index+j]);
}
}
}
const NzAxisAlignedBox& NzKeyframeMesh::GetAABB() const
{
#if NAZARA_UTILITY_SAFE
@ -475,6 +500,7 @@ void NzKeyframeMesh::SetPosition(unsigned int frameIndex, unsigned int vertexInd
unsigned int index = frameIndex*vertexCount + vertexIndex;
m_impl->positions[index] = position;
m_impl->aabb[frameIndex+1].SetNull(); // Invalidation de l'AABB
}
void NzKeyframeMesh::SetTangent(unsigned int frameIndex, unsigned int vertexIndex, const NzVector3f& tangent)

View File

@ -178,7 +178,6 @@ namespace
NzByteSwap(&translate.z, sizeof(float));
#endif
NzAxisAlignedBox aabb;
for (unsigned int t = 0; t < header.num_tris; ++t)
{
for (unsigned int v = 0; v < 3; ++v)
@ -186,27 +185,25 @@ namespace
const md2_vertex& vert = vertices[triangles[t].vertices[v]];
NzVector3f position = rotationQuat * NzVector3f(vert.x * scale.x + translate.x, vert.y * scale.y + translate.y, vert.z * scale.z + translate.z);
// On fait en sorte d'étendre l'AABB pour qu'il contienne ce sommet
aabb.ExtendTo(position);
// On calcule l'indice (On affecte dans le sens inverse)
unsigned int vertexIndex = vertexCount - (t*3 + v) - 1;
// Et on finit par copier les éléments dans le buffer
subMesh->SetNormal(f, vertexIndex, md2Normals[vert.n]);
subMesh->SetPosition(f, vertexIndex, position);
}
}
}
if (f == 0)
// Définit les coordonnées de textures
for (unsigned int t = 0; t < header.num_tris; ++t)
{
for (unsigned int v = 0; v < 3; ++v)
{
// On ne définit les coordonnées de texture que lors de la première frame
const md2_texCoord& texC = texCoords[triangles[t].texCoords[v]];
subMesh->SetTexCoords(vertexIndex, NzVector2f(texC.u / static_cast<float>(header.skinwidth), 1.f - texC.v / static_cast<float>(header.skinheight)));
subMesh->SetTexCoords(vertexCount - (t*3 + v) - 1, NzVector2f(texC.u / static_cast<float>(header.skinwidth), 1.f - texC.v / static_cast<float>(header.skinheight)));
}
}
}
subMesh->SetAABB(f, aabb);
}
subMesh->SetMaterialIndex(0);
mesh->AddSubMesh(subMesh.release());