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

View File

@ -103,7 +103,9 @@ namespace scene
bool angleWeighted=false) const=0;
//! 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. */
void scale(IMesh* mesh, const core::vector3df& factor) const
{
@ -111,7 +113,9 @@ namespace scene
}
//! 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. */
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 m transformation matrix.
\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);
@ -158,18 +165,25 @@ namespace scene
if ( m.getInverse(invT) )
{
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
/** \param buffer Meshbuffer on which the operation is performed.
\param m transformation matrix.
\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);
@ -179,9 +193,13 @@ namespace scene
if ( m.getInverse(invT) )
{
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

View File

@ -277,6 +277,32 @@ namespace scene
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
class SVertexTCoordsScaleManipulator : public IVertexManipulator
{

View File

@ -221,10 +221,10 @@ namespace core
//! Translate a vector by the inverse of the translation part of this matrix.
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;
//! 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;
//! An alternate transform vector method, writing into a second vector