Commit 84eeb0e6 authored by hybrid's avatar hybrid

Added 32bit support to some more of the mesh manipulator methods....

Added 32bit support to some more of the mesh manipulator methods. Unfortunately, the cloning methods (createXXX) will require huge code duplication, so I left them unchanged so far.

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@3765 dfc29bdd-3216-0410-991c-e03cc46cb475
parent 1e321bc0
...@@ -44,6 +44,14 @@ namespace scene ...@@ -44,6 +44,14 @@ namespace scene
apply(scene::SVertexColorSetAlphaManipulator(alpha), mesh); apply(scene::SVertexColorSetAlphaManipulator(alpha), mesh);
} }
//! Sets the alpha vertex color value of the whole mesh to a new value.
/** \param buffer Meshbuffer on which the operation is performed.
\param alpha New alpha value. Must be a value between 0 and 255. */
void setVertexColorAlpha(IMeshBuffer* buffer, s32 alpha) const
{
apply(scene::SVertexColorSetAlphaManipulator(alpha), buffer);
}
//! Sets the colors of all vertices to one color //! Sets the colors of all vertices to one color
/** \param mesh Mesh on which the operation is performed. /** \param mesh Mesh on which the operation is performed.
\param color New color. */ \param color New color. */
...@@ -52,17 +60,27 @@ namespace scene ...@@ -52,17 +60,27 @@ namespace scene
apply(scene::SVertexColorSetManipulator(color), mesh); apply(scene::SVertexColorSetManipulator(color), mesh);
} }
//! Sets the colors of all vertices to one color
/** \param buffer Meshbuffer on which the operation is performed.
\param color New color. */
void setVertexColors(IMeshBuffer* buffer, video::SColor color) const
{
apply(scene::SVertexColorSetManipulator(color), buffer);
}
//! 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.
\param angleWeighted: If the normals shall be smoothed in relation to their angles. More expensive, but also higher precision. */ \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; 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.
\param angleWeighted: If the normals shall be smoothed in relation to their angles. More expensive, but also higher precision. */ \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; virtual void recalculateNormals(IMeshBuffer* buffer,
bool smooth = false, bool angleWeighted = false) const=0;
//! Recalculates tangents, requires a tangent mesh //! Recalculates tangents, requires a tangent mesh
/** \param mesh Mesh on which the operation is performed. /** \param mesh Mesh on which the operation is performed.
...@@ -74,6 +92,16 @@ namespace scene ...@@ -74,6 +92,16 @@ namespace scene
bool recalculateNormals=false, bool smooth=false, bool recalculateNormals=false, bool smooth=false,
bool angleWeighted=false) const=0; bool angleWeighted=false) const=0;
//! Recalculates tangents, requires a tangent mesh buffer
/** \param buffer Meshbuffer on which the operation is performed.
\param recalculateNormals If the normals shall be recalculated, otherwise original normals of the buffer are used unchanged.
\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 recalculateTangents(IMeshBuffer* buffer,
bool recalculateNormals=false, bool smooth=false,
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. /** \param mesh Mesh on which the operation is performed.
\param factor Scale factor for each axis. */ \param factor Scale factor for each axis. */
...@@ -136,28 +164,31 @@ namespace scene ...@@ -136,28 +164,31 @@ namespace scene
\param m transformation matrix. */ \param m transformation matrix. */
_IRR_DEPRECATED_ virtual void transformMesh(IMesh* mesh, const core::matrix4& m) const {return transform(mesh,m);} _IRR_DEPRECATED_ virtual void transformMesh(IMesh* mesh, const core::matrix4& m) const {return transform(mesh,m);}
//! Clones a static IMesh into a modifiable SMesh.
/** All meshbuffers in the returned SMesh
are of type SMeshBuffer or SMeshBufferLightMap.
\param mesh Mesh to copy.
\return Cloned mesh. If you no longer need the
cloned mesh, you should call SMesh::drop(). See
IReferenceCounted::drop() for more information. */
virtual SMesh* createMeshCopy(IMesh* mesh) const = 0;
//! Creates a planar texture mapping on the mesh //! Creates a planar texture mapping on the mesh
/** \param mesh: Mesh on which the operation is performed. /** \param mesh: Mesh on which the operation is performed.
\param resolution: resolution of the planar mapping. This is \param resolution: resolution of the planar mapping. This is
the value specifying which is the relation between world space the value specifying which is the relation between world space
and texture coordinate space. */ and texture coordinate space. */
virtual void makePlanarTextureMapping(IMesh* mesh, f32 resolution=0.001f) const =0; virtual void makePlanarTextureMapping(IMesh* mesh, f32 resolution=0.001f) const=0;
//! Creates a planar texture mapping on the meshbuffer //! Creates a planar texture mapping on the meshbuffer
/** \param meshbuffer: Buffer on which the operation is performed. /** \param meshbuffer: Buffer on which the operation is performed.
\param resolution: resolution of the planar mapping. This is \param resolution: resolution of the planar mapping. This is
the value specifying which is the relation between world space the value specifying which is the relation between world space
and texture coordinate space. */ and texture coordinate space. */
virtual void makePlanarTextureMapping(scene::IMeshBuffer* meshbuffer, f32 resolution=0.001f) const =0; virtual void makePlanarTextureMapping(scene::IMeshBuffer* meshbuffer, f32 resolution=0.001f) const=0;
//! Creates a planar texture mapping on the buffer
/** This method is currently implemented towards the LWO planar mapping. A more general biasing might be required.
\param mesh Mesh on which the operation is performed.
\param resolutionS Resolution of the planar mapping in horizontal direction. This is the ratio between object space and texture space.
\param resolutionT Resolution of the planar mapping in vertical direction. This is the ratio between object space and texture space.
\param axis The axis along which the texture is projected. The allowed values are 0 (X), 1(Y), and 2(Z).
\param offset Vector added to the vertex positions (in object coordinates).
*/
virtual void makePlanarTextureMapping(scene::IMesh* mesh,
f32 resolutionS, f32 resolutionT,
u8 axis, const core::vector3df& offset) const=0;
//! Creates a planar texture mapping on the meshbuffer //! Creates a planar texture mapping on the meshbuffer
/** This method is currently implemented towards the LWO planar mapping. A more general biasing might be required. /** This method is currently implemented towards the LWO planar mapping. A more general biasing might be required.
...@@ -167,7 +198,18 @@ namespace scene ...@@ -167,7 +198,18 @@ namespace scene
\param axis The axis along which the texture is projected. The allowed values are 0 (X), 1(Y), and 2(Z). \param axis The axis along which the texture is projected. The allowed values are 0 (X), 1(Y), and 2(Z).
\param offset Vector added to the vertex positions (in object coordinates). \param offset Vector added to the vertex positions (in object coordinates).
*/ */
virtual void makePlanarTextureMapping(scene::IMeshBuffer* buffer, f32 resolutionS, f32 resolutionT, u8 axis, const core::vector3df& offset) const =0; virtual void makePlanarTextureMapping(scene::IMeshBuffer* buffer,
f32 resolutionS, f32 resolutionT,
u8 axis, const core::vector3df& offset) const=0;
//! Clones a static IMesh into a modifiable SMesh.
/** All meshbuffers in the returned SMesh
are of type SMeshBuffer or SMeshBufferLightMap.
\param mesh Mesh to copy.
\return Cloned mesh. If you no longer need the
cloned mesh, you should call SMesh::drop(). See
IReferenceCounted::drop() for more information. */
virtual SMesh* createMeshCopy(IMesh* mesh) const = 0;
//! Creates a copy of the mesh, which will only consist of S3DVertexTangents vertices. //! Creates a copy of the mesh, which will only consist of S3DVertexTangents vertices.
/** This is useful if you want to draw tangent space normal /** This is useful if you want to draw tangent space normal
...@@ -186,7 +228,9 @@ namespace scene ...@@ -186,7 +228,9 @@ namespace scene
you no longer need the cloned mesh, you should call you no longer need the cloned mesh, you should call
IMesh::drop(). See IReferenceCounted::drop() for more IMesh::drop(). See IReferenceCounted::drop() for more
information. */ information. */
virtual IMesh* createMeshWithTangents(IMesh* mesh, bool recalculateNormals=false, bool smooth=false, bool angleWeighted=false, bool recalculateTangents=true) const = 0; virtual IMesh* createMeshWithTangents(IMesh* mesh,
bool recalculateNormals=false, bool smooth=false,
bool angleWeighted=false, bool recalculateTangents=true) const=0;
//! Creates a copy of the mesh, which will only consist of S3DVertex2TCoord vertices. //! Creates a copy of the mesh, which will only consist of S3DVertex2TCoord vertices.
/** \param mesh Input mesh /** \param mesh Input mesh
......
...@@ -48,29 +48,38 @@ void CMeshManipulator::flipSurfaces(scene::IMesh* mesh) const ...@@ -48,29 +48,38 @@ void CMeshManipulator::flipSurfaces(scene::IMesh* mesh) const
{ {
IMeshBuffer* buffer = mesh->getMeshBuffer(b); IMeshBuffer* buffer = mesh->getMeshBuffer(b);
const u32 idxcnt = buffer->getIndexCount(); const u32 idxcnt = buffer->getIndexCount();
u16* idx = buffer->getIndices(); if (buffer->getIndexType() == video::EIT_16BIT)
s32 tmp;
for (u32 i=0; i<idxcnt; i+=3)
{ {
tmp = idx[i+1]; u16* idx = buffer->getIndices();
idx[i+1] = idx[i+2]; for (u32 i=0; i<idxcnt; i+=3)
idx[i+2] = tmp; {
const u16 tmp = idx[i+1];
idx[i+1] = idx[i+2];
idx[i+2] = tmp;
}
}
else
{
u32* idx = reinterpret_cast<u32*>(buffer->getIndices());
for (u32 i=0; i<idxcnt; i+=3)
{
const u32 tmp = idx[i+1];
idx[i+1] = idx[i+2];
idx[i+2] = tmp;
}
} }
} }
} }
//! Recalculates all normals of the mesh buffer. namespace
/** \param buffer: Mesh buffer on which the operation is performed. */ {
void CMeshManipulator::recalculateNormals(IMeshBuffer* buffer, bool smooth, bool angleWeighted) const template <typename T>
void recalculateNormalsT(IMeshBuffer* buffer, bool smooth, bool angleWeighted)
{ {
if (!buffer)
return;
const u32 vtxcnt = buffer->getVertexCount(); const u32 vtxcnt = buffer->getVertexCount();
const u32 idxcnt = buffer->getIndexCount(); const u32 idxcnt = buffer->getIndexCount();
const u16* idx = buffer->getIndices(); const T* idx = reinterpret_cast<T*>(buffer->getIndices());
if (!smooth) if (!smooth)
{ {
...@@ -90,7 +99,7 @@ void CMeshManipulator::recalculateNormals(IMeshBuffer* buffer, bool smooth, bool ...@@ -90,7 +99,7 @@ void CMeshManipulator::recalculateNormals(IMeshBuffer* buffer, bool smooth, bool
u32 i; u32 i;
for ( i = 0; i!= vtxcnt; ++i ) for ( i = 0; i!= vtxcnt; ++i )
buffer->getNormal(i).set( 0.f, 0.f, 0.f ); buffer->getNormal(i).set(0.f, 0.f, 0.f);
for ( i=0; i<idxcnt; i+=3) for ( i=0; i<idxcnt; i+=3)
{ {
...@@ -111,6 +120,21 @@ void CMeshManipulator::recalculateNormals(IMeshBuffer* buffer, bool smooth, bool ...@@ -111,6 +120,21 @@ void CMeshManipulator::recalculateNormals(IMeshBuffer* buffer, bool smooth, bool
buffer->getNormal(i).normalize(); buffer->getNormal(i).normalize();
} }
} }
}
//! Recalculates all normals of the mesh buffer.
/** \param buffer: Mesh buffer on which the operation is performed. */
void CMeshManipulator::recalculateNormals(IMeshBuffer* buffer, bool smooth, bool angleWeighted) const
{
if (!buffer)
return;
if (buffer->getIndexType()==video::EIT_16BIT)
recalculateNormalsT<u16>(buffer, smooth, angleWeighted);
else
recalculateNormalsT<u32>(buffer, smooth, angleWeighted);
}
//! Recalculates all normals of the mesh. //! Recalculates all normals of the mesh.
...@@ -126,264 +150,297 @@ void CMeshManipulator::recalculateNormals(scene::IMesh* mesh, bool smooth, bool ...@@ -126,264 +150,297 @@ void CMeshManipulator::recalculateNormals(scene::IMesh* mesh, bool smooth, bool
} }
//! Recalculates tangents, requires a tangent mesh namespace
void CMeshManipulator::recalculateTangents(IMesh* mesh, bool recalculateNormals, bool smooth, bool angleWeighted) const {
void calculateTangents(
core::vector3df& normal,
core::vector3df& tangent,
core::vector3df& binormal,
const core::vector3df& vt1, const core::vector3df& vt2, const core::vector3df& vt3, // vertices
const core::vector2df& tc1, const core::vector2df& tc2, const core::vector2df& tc3) // texture coords
{ {
if (!mesh || !mesh->getMeshBufferCount() || (mesh->getMeshBuffer(0)->getVertexType()!= video::EVT_TANGENTS)) // choose one of them:
//#define USE_NVIDIA_GLH_VERSION // use version used by nvidia in glh headers
#define USE_IRR_VERSION
#ifdef USE_IRR_VERSION
core::vector3df v1 = vt1 - vt2;
core::vector3df v2 = vt3 - vt1;
normal = v2.crossProduct(v1);
normal.normalize();
// binormal
f32 deltaX1 = tc1.X - tc2.X;
f32 deltaX2 = tc3.X - tc1.X;
binormal = (v1 * deltaX2) - (v2 * deltaX1);
binormal.normalize();
// tangent
f32 deltaY1 = tc1.Y - tc2.Y;
f32 deltaY2 = tc3.Y - tc1.Y;
tangent = (v1 * deltaY2) - (v2 * deltaY1);
tangent.normalize();
// adjust
core::vector3df txb = tangent.crossProduct(binormal);
if (txb.dotProduct(normal) < 0.0f)
{
tangent *= -1.0f;
binormal *= -1.0f;
}
#endif // USE_IRR_VERSION
#ifdef USE_NVIDIA_GLH_VERSION
tangent.set(0,0,0);
binormal.set(0,0,0);
core::vector3df v1(vt2.X - vt1.X, tc2.X - tc1.X, tc2.Y - tc1.Y);
core::vector3df v2(vt3.X - vt1.X, tc3.X - tc1.X, tc3.Y - tc1.Y);
core::vector3df txb = v1.crossProduct(v2);
if ( !core::iszero ( txb.X ) )
{
tangent.X = -txb.Y / txb.X;
binormal.X = -txb.Z / txb.X;
}
v1.X = vt2.Y - vt1.Y;
v2.X = vt3.Y - vt1.Y;
txb = v1.crossProduct(v2);
if ( !core::iszero ( txb.X ) )
{
tangent.Y = -txb.Y / txb.X;
binormal.Y = -txb.Z / txb.X;
}
v1.X = vt2.Z - vt1.Z;
v2.X = vt3.Z - vt1.Z;
txb = v1.crossProduct(v2);
if ( !core::iszero ( txb.X ) )
{
tangent.Z = -txb.Y / txb.X;
binormal.Z = -txb.Z / txb.X;
}
tangent.normalize();
binormal.normalize();
normal = tangent.crossProduct(binormal);
normal.normalize();
binormal = tangent.crossProduct(normal);
binormal.normalize();
core::plane3d<f32> pl(vt1, vt2, vt3);
if(normal.dotProduct(pl.Normal) < 0.0f )
normal *= -1.0f;
#endif // USE_NVIDIA_GLH_VERSION
}
//! Recalculates tangents for a tangent mesh buffer
template <typename T>
void recalculateTangentsT(IMeshBuffer* buffer, bool recalculateNormals, bool smooth, bool angleWeighted)
{
if (!buffer || (buffer->getVertexType()!= video::EVT_TANGENTS))
return; return;
const u32 meshBufferCount = mesh->getMeshBufferCount(); const u32 vtxCnt = buffer->getVertexCount();
for (u32 b=0; b<meshBufferCount; ++b) const u32 idxCnt = buffer->getIndexCount();
T* idx = reinterpret_cast<T*>(buffer->getIndices());
video::S3DVertexTangents* v =
(video::S3DVertexTangents*)buffer->getVertices();
if (smooth)
{ {
IMeshBuffer* clone = mesh->getMeshBuffer(b); u32 i;
const u32 vtxCnt = clone->getVertexCount();
const u32 idxCnt = clone->getIndexCount();
u16* idx = clone->getIndices(); for ( i = 0; i!= vtxCnt; ++i )
video::S3DVertexTangents* v = {
(video::S3DVertexTangents*)clone->getVertices(); if (recalculateNormals)
v[i].Normal.set( 0.f, 0.f, 0.f );
v[i].Tangent.set( 0.f, 0.f, 0.f );
v[i].Binormal.set( 0.f, 0.f, 0.f );
}
if (smooth) //Each vertex gets the sum of the tangents and binormals from the faces around it
for ( i=0; i<idxCnt; i+=3)
{ {
u32 i; // if this triangle is degenerate, skip it!
if (v[idx[i+0]].Pos == v[idx[i+1]].Pos ||
v[idx[i+0]].Pos == v[idx[i+2]].Pos ||
v[idx[i+1]].Pos == v[idx[i+2]].Pos
/*||
v[idx[i+0]].TCoords == v[idx[i+1]].TCoords ||
v[idx[i+0]].TCoords == v[idx[i+2]].TCoords ||
v[idx[i+1]].TCoords == v[idx[i+2]].TCoords */
)
continue;
//Angle-weighted normals look better, but are slightly more CPU intensive to calculate
core::vector3df weight(1.f,1.f,1.f);
if (angleWeighted)
weight = getAngleWeight(v[i+0].Pos,v[i+1].Pos,v[i+2].Pos);
core::vector3df localNormal;
core::vector3df localTangent;
core::vector3df localBinormal;
calculateTangents(
localNormal,
localTangent,
localBinormal,
v[idx[i+0]].Pos,
v[idx[i+1]].Pos,
v[idx[i+2]].Pos,
v[idx[i+0]].TCoords,
v[idx[i+1]].TCoords,
v[idx[i+2]].TCoords);
for ( i = 0; i!= vtxCnt; ++i ) if (recalculateNormals)
{ v[idx[i+0]].Normal += localNormal * weight.X;
if (recalculateNormals) v[idx[i+0]].Tangent += localTangent * weight.X;
v[i].Normal.set( 0.f, 0.f, 0.f ); v[idx[i+0]].Binormal += localBinormal * weight.X;
v[i].Tangent.set( 0.f, 0.f, 0.f );
v[i].Binormal.set( 0.f, 0.f, 0.f ); calculateTangents(
} localNormal,
localTangent,
localBinormal,
v[idx[i+1]].Pos,
v[idx[i+2]].Pos,
v[idx[i+0]].Pos,
v[idx[i+1]].TCoords,
v[idx[i+2]].TCoords,
v[idx[i+0]].TCoords);
//Each vertex gets the sum of the tangents and binormals from the faces around it if (recalculateNormals)
for ( i=0; i<idxCnt; i+=3) v[idx[i+1]].Normal += localNormal * weight.Y;
{ v[idx[i+1]].Tangent += localTangent * weight.Y;
// if this triangle is degenerate, skip it! v[idx[i+1]].Binormal += localBinormal * weight.Y;
if (v[idx[i+0]].Pos == v[idx[i+1]].Pos ||
v[idx[i+0]].Pos == v[idx[i+2]].Pos || calculateTangents(
v[idx[i+1]].Pos == v[idx[i+2]].Pos localNormal,
/*|| localTangent,
v[idx[i+0]].TCoords == v[idx[i+1]].TCoords || localBinormal,
v[idx[i+0]].TCoords == v[idx[i+2]].TCoords || v[idx[i+2]].Pos,
v[idx[i+1]].TCoords == v[idx[i+2]].TCoords */ v[idx[i+0]].Pos,
) v[idx[i+1]].Pos,
continue; v[idx[i+2]].TCoords,
v[idx[i+0]].TCoords,
//Angle-weighted normals look better, but are slightly more CPU intensive to calculate v[idx[i+1]].TCoords);
core::vector3df weight(1.f,1.f,1.f);
if (angleWeighted)
weight = getAngleWeight(v[i+0].Pos,v[i+1].Pos,v[i+2].Pos);
core::vector3df localNormal;
core::vector3df localTangent;
core::vector3df localBinormal;
calculateTangents(
localNormal,
localTangent,
localBinormal,
v[idx[i+0]].Pos,
v[idx[i+1]].Pos,
v[idx[i+2]].Pos,
v[idx[i+0]].TCoords,
v[idx[i+1]].TCoords,
v[idx[i+2]].TCoords);
if (recalculateNormals)
v[idx[i+0]].Normal += localNormal * weight.X;
v[idx[i+0]].Tangent += localTangent * weight.X;
v[idx[i+0]].Binormal += localBinormal * weight.X;
calculateTangents(
localNormal,
localTangent,
localBinormal,
v[idx[i+1]].Pos,
v[idx[i+2]].Pos,
v[idx[i+0]].Pos,
v[idx[i+1]].TCoords,
v[idx[i+2]].TCoords,
v[idx[i+0]].TCoords);
if (recalculateNormals)
v[idx[i+1]].Normal += localNormal * weight.Y;
v[idx[i+1]].Tangent += localTangent * weight.Y;
v[idx[i+1]].Binormal += localBinormal * weight.Y;
calculateTangents(
localNormal,
localTangent,
localBinormal,
v[idx[i+2]].Pos,
v[idx[i+0]].Pos,
v[idx[i+1]].Pos,
v[idx[i+2]].TCoords,
v[idx[i+0]].TCoords,
v[idx[i+1]].TCoords);
if (recalculateNormals)
v[idx[i+2]].Normal += localNormal * weight.Z;
v[idx[i+2]].Tangent += localTangent * weight.Z;
v[idx[i+2]].Binormal += localBinormal * weight.Z;
}
// Normalize the tangents and binormals
if (recalculateNormals) if (recalculateNormals)
{ v[idx[i+2]].Normal += localNormal * weight.Z;
for ( i = 0; i!= vtxCnt; ++i ) v[idx[i+2]].Tangent += localTangent * weight.Z;
v[i].Normal.normalize(); v[idx[i+2]].Binormal += localBinormal * weight.Z;
} }
// Normalize the tangents and binormals
if (recalculateNormals)
{
for ( i = 0; i!= vtxCnt; ++i ) for ( i = 0; i!= vtxCnt; ++i )
{ v[i].Normal.normalize();
v[i].Tangent.normalize();
v[i].Binormal.normalize();
}
} }
else for ( i = 0; i!= vtxCnt; ++i )
{ {
core::vector3df localNormal; v[i].Tangent.normalize();
for (u32 i=0; i<idxCnt; i+=3) v[i].Binormal.normalize();
{
calculateTangents(
localNormal,
v[idx[i+0]].Tangent,
v[idx[i+0]].Binormal,
v[idx[i+0]].Pos,
v[idx[i+1]].Pos,
v[idx[i+2]].Pos,
v[idx[i+0]].TCoords,
v[idx[i+1]].TCoords,
v[idx[i+2]].TCoords);
if (recalculateNormals)
v[idx[i+0]].Normal=localNormal;
calculateTangents(
localNormal,
v[idx[i+1]].Tangent,
v[idx[i+1]].Binormal,
v[idx[i+1]].Pos,
v[idx[i+2]].Pos,
v[idx[i+0]].Pos,
v[idx[i+1]].TCoords,
v[idx[i+2]].TCoords,
v[idx[i+0]].TCoords);
if (recalculateNormals)
v[idx[i+1]].Normal=localNormal;
calculateTangents(
localNormal,
v[idx[i+2]].Tangent,
v[idx[i+2]].Binormal,
v[idx[i+2]].Pos,
v[idx[i+0]].Pos,
v[idx[i+1]].Pos,
v[idx[i+2]].TCoords,
v[idx[i+0]].TCoords,
v[idx[i+1]].TCoords);
if (recalculateNormals)
v[idx[i+2]].Normal=localNormal;
}
} }
} }
else
{
core::vector3df localNormal;
for (u32 i=0; i<idxCnt; i+=3)
{
calculateTangents(
localNormal,
v[idx[i+0]].Tangent,
v[idx[i+0]].Binormal,
v[idx[i+0]].Pos,
v[idx[i+1]].Pos,
v[idx[i+2]].Pos,
v[idx[i+0]].TCoords,
v[idx[i+1]].TCoords,
v[idx[i+2]].TCoords);
if (recalculateNormals)
v[idx[i+0]].Normal=localNormal;
calculateTangents(
localNormal,
v[idx[i+1]].Tangent,
v[idx[i+1]].Binormal,
v[idx[i+1]].Pos,
v[idx[i+2]].Pos,
v[idx[i+0]].Pos,
v[idx[i+1]].TCoords,
v[idx[i+2]].TCoords,
v[idx[i+0]].TCoords);
if (recalculateNormals)
v[idx[i+1]].Normal=localNormal;
calculateTangents(
localNormal,
v[idx[i+2]].Tangent,
v[idx[i+2]].Binormal,
v[idx[i+2]].Pos,
v[idx[i+0]].Pos,
v[idx[i+1]].Pos,
v[idx[i+2]].TCoords,
v[idx[i+0]].TCoords,
v[idx[i+1]].TCoords);
if (recalculateNormals)
v[idx[i+2]].Normal=localNormal;
}
}
}
} }
//! Clones a static IMesh into a modifyable SMesh. //! Recalculates tangents for a tangent mesh buffer
SMesh* CMeshManipulator::createMeshCopy(scene::IMesh* mesh) const void CMeshManipulator::recalculateTangents(IMeshBuffer* buffer, bool recalculateNormals, bool smooth, bool angleWeighted) const
{ {
if (!mesh) if (buffer && (buffer->getVertexType() == video::EVT_TANGENTS))
return 0;
SMesh* clone = new SMesh();
const u32 meshBufferCount = mesh->getMeshBufferCount();
for ( u32 b=0; b<meshBufferCount; ++b)
{ {
const IMeshBuffer* const mb = mesh->getMeshBuffer(b); if (buffer->getIndexType() == video::EIT_16BIT)
switch(mb->getVertexType()) recalculateTangentsT<u16>(buffer, recalculateNormals, smooth, angleWeighted);
{ else
case video::EVT_STANDARD: recalculateTangentsT<u32>(buffer, recalculateNormals, smooth, angleWeighted);
{ }
SMeshBuffer* buffer = new SMeshBuffer();
buffer->Material = mb->getMaterial();
const u32 vcount = mb->getVertexCount();
buffer->Vertices.reallocate(vcount);
video::S3DVertex* vertices = (video::S3DVertex*)mb->getVertices();
for (u32 i=0; i < vcount; ++i)
buffer->Vertices.push_back(vertices[i]);
const u32 icount = mb->getIndexCount();
buffer->Indices.reallocate(icount);
const u16* indices = mb->getIndices();
for (u32 i=0; i < icount; ++i)
buffer->Indices.push_back(indices[i]);
clone->addMeshBuffer(buffer);
buffer->drop();
}
break;
case video::EVT_2TCOORDS:
{
SMeshBufferLightMap* buffer = new SMeshBufferLightMap();
buffer->Material = mb->getMaterial();
const u32 vcount = mb->getVertexCount();
buffer->Vertices.reallocate(vcount);
video::S3DVertex2TCoords* vertices = (video::S3DVertex2TCoords*)mb->getVertices();
for (u32 i=0; i < vcount; ++i)
buffer->Vertices.push_back(vertices[i]);
const u32 icount = mb->getIndexCount();
buffer->Indices.reallocate(icount);
const u16* indices = mb->getIndices();
for (u32 i=0; i < icount; ++i)
buffer->Indices.push_back(indices[i]);
clone->addMeshBuffer(buffer);
buffer->drop();
}
break;
case video::EVT_TANGENTS:
{
SMeshBufferTangents* buffer = new SMeshBufferTangents();
buffer->Material = mb->getMaterial();
const u32 vcount = mb->getVertexCount();
buffer->Vertices.reallocate(vcount);
video::S3DVertexTangents* vertices = (video::S3DVertexTangents*)mb->getVertices();
for (u32 i=0; i < vcount; ++i)
buffer->Vertices.push_back(vertices[i]);
const u32 icount = mb->getIndexCount();
buffer->Indices.reallocate(icount);
const u16* indices = mb->getIndices();
for (u32 i=0; i < icount; ++i)
buffer->Indices.push_back(indices[i]);
clone->addMeshBuffer(buffer);
buffer->drop();
}
break;
}// end switch
}// end for all mesh buffers
clone->BoundingBox = mesh->getBoundingBox();
return clone;
} }
//! Creates a planar texture mapping on the mesh //! Recalculates tangents for all tangent mesh buffers
void CMeshManipulator::makePlanarTextureMapping(scene::IMesh* mesh, f32 resolution=0.01f) const void CMeshManipulator::recalculateTangents(IMesh* mesh, bool recalculateNormals, bool smooth, bool angleWeighted) const
{ {
if (!mesh) if (!mesh)
return; return;
const u32 bcount = mesh->getMeshBufferCount(); const u32 meshBufferCount = mesh->getMeshBufferCount();
for ( u32 b=0; b<bcount; ++b) for (u32 b=0; b<meshBufferCount; ++b)
{ {
makePlanarTextureMapping(mesh->getMeshBuffer(b), resolution); recalculateTangents(mesh->getMeshBuffer(b), recalculateNormals, smooth, angleWeighted);
} }
} }
namespace
{
//! Creates a planar texture mapping on the meshbuffer //! Creates a planar texture mapping on the meshbuffer
void CMeshManipulator::makePlanarTextureMapping(scene::IMeshBuffer* buffer, f32 resolution) const template<typename T>
void makePlanarTextureMappingT(scene::IMeshBuffer* buffer, f32 resolution)
{ {
u32 idxcnt = buffer->getIndexCount(); u32 idxcnt = buffer->getIndexCount();
u16* idx = buffer->getIndices(); T* idx = reinterpret_cast<T*>(buffer->getIndices());
for (u32 i=0; i<idxcnt; i+=3) for (u32 i=0; i<idxcnt; i+=3)
{ {
...@@ -420,13 +477,44 @@ void CMeshManipulator::makePlanarTextureMapping(scene::IMeshBuffer* buffer, f32 ...@@ -420,13 +477,44 @@ void CMeshManipulator::makePlanarTextureMapping(scene::IMeshBuffer* buffer, f32
} }
} }
} }
}
//! Creates a planar texture mapping on the meshbuffer //! Creates a planar texture mapping on the meshbuffer
void CMeshManipulator::makePlanarTextureMapping(scene::IMeshBuffer* buffer, f32 resolutionS, f32 resolutionT, u8 axis, const core::vector3df& offset) const void CMeshManipulator::makePlanarTextureMapping(scene::IMeshBuffer* buffer, f32 resolution) const
{
if (!buffer)
return;
if (buffer->getIndexType()==video::EIT_16BIT)
makePlanarTextureMappingT<u16>(buffer, resolution);
else
makePlanarTextureMappingT<u32>(buffer, resolution);
}
//! Creates a planar texture mapping on the mesh
void CMeshManipulator::makePlanarTextureMapping(scene::IMesh* mesh, f32 resolution) const
{
if (!mesh)
return;
const u32 bcount = mesh->getMeshBufferCount();
for ( u32 b=0; b<bcount; ++b)
{
makePlanarTextureMapping(mesh->getMeshBuffer(b), resolution);
}
}
namespace
{
//! Creates a planar texture mapping on the meshbuffer
template <typename T>
void makePlanarTextureMappingT(scene::IMeshBuffer* buffer, f32 resolutionS, f32 resolutionT, u8 axis, const core::vector3df& offset)
{ {
u32 idxcnt = buffer->getIndexCount(); u32 idxcnt = buffer->getIndexCount();
u16* idx = buffer->getIndices(); T* idx = reinterpret_cast<T*>(buffer->getIndices());
for (u32 i=0; i<idxcnt; i+=3) for (u32 i=0; i<idxcnt; i+=3)
{ {
...@@ -457,9 +545,117 @@ void CMeshManipulator::makePlanarTextureMapping(scene::IMeshBuffer* buffer, f32 ...@@ -457,9 +545,117 @@ void CMeshManipulator::makePlanarTextureMapping(scene::IMeshBuffer* buffer, f32
} }
} }
} }
}
//! Creates a planar texture mapping on the meshbuffer
void CMeshManipulator::makePlanarTextureMapping(scene::IMeshBuffer* buffer, f32 resolutionS, f32 resolutionT, u8 axis, const core::vector3df& offset) const
{
if (!buffer)
return;
if (buffer->getIndexType()==video::EIT_16BIT)
makePlanarTextureMappingT<u16>(buffer, resolutionS, resolutionT, axis, offset);
else
makePlanarTextureMappingT<u32>(buffer, resolutionS, resolutionT, axis, offset);
}
//! Creates a planar texture mapping on the mesh
void CMeshManipulator::makePlanarTextureMapping(scene::IMesh* mesh, f32 resolutionS, f32 resolutionT, u8 axis, const core::vector3df& offset) const
{
if (!mesh)
return;
const u32 bcount = mesh->getMeshBufferCount();
for ( u32 b=0; b<bcount; ++b)
{
makePlanarTextureMapping(mesh->getMeshBuffer(b), resolutionS, resolutionT, axis, offset);
}
}
//! Clones a static IMesh into a modifyable SMesh.
// not yet 32bit
SMesh* CMeshManipulator::createMeshCopy(scene::IMesh* mesh) const
{
if (!mesh)
return 0;
SMesh* clone = new SMesh();
const u32 meshBufferCount = mesh->getMeshBufferCount();
for ( u32 b=0; b<meshBufferCount; ++b)
{
const IMeshBuffer* const mb = mesh->getMeshBuffer(b);
switch(mb->getVertexType())
{
case video::EVT_STANDARD:
{
SMeshBuffer* buffer = new SMeshBuffer();
buffer->Material = mb->getMaterial();
const u32 vcount = mb->getVertexCount();
buffer->Vertices.reallocate(vcount);
video::S3DVertex* vertices = (video::S3DVertex*)mb->getVertices();
for (u32 i=0; i < vcount; ++i)
buffer->Vertices.push_back(vertices[i]);
const u32 icount = mb->getIndexCount();
buffer->Indices.reallocate(icount);
const u16* indices = mb->getIndices();
for (u32 i=0; i < icount; ++i)
buffer->Indices.push_back(indices[i]);
clone->addMeshBuffer(buffer);
buffer->drop();
}
break;
case video::EVT_2TCOORDS:
{
SMeshBufferLightMap* buffer = new SMeshBufferLightMap();
buffer->Material = mb->getMaterial();
const u32 vcount = mb->getVertexCount();
buffer->Vertices.reallocate(vcount);
video::S3DVertex2TCoords* vertices = (video::S3DVertex2TCoords*)mb->getVertices();
for (u32 i=0; i < vcount; ++i)
buffer->Vertices.push_back(vertices[i]);
const u32 icount = mb->getIndexCount();
buffer->Indices.reallocate(icount);
const u16* indices = mb->getIndices();
for (u32 i=0; i < icount; ++i)
buffer->Indices.push_back(indices[i]);
clone->addMeshBuffer(buffer);
buffer->drop();
}
break;
case video::EVT_TANGENTS:
{
SMeshBufferTangents* buffer = new SMeshBufferTangents();
buffer->Material = mb->getMaterial();
const u32 vcount = mb->getVertexCount();
buffer->Vertices.reallocate(vcount);
video::S3DVertexTangents* vertices = (video::S3DVertexTangents*)mb->getVertices();
for (u32 i=0; i < vcount; ++i)
buffer->Vertices.push_back(vertices[i]);
const u32 icount = mb->getIndexCount();
buffer->Indices.reallocate(icount);
const u16* indices = mb->getIndices();
for (u32 i=0; i < icount; ++i)
buffer->Indices.push_back(indices[i]);
clone->addMeshBuffer(buffer);
buffer->drop();
}
break;
}// end switch
}// end for all mesh buffers
clone->BoundingBox = mesh->getBoundingBox();
return clone;
}
//! Creates a copy of the mesh, which will only consist of unique primitives //! Creates a copy of the mesh, which will only consist of unique primitives
// not yet 32bit
IMesh* CMeshManipulator::createMeshUniquePrimitives(IMesh* mesh) const IMesh* CMeshManipulator::createMeshUniquePrimitives(IMesh* mesh) const
{ {
if (!mesh) if (!mesh)
...@@ -562,7 +758,9 @@ IMesh* CMeshManipulator::createMeshUniquePrimitives(IMesh* mesh) const ...@@ -562,7 +758,9 @@ IMesh* CMeshManipulator::createMeshUniquePrimitives(IMesh* mesh) const
return clone; return clone;
} }
//! Creates a copy of a mesh, which will have identical vertices welded together //! Creates a copy of a mesh, which will have identical vertices welded together
// not yet 32bit
IMesh* CMeshManipulator::createMeshWelded(IMesh *mesh, f32 tolerance) const IMesh* CMeshManipulator::createMeshWelded(IMesh *mesh, f32 tolerance) const
{ {
SMesh* clone = new SMesh(); SMesh* clone = new SMesh();
...@@ -731,6 +929,7 @@ IMesh* CMeshManipulator::createMeshWelded(IMesh *mesh, f32 tolerance) const ...@@ -731,6 +929,7 @@ IMesh* CMeshManipulator::createMeshWelded(IMesh *mesh, f32 tolerance) const
//! Creates a copy of the mesh, which will only consist of S3DVertexTangents vertices. //! Creates a copy of the mesh, which will only consist of S3DVertexTangents vertices.
// not yet 32bit
IMesh* CMeshManipulator::createMeshWithTangents(IMesh* mesh, bool recalculateNormals, bool smooth, bool angleWeighted, bool calculateTangents) const IMesh* CMeshManipulator::createMeshWithTangents(IMesh* mesh, bool recalculateNormals, bool smooth, bool angleWeighted, bool calculateTangents) const
{ {
if (!mesh) if (!mesh)
...@@ -751,7 +950,7 @@ IMesh* CMeshManipulator::createMeshWithTangents(IMesh* mesh, bool recalculateNor ...@@ -751,7 +950,7 @@ IMesh* CMeshManipulator::createMeshWithTangents(IMesh* mesh, bool recalculateNor
buffer->Material = original->getMaterial(); buffer->Material = original->getMaterial();
buffer->Vertices.reallocate(idxCnt); buffer->Vertices.reallocate(idxCnt);
buffer->Indices.set_used(idxCnt); buffer->Indices.reallocate(idxCnt);
core::map<video::S3DVertexTangents, int> vertMap; core::map<video::S3DVertexTangents, int> vertMap;
int vertLocation; int vertLocation;
...@@ -801,7 +1000,7 @@ IMesh* CMeshManipulator::createMeshWithTangents(IMesh* mesh, bool recalculateNor ...@@ -801,7 +1000,7 @@ IMesh* CMeshManipulator::createMeshWithTangents(IMesh* mesh, bool recalculateNor
} }
// create new indices // create new indices
buffer->Indices[i] = vertLocation; buffer->Indices.push_back(vertLocation);
} }
buffer->recalculateBoundingBox(); buffer->recalculateBoundingBox();
...@@ -819,6 +1018,7 @@ IMesh* CMeshManipulator::createMeshWithTangents(IMesh* mesh, bool recalculateNor ...@@ -819,6 +1018,7 @@ IMesh* CMeshManipulator::createMeshWithTangents(IMesh* mesh, bool recalculateNor
//! Creates a copy of the mesh, which will only consist of S3DVertex2TCoords vertices. //! Creates a copy of the mesh, which will only consist of S3DVertex2TCoords vertices.
// not yet 32bit
IMesh* CMeshManipulator::createMeshWith2TCoords(IMesh* mesh) const IMesh* CMeshManipulator::createMeshWith2TCoords(IMesh* mesh) const
{ {
if (!mesh) if (!mesh)
...@@ -838,7 +1038,7 @@ IMesh* CMeshManipulator::createMeshWith2TCoords(IMesh* mesh) const ...@@ -838,7 +1038,7 @@ IMesh* CMeshManipulator::createMeshWith2TCoords(IMesh* mesh) const
SMeshBufferLightMap* buffer = new SMeshBufferLightMap(); SMeshBufferLightMap* buffer = new SMeshBufferLightMap();
buffer->Material = original->getMaterial(); buffer->Material = original->getMaterial();
buffer->Vertices.reallocate(idxCnt); buffer->Vertices.reallocate(idxCnt);
buffer->Indices.set_used(idxCnt); buffer->Indices.reallocate(idxCnt);
core::map<video::S3DVertex2TCoords, int> vertMap; core::map<video::S3DVertex2TCoords, int> vertMap;
int vertLocation; int vertLocation;
...@@ -888,7 +1088,7 @@ IMesh* CMeshManipulator::createMeshWith2TCoords(IMesh* mesh) const ...@@ -888,7 +1088,7 @@ IMesh* CMeshManipulator::createMeshWith2TCoords(IMesh* mesh) const
} }
// create new indices // create new indices
buffer->Indices[i] = vertLocation; buffer->Indices.push_back(vertLocation);
} }
buffer->recalculateBoundingBox(); buffer->recalculateBoundingBox();
...@@ -901,7 +1101,9 @@ IMesh* CMeshManipulator::createMeshWith2TCoords(IMesh* mesh) const ...@@ -901,7 +1101,9 @@ IMesh* CMeshManipulator::createMeshWith2TCoords(IMesh* mesh) const
return clone; return clone;
} }
//! Creates a copy of the mesh, which will only consist of S3DVertex vertices. //! Creates a copy of the mesh, which will only consist of S3DVertex vertices.
// not yet 32bit
IMesh* CMeshManipulator::createMeshWith1TCoords(IMesh* mesh) const IMesh* CMeshManipulator::createMeshWith1TCoords(IMesh* mesh) const
{ {
if (!mesh) if (!mesh)
...@@ -913,14 +1115,14 @@ IMesh* CMeshManipulator::createMeshWith1TCoords(IMesh* mesh) const ...@@ -913,14 +1115,14 @@ IMesh* CMeshManipulator::createMeshWith1TCoords(IMesh* mesh) const
for (u32 b=0; b<meshBufferCount; ++b) for (u32 b=0; b<meshBufferCount; ++b)
{ {
const IMeshBuffer* const original = mesh->getMeshBuffer(b); IMeshBuffer* original = mesh->getMeshBuffer(b);
const u32 idxCnt = original->getIndexCount(); const u32 idxCnt = original->getIndexCount();
const u16* idx = original->getIndices(); const u16* idx = original->getIndices();
SMeshBuffer* buffer = new SMeshBuffer(); SMeshBuffer* buffer = new SMeshBuffer();
buffer->Material = original->getMaterial(); buffer->Material = original->getMaterial();
buffer->Vertices.reallocate(idxCnt); buffer->Vertices.reallocate(idxCnt);
buffer->Indices.set_used(idxCnt); buffer->Indices.reallocate(idxCnt);
core::map<video::S3DVertex, int> vertMap; core::map<video::S3DVertex, int> vertMap;
int vertLocation; int vertLocation;
...@@ -969,10 +1171,9 @@ IMesh* CMeshManipulator::createMeshWith1TCoords(IMesh* mesh) const ...@@ -969,10 +1171,9 @@ IMesh* CMeshManipulator::createMeshWith1TCoords(IMesh* mesh) const
} }
// create new indices // create new indices
buffer->Indices[i] = vertLocation; buffer->Indices.push_back(vertLocation);
} }
buffer->recalculateBoundingBox(); buffer->recalculateBoundingBox();
// add new buffer // add new buffer
clone->addMeshBuffer(buffer); clone->addMeshBuffer(buffer);
buffer->drop(); buffer->drop();
...@@ -983,103 +1184,6 @@ IMesh* CMeshManipulator::createMeshWith1TCoords(IMesh* mesh) const ...@@ -983,103 +1184,6 @@ IMesh* CMeshManipulator::createMeshWith1TCoords(IMesh* mesh) const
} }
void CMeshManipulator::calculateTangents(
core::vector3df& normal,
core::vector3df& tangent,
core::vector3df& binormal,
const core::vector3df& vt1, const core::vector3df& vt2, const core::vector3df& vt3, // vertices
const core::vector2df& tc1, const core::vector2df& tc2, const core::vector2df& tc3) // texture coords
{
// choose one of them:
//#define USE_NVIDIA_GLH_VERSION // use version used by nvidia in glh headers
#define USE_IRR_VERSION
#ifdef USE_IRR_VERSION
core::vector3df v1 = vt1 - vt2;
core::vector3df v2 = vt3 - vt1;
normal = v2.crossProduct(v1);
normal.normalize();
// binormal
f32 deltaX1 = tc1.X - tc2.X;
f32 deltaX2 = tc3.X - tc1.X;
binormal = (v1 * deltaX2) - (v2 * deltaX1);
binormal.normalize();
// tangent
f32 deltaY1 = tc1.Y - tc2.Y;
f32 deltaY2 = tc3.Y - tc1.Y;
tangent = (v1 * deltaY2) - (v2 * deltaY1);
tangent.normalize();
// adjust
core::vector3df txb = tangent.crossProduct(binormal);
if (txb.dotProduct(normal) < 0.0f)
{
tangent *= -1.0f;
binormal *= -1.0f;
}
#endif // USE_IRR_VERSION
#ifdef USE_NVIDIA_GLH_VERSION
tangent.set(0,0,0);
binormal.set(0,0,0);
core::vector3df v1(vt2.X - vt1.X, tc2.X - tc1.X, tc2.Y - tc1.Y);
core::vector3df v2(vt3.X - vt1.X, tc3.X - tc1.X, tc3.Y - tc1.Y);
core::vector3df txb = v1.crossProduct(v2);
if ( !core::iszero ( txb.X ) )
{
tangent.X = -txb.Y / txb.X;
binormal.X = -txb.Z / txb.X;
}
v1.X = vt2.Y - vt1.Y;
v2.X = vt3.Y - vt1.Y;
txb = v1.crossProduct(v2);
if ( !core::iszero ( txb.X ) )
{
tangent.Y = -txb.Y / txb.X;
binormal.Y = -txb.Z / txb.X;
}
v1.X = vt2.Z - vt1.Z;
v2.X = vt3.Z - vt1.Z;
txb = v1.crossProduct(v2);
if ( !core::iszero ( txb.X ) )
{
tangent.Z = -txb.Y / txb.X;
binormal.Z = -txb.Z / txb.X;
}
tangent.normalize();
binormal.normalize();
normal = tangent.crossProduct(binormal);
normal.normalize();
binormal = tangent.crossProduct(normal);
binormal.normalize();
core::plane3d<f32> pl(vt1, vt2, vt3);
if(normal.dotProduct(pl.Normal) < 0.0f )
normal *= -1.0f;
#endif // USE_NVIDIA_GLH_VERSION
}
//! Returns amount of polygons in mesh. //! Returns amount of polygons in mesh.
s32 CMeshManipulator::getPolyCount(scene::IMesh* mesh) const s32 CMeshManipulator::getPolyCount(scene::IMesh* mesh) const
{ {
......
...@@ -43,7 +43,7 @@ public: ...@@ -43,7 +43,7 @@ public:
\param resolution: resolution of the planar mapping. This is the value \param resolution: resolution of the planar mapping. This is the value
specifying which is the relation between world space and specifying which is the relation between world space and
texture coordinate space. */ texture coordinate space. */
virtual void makePlanarTextureMapping(scene::IMesh* mesh, f32 resolution) const; virtual void makePlanarTextureMapping(scene::IMesh* mesh, f32 resolution=0.001f) const;
//! Creates a planar texture mapping on the meshbuffer //! Creates a planar texture mapping on the meshbuffer
virtual void makePlanarTextureMapping(scene::IMeshBuffer* meshbuffer, f32 resolution=0.001f) const; virtual void makePlanarTextureMapping(scene::IMeshBuffer* meshbuffer, f32 resolution=0.001f) const;
...@@ -51,6 +51,12 @@ public: ...@@ -51,6 +51,12 @@ public:
//! Creates a planar texture mapping on the meshbuffer //! Creates a planar texture mapping on the meshbuffer
void makePlanarTextureMapping(scene::IMeshBuffer* buffer, f32 resolutionS, f32 resolutionT, u8 axis, const core::vector3df& offset) const; void makePlanarTextureMapping(scene::IMeshBuffer* buffer, f32 resolutionS, f32 resolutionT, u8 axis, const core::vector3df& offset) const;
//! Creates a planar texture mapping on the mesh
void makePlanarTextureMapping(scene::IMesh* mesh, f32 resolutionS, f32 resolutionT, u8 axis, const core::vector3df& offset) const;
//! Recalculates tangents, requires a tangent mesh buffer
virtual void recalculateTangents(IMeshBuffer* buffer, bool recalculateNormals=false, bool smooth=false, bool angleWeighted=false) const;
//! Recalculates tangents, requires a tangent mesh //! Recalculates tangents, requires a tangent mesh
virtual void recalculateTangents(IMesh* mesh, bool recalculateNormals=false, bool smooth=false, bool angleWeighted=false) const; virtual void recalculateTangents(IMesh* mesh, bool recalculateNormals=false, bool smooth=false, bool angleWeighted=false) const;
...@@ -77,14 +83,6 @@ public: ...@@ -77,14 +83,6 @@ public:
//! create a new AnimatedMesh and adds the mesh to it //! create a new AnimatedMesh and adds the mesh to it
virtual IAnimatedMesh * createAnimatedMesh(scene::IMesh* mesh,scene::E_ANIMATED_MESH_TYPE type) const; virtual IAnimatedMesh * createAnimatedMesh(scene::IMesh* mesh,scene::E_ANIMATED_MESH_TYPE type) const;
private:
static void calculateTangents(core::vector3df& normal,
core::vector3df& tangent,
core::vector3df& binormal,
const core::vector3df& vt1, const core::vector3df& vt2, const core::vector3df& vt3,
const core::vector2df& tc1, const core::vector2df& tc2, const core::vector2df& tc3);
}; };
} // end namespace scene } // end namespace scene
......
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