Added generation of tangent space which can keep the original normals, by ryanclark. Note that inaccuracies of the tangent space may arise if you keep the original tangents. Angle weighted smoothing seems to be bogus, maybe indices are wrong.
git-svn-id: http://svn.code.sf.net/p/irrlicht/code/trunk@1392 dfc29bdd-3216-0410-991c-e03cc46cb475
This commit is contained in:
parent
029707298c
commit
6da17e04b6
@ -93,13 +93,18 @@ namespace scene
|
||||
mapped geometry because it calculates the tangent and binormal
|
||||
data which is needed there.
|
||||
\param mesh Input mesh
|
||||
\param smooth The normals are smoothed across the meshbuffer's faces if this flag is set.
|
||||
\param recalculateNormals The normals are recalculated if set,
|
||||
otherwise the original ones are kept. Note that keeping the
|
||||
normals may introduce inaccurate tangents if the normals are
|
||||
very different to those calculated from the faces.
|
||||
\param smooth The normals/tangents are smoothed across the
|
||||
meshbuffer's faces if this flag is set.
|
||||
\param angleWeighted Improved smoothing calculation used
|
||||
\return Mesh consisting only of S3DVertexTangents vertices. If
|
||||
you no longer need the cloned mesh, you should call
|
||||
IMesh::drop(). See IReferenceCounted::drop() for more
|
||||
information. */
|
||||
virtual IMesh* createMeshWithTangents(IMesh* mesh, bool smooth=false, bool angleWeighted=false) const = 0;
|
||||
virtual IMesh* createMeshWithTangents(IMesh* mesh, bool recalculateNormals=false, bool smooth=false, bool angleWeighted=false) const = 0;
|
||||
|
||||
//! Creates a copy of the mesh, which will only consist of S3DVertex2TCoord vertices.
|
||||
/** \param mesh Input mesh
|
||||
|
@ -751,7 +751,7 @@ IMesh* CMeshManipulator::createMeshWelded(IMesh *mesh, f32 tolerance) const
|
||||
|
||||
|
||||
//! Creates a copy of the mesh, which will only consist of S3DVertexTangents vertices.
|
||||
IMesh* CMeshManipulator::createMeshWithTangents(IMesh* mesh, bool smooth, bool angleWeighted) const
|
||||
IMesh* CMeshManipulator::createMeshWithTangents(IMesh* mesh, bool recalculateNormals, bool smooth, bool angleWeighted) const
|
||||
{
|
||||
if (!mesh)
|
||||
return 0;
|
||||
@ -764,7 +764,7 @@ IMesh* CMeshManipulator::createMeshWithTangents(IMesh* mesh, bool smooth, bool a
|
||||
|
||||
for (b=0; b<meshBufferCount; ++b)
|
||||
{
|
||||
const s32 idxCnt = mesh->getMeshBuffer(b)->getIndexCount();
|
||||
const u32 idxCnt = mesh->getMeshBuffer(b)->getIndexCount();
|
||||
const u16* idx = mesh->getMeshBuffer(b)->getIndices();
|
||||
|
||||
SMeshBufferTangents* buffer = new SMeshBufferTangents();
|
||||
@ -780,10 +780,10 @@ IMesh* CMeshManipulator::createMeshWithTangents(IMesh* mesh, bool smooth, bool a
|
||||
video::S3DVertex* v =
|
||||
(video::S3DVertex*)mesh->getMeshBuffer(b)->getVertices();
|
||||
|
||||
for (s32 i=0; i<idxCnt; ++i)
|
||||
for (u32 i=0; i<idxCnt; ++i)
|
||||
buffer->Vertices.push_back(
|
||||
video::S3DVertexTangents(
|
||||
v[idx[i]].Pos, v[idx[i]].Color, v[idx[i]].TCoords));
|
||||
v[idx[i]].Pos, v[idx[i]].Normal, v[idx[i]].Color, v[idx[i]].TCoords));
|
||||
}
|
||||
break;
|
||||
case video::EVT_2TCOORDS:
|
||||
@ -791,9 +791,9 @@ IMesh* CMeshManipulator::createMeshWithTangents(IMesh* mesh, bool smooth, bool a
|
||||
video::S3DVertex2TCoords* v =
|
||||
(video::S3DVertex2TCoords*)mesh->getMeshBuffer(b)->getVertices();
|
||||
|
||||
for (s32 i=0; i<idxCnt; ++i)
|
||||
for (u32 i=0; i<idxCnt; ++i)
|
||||
buffer->Vertices.push_back(video::S3DVertexTangents(
|
||||
v[idx[i]].Pos, v[idx[i]].Color, v[idx[i]].TCoords));
|
||||
v[idx[i]].Pos, v[idx[i]].Normal, v[idx[i]].Color, v[idx[i]].TCoords));
|
||||
}
|
||||
break;
|
||||
case video::EVT_TANGENTS:
|
||||
@ -801,7 +801,7 @@ IMesh* CMeshManipulator::createMeshWithTangents(IMesh* mesh, bool smooth, bool a
|
||||
video::S3DVertexTangents* v =
|
||||
(video::S3DVertexTangents*)mesh->getMeshBuffer(b)->getVertices();
|
||||
|
||||
for (s32 i=0; i<idxCnt; ++i)
|
||||
for (u32 i=0; i<idxCnt; ++i)
|
||||
buffer->Vertices.push_back(v[idx[i]]);
|
||||
}
|
||||
break;
|
||||
@ -810,7 +810,7 @@ IMesh* CMeshManipulator::createMeshWithTangents(IMesh* mesh, bool smooth, bool a
|
||||
// create new indices
|
||||
|
||||
buffer->Indices.set_used(idxCnt);
|
||||
for (s32 i=0; i<idxCnt; ++i)
|
||||
for (u32 i=0; i<idxCnt; ++i)
|
||||
buffer->Indices[i] = i;
|
||||
|
||||
buffer->setBoundingBox(mesh->getMeshBuffer(b)->getBoundingBox());
|
||||
@ -837,6 +837,7 @@ IMesh* CMeshManipulator::createMeshWithTangents(IMesh* mesh, bool smooth, bool a
|
||||
|
||||
for ( i = 0; i!= vtxCnt; ++i )
|
||||
{
|
||||
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 );
|
||||
@ -875,6 +876,7 @@ IMesh* CMeshManipulator::createMeshWithTangents(IMesh* mesh, bool smooth, bool a
|
||||
v[idx[i+1]].TCoords,
|
||||
v[idx[i+2]].TCoords);
|
||||
|
||||
if (recalculateNormals)
|
||||
v[idx[i+0]].Tangent += localTangent * weight.X;
|
||||
v[idx[i+0]].Binormal += localBinormal * weight.X;
|
||||
v[idx[i+0]].Normal += localNormal * weight.X;
|
||||
@ -890,6 +892,7 @@ IMesh* CMeshManipulator::createMeshWithTangents(IMesh* mesh, bool smooth, bool a
|
||||
v[idx[i+2]].TCoords,
|
||||
v[idx[i+0]].TCoords);
|
||||
|
||||
if (recalculateNormals)
|
||||
v[idx[i+1]].Tangent += localTangent * weight.Y;
|
||||
v[idx[i+1]].Binormal += localBinormal * weight.Y;
|
||||
v[idx[i+1]].Normal += localNormal * weight.Y;
|
||||
@ -905,25 +908,31 @@ IMesh* CMeshManipulator::createMeshWithTangents(IMesh* mesh, bool smooth, bool a
|
||||
v[idx[i+0]].TCoords,
|
||||
v[idx[i+1]].TCoords);
|
||||
|
||||
if (recalculateNormals)
|
||||
v[idx[i+2]].Tangent += localTangent * weight.Z;
|
||||
v[idx[i+2]].Binormal += localBinormal * weight.Z;
|
||||
v[idx[i+2]].Normal += localNormal * weight.Z;
|
||||
}
|
||||
|
||||
// Normalize the tangents and binormals
|
||||
if (recalculateNormals)
|
||||
{
|
||||
for ( i = 0; i!= vtxCnt; ++i )
|
||||
v[i].Normal.normalize();
|
||||
}
|
||||
for ( i = 0; i!= vtxCnt; ++i )
|
||||
{
|
||||
v[i].Tangent.normalize();
|
||||
v[i].Binormal.normalize();
|
||||
v[i].Normal.normalize();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
core::vector3df localNormal;
|
||||
for (u32 i=0; i<idxCnt; i+=3)
|
||||
{
|
||||
calculateTangents(
|
||||
v[idx[i+0]].Normal,
|
||||
localNormal,
|
||||
v[idx[i+0]].Tangent,
|
||||
v[idx[i+0]].Binormal,
|
||||
v[idx[i+0]].Pos,
|
||||
@ -932,9 +941,11 @@ IMesh* CMeshManipulator::createMeshWithTangents(IMesh* mesh, bool smooth, bool a
|
||||
v[idx[i+0]].TCoords,
|
||||
v[idx[i+1]].TCoords,
|
||||
v[idx[i+2]].TCoords);
|
||||
if (recalculateNormals)
|
||||
v[idx[i+0]].Normal=localNormal;
|
||||
|
||||
calculateTangents(
|
||||
v[idx[i+1]].Normal,
|
||||
localNormal,
|
||||
v[idx[i+1]].Tangent,
|
||||
v[idx[i+1]].Binormal,
|
||||
v[idx[i+1]].Pos,
|
||||
@ -943,9 +954,11 @@ IMesh* CMeshManipulator::createMeshWithTangents(IMesh* mesh, bool smooth, bool a
|
||||
v[idx[i+1]].TCoords,
|
||||
v[idx[i+2]].TCoords,
|
||||
v[idx[i+0]].TCoords);
|
||||
if (recalculateNormals)
|
||||
v[idx[i+1]].Normal=localNormal;
|
||||
|
||||
calculateTangents(
|
||||
v[idx[i+2]].Normal,
|
||||
localNormal,
|
||||
v[idx[i+2]].Tangent,
|
||||
v[idx[i+2]].Binormal,
|
||||
v[idx[i+2]].Pos,
|
||||
@ -954,6 +967,8 @@ IMesh* CMeshManipulator::createMeshWithTangents(IMesh* mesh, bool smooth, bool a
|
||||
v[idx[i+2]].TCoords,
|
||||
v[idx[i+0]].TCoords,
|
||||
v[idx[i+1]].TCoords);
|
||||
if (recalculateNormals)
|
||||
v[idx[i+2]].Normal=localNormal;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1037,7 +1052,6 @@ IMesh* CMeshManipulator::createMeshWith2TCoords(IMesh* mesh) const
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CMeshManipulator::calculateTangents(
|
||||
core::vector3df& normal,
|
||||
core::vector3df& tangent,
|
||||
|
@ -68,7 +68,7 @@ public:
|
||||
virtual void makePlanarTextureMapping(scene::IMesh* mesh, f32 resolution) const;
|
||||
|
||||
//! Creates a copy of the mesh, which will only consist of S3DVertexTangents vertices.
|
||||
virtual IMesh* createMeshWithTangents(IMesh* mesh, bool smooth=false, bool angleWeighted=false) const;
|
||||
virtual IMesh* createMeshWithTangents(IMesh* mesh, bool recalculateNormals=false, bool smooth=false, bool angleWeighted=false) const;
|
||||
|
||||
//! Creates a copy of the mesh, which will only consist of S3D2TCoords vertices.
|
||||
virtual IMesh* createMeshWith2TCoords(IMesh* mesh) const;
|
||||
|
Loading…
x
Reference in New Issue
Block a user