Commit 05cdfb61 authored by hybrid's avatar hybrid

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
parent 26682d01
...@@ -52,13 +52,15 @@ namespace scene ...@@ -52,13 +52,15 @@ namespace scene
//! Recalculates all normals of the mesh. //! Recalculates all normals of the mesh.
/** \param mesh: Mesh on which the operation is performed. /** \param mesh: Mesh on which the operation is performed.
\param smooth: If the normals shall be smoothed. */ \param smooth: If the normals shall be smoothed.
virtual void recalculateNormals(IMesh* mesh, bool smooth = false) const = 0; \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. //! Recalculates all normals of the mesh buffer.
/** \param buffer: Mesh buffer on which the operation is performed. /** \param buffer: Mesh buffer on which the operation is performed.
\param smooth: If the normals shall be smoothed. */ \param smooth: If the normals shall be smoothed.
virtual void recalculateNormals(IMeshBuffer* buffer, bool smooth = false) const = 0; \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. //! Scales the whole mesh.
/** \param mesh: Mesh on which the operation is performed. /** \param mesh: Mesh on which the operation is performed.
......
...@@ -168,7 +168,7 @@ void CMeshManipulator::setVertexColors(IMesh* mesh, video::SColor color) const ...@@ -168,7 +168,7 @@ void CMeshManipulator::setVertexColors(IMesh* mesh, video::SColor color) const
//! Recalculates all normals of the mesh buffer. //! Recalculates all normals of the mesh buffer.
/** \param buffer: Mesh buffer on which the operation is performed. */ /** \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) if (!buffer)
return; return;
...@@ -178,6 +178,7 @@ void CMeshManipulator::recalculateNormals(IMeshBuffer* buffer, bool smooth) cons ...@@ -178,6 +178,7 @@ void CMeshManipulator::recalculateNormals(IMeshBuffer* buffer, bool smooth) cons
const u16* idx = buffer->getIndices(); const u16* idx = buffer->getIndices();
if (!smooth) if (!smooth)
{
for (u32 i=0; i<idxcnt; i+=3) for (u32 i=0; i<idxcnt; i+=3)
{ {
const core::vector3df& v1 = buffer->getPosition(idx[i+0]); const core::vector3df& v1 = buffer->getPosition(idx[i+0]);
...@@ -188,6 +189,7 @@ void CMeshManipulator::recalculateNormals(IMeshBuffer* buffer, bool smooth) cons ...@@ -188,6 +189,7 @@ void CMeshManipulator::recalculateNormals(IMeshBuffer* buffer, bool smooth) cons
buffer->getNormal(idx[i+1]) = normal; buffer->getNormal(idx[i+1]) = normal;
buffer->getNormal(idx[i+2]) = normal; buffer->getNormal(idx[i+2]) = normal;
} }
}
else else
{ {
u32 i; u32 i;
...@@ -200,7 +202,25 @@ void CMeshManipulator::recalculateNormals(IMeshBuffer* buffer, bool smooth) cons ...@@ -200,7 +202,25 @@ void CMeshManipulator::recalculateNormals(IMeshBuffer* buffer, bool smooth) cons
const core::vector3df& v1 = buffer->getPosition(idx[i+0]); const core::vector3df& v1 = buffer->getPosition(idx[i+0]);
const core::vector3df& v2 = buffer->getPosition(idx[i+1]); const core::vector3df& v2 = buffer->getPosition(idx[i+1]);
const core::vector3df& v3 = buffer->getPosition(idx[i+2]); 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+0]) += normal;
buffer->getNormal(idx[i+1]) += normal; buffer->getNormal(idx[i+1]) += normal;
buffer->getNormal(idx[i+2]) += normal; buffer->getNormal(idx[i+2]) += normal;
...@@ -212,17 +232,16 @@ void CMeshManipulator::recalculateNormals(IMeshBuffer* buffer, bool smooth) cons ...@@ -212,17 +232,16 @@ void CMeshManipulator::recalculateNormals(IMeshBuffer* buffer, bool smooth) cons
} }
//! Recalculates all normals of the mesh. //! Recalculates all normals of the mesh.
//! \param mesh: Mesh on which the operation is performed. //! \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) if (!mesh)
return; return;
const u32 bcount = mesh->getMeshBufferCount(); const u32 bcount = mesh->getMeshBufferCount();
for ( u32 b=0; b<bcount; ++b) for ( u32 b=0; b<bcount; ++b)
recalculateNormals(mesh->getMeshBuffer(b), smooth); recalculateNormals(mesh->getMeshBuffer(b), smooth, angleWeighted);
} }
......
...@@ -40,12 +40,12 @@ public: ...@@ -40,12 +40,12 @@ public:
//! Recalculates all normals of the mesh. //! Recalculates all normals of the mesh.
/** \param mesh: Mesh on which the operation is performed. /** \param mesh: Mesh on which the operation is performed.
\param smooth: Whether to use smoothed normals. */ \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. //! Recalculates all normals of the mesh buffer.
/** \param buffer: Mesh buffer on which the operation is performed. /** \param buffer: Mesh buffer on which the operation is performed.
\param smooth: Whether to use smoothed normals. */ \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. //! Scales the whole mesh.
//! \param mesh: Mesh on which the operation is performed. //! \param mesh: Mesh on which the operation is performed.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment