From cc457467999b013ce79275c66f9baaf59f4507f2 Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 3 Dec 2012 14:49:56 +0100 Subject: [PATCH] Improved keyframe mesh interface Also improved animation performance by using a discard-and-write lock when interpoling. Former-commit-id: 277b5ad8f148ab73b99edf83cf8c6e5d0e6dfc82 --- include/Nazara/Utility/KeyframeMesh.hpp | 5 +- src/Nazara/Utility/KeyframeMesh.cpp | 66 ++++++++++------------- src/Nazara/Utility/Loaders/MD2/Loader.cpp | 12 ++--- 3 files changed, 38 insertions(+), 45 deletions(-) diff --git a/include/Nazara/Utility/KeyframeMesh.hpp b/include/Nazara/Utility/KeyframeMesh.hpp index 0ece85e77..981561f86 100644 --- a/include/Nazara/Utility/KeyframeMesh.hpp +++ b/include/Nazara/Utility/KeyframeMesh.hpp @@ -30,7 +30,7 @@ class NAZARA_API NzKeyframeMesh final : public NzSubMesh nzAnimationType GetAnimationType() const override; unsigned int GetFrameCount() const; const NzIndexBuffer* GetIndexBuffer() const override; - bool GetVertex(NzMeshVertex* dest, unsigned int frameIndex, unsigned int vertexIndex, bool queryUV = true) const; + void GetVertex(unsigned int frameIndex, unsigned int vertexIndex, NzMeshVertex* dest) const; const NzVertexBuffer* GetVertexBuffer() const override; void Interpolate(const NzAnimation* animation, unsigned int frameA, unsigned int frameB, float interpolation) const; @@ -42,7 +42,8 @@ class NAZARA_API NzKeyframeMesh final : public NzSubMesh void SetAABB(unsigned int frameIndex, const NzAxisAlignedBox& aabb); void SetIndexBuffer(const NzIndexBuffer* indexBuffer); - bool SetVertex(const NzMeshVertex& source, unsigned int frameIndex, unsigned int vertexIndex, bool setUV = true); + void SetVertex(unsigned int frameIndex, unsigned int vertexIndex, const NzMeshVertex& source); + void SetTexCoords(unsigned int vertexIndex, const NzVector2f& uv); void Unlock() const; diff --git a/src/Nazara/Utility/KeyframeMesh.cpp b/src/Nazara/Utility/KeyframeMesh.cpp index 69c2aa9de..0ec30e92f 100644 --- a/src/Nazara/Utility/KeyframeMesh.cpp +++ b/src/Nazara/Utility/KeyframeMesh.cpp @@ -15,6 +15,7 @@ struct NzKeyframeMeshImpl nzBufferAccess lockAccess; NzAxisAlignedBox* aabb; NzMeshVertex* lockBuffer; + NzVector2f* uv; NzVector3f* normals; NzVector3f* positions; NzVector3f* tangents; @@ -70,6 +71,7 @@ bool NzKeyframeMesh::Create(NzVertexBuffer* vertexBuffer, unsigned int frameCoun m_impl->positions = new NzVector3f[frameCount*vertexCount]; m_impl->normals = new NzVector3f[frameCount*vertexCount]; m_impl->tangents = new NzVector3f[frameCount*vertexCount]; + m_impl->uv = new NzVector2f[vertexCount]; if (lock && !Lock(nzBufferAccess_DiscardAndWrite)) { @@ -98,6 +100,7 @@ void NzKeyframeMesh::Destroy() delete[] m_impl->normals; delete[] m_impl->positions; delete[] m_impl->tangents; + delete[] m_impl->uv; delete m_impl; m_impl = nullptr; @@ -161,19 +164,19 @@ const NzIndexBuffer* NzKeyframeMesh::GetIndexBuffer() const return m_impl->indexBuffer; } -bool NzKeyframeMesh::GetVertex(NzMeshVertex* dest, unsigned int frameIndex, unsigned int vertexIndex, bool queryUV) const +void NzKeyframeMesh::GetVertex(unsigned int frameIndex, unsigned int vertexIndex, NzMeshVertex* dest) const { #if NAZARA_UTILITY_SAFE if (!m_impl) { NazaraError("Keyframe mesh not created"); - return false; + return; } if (frameIndex >= m_impl->frameCount) { NazaraError("Frame index out of bounds (" + NzString::Number(frameIndex) + " >= " + NzString::Number(m_impl->frameCount) + ')'); - return false; + return; } #endif @@ -183,7 +186,7 @@ bool NzKeyframeMesh::GetVertex(NzMeshVertex* dest, unsigned int frameIndex, unsi if (vertexIndex >= vertexCount) { NazaraError("Vertex index out of bounds (" + NzString::Number(vertexIndex) + " >= " + NzString::Number(vertexCount) + ')'); - return false; + return; } #endif @@ -192,22 +195,7 @@ bool NzKeyframeMesh::GetVertex(NzMeshVertex* dest, unsigned int frameIndex, unsi dest->normal = m_impl->normals[index]; dest->position = m_impl->positions[index]; dest->tangent = m_impl->tangents[index]; - - if (queryUV) - { - if (!Lock(nzBufferAccess_ReadOnly)) - { - NazaraError("Failed to query UV"); - return false; - } - - NzMeshVertex& vertex = m_impl->lockBuffer[vertexIndex]; - dest->uv = vertex.uv; - - Unlock(); - } - - return true; + dest->uv = m_impl->uv[vertexIndex]; } const NzVertexBuffer* NzKeyframeMesh::GetVertexBuffer() const @@ -354,19 +342,19 @@ void NzKeyframeMesh::SetIndexBuffer(const NzIndexBuffer* indexBuffer) m_impl->indexBuffer = indexBuffer; } -bool NzKeyframeMesh::SetVertex(const NzMeshVertex& source, unsigned int frameIndex, unsigned int vertexIndex, bool setUV) +void NzKeyframeMesh::SetVertex(unsigned int frameIndex, unsigned int vertexIndex, const NzMeshVertex& source) { #if NAZARA_UTILITY_SAFE if (!m_impl) { NazaraError("Keyframe mesh not created"); - return false; + return; } if (frameIndex >= m_impl->frameCount) { NazaraError("Frame index out of bounds (" + NzString::Number(frameIndex) + " >= " + NzString::Number(m_impl->frameCount) + ')'); - return false; + return; } #endif @@ -376,7 +364,7 @@ bool NzKeyframeMesh::SetVertex(const NzMeshVertex& source, unsigned int frameInd if (vertexIndex >= vertexCount) { NazaraError("Vertex index out of bounds (" + NzString::Number(vertexIndex) + " >= " + NzString::Number(vertexCount) + ')'); - return false; + return; } #endif @@ -385,22 +373,25 @@ bool NzKeyframeMesh::SetVertex(const NzMeshVertex& source, unsigned int frameInd m_impl->normals[index] = source.normal; m_impl->positions[index] = source.position; m_impl->tangents[index] = source.tangent; +} - if (setUV) +void NzKeyframeMesh::SetTexCoords(unsigned int vertexIndex, const NzVector2f& uv) +{ + #if NAZARA_UTILITY_SAFE + if (!m_impl) { - if (!Lock(nzBufferAccess_WriteOnly)) - { - NazaraError("Failed to write UV"); - return false; - } - - NzMeshVertex& vertex = m_impl->lockBuffer[vertexIndex]; - vertex.uv = source.uv; - - Unlock(); + NazaraError("Keyframe mesh not created"); + return; } - return true; + if (vertexIndex >= m_impl->vertexBuffer->GetVertexCount()) + { + NazaraError("Vertex index out of bounds (" + NzString::Number(vertexIndex) + " >= " + NzString::Number(m_impl->vertexBuffer->GetVertexCount()) + ')'); + return; + } + #endif + + m_impl->uv[vertexIndex] = uv; } void NzKeyframeMesh::Unlock() const @@ -439,7 +430,7 @@ void NzKeyframeMesh::InterpolateImpl(unsigned int frameA, unsigned int frameB, f // Interpolation de l'AABB m_impl->aabb[0] = NzAxisAlignedBox::Lerp(m_impl->aabb[frameA+1], m_impl->aabb[frameB+1], interpolation); - if (!Lock(nzBufferAccess_WriteOnly)) + if (!Lock(nzBufferAccess_DiscardAndWrite)) { NazaraError("Failed to lock vertex buffer"); return; @@ -457,6 +448,7 @@ void NzKeyframeMesh::InterpolateImpl(unsigned int frameA, unsigned int frameB, f vertex->normal = NzVector3f::Lerp(m_impl->positions[frameA+i], m_impl->positions[frameB+i], interpolation); vertex->position = NzVector3f::Lerp(m_impl->positions[frameA+i], m_impl->positions[frameB+i], interpolation); vertex->tangent = NzVector3f::Lerp(m_impl->positions[frameA+i], m_impl->positions[frameB+i], interpolation); + vertex->uv = m_impl->uv[i]; vertex++; } diff --git a/src/Nazara/Utility/Loaders/MD2/Loader.cpp b/src/Nazara/Utility/Loaders/MD2/Loader.cpp index c4cc78ce8..c56f26a6b 100644 --- a/src/Nazara/Utility/Loaders/MD2/Loader.cpp +++ b/src/Nazara/Utility/Loaders/MD2/Loader.cpp @@ -103,7 +103,7 @@ namespace /// Chargement des submesh // Actuellement le loader ne charge qu'un submesh - // TODO: Utiliser les commandes OpenGL pour créer des indices et accélérer le rendu + // FIXME: Utiliser les commandes OpenGL ? unsigned int vertexCount = header.num_tris * 3; std::unique_ptr vertexBuffer(new NzVertexBuffer(NzMesh::GetDeclaration(), vertexCount, parameters.storage, nzBufferUsage_Dynamic)); @@ -194,15 +194,15 @@ namespace vertex.normal = md2Normals[vert.n]; vertex.position = position; - // On ne définit les coordonnées de texture que pour la première frame - bool firstFrame = (f == 0); - if (firstFrame) + unsigned int vertexIndex = vertexCount - (t*3 + v) - 1; + if (f == 0) { + // 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]]; - vertex.uv.Set(texC.u / static_cast(header.skinwidth), 1.f - texC.v / static_cast(header.skinheight)); + subMesh->SetTexCoords(vertexIndex, NzVector2f(texC.u / static_cast(header.skinwidth), 1.f - texC.v / static_cast(header.skinheight))); } - subMesh->SetVertex(vertex, f, vertexCount - (t*3 + v) - 1, firstFrame); + subMesh->SetVertex(f, vertexIndex, vertex); } }