Added mesh generation of normals and tangents
Former-commit-id: 42b29acf5701b19156d6966b402baf11c87f3476
This commit is contained in:
parent
cf47081224
commit
85c3224752
|
|
@ -55,6 +55,10 @@ class NAZARA_API NzMesh : public NzResource, NzResourceListener
|
|||
bool CreateStatic();
|
||||
void Destroy();
|
||||
|
||||
void GenerateNormals();
|
||||
void GenerateNormalsAndTangents();
|
||||
void GenerateTangents();
|
||||
|
||||
const NzAxisAlignedBox& GetAABB() const;
|
||||
NzString GetAnimation() const;
|
||||
nzAnimationType GetAnimationType() const;
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@
|
|||
#include <Nazara/Utility/SkeletalMesh.hpp>
|
||||
#include <Nazara/Utility/Skeleton.hpp>
|
||||
#include <Nazara/Utility/SubMesh.hpp>
|
||||
#include <Nazara/Utility/TriangleIterator.hpp>
|
||||
#include <Nazara/Utility/VertexMapper.hpp>
|
||||
#include <cstring>
|
||||
#include <deque>
|
||||
#include <map>
|
||||
|
|
@ -262,6 +264,159 @@ void NzMesh::Destroy()
|
|||
}
|
||||
}
|
||||
|
||||
void NzMesh::GenerateNormals()
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Mesh not created");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
for (NzSubMesh* subMesh : m_impl->subMeshes)
|
||||
{
|
||||
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()
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Mesh not created");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
for (NzSubMesh* subMesh : m_impl->subMeshes)
|
||||
{
|
||||
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()
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Mesh not created");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
for (NzSubMesh* subMesh : m_impl->subMeshes)
|
||||
{
|
||||
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 NzAxisAlignedBox& NzMesh::GetAABB() const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
|
|
|
|||
Loading…
Reference in New Issue