New mesh policy

Former-commit-id: cc5854d55e1e4bb83e5e081434b87ec22fcb8bff
This commit is contained in:
Lynix 2013-03-02 00:17:40 +01:00
parent 347b267d43
commit 0df64e03ae
19 changed files with 132 additions and 209 deletions

View File

@ -16,7 +16,9 @@
struct NAZARA_API NzAnimationParams struct NAZARA_API NzAnimationParams
{ {
// La frame de fin à charger
unsigned int endFrame = static_cast<unsigned int>(-1); unsigned int endFrame = static_cast<unsigned int>(-1);
// La frame de début à charger
unsigned int startFrame = 0; unsigned int startFrame = 0;
bool IsValid() const; bool IsValid() const;

View File

@ -36,7 +36,7 @@
#define NAZARA_UTILITY_MEMORYLEAKTRACKER 0 #define NAZARA_UTILITY_MEMORYLEAKTRACKER 0
// Le skinning doit-il prendre avantage du multi-threading ? (Boost de performances sur les processeurs multi-coeurs) // Le skinning doit-il prendre avantage du multi-threading ? (Boost de performances sur les processeurs multi-coeurs)
#define NAZARA_UTILITY_MULTITHREADED_SKINNING 1 #define NAZARA_UTILITY_MULTITHREADED_SKINNING 0 ///FIXME: Bug du TaskScheduler
// Active les tests de sécurité basés sur le code (Conseillé pour le développement) // Active les tests de sécurité basés sur le code (Conseillé pour le développement)
#define NAZARA_UTILITY_SAFE 1 #define NAZARA_UTILITY_SAFE 1

View File

@ -37,9 +37,9 @@ class NAZARA_API NzKeyframeMesh final : public NzSubMesh
NzVector3f GetTangent(unsigned int frameIndex, unsigned int vertexIndex) const; NzVector3f GetTangent(unsigned int frameIndex, unsigned int vertexIndex) const;
NzVector2f GetTexCoords(unsigned int vertexIndex) const; NzVector2f GetTexCoords(unsigned int vertexIndex) const;
void GetVertex(unsigned int frameIndex, unsigned int vertexIndex, NzMeshVertex* dest) const; void GetVertex(unsigned int frameIndex, unsigned int vertexIndex, NzMeshVertex* dest) const;
NzVertexBuffer* GetVertexBuffer();
NzVertexBuffer* GetVertexBuffer() override; const NzVertexBuffer* GetVertexBuffer() const;
const NzVertexBuffer* GetVertexBuffer() const override; unsigned int GetVertexCount() const override;
void Interpolate(const NzAnimation* animation, unsigned int frameA, unsigned int frameB, float interpolation) const; void Interpolate(const NzAnimation* animation, unsigned int frameA, unsigned int frameB, float interpolation) const;

View File

@ -20,9 +20,12 @@
struct NAZARA_API NzMeshParams struct NAZARA_API NzMeshParams
{ {
NzMeshParams(); // Vérifie que le storage indiqué un peu plus bas est supporté NzMeshParams(); // Vérifie que le storage par défaut est supporté (software autrement)
// Si ceci sera le stockage choisi par le loader
nzBufferStorage storage = nzBufferStorage_Hardware; nzBufferStorage storage = nzBufferStorage_Hardware;
// Le loader doit-il charger une version animée du mesh si possible ?
bool animated = true; bool animated = true;
bool IsValid() const; bool IsValid() const;
@ -48,8 +51,6 @@ class NAZARA_API NzMesh : public NzResource, NzResourceListener
bool AddSubMesh(NzSubMesh* subMesh); bool AddSubMesh(NzSubMesh* subMesh);
bool AddSubMesh(const NzString& identifier, NzSubMesh* subMesh); bool AddSubMesh(const NzString& identifier, NzSubMesh* subMesh);
void Animate(const NzAnimation* animation, unsigned int frameA, unsigned int frameB, float interpolation, NzSkeleton* skeleton) const;
bool CreateKeyframe(); bool CreateKeyframe();
bool CreateSkeletal(unsigned int jointCount); bool CreateSkeletal(unsigned int jointCount);
bool CreateStatic(); bool CreateStatic();
@ -94,8 +95,6 @@ class NAZARA_API NzMesh : public NzResource, NzResourceListener
void SetMaterial(unsigned int matIndex, const NzString& materialPath); void SetMaterial(unsigned int matIndex, const NzString& materialPath);
void SetMaterialCount(unsigned int matCount); void SetMaterialCount(unsigned int matCount);
void Skin(const NzSkeleton* skeleton) const;
static const NzVertexDeclaration* GetDeclaration(); static const NzVertexDeclaration* GetDeclaration();
private: private:

View File

@ -263,7 +263,7 @@ inline nzUInt8 NzPixelFormat::GetBytesPerPixel(nzPixelFormat format)
#if NAZARA_UTILITY_SAFE #if NAZARA_UTILITY_SAFE
if (bytesPerPixel == 0) if (bytesPerPixel == 0)
NazaraWarning("This format is invalid or uses less than one byte per pixel"); NazaraWarning("This format is either invalid or using less than one byte per pixel");
#endif #endif
return bytesPerPixel; return bytesPerPixel;

View File

@ -32,7 +32,7 @@ class NAZARA_API NzSkeletalMesh final : public NzSubMesh
NzSkeletalMesh(const NzMesh* parent); NzSkeletalMesh(const NzMesh* parent);
virtual ~NzSkeletalMesh(); virtual ~NzSkeletalMesh();
bool Create(NzVertexBuffer* vertexBuffer, unsigned int weightCount); bool Create(unsigned int vertexCount, unsigned int weightCount);
void Destroy(); void Destroy();
void Finish(); void Finish();
@ -42,8 +42,7 @@ class NAZARA_API NzSkeletalMesh final : public NzSubMesh
void* GetBindPoseBuffer(); void* GetBindPoseBuffer();
const void* GetBindPoseBuffer() const; const void* GetBindPoseBuffer() const;
const NzIndexBuffer* GetIndexBuffer() const override; const NzIndexBuffer* GetIndexBuffer() const override;
NzVertexBuffer* GetVertexBuffer() override; unsigned int GetVertexCount() const override;
const NzVertexBuffer* GetVertexBuffer() const override;
NzVertexWeight* GetVertexWeight(unsigned int vertexIndex = 0); NzVertexWeight* GetVertexWeight(unsigned int vertexIndex = 0);
const NzVertexWeight* GetVertexWeight(unsigned int vertexIndex = 0) const; const NzVertexWeight* GetVertexWeight(unsigned int vertexIndex = 0) const;
NzWeight* GetWeight(unsigned int weightIndex = 0); NzWeight* GetWeight(unsigned int weightIndex = 0);
@ -53,8 +52,8 @@ class NAZARA_API NzSkeletalMesh final : public NzSubMesh
bool IsAnimated() const final; bool IsAnimated() const final;
bool IsValid() const; bool IsValid() const;
void Skin() const; void Skin(NzMeshVertex* outputBuffer) const;
void Skin(const NzSkeleton* skeleton) const; void Skin(NzMeshVertex* outputBuffer, const NzSkeleton* skeleton) const;
void SetIndexBuffer(const NzIndexBuffer* indexBuffer); void SetIndexBuffer(const NzIndexBuffer* indexBuffer);

View File

@ -27,8 +27,9 @@ class NAZARA_API NzStaticMesh final : public NzSubMesh, NzResourceListener
const NzCubef& GetAABB() const override; const NzCubef& GetAABB() const override;
nzAnimationType GetAnimationType() const final; nzAnimationType GetAnimationType() const final;
const NzIndexBuffer* GetIndexBuffer() const override; const NzIndexBuffer* GetIndexBuffer() const override;
NzVertexBuffer* GetVertexBuffer() override; NzVertexBuffer* GetVertexBuffer();
const NzVertexBuffer* GetVertexBuffer() const override; const NzVertexBuffer* GetVertexBuffer() const;
unsigned int GetVertexCount() const override;
bool IsAnimated() const final; bool IsAnimated() const final;
bool IsValid() const; bool IsValid() const;

View File

@ -33,9 +33,7 @@ class NAZARA_API NzSubMesh : public NzResource
unsigned int GetMaterialIndex() const; unsigned int GetMaterialIndex() const;
const NzMesh* GetParent() const; const NzMesh* GetParent() const;
nzPrimitiveType GetPrimitiveType() const; nzPrimitiveType GetPrimitiveType() const;
virtual NzVertexBuffer* GetVertexBuffer() = 0; virtual unsigned int GetVertexCount() const = 0;
virtual const NzVertexBuffer* GetVertexBuffer() const = 0;
virtual unsigned int GetVertexCount() const;
virtual bool IsAnimated() const = 0; virtual bool IsAnimated() const = 0;

View File

@ -350,6 +350,19 @@ const NzVertexBuffer* NzKeyframeMesh::GetVertexBuffer() const
return m_impl->vertexBuffer; return m_impl->vertexBuffer;
} }
unsigned int NzKeyframeMesh::GetVertexCount() const
{
#if NAZARA_UTILITY_SAFE
if (!m_impl)
{
NazaraError("Keyframe mesh not created");
return 0;
}
#endif
return m_impl->vertexBuffer->GetVertexCount();
}
void NzKeyframeMesh::Interpolate(const NzAnimation* animation, unsigned int frameA, unsigned int frameB, float interpolation) const void NzKeyframeMesh::Interpolate(const NzAnimation* animation, unsigned int frameA, unsigned int frameB, float interpolation) const
{ {
#if NAZARA_UTILITY_SAFE #if NAZARA_UTILITY_SAFE

View File

@ -239,7 +239,6 @@ bool NzMD5AnimParser::Parse(NzAnimation* animation)
} }
sequenceJoint.scale = NzVector3f(1.f, 1.f, 1.f); sequenceJoint.scale = NzVector3f(1.f, 1.f, 1.f);
} }
} }

View File

@ -203,10 +203,8 @@ bool NzMD5MeshParser::Parse(NzMesh* mesh)
indexMapper.Unmap(); indexMapper.Unmap();
std::unique_ptr<NzVertexBuffer> vertexBuffer(new NzVertexBuffer(NzMesh::GetDeclaration(), vertexCount, m_parameters.storage, nzBufferUsage_Dynamic));
std::unique_ptr<NzSkeletalMesh> subMesh(new NzSkeletalMesh(mesh)); std::unique_ptr<NzSkeletalMesh> subMesh(new NzSkeletalMesh(mesh));
if (!subMesh->Create(vertexBuffer.get(), weightCount)) if (!subMesh->Create(vertexCount, weightCount))
{ {
NazaraError("Failed to create skeletal mesh"); NazaraError("Failed to create skeletal mesh");
continue; continue;
@ -216,9 +214,6 @@ bool NzMD5MeshParser::Parse(NzMesh* mesh)
indexBuffer->SetPersistent(false); indexBuffer->SetPersistent(false);
indexBuffer.release(); indexBuffer.release();
vertexBuffer->SetPersistent(false);
vertexBuffer.release();
NzWeight* weights = subMesh->GetWeight(); NzWeight* weights = subMesh->GetWeight();
for (unsigned int j = 0; j < weightCount; ++j) for (unsigned int j = 0; j < weightCount; ++j)
{ {
@ -306,7 +301,7 @@ bool NzMD5MeshParser::Parse(NzMesh* mesh)
indexMapper.Unmap(); indexMapper.Unmap();
// Vertex buffer // Vertex buffer
std::unique_ptr<NzVertexBuffer> vertexBuffer(new NzVertexBuffer(NzMesh::GetDeclaration(), vertexCount, m_parameters.storage, nzBufferUsage_Dynamic)); std::unique_ptr<NzVertexBuffer> vertexBuffer(new NzVertexBuffer(NzMesh::GetDeclaration(), vertexCount, m_parameters.storage));
NzBufferMapper<NzVertexBuffer> vertexMapper(vertexBuffer.get(), nzBufferAccess_WriteOnly); NzBufferMapper<NzVertexBuffer> vertexMapper(vertexBuffer.get(), nzBufferAccess_WriteOnly);
NzMeshVertex* vertex = reinterpret_cast<NzMeshVertex*>(vertexMapper.GetPointer()); NzMeshVertex* vertex = reinterpret_cast<NzMeshVertex*>(vertexMapper.GetPointer());

View File

@ -131,85 +131,6 @@ bool NzMesh::AddSubMesh(const NzString& identifier, NzSubMesh* subMesh)
return true; return true;
} }
void NzMesh::Animate(const NzAnimation* animation, unsigned int frameA, unsigned int frameB, float interpolation, NzSkeleton* skeleton) const
{
#if NAZARA_UTILITY_SAFE
if (!m_impl)
{
NazaraError("Mesh not created");
return;
}
if (!animation || !animation->IsValid())
{
NazaraError("Animation must be valid");
return;
}
if (animation->GetType() != m_impl->animationType)
{
NazaraError("Animation type must match mesh animation type");
return;
}
unsigned int frameCount = animation->GetFrameCount();
if (frameA >= frameCount)
{
NazaraError("Frame A is out of range (" + NzString::Number(frameA) + " >= " + NzString::Number(frameCount) + ')');
return;
}
if (frameB >= frameCount)
{
NazaraError("Frame B is out of range (" + NzString::Number(frameB) + " >= " + NzString::Number(frameCount) + ')');
return;
}
#endif
#ifdef NAZARA_DEBUG
if (interpolation < 0.f || interpolation > 1.f)
{
NazaraError("Interpolation must be in range [0..1] (Got " + NzString::Number(interpolation) + ')');
return;
}
#endif
switch (m_impl->animationType)
{
case nzAnimationType_Keyframe:
for (NzSubMesh* subMesh : m_impl->subMeshes)
{
NzKeyframeMesh* keyframeMesh = static_cast<NzKeyframeMesh*>(subMesh);
keyframeMesh->InterpolateImpl(frameA, frameB, interpolation);
}
break;
case nzAnimationType_Skeletal:
#if NAZARA_UTILITY_SAFE
if (!skeleton)
{
NazaraError("Skeleton must be valid for skeletal animation");
return;
}
#endif
animation->AnimateSkeleton(skeleton, frameA, frameB, interpolation);
for (NzSubMesh* subMesh : m_impl->subMeshes)
{
NzSkeletalMesh* skeletalMesh = static_cast<NzSkeletalMesh*>(subMesh);
skeletalMesh->Skin(skeleton);
}
break;
case nzAnimationType_Static:
// Le safe mode est censé nous protéger de cet appel
NazaraInternalError("Static mesh has no animation, please enable safe mode");
break;
}
m_impl->aabbUpdated = false; // On invalide l'AABB
}
bool NzMesh::CreateKeyframe() bool NzMesh::CreateKeyframe()
{ {
Destroy(); Destroy();
@ -432,6 +353,8 @@ const NzCubef& NzMesh::GetAABB() const
if (!m_impl->aabbUpdated) if (!m_impl->aabbUpdated)
{ {
m_impl->aabb.MakeZero();
for (NzSubMesh* subMesh : m_impl->subMeshes) for (NzSubMesh* subMesh : m_impl->subMeshes)
m_impl->aabb.ExtendTo(subMesh->GetAABB()); m_impl->aabb.ExtendTo(subMesh->GetAABB());
@ -878,29 +801,6 @@ void NzMesh::SetMaterialCount(unsigned int matCount)
#endif #endif
} }
void NzMesh::Skin(const NzSkeleton* skeleton) const
{
#if NAZARA_UTILITY_SAFE
if (!m_impl)
{
NazaraError("Mesh not created");
return;
}
if (m_impl->animationType != nzAnimationType_Skeletal)
{
NazaraError("Mesh's animation type is not skeletal");
return;
}
#endif
for (NzSubMesh* subMesh : m_impl->subMeshes)
{
NzSkeletalMesh* skeletalMesh = static_cast<NzSkeletalMesh*>(subMesh);
skeletalMesh->Skin(skeleton);
}
}
const NzVertexDeclaration* NzMesh::GetDeclaration() const NzVertexDeclaration* NzMesh::GetDeclaration()
{ {
static NzVertexDeclaration declaration; static NzVertexDeclaration declaration;

View File

@ -17,7 +17,7 @@ m_derivedUpdated(false),
m_inheritPosition(true), m_inheritPosition(true),
m_inheritRotation(true), m_inheritRotation(true),
m_inheritScale(true), m_inheritScale(true),
m_matrixUpdated(false) m_transformMatrixUpdated(false)
{ {
} }
@ -33,7 +33,7 @@ m_derivedUpdated(false),
m_inheritPosition(node.m_inheritPosition), m_inheritPosition(node.m_inheritPosition),
m_inheritRotation(node.m_inheritRotation), m_inheritRotation(node.m_inheritRotation),
m_inheritScale(node.m_inheritScale), m_inheritScale(node.m_inheritScale),
m_matrixUpdated(false) m_transformMatrixUpdated(false)
{ {
if (m_parent) if (m_parent)
m_parent->AddChild(this); m_parent->AddChild(this);
@ -48,6 +48,23 @@ NzNode::~NzNode()
m_parent->RemoveChild(this); m_parent->RemoveChild(this);
} }
void NzNode::EnsureDerivedUpdate() const
{
if (!m_derivedUpdated)
UpdateDerived();
}
void NzNode::EnsureTransformMatrixUpdate() const
{
if (!m_transformMatrixUpdated)
UpdateTransformMatrix();
}
const std::vector<NzNode*>& NzNode::GetChilds() const
{
return m_childs;
}
bool NzNode::GetInheritPosition() const bool NzNode::GetInheritPosition() const
{ {
return m_inheritPosition; return m_inheritPosition;
@ -78,6 +95,11 @@ NzVector3f NzNode::GetInitialScale() const
return m_initialScale; return m_initialScale;
} }
nzNodeType NzNode::GetNodeType() const
{
return nzNodeType_Default;
}
const NzNode* NzNode::GetParent() const const NzNode* NzNode::GetParent() const
{ {
return m_parent; return m_parent;
@ -139,12 +161,17 @@ NzVector3f NzNode::GetScale(nzCoordSys coordSys) const
const NzMatrix4f& NzNode::GetTransformMatrix() const const NzMatrix4f& NzNode::GetTransformMatrix() const
{ {
if (!m_matrixUpdated) if (!m_transformMatrixUpdated)
UpdateMatrix(); UpdateTransformMatrix();
return m_transformMatrix; return m_transformMatrix;
} }
bool NzNode::HasChilds() const
{
return !m_childs.empty();
}
NzNode& NzNode::Interpolate(const NzNode& nodeA, const NzNode& nodeB, float interpolation) NzNode& NzNode::Interpolate(const NzNode& nodeA, const NzNode& nodeB, float interpolation)
{ {
m_position = NzVector3f::Lerp(nodeA.m_position, nodeB.m_position, interpolation); m_position = NzVector3f::Lerp(nodeA.m_position, nodeB.m_position, interpolation);
@ -166,7 +193,7 @@ NzNode& NzNode::Move(const NzVector3f& movement, nzCoordSys coordSys)
if (!m_parent->m_derivedUpdated) if (!m_parent->m_derivedUpdated)
m_parent->UpdateDerived(); m_parent->UpdateDerived();
m_position += (m_parent->m_derivedRotation.GetInverse() * movement) / m_parent->m_derivedPosition; // Compensation m_position += (m_parent->m_derivedRotation.GetConjugate()*(movement - m_parent->m_derivedPosition))/m_parent->m_derivedScale; // Compensation
} }
else else
m_position += movement; // Rien n'affecte le node m_position += movement; // Rien n'affecte le node
@ -201,7 +228,7 @@ NzNode& NzNode::Rotate(const NzQuaternionf& rotation, nzCoordSys coordSys)
if (!m_derivedUpdated) if (!m_derivedUpdated)
UpdateDerived(); UpdateDerived();
m_rotation *= m_derivedRotation.GetInverse() * q * m_derivedRotation; m_rotation *= m_derivedRotation.GetInverse() * q * m_derivedRotation; ///FIXME: Correct ?
break; break;
} }
@ -349,6 +376,8 @@ void NzNode::SetParent(const NzNode* node, bool keepDerived)
Invalidate(); Invalidate();
} }
OnParenting(node);
} }
void NzNode::SetParent(const NzNode& node, bool keepDerived) void NzNode::SetParent(const NzNode& node, bool keepDerived)
@ -461,33 +490,38 @@ NzNode& NzNode::operator=(const NzNode& node)
void NzNode::AddChild(NzNode* node) const void NzNode::AddChild(NzNode* node) const
{ {
auto pair = m_childs.insert(node);
if (pair.second)
node->Invalidate();
#ifdef NAZARA_DEBUG #ifdef NAZARA_DEBUG
else if (std::find(m_childs.begin(), m_childs.end(), node) != m_childs.end())
NazaraWarning("Child already in set"); {
NazaraWarning("Is already a child");
return;
}
#endif #endif
m_childs.push_back(node);
} }
void NzNode::Invalidate() void NzNode::Invalidate()
{ {
m_derivedUpdated = false; m_derivedUpdated = false;
m_matrixUpdated = false; m_transformMatrixUpdated = false;
for (NzNode* node : m_childs) for (NzNode* node : m_childs)
node->Invalidate(); node->Invalidate();
} }
void NzNode::OnParenting(const NzNode* parent)
{
NazaraUnused(parent);
}
void NzNode::RemoveChild(NzNode* node) const void NzNode::RemoveChild(NzNode* node) const
{ {
#ifdef NAZARA_DEBUG auto it = std::find(m_childs.begin(), m_childs.end(), node);
if (m_childs.erase(node) == 0) if (it != m_childs.end())
NazaraWarning("Child not found in set"); m_childs.erase(it);
#else else
m_childs.erase(node); NazaraWarning("Child not found");
#endif
} }
void NzNode::UpdateDerived() const void NzNode::UpdateDerived() const
@ -524,12 +558,11 @@ void NzNode::UpdateDerived() const
m_derivedUpdated = true; m_derivedUpdated = true;
} }
void NzNode::UpdateMatrix() const void NzNode::UpdateTransformMatrix() const
{ {
if (!m_derivedUpdated) if (!m_derivedUpdated)
UpdateDerived(); UpdateDerived();
m_transformMatrix.MakeTransform(m_derivedPosition, m_derivedScale, m_derivedRotation); m_transformMatrix.MakeTransform(m_derivedPosition, m_derivedScale, m_derivedRotation);
m_transformMatrixUpdated = true;
m_matrixUpdated = true;
} }

View File

@ -2,6 +2,8 @@
// This file is part of the "Nazara Engine - Utility module" // This file is part of the "Nazara Engine - Utility module"
// For conditions of distribution and use, see copyright notice in Config.hpp // For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/Clock.hpp>
#include <Nazara/Utility/SkeletalMesh.hpp> #include <Nazara/Utility/SkeletalMesh.hpp>
#include <Nazara/Core/TaskScheduler.hpp> #include <Nazara/Core/TaskScheduler.hpp>
#include <Nazara/Utility/BufferMapper.hpp> #include <Nazara/Utility/BufferMapper.hpp>
@ -135,7 +137,7 @@ struct NzSkeletalMeshImpl
NzCubef aabb; NzCubef aabb;
nzUInt8* bindPoseBuffer; nzUInt8* bindPoseBuffer;
const NzIndexBuffer* indexBuffer = nullptr; const NzIndexBuffer* indexBuffer = nullptr;
NzVertexBuffer* vertexBuffer; unsigned int vertexCount;
}; };
NzSkeletalMesh::NzSkeletalMesh(const NzMesh* parent) : NzSkeletalMesh::NzSkeletalMesh(const NzMesh* parent) :
@ -148,14 +150,14 @@ NzSkeletalMesh::~NzSkeletalMesh()
Destroy(); Destroy();
} }
bool NzSkeletalMesh::Create(NzVertexBuffer* vertexBuffer, unsigned int weightCount) bool NzSkeletalMesh::Create(unsigned int vertexCount, unsigned int weightCount)
{ {
Destroy(); Destroy();
#if NAZARA_UTILITY_SAFE #if NAZARA_UTILITY_SAFE
if (!vertexBuffer) if (vertexCount == 0)
{ {
NazaraError("Invalid vertex buffer"); NazaraError("Vertex count must be over 0");
return false; return false;
} }
@ -166,13 +168,9 @@ bool NzSkeletalMesh::Create(NzVertexBuffer* vertexBuffer, unsigned int weightCou
} }
#endif #endif
vertexBuffer->AddResourceReference();
unsigned int vertexCount = vertexBuffer->GetVertexCount();
m_impl = new NzSkeletalMeshImpl; m_impl = new NzSkeletalMeshImpl;
m_impl->bindPoseBuffer = new nzUInt8[vertexCount*vertexBuffer->GetTypeSize()]; m_impl->bindPoseBuffer = new nzUInt8[vertexCount*sizeof(NzMeshVertex)];
m_impl->vertexBuffer = vertexBuffer; m_impl->vertexCount = vertexCount;
m_impl->vertexWeights.resize(vertexCount); m_impl->vertexWeights.resize(vertexCount);
m_impl->weights.resize(weightCount); m_impl->weights.resize(weightCount);
@ -186,9 +184,6 @@ void NzSkeletalMesh::Destroy()
if (m_impl->indexBuffer) if (m_impl->indexBuffer)
m_impl->indexBuffer->RemoveResourceReference(); m_impl->indexBuffer->RemoveResourceReference();
if (m_impl->vertexBuffer)
m_impl->vertexBuffer->RemoveResourceReference();
delete[] m_impl->bindPoseBuffer; delete[] m_impl->bindPoseBuffer;
delete m_impl; delete m_impl;
m_impl = nullptr; m_impl = nullptr;
@ -205,7 +200,7 @@ void NzSkeletalMesh::Finish()
} }
#endif #endif
Skin(); // Rien à faire de particulier
} }
const NzCubef& NzSkeletalMesh::GetAABB() const const NzCubef& NzSkeletalMesh::GetAABB() const
@ -267,30 +262,17 @@ const NzIndexBuffer* NzSkeletalMesh::GetIndexBuffer() const
return m_impl->indexBuffer; return m_impl->indexBuffer;
} }
NzVertexBuffer* NzSkeletalMesh::GetVertexBuffer() unsigned int NzSkeletalMesh::GetVertexCount() const
{ {
#if NAZARA_UTILITY_SAFE #if NAZARA_UTILITY_SAFE
if (!m_impl) if (!m_impl)
{ {
NazaraError("Skeletal mesh not created"); NazaraError("Skeletal mesh not created");
return nullptr; return 0;
} }
#endif #endif
return m_impl->vertexBuffer; return m_impl->vertexCount;
}
const NzVertexBuffer* NzSkeletalMesh::GetVertexBuffer() const
{
#if NAZARA_UTILITY_SAFE
if (!m_impl)
{
NazaraError("Skeletal mesh not created");
return nullptr;
}
#endif
return m_impl->vertexBuffer;
} }
NzVertexWeight* NzSkeletalMesh::GetVertexWeight(unsigned int vertexIndex) NzVertexWeight* NzSkeletalMesh::GetVertexWeight(unsigned int vertexIndex)
@ -368,7 +350,7 @@ bool NzSkeletalMesh::IsValid() const
return m_impl != nullptr; return m_impl != nullptr;
} }
void NzSkeletalMesh::Skin() const void NzSkeletalMesh::Skin(NzMeshVertex* outputBuffer) const
{ {
#if NAZARA_UTILITY_SAFE #if NAZARA_UTILITY_SAFE
if (!m_impl) if (!m_impl)
@ -378,10 +360,10 @@ void NzSkeletalMesh::Skin() const
} }
#endif #endif
Skin(m_parent->GetSkeleton()); Skin(outputBuffer, m_parent->GetSkeleton());
} }
void NzSkeletalMesh::Skin(const NzSkeleton* skeleton) const void NzSkeletalMesh::Skin(NzMeshVertex* outputBuffer, const NzSkeleton* skeleton) const
{ {
#if NAZARA_UTILITY_SAFE #if NAZARA_UTILITY_SAFE
if (!m_impl) if (!m_impl)
@ -391,27 +373,27 @@ void NzSkeletalMesh::Skin(const NzSkeleton* skeleton) const
} }
#endif #endif
NzBufferMapper<NzVertexBuffer> mapper(m_impl->vertexBuffer, nzBufferAccess_DiscardAndWrite);
SkinningInfos skinningInfos; SkinningInfos skinningInfos;
skinningInfos.inputVertex = reinterpret_cast<const NzMeshVertex*>(m_impl->bindPoseBuffer); skinningInfos.inputVertex = reinterpret_cast<const NzMeshVertex*>(m_impl->bindPoseBuffer);
skinningInfos.outputVertex = reinterpret_cast<NzMeshVertex*>(mapper.GetPointer()); skinningInfos.outputVertex = outputBuffer;
skinningInfos.joints = skeleton->GetJoints(); skinningInfos.joints = skeleton->GetJoints();
skinningInfos.vertexWeights = &m_impl->vertexWeights[0]; skinningInfos.vertexWeights = &m_impl->vertexWeights[0];
skinningInfos.weights = &m_impl->weights[0]; skinningInfos.weights = &m_impl->weights[0];
unsigned int vertexCount = m_impl->vertexBuffer->GetVertexCount();
#if NAZARA_UTILITY_MULTITHREADED_SKINNING #if NAZARA_UTILITY_MULTITHREADED_SKINNING
unsigned int jointCount = skeleton->GetJointCount();
for (unsigned int i = 0; i < jointCount; ++i)
skinningInfos.joints[i].EnsureTransformMatrixUpdate();
unsigned int workerCount = NzTaskScheduler::GetWorkerCount(); unsigned int workerCount = NzTaskScheduler::GetWorkerCount();
std::ldiv_t div = std::ldiv(vertexCount, workerCount); // Qui sait, peut-être que ça permet des optimisations plus facilement std::ldiv_t div = std::ldiv(m_impl->vertexCount, workerCount); // Qui sait, peut-être que ça permet des optimisations plus efficaces
for (unsigned int i = 0; i < workerCount; ++i) for (unsigned int i = 0; i < workerCount; ++i)
NzTaskScheduler::AddTask(Skin_PositionNormalTangent, skinningInfos, i*div.quot, (i == workerCount-1) ? div.quot + div.rem : div.quot); NzTaskScheduler::AddTask(Skin_PositionNormalTangent, skinningInfos, i*div.quot, (i == workerCount-1) ? div.quot + div.rem : div.quot);
NzTaskScheduler::WaitForTasks(); NzTaskScheduler::WaitForTasks();
#else #else
Skin_PositionNormalTangent(skinningInfos, 0, vertexCount); Skin_PositionNormalTangent(skinningInfos, 0, m_impl->vertexCount);
#endif #endif
m_impl->aabb = skeleton->GetAABB(); m_impl->aabb = skeleton->GetAABB();

View File

@ -63,6 +63,8 @@ bool NzStaticMesh::GenerateAABB()
// On lock le buffer pour itérer sur toutes les positions et composer notre AABB // On lock le buffer pour itérer sur toutes les positions et composer notre AABB
NzBufferMapper<NzVertexBuffer> mapper(m_vertexBuffer, nzBufferAccess_ReadOnly); NzBufferMapper<NzVertexBuffer> mapper(m_vertexBuffer, nzBufferAccess_ReadOnly);
m_aabb.MakeZero();
NzMeshVertex* vertex = reinterpret_cast<NzMeshVertex*>(mapper.GetPointer()); NzMeshVertex* vertex = reinterpret_cast<NzMeshVertex*>(mapper.GetPointer());
unsigned int vertexCount = m_vertexBuffer->GetVertexCount(); unsigned int vertexCount = m_vertexBuffer->GetVertexCount();
for (unsigned int i = 0; i < vertexCount; ++i) for (unsigned int i = 0; i < vertexCount; ++i)
@ -99,6 +101,11 @@ const NzVertexBuffer* NzStaticMesh::GetVertexBuffer() const
return m_vertexBuffer; return m_vertexBuffer;
} }
unsigned int NzStaticMesh::GetVertexCount() const
{
return m_vertexBuffer->GetVertexCount();
}
bool NzStaticMesh::IsAnimated() const bool NzStaticMesh::IsAnimated() const
{ {
return false; return false;

View File

@ -34,11 +34,6 @@ unsigned int NzSubMesh::GetMaterialIndex() const
return m_matIndex; return m_matIndex;
} }
unsigned int NzSubMesh::GetVertexCount() const
{
return GetVertexBuffer()->GetVertexCount();
}
void NzSubMesh::SetPrimitiveType(nzPrimitiveType primitiveType) void NzSubMesh::SetPrimitiveType(nzPrimitiveType primitiveType)
{ {
m_primitiveType = primitiveType; m_primitiveType = primitiveType;

View File

@ -22,7 +22,7 @@ m_vertexMapper(subMesh)
if (indexBuffer) if (indexBuffer)
m_indexCount = indexBuffer->GetIndexCount(); m_indexCount = indexBuffer->GetIndexCount();
else else
m_indexCount = subMesh->GetVertexBuffer()->GetVertexCount(); m_indexCount = subMesh->GetVertexCount();
} }
bool NzTriangleIterator::Advance() bool NzTriangleIterator::Advance()

View File

@ -59,10 +59,10 @@ namespace
class KeyframeMeshVertexMapper : public SubMeshVertexMapper class KeyframeMeshVertexMapper : public SubMeshVertexMapper
{ {
public: public:
KeyframeMeshVertexMapper(NzSubMesh* subMesh) : KeyframeMeshVertexMapper(NzKeyframeMesh* subMesh) :
SubMeshVertexMapper(subMesh) SubMeshVertexMapper(subMesh),
m_mesh(subMesh)
{ {
m_mesh = static_cast<NzKeyframeMesh*>(subMesh);
m_vertexPerFrame = m_mesh->GetVertexCount(); m_vertexPerFrame = m_mesh->GetVertexCount();
} }
@ -123,10 +123,10 @@ namespace
class SkeletalMeshVertexMapper : public SubMeshVertexMapper class SkeletalMeshVertexMapper : public SubMeshVertexMapper
{ {
public: public:
SkeletalMeshVertexMapper(NzSubMesh* subMesh) : SkeletalMeshVertexMapper(NzSkeletalMesh* subMesh) :
SubMeshVertexMapper(subMesh) SubMeshVertexMapper(subMesh),
m_mesh(subMesh)
{ {
m_mesh = static_cast<NzSkeletalMesh*>(subMesh);
m_vertices = reinterpret_cast<NzMeshVertex*>(m_mesh->GetBindPoseBuffer()); m_vertices = reinterpret_cast<NzMeshVertex*>(m_mesh->GetBindPoseBuffer());
m_mesh->AddResourceReference(); m_mesh->AddResourceReference();
@ -190,7 +190,7 @@ namespace
class StaticMeshVertexMapper : public SubMeshVertexMapper class StaticMeshVertexMapper : public SubMeshVertexMapper
{ {
public: public:
StaticMeshVertexMapper(NzSubMesh* subMesh) : StaticMeshVertexMapper(NzStaticMesh* subMesh) :
SubMeshVertexMapper(subMesh), SubMeshVertexMapper(subMesh),
m_vertexMapper(subMesh->GetVertexBuffer(), nzBufferAccess_ReadWrite) m_vertexMapper(subMesh->GetVertexBuffer(), nzBufferAccess_ReadWrite)
{ {
@ -257,15 +257,15 @@ NzVertexMapper::NzVertexMapper(NzSubMesh* subMesh)
switch (subMesh->GetAnimationType()) switch (subMesh->GetAnimationType())
{ {
case nzAnimationType_Keyframe: case nzAnimationType_Keyframe:
m_impl = new KeyframeMeshVertexMapper(subMesh); m_impl = new KeyframeMeshVertexMapper(static_cast<NzKeyframeMesh*>(subMesh));
break; break;
case nzAnimationType_Skeletal: case nzAnimationType_Skeletal:
m_impl = new SkeletalMeshVertexMapper(subMesh); m_impl = new SkeletalMeshVertexMapper(static_cast<NzSkeletalMesh*>(subMesh));
break; break;
case nzAnimationType_Static: case nzAnimationType_Static:
m_impl = new StaticMeshVertexMapper(subMesh); m_impl = new StaticMeshVertexMapper(static_cast<NzStaticMesh*>(subMesh));
break; break;
} }
#ifdef NAZARA_DEBUG #ifdef NAZARA_DEBUG