Added angleweighted smoothing of normals, by ryanclark.

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@1389 dfc29bdd-3216-0410-991c-e03cc46cb475
master
hybrid 2008-06-20 08:34:39 +00:00
parent 26682d0102
commit 05cdfb61ab
3 changed files with 32 additions and 11 deletions

View File

@ -52,13 +52,15 @@ namespace scene
//! Recalculates all normals of the mesh.
/** \param mesh: Mesh on which the operation is performed.
\param smooth: If the normals shall be smoothed. */
virtual void recalculateNormals(IMesh* mesh, bool smooth = false) const = 0;
\param smooth: If the normals shall be smoothed.
\param angleWeighted: If the normals shall be smoothed in relation to their angles. More expensive, but also higher precision. */
virtual void recalculateNormals(IMesh* mesh, bool smooth = false, bool angleWeighted = false) const = 0;
//! Recalculates all normals of the mesh buffer.
/** \param buffer: Mesh buffer on which the operation is performed.
\param smooth: If the normals shall be smoothed. */
virtual void recalculateNormals(IMeshBuffer* buffer, bool smooth = false) const = 0;
\param smooth: If the normals shall be smoothed.
\param angleWeighted: If the normals shall be smoothed in relation to their angles. More expensive, but also higher precision. */
virtual void recalculateNormals(IMeshBuffer* buffer, bool smooth = false, bool angleWeighted = false) const = 0;
//! Scales the whole mesh.
/** \param mesh: Mesh on which the operation is performed.

View File

@ -168,7 +168,7 @@ void CMeshManipulator::setVertexColors(IMesh* mesh, video::SColor color) const
//! Recalculates all normals of the mesh buffer.
/** \param buffer: Mesh buffer on which the operation is performed. */
void CMeshManipulator::recalculateNormals(IMeshBuffer* buffer, bool smooth) const
void CMeshManipulator::recalculateNormals(IMeshBuffer* buffer, bool smooth, bool angleWeighted) const
{
if (!buffer)
return;
@ -178,6 +178,7 @@ void CMeshManipulator::recalculateNormals(IMeshBuffer* buffer, bool smooth) cons
const u16* idx = buffer->getIndices();
if (!smooth)
{
for (u32 i=0; i<idxcnt; i+=3)
{
const core::vector3df& v1 = buffer->getPosition(idx[i+0]);
@ -188,6 +189,7 @@ void CMeshManipulator::recalculateNormals(IMeshBuffer* buffer, bool smooth) cons
buffer->getNormal(idx[i+1]) = normal;
buffer->getNormal(idx[i+2]) = normal;
}
}
else
{
u32 i;
@ -200,7 +202,25 @@ void CMeshManipulator::recalculateNormals(IMeshBuffer* buffer, bool smooth) cons
const core::vector3df& v1 = buffer->getPosition(idx[i+0]);
const core::vector3df& v2 = buffer->getPosition(idx[i+1]);
const core::vector3df& v3 = buffer->getPosition(idx[i+2]);
const core::vector3df normal = core::plane3d<f32>(v1, v2, v3).Normal;
core::vector3df normal = core::plane3d<f32>(v1, v2, v3).Normal;
if (angleWeighted)
{
// Calculate this triangle's weight for each of its three vertices
// start by calculating the lengths of its sides
const f32 a = v2.getDistanceFromSQ(v3);
const f32 asqrt = sqrtf(a);
const f32 b = v1.getDistanceFromSQ(v3);
const f32 bsqrt = sqrtf(b);
const f32 c = v1.getDistanceFromSQ(v2);
const f32 csqrt = sqrtf(c);
// use them to find the angle at each vertex
const core::vector3df weight(
acosf((b + c - a) / (2.f * bsqrt * csqrt)),
acosf((-b + c + a) / (2.f * asqrt * csqrt)),
acosf((b - c + a) / (2.f * bsqrt * asqrt)));
normal *= weight;
}
buffer->getNormal(idx[i+0]) += normal;
buffer->getNormal(idx[i+1]) += normal;
buffer->getNormal(idx[i+2]) += normal;
@ -212,17 +232,16 @@ void CMeshManipulator::recalculateNormals(IMeshBuffer* buffer, bool smooth) cons
}
//! Recalculates all normals of the mesh.
//! \param mesh: Mesh on which the operation is performed.
void CMeshManipulator::recalculateNormals(scene::IMesh* mesh, bool smooth) const
void CMeshManipulator::recalculateNormals(scene::IMesh* mesh, bool smooth, bool angleWeighted) const
{
if (!mesh)
return;
const u32 bcount = mesh->getMeshBufferCount();
for ( u32 b=0; b<bcount; ++b)
recalculateNormals(mesh->getMeshBuffer(b), smooth);
recalculateNormals(mesh->getMeshBuffer(b), smooth, angleWeighted);
}

View File

@ -40,12 +40,12 @@ public:
//! Recalculates all normals of the mesh.
/** \param mesh: Mesh on which the operation is performed.
\param smooth: Whether to use smoothed normals. */
virtual void recalculateNormals(scene::IMesh* mesh, bool smooth = false) const;
virtual void recalculateNormals(scene::IMesh* mesh, bool smooth = false, bool angleWeighted = false) const;
//! Recalculates all normals of the mesh buffer.
/** \param buffer: Mesh buffer on which the operation is performed.
\param smooth: Whether to use smoothed normals. */
virtual void recalculateNormals(IMeshBuffer* buffer, bool smooth = false) const;
virtual void recalculateNormals(IMeshBuffer* buffer, bool smooth = false, bool angleWeighted = false) const;
//! Scales the whole mesh.
//! \param mesh: Mesh on which the operation is performed.