IMeshManipulator::transform can now also normalize normals

Also only update normals now using inner 3x3 matrix (same result usually as last column is 0,0,0 but faster)
And adding some comments.

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@6419 dfc29bdd-3216-0410-991c-e03cc46cb475
This commit is contained in:
cutealien 2022-08-26 14:09:04 +00:00
parent 662001566b
commit eafbe063be
3 changed files with 54 additions and 10 deletions

@ -103,7 +103,9 @@ namespace scene
bool angleWeighted=false) const=0; bool angleWeighted=false) const=0;
//! Scales the actual mesh, not a scene node. //! Scales the actual mesh, not a scene node.
/** \param mesh Mesh on which the operation is performed. /** Note: When your scale are not uniform then
prefer the transform function to have correct normals.
\param mesh Mesh on which the operation is performed.
\param factor Scale factor for each axis. */ \param factor Scale factor for each axis. */
void scale(IMesh* mesh, const core::vector3df& factor) const void scale(IMesh* mesh, const core::vector3df& factor) const
{ {
@ -111,7 +113,9 @@ namespace scene
} }
//! Scales the actual meshbuffer, not a scene node. //! Scales the actual meshbuffer, not a scene node.
/** \param buffer Meshbuffer on which the operation is performed. /** Note: When your scale are not uniform then
prefer the transform function to have correct normals.
\param buffer Meshbuffer on which the operation is performed.
\param factor Scale factor for each axis. */ \param factor Scale factor for each axis. */
void scale(IMeshBuffer* buffer, const core::vector3df& factor) const void scale(IMeshBuffer* buffer, const core::vector3df& factor) const
{ {
@ -146,9 +150,12 @@ namespace scene
/** \param mesh Mesh on which the operation is performed. /** \param mesh Mesh on which the operation is performed.
\param m transformation matrix. \param m transformation matrix.
\param normalsUpdate When 0 - don't update normals. \param normalsUpdate When 0 - don't update normals.
When 1 - update normals with inverse transposed of the transformation matrix When 1 - update normals with inner 3x3 matrix of the inverse transposed of the transformation matrix
should be set when the matrix has some non-uniform scaling
\param normalizeNormals When true it normalizes all normals again.
Usually makes sense to set this as well when normalsUpdate is 1
*/ */
void transform(IMesh* mesh, const core::matrix4& m, u32 normalsUpdate = 0) const void transform(IMesh* mesh, const core::matrix4& m, u32 normalsUpdate = 0, bool normalizeNormals=false) const
{ {
apply(SVertexPositionTransformManipulator(m), mesh, true); apply(SVertexPositionTransformManipulator(m), mesh, true);
@ -158,18 +165,25 @@ namespace scene
if ( m.getInverse(invT) ) if ( m.getInverse(invT) )
{ {
invT = invT.getTransposed(); invT = invT.getTransposed();
apply(SVertexNormalTransformManipulator(invT), mesh, false); apply(SVertexNormalRotateScaleManipulator(invT), mesh, false);
} }
} }
if ( normalizeNormals )
{
apply(SVertexNormalizeNormalManipulator(), mesh, false);
}
} }
//! Applies a transformation to a meshbuffer //! Applies a transformation to a meshbuffer
/** \param buffer Meshbuffer on which the operation is performed. /** \param buffer Meshbuffer on which the operation is performed.
\param m transformation matrix. \param m transformation matrix.
\param normalsUpdate When 0 - don't update normals. \param normalsUpdate When 0 - don't update normals.
When 1 - update normals with inverse transposed of the transformation matrix When 1 - update normals with inner 3x3 matrix of the inverse transposed of the transformation matrix
should be set when the matrix has some non-uniform scaling
\param normalizeNormals When true it normalizes all normals again.
Usually makes sense to set this as well when normalsUpdate is 1
*/ */
void transform(IMeshBuffer* buffer, const core::matrix4& m, u32 normalsUpdate = 0) const void transform(IMeshBuffer* buffer, const core::matrix4& m, u32 normalsUpdate = 0, bool normalizeNormals=false) const
{ {
apply(SVertexPositionTransformManipulator(m), buffer, true); apply(SVertexPositionTransformManipulator(m), buffer, true);
@ -179,9 +193,13 @@ namespace scene
if ( m.getInverse(invT) ) if ( m.getInverse(invT) )
{ {
invT = invT.getTransposed(); invT = invT.getTransposed();
apply(SVertexNormalTransformManipulator(invT), buffer, false); apply(SVertexNormalRotateScaleManipulator(invT), buffer, false);
} }
} }
if ( normalizeNormals )
{
apply(SVertexNormalizeNormalManipulator(), buffer, false);
}
} }
//! Applies a transformation to a mesh //! Applies a transformation to a mesh

@ -277,6 +277,32 @@ namespace scene
core::matrix4 Transformation; core::matrix4 Transformation;
}; };
//! Vertex manipulator which transforms the normal of the vertex with the rotate/scale part of the given matrix (inner 3x3)
class SVertexNormalRotateScaleManipulator : public IVertexManipulator
{
public:
SVertexNormalRotateScaleManipulator(const core::matrix4& m) : Transformation(m) {}
template <typename VType>
void operator()(VType& vertex) const
{
Transformation.rotateVect(vertex.Normal);
}
private:
core::matrix4 Transformation;
};
//! Vertex manipulator which normalizes the normal of the vertex
class SVertexNormalizeNormalManipulator : public IVertexManipulator
{
public:
SVertexNormalizeNormalManipulator() {}
template <typename VType>
void operator()(VType& vertex) const
{
vertex.Normal.normalize();
}
};
//! Vertex manipulator which scales the TCoords of the vertex //! Vertex manipulator which scales the TCoords of the vertex
class SVertexTCoordsScaleManipulator : public IVertexManipulator class SVertexTCoordsScaleManipulator : public IVertexManipulator
{ {

@ -221,10 +221,10 @@ namespace core
//! Translate a vector by the inverse of the translation part of this matrix. //! Translate a vector by the inverse of the translation part of this matrix.
void inverseTranslateVect( vector3df& vect ) const; void inverseTranslateVect( vector3df& vect ) const;
//! Rotate a vector by the inverse of the rotation part of this matrix. //! Tranform (rotate/scale) a vector by the inverse of the rotation part this matrix
void inverseRotateVect( vector3df& vect ) const; void inverseRotateVect( vector3df& vect ) const;
//! Rotate a vector by the rotation part of this matrix. //! Transform (rotate/scale) a vector by the rotation part of this matrix.
void rotateVect( vector3df& vect ) const; void rotateVect( vector3df& vect ) const;
//! An alternate transform vector method, writing into a second vector //! An alternate transform vector method, writing into a second vector