Moved normal/tangents generation to submeshes
Former-commit-id: d043284a1a5810b429cc76d8bc071010985a523b
This commit is contained in:
parent
83b6e429f8
commit
ad978dc85a
|
|
@ -40,8 +40,6 @@ class NAZARA_API NzSkeletalMesh final : public NzSubMesh
|
||||||
bool Create(unsigned int vertexCount, unsigned int weightCount);
|
bool Create(unsigned int vertexCount, unsigned int weightCount);
|
||||||
void Destroy();
|
void Destroy();
|
||||||
|
|
||||||
void Finish();
|
|
||||||
|
|
||||||
const NzCubef& GetAABB() const;
|
const NzCubef& GetAABB() const;
|
||||||
nzAnimationType GetAnimationType() const final;
|
nzAnimationType GetAnimationType() const final;
|
||||||
void* GetBindPoseBuffer();
|
void* GetBindPoseBuffer();
|
||||||
|
|
|
||||||
|
|
@ -25,8 +25,6 @@ class NAZARA_API NzStaticMesh final : public NzSubMesh, NzResourceListener
|
||||||
bool Create(NzVertexBuffer* vertexBuffer);
|
bool Create(NzVertexBuffer* vertexBuffer);
|
||||||
void Destroy();
|
void Destroy();
|
||||||
|
|
||||||
void Finish();
|
|
||||||
|
|
||||||
bool GenerateAABB();
|
bool GenerateAABB();
|
||||||
|
|
||||||
const NzCubef& GetAABB() const override;
|
const NzCubef& GetAABB() const override;
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,9 @@ class NAZARA_API NzSubMesh : public NzResource
|
||||||
NzSubMesh(const NzMesh* parent);
|
NzSubMesh(const NzMesh* parent);
|
||||||
virtual ~NzSubMesh();
|
virtual ~NzSubMesh();
|
||||||
|
|
||||||
virtual void Finish() = 0; ///DOC: Mets le mesh dans sa position d'origine et calcule son AABB
|
void GenerateNormals();
|
||||||
|
void GenerateNormalsAndTangents();
|
||||||
|
void GenerateTangents();
|
||||||
|
|
||||||
virtual const NzCubef& GetAABB() const = 0;
|
virtual const NzCubef& GetAABB() const = 0;
|
||||||
virtual nzAnimationType GetAnimationType() const = 0;
|
virtual nzAnimationType GetAnimationType() const = 0;
|
||||||
|
|
|
||||||
|
|
@ -214,11 +214,11 @@ namespace
|
||||||
vertexBuffer->SetPersistent(false);
|
vertexBuffer->SetPersistent(false);
|
||||||
vertexBuffer.release();
|
vertexBuffer.release();
|
||||||
|
|
||||||
|
subMesh->GenerateAABB();
|
||||||
|
subMesh->GenerateTangents();
|
||||||
subMesh->SetMaterialIndex(0);
|
subMesh->SetMaterialIndex(0);
|
||||||
mesh->AddSubMesh(subMesh.release());
|
mesh->AddSubMesh(subMesh.release());
|
||||||
|
|
||||||
mesh->GenerateTangents();
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -343,6 +343,7 @@ bool NzMD5MeshParser::Parse(NzMesh* mesh)
|
||||||
|
|
||||||
// Material
|
// Material
|
||||||
mesh->SetMaterial(i, baseDir + md5Mesh.shader);
|
mesh->SetMaterial(i, baseDir + md5Mesh.shader);
|
||||||
|
subMesh->GenerateNormalsAndTangents();
|
||||||
subMesh->SetMaterialIndex(i);
|
subMesh->SetMaterialIndex(i);
|
||||||
|
|
||||||
if (!mesh->AddSubMesh(subMesh.get()))
|
if (!mesh->AddSubMesh(subMesh.get()))
|
||||||
|
|
@ -355,8 +356,6 @@ bool NzMD5MeshParser::Parse(NzMesh* mesh)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mesh->GenerateNormalsAndTangents();
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,6 @@
|
||||||
#include <Nazara/Utility/SkeletalMesh.hpp>
|
#include <Nazara/Utility/SkeletalMesh.hpp>
|
||||||
#include <Nazara/Utility/Skeleton.hpp>
|
#include <Nazara/Utility/Skeleton.hpp>
|
||||||
#include <Nazara/Utility/SubMesh.hpp>
|
#include <Nazara/Utility/SubMesh.hpp>
|
||||||
#include <Nazara/Utility/TriangleIterator.hpp>
|
|
||||||
#include <Nazara/Utility/VertexMapper.hpp>
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <deque>
|
#include <deque>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
@ -75,7 +73,6 @@ bool NzMesh::AddSubMesh(NzSubMesh* subMesh)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
subMesh->AddResourceListener(this, m_impl->subMeshes.size());
|
subMesh->AddResourceListener(this, m_impl->subMeshes.size());
|
||||||
subMesh->Finish();
|
|
||||||
|
|
||||||
m_impl->aabbUpdated = false; // On invalide l'AABB
|
m_impl->aabbUpdated = false; // On invalide l'AABB
|
||||||
m_impl->subMeshes.push_back(subMesh);
|
m_impl->subMeshes.push_back(subMesh);
|
||||||
|
|
@ -121,7 +118,6 @@ bool NzMesh::AddSubMesh(const NzString& identifier, NzSubMesh* subMesh)
|
||||||
int index = m_impl->subMeshes.size();
|
int index = m_impl->subMeshes.size();
|
||||||
|
|
||||||
subMesh->AddResourceListener(this, index);
|
subMesh->AddResourceListener(this, index);
|
||||||
subMesh->Finish();
|
|
||||||
|
|
||||||
m_impl->aabbUpdated = false; // On invalide l'AABB
|
m_impl->aabbUpdated = false; // On invalide l'AABB
|
||||||
m_impl->subMeshes.push_back(subMesh);
|
m_impl->subMeshes.push_back(subMesh);
|
||||||
|
|
@ -185,34 +181,7 @@ void NzMesh::GenerateNormals()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (NzSubMesh* subMesh : m_impl->subMeshes)
|
for (NzSubMesh* subMesh : m_impl->subMeshes)
|
||||||
{
|
subMesh->GenerateNormals();
|
||||||
NzVertexMapper mapper1(subMesh);
|
|
||||||
unsigned int vertexCount = mapper1.GetVertexCount();
|
|
||||||
for (unsigned int i = 0; i < vertexCount; ++i)
|
|
||||||
mapper1.SetNormal(i, NzVector3f::Zero());
|
|
||||||
|
|
||||||
mapper1.Unmap();
|
|
||||||
|
|
||||||
NzTriangleIterator iterator(subMesh);
|
|
||||||
do
|
|
||||||
{
|
|
||||||
NzVector3f pos0 = iterator.GetPosition(0);
|
|
||||||
|
|
||||||
NzVector3f dv[2];
|
|
||||||
dv[0] = iterator.GetPosition(1) - pos0;
|
|
||||||
dv[1] = iterator.GetPosition(2) - pos0;
|
|
||||||
|
|
||||||
NzVector3f normal = dv[0].CrossProduct(dv[1]);
|
|
||||||
|
|
||||||
for (unsigned int i = 0; i < 3; ++i)
|
|
||||||
iterator.SetNormal(i, iterator.GetNormal(i) + normal);
|
|
||||||
}
|
|
||||||
while (iterator.Advance());
|
|
||||||
|
|
||||||
NzVertexMapper mapper2(subMesh);
|
|
||||||
for (unsigned int i = 0; i < vertexCount; ++i)
|
|
||||||
mapper2.SetNormal(i, NzVector3f::Normalize(mapper2.GetNormal(i)));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void NzMesh::GenerateNormalsAndTangents()
|
void NzMesh::GenerateNormalsAndTangents()
|
||||||
|
|
@ -226,55 +195,7 @@ void NzMesh::GenerateNormalsAndTangents()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (NzSubMesh* subMesh : m_impl->subMeshes)
|
for (NzSubMesh* subMesh : m_impl->subMeshes)
|
||||||
{
|
subMesh->GenerateNormalsAndTangents();
|
||||||
NzVertexMapper mapper1(subMesh);
|
|
||||||
unsigned int vertexCount = mapper1.GetVertexCount();
|
|
||||||
for (unsigned int i = 0; i < vertexCount; ++i)
|
|
||||||
{
|
|
||||||
mapper1.SetNormal(i, NzVector3f::Zero());
|
|
||||||
mapper1.SetTangent(i, NzVector3f::Zero());
|
|
||||||
}
|
|
||||||
|
|
||||||
mapper1.Unmap();
|
|
||||||
|
|
||||||
NzTriangleIterator iterator(subMesh);
|
|
||||||
do
|
|
||||||
{
|
|
||||||
NzVector3f pos0 = iterator.GetPosition(0);
|
|
||||||
NzVector2f uv0 = iterator.GetTexCoords(0);
|
|
||||||
|
|
||||||
NzVector3f dv[2];
|
|
||||||
dv[0] = iterator.GetPosition(1) - pos0;
|
|
||||||
dv[1] = iterator.GetPosition(2) - pos0;
|
|
||||||
|
|
||||||
NzVector3f normal = dv[0].CrossProduct(dv[1]);
|
|
||||||
|
|
||||||
NzVector2f duv[2];
|
|
||||||
duv[0] = iterator.GetTexCoords(1) - uv0;
|
|
||||||
duv[1] = iterator.GetTexCoords(2) - uv0;
|
|
||||||
|
|
||||||
float coef = 1.f / (duv[0].x*duv[1].y - duv[1].x*duv[0].y);
|
|
||||||
|
|
||||||
NzVector3f tangent;
|
|
||||||
tangent.x = coef * (dv[0].x*duv[1].y + dv[1].x*(-duv[0].y));
|
|
||||||
tangent.y = coef * (dv[0].y*duv[1].y + dv[1].y*(-duv[0].y));
|
|
||||||
tangent.z = coef * (dv[0].z*duv[1].y + dv[1].z*(-duv[0].y));
|
|
||||||
|
|
||||||
for (unsigned int i = 0; i < 3; ++i)
|
|
||||||
{
|
|
||||||
iterator.SetNormal(i, iterator.GetNormal(i) + normal);
|
|
||||||
iterator.SetTangent(i, iterator.GetTangent(i) + tangent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while (iterator.Advance());
|
|
||||||
|
|
||||||
NzVertexMapper mapper2(subMesh);
|
|
||||||
for (unsigned int i = 0; i < vertexCount; ++i)
|
|
||||||
{
|
|
||||||
mapper2.SetNormal(i, NzVector3f::Normalize(mapper2.GetNormal(i)));
|
|
||||||
mapper2.SetTangent(i, NzVector3f::Normalize(mapper2.GetTangent(i)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void NzMesh::GenerateTangents()
|
void NzMesh::GenerateTangents()
|
||||||
|
|
@ -288,43 +209,7 @@ void NzMesh::GenerateTangents()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (NzSubMesh* subMesh : m_impl->subMeshes)
|
for (NzSubMesh* subMesh : m_impl->subMeshes)
|
||||||
{
|
subMesh->GenerateTangents();
|
||||||
NzTriangleIterator iterator(subMesh);
|
|
||||||
do
|
|
||||||
{
|
|
||||||
NzVector3f pos0 = iterator.GetPosition(0);
|
|
||||||
NzVector2f uv0 = iterator.GetTexCoords(0);
|
|
||||||
|
|
||||||
NzVector3f dv[2];
|
|
||||||
dv[0] = iterator.GetPosition(1) - pos0;
|
|
||||||
dv[1] = iterator.GetPosition(2) - pos0;
|
|
||||||
|
|
||||||
NzVector2f duv[2];
|
|
||||||
duv[0] = iterator.GetTexCoords(1) - uv0;
|
|
||||||
duv[1] = iterator.GetTexCoords(2) - uv0;
|
|
||||||
|
|
||||||
float ds[2];
|
|
||||||
ds[0] = iterator.GetTexCoords(1).x - uv0.x;
|
|
||||||
ds[1] = iterator.GetTexCoords(2).x - uv0.x;
|
|
||||||
|
|
||||||
NzVector3f ppt;
|
|
||||||
ppt.x = ds[0]*dv[1].x - dv[0].x*ds[1];
|
|
||||||
ppt.y = ds[0]*dv[1].y - dv[0].y*ds[1];
|
|
||||||
ppt.z = ds[0]*dv[1].z - dv[0].z*ds[1];
|
|
||||||
ppt.Normalize();
|
|
||||||
|
|
||||||
for (unsigned int i = 0; i < 3; ++i)
|
|
||||||
{
|
|
||||||
NzVector3f normal = iterator.GetNormal(i);
|
|
||||||
float d = ppt.DotProduct(normal);
|
|
||||||
|
|
||||||
NzVector3f tangent = ppt - (d * normal);
|
|
||||||
|
|
||||||
iterator.SetTangent(i, tangent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while (iterator.Advance());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const NzCubef& NzMesh::GetAABB() const
|
const NzCubef& NzMesh::GetAABB() const
|
||||||
|
|
|
||||||
|
|
@ -187,19 +187,6 @@ void NzSkeletalMesh::Destroy()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NzSkeletalMesh::Finish()
|
|
||||||
{
|
|
||||||
#if NAZARA_UTILITY_SAFE
|
|
||||||
if (!m_impl)
|
|
||||||
{
|
|
||||||
NazaraError("Skeletal mesh not created");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Rien à faire de particulier
|
|
||||||
}
|
|
||||||
|
|
||||||
const NzCubef& NzSkeletalMesh::GetAABB() const
|
const NzCubef& NzSkeletalMesh::GetAABB() const
|
||||||
{
|
{
|
||||||
#if NAZARA_UTILITY_SAFE
|
#if NAZARA_UTILITY_SAFE
|
||||||
|
|
|
||||||
|
|
@ -52,12 +52,6 @@ void NzStaticMesh::Destroy()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NzStaticMesh::Finish()
|
|
||||||
{
|
|
||||||
// La seule chose à faire ici est de calculer l'AABB
|
|
||||||
GenerateAABB();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool NzStaticMesh::GenerateAABB()
|
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
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,8 @@
|
||||||
#include <Nazara/Core/String.hpp>
|
#include <Nazara/Core/String.hpp>
|
||||||
#include <Nazara/Utility/Config.hpp>
|
#include <Nazara/Utility/Config.hpp>
|
||||||
#include <Nazara/Utility/Mesh.hpp>
|
#include <Nazara/Utility/Mesh.hpp>
|
||||||
|
#include <Nazara/Utility/TriangleIterator.hpp>
|
||||||
|
#include <Nazara/Utility/VertexMapper.hpp>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <Nazara/Utility/Debug.hpp>
|
#include <Nazara/Utility/Debug.hpp>
|
||||||
|
|
||||||
|
|
@ -19,6 +21,126 @@ m_matIndex(0)
|
||||||
|
|
||||||
NzSubMesh::~NzSubMesh() = default;
|
NzSubMesh::~NzSubMesh() = default;
|
||||||
|
|
||||||
|
void NzSubMesh::GenerateNormals()
|
||||||
|
{
|
||||||
|
NzVertexMapper mapper1(this);
|
||||||
|
unsigned int vertexCount = mapper1.GetVertexCount();
|
||||||
|
for (unsigned int i = 0; i < vertexCount; ++i)
|
||||||
|
mapper1.SetNormal(i, NzVector3f::Zero());
|
||||||
|
|
||||||
|
mapper1.Unmap();
|
||||||
|
|
||||||
|
NzTriangleIterator iterator(this);
|
||||||
|
do
|
||||||
|
{
|
||||||
|
NzVector3f pos0 = iterator.GetPosition(0);
|
||||||
|
|
||||||
|
NzVector3f dv[2];
|
||||||
|
dv[0] = iterator.GetPosition(1) - pos0;
|
||||||
|
dv[1] = iterator.GetPosition(2) - pos0;
|
||||||
|
|
||||||
|
NzVector3f normal = dv[0].CrossProduct(dv[1]);
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < 3; ++i)
|
||||||
|
iterator.SetNormal(i, iterator.GetNormal(i) + normal);
|
||||||
|
}
|
||||||
|
while (iterator.Advance());
|
||||||
|
|
||||||
|
NzVertexMapper mapper2(this);
|
||||||
|
for (unsigned int i = 0; i < vertexCount; ++i)
|
||||||
|
mapper2.SetNormal(i, NzVector3f::Normalize(mapper2.GetNormal(i)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void NzSubMesh::GenerateNormalsAndTangents()
|
||||||
|
{
|
||||||
|
NzVertexMapper mapper1(this);
|
||||||
|
unsigned int vertexCount = mapper1.GetVertexCount();
|
||||||
|
for (unsigned int i = 0; i < vertexCount; ++i)
|
||||||
|
{
|
||||||
|
mapper1.SetNormal(i, NzVector3f::Zero());
|
||||||
|
mapper1.SetTangent(i, NzVector3f::Zero());
|
||||||
|
}
|
||||||
|
|
||||||
|
mapper1.Unmap();
|
||||||
|
|
||||||
|
NzTriangleIterator iterator(this);
|
||||||
|
do
|
||||||
|
{
|
||||||
|
NzVector3f pos0 = iterator.GetPosition(0);
|
||||||
|
NzVector2f uv0 = iterator.GetTexCoord(0);
|
||||||
|
|
||||||
|
NzVector3f dv[2];
|
||||||
|
dv[0] = iterator.GetPosition(1) - pos0;
|
||||||
|
dv[1] = iterator.GetPosition(2) - pos0;
|
||||||
|
|
||||||
|
NzVector3f normal = dv[0].CrossProduct(dv[1]);
|
||||||
|
|
||||||
|
NzVector2f duv[2];
|
||||||
|
duv[0] = iterator.GetTexCoord(1) - uv0;
|
||||||
|
duv[1] = iterator.GetTexCoord(2) - uv0;
|
||||||
|
|
||||||
|
float coef = 1.f / (duv[0].x*duv[1].y - duv[1].x*duv[0].y);
|
||||||
|
|
||||||
|
NzVector3f tangent;
|
||||||
|
tangent.x = coef * (dv[0].x*duv[1].y + dv[1].x*(-duv[0].y));
|
||||||
|
tangent.y = coef * (dv[0].y*duv[1].y + dv[1].y*(-duv[0].y));
|
||||||
|
tangent.z = coef * (dv[0].z*duv[1].y + dv[1].z*(-duv[0].y));
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < 3; ++i)
|
||||||
|
{
|
||||||
|
iterator.SetNormal(i, iterator.GetNormal(i) + normal);
|
||||||
|
iterator.SetTangent(i, iterator.GetTangent(i) + tangent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (iterator.Advance());
|
||||||
|
|
||||||
|
NzVertexMapper mapper2(this);
|
||||||
|
for (unsigned int i = 0; i < vertexCount; ++i)
|
||||||
|
{
|
||||||
|
mapper2.SetNormal(i, NzVector3f::Normalize(mapper2.GetNormal(i)));
|
||||||
|
mapper2.SetTangent(i, NzVector3f::Normalize(mapper2.GetTangent(i)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NzSubMesh::GenerateTangents()
|
||||||
|
{
|
||||||
|
NzTriangleIterator iterator(this);
|
||||||
|
do
|
||||||
|
{
|
||||||
|
NzVector3f pos0 = iterator.GetPosition(0);
|
||||||
|
NzVector2f uv0 = iterator.GetTexCoord(0);
|
||||||
|
|
||||||
|
NzVector3f dv[2];
|
||||||
|
dv[0] = iterator.GetPosition(1) - pos0;
|
||||||
|
dv[1] = iterator.GetPosition(2) - pos0;
|
||||||
|
|
||||||
|
NzVector2f duv[2];
|
||||||
|
duv[0] = iterator.GetTexCoord(1) - uv0;
|
||||||
|
duv[1] = iterator.GetTexCoord(2) - uv0;
|
||||||
|
|
||||||
|
float ds[2];
|
||||||
|
ds[0] = iterator.GetTexCoord(1).x - uv0.x;
|
||||||
|
ds[1] = iterator.GetTexCoord(2).x - uv0.x;
|
||||||
|
|
||||||
|
NzVector3f ppt;
|
||||||
|
ppt.x = ds[0]*dv[1].x - dv[0].x*ds[1];
|
||||||
|
ppt.y = ds[0]*dv[1].y - dv[0].y*ds[1];
|
||||||
|
ppt.z = ds[0]*dv[1].z - dv[0].z*ds[1];
|
||||||
|
ppt.Normalize();
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < 3; ++i)
|
||||||
|
{
|
||||||
|
NzVector3f normal = iterator.GetNormal(i);
|
||||||
|
float d = ppt.DotProduct(normal);
|
||||||
|
|
||||||
|
NzVector3f tangent = ppt - (d * normal);
|
||||||
|
|
||||||
|
iterator.SetTangent(i, tangent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (iterator.Advance());
|
||||||
|
}
|
||||||
|
|
||||||
const NzMesh* NzSubMesh::GetParent() const
|
const NzMesh* NzSubMesh::GetParent() const
|
||||||
{
|
{
|
||||||
return m_parent;
|
return m_parent;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue