small changes and code rearrangement
MODIFY
include/irr/asset/IMeshManipulator.h
include/irr/asset/IMeshManipulator.h
@@ -18,20 +18,6 @@ namespace irr
{
namespace asset
{
- //vertex data needed for CSmoothNormalGenerator
- struct SSNGVertexData
- {
- uint32_t indexOffset; //offset of the vertex into index buffer
- uint32_t hash; //
- float wage; //angle wage of the vertex
- core::vector4df_SIMD position; //position of the vertex in 3D space
- core::vector3df_SIMD parentTriangleFaceNormal; //
- };
-
- typedef std::function<bool(const SSNGVertexData&, const SSNGVertexData&, asset::ICPUMeshBuffer*)> VxCmpFunction;
- //function used by IMeshManipulatro::calculateSmoothNormals
- bool defaultVxCmpFunction(const SSNGVertexData& v0, const SSNGVertexData& v1, asset::ICPUMeshBuffer* tirangleSoupMeshBuffer);
-
//! An interface for easy manipulation of meshes.
/** Scale, set alpha value, flip surfaces, and so on. This exists for
fixing problems with wrong imported or exported meshes quickly after
@@ -73,6 +59,18 @@ namespace asset
E_ERROR_METRIC method;
core::vectorSIMDf epsilon;
};
+
+ //vertex data needed for CSmoothNormalGenerator
+ struct SSNGVertexData
+ {
+ uint32_t indexOffset; //offset of the vertex into index buffer
+ uint32_t hash; //
+ float wage; //angle wage of the vertex
+ core::vector4df_SIMD position; //position of the vertex in 3D space
+ core::vector3df_SIMD parentTriangleFaceNormal; //
+ };
+ typedef std::function<bool(const IMeshManipulator::SSNGVertexData&, const IMeshManipulator::SSNGVertexData&, asset::ICPUMeshBuffer*)> VxCmpFunction;
+
public:
//! Flips the direction of surfaces.
/** Changes backfacing triangles to frontfacing
@@ -90,7 +88,12 @@ namespace asset
//
virtual asset::ICPUMeshBuffer* calculateSmoothNormals(asset::ICPUMeshBuffer* inbuffer, float epsilon = 1.525e-5f,
- asset::E_VERTEX_ATTRIBUTE_ID normalAttrID = asset::E_VERTEX_ATTRIBUTE_ID::EVAI_ATTR3, VxCmpFunction vxcmp = defaultVxCmpFunction) const = 0;
+ asset::E_VERTEX_ATTRIBUTE_ID normalAttrID = asset::E_VERTEX_ATTRIBUTE_ID::EVAI_ATTR3,
+ VxCmpFunction vxcmp = [](const IMeshManipulator::SSNGVertexData& v0, const IMeshManipulator::SSNGVertexData& v1, asset::ICPUMeshBuffer* buffer)
+ {
+ static constexpr float cosOf45Deg = 0.70710678118f;
+ return v0.parentTriangleFaceNormal.dotProductAsFloat(v1.parentTriangleFaceNormal) > cosOf45Deg;
+ }) const = 0;
//! Creates a copy of a mesh with vertices welded
/** \param mesh Input mesh

MODIFY
src/irr/asset/CMeshManipulator.cpp
src/irr/asset/CMeshManipulator.cpp
@@ -136,370 +136,6 @@ void CMeshManipulator::flipSurfaces(asset::ICPUMeshBuffer* inbuffer) const
}
}
-
-#ifndef NEW_MESHES
-namespace
-{
-template <typename T>
-void recalculateNormalsT(IMeshBuffer* buffer, bool smooth, bool angleWeighted)
-{
- const uint32_t vtxcnt = buffer->getVertexCount();
- const uint32_t idxcnt = buffer->getIndexCount();
- const T* idx = reinterpret_cast<T*>(buffer->getIndices());
-
- if (!smooth)
- {
- for (uint32_t i=0; i<idxcnt; i+=3)
- {
- const core::vector3df& v1 = buffer->getPosition(idx[i+0]);
- const core::vector3df& v2 = buffer->getPosition(idx[i+1]);
- const core::vector3df& v3 = buffer->getPosition(idx[i+2]);
- const core::vector3df normal = core::plane3d<float>(v1, v2, v3).Normal;
- buffer->getNormal(idx[i+0]) = normal;
- buffer->getNormal(idx[i+1]) = normal;
- buffer->getNormal(idx[i+2]) = normal;
- }
- }
- else
- {
- uint32_t i;
-
- for ( i = 0; i!= vtxcnt; ++i )
- buffer->getNormal(i).set(0.f, 0.f, 0.f);
-
- for ( i=0; i<idxcnt; i+=3)
- {
- const core::vector3df& v1 = buffer->getPosition(idx[i+0]);
- const core::vector3df& v2 = buffer->getPosition(idx[i+1]);
- const core::vector3df& v3 = buffer->getPosition(idx[i+2]);
- const core::vector3df normal = core::plane3d<float>(v1, v2, v3).Normal;
-
- core::vector3df weight(1.f,1.f,1.f);
- if (angleWeighted)
- weight = irr::scene::getAngleWeight(v1,v2,v3); // writing irr::scene:: necessary for borland
-
- buffer->getNormal(idx[i+0]) += weight.X*normal;
- buffer->getNormal(idx[i+1]) += weight.Y*normal;
- buffer->getNormal(idx[i+2]) += weight.Z*normal;
- }
-
- for ( i = 0; i!= vtxcnt; ++i )
- 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()==EIT_16BIT)
- recalculateNormalsT<uint16_t>(buffer, smooth, angleWeighted);
- else
- recalculateNormalsT<uint32_t>(buffer, smooth, angleWeighted);
-}
-
-
-//! Recalculates all normals of the mesh.
-//! \param mesh: Mesh on which the operation is performed.
-void CMeshManipulator::recalculateNormals(scene::IMesh* mesh, bool smooth, bool angleWeighted) const
-{
- if (!mesh)
- return;
-
- const uint32_t bcount = mesh->getMeshBufferCount();
- for ( uint32_t b=0; b<bcount; ++b)
- recalculateNormals(mesh->getMeshBuffer(b), smooth, angleWeighted);
-}
-
-
-namespace
-{
-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
-{
- // 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
-
- float deltaX1 = tc1.X - tc2.X;
- float deltaX2 = tc3.X - tc1.X;
- binormal = (v1 * deltaX2) - (v2 * deltaX1);
- binormal.normalize();
-
- // tangent
-
- float deltaY1 = tc1.Y - tc2.Y;
- float 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<float> 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;
-
- const uint32_t vtxCnt = buffer->getVertexCount();
- const uint32_t idxCnt = buffer->getIndexCount();
-
- T* idx = reinterpret_cast<T*>(buffer->getIndices());
- video::S3DVertexTangents* v =
- (video::S3DVertexTangents*)buffer->getVertices();
-
- if (smooth)
- {
- uint32_t i;
-
- 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 );
- }
-
- //Each vertex gets the sum of the tangents and binormals from the faces around it
- for ( i=0; i<idxCnt; i+=3)
- {
- // 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 = irr::scene::getAngleWeight(v[i+0].Pos,v[i+1].Pos,v[i+2].Pos); // writing irr::scene:: necessary for borland
- 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)
- {
- for ( i = 0; i!= vtxCnt; ++i )
- v[i].Normal.normalize();
- }
- for ( i = 0; i!= vtxCnt; ++i )
- {
- v[i].Tangent.normalize();
- v[i].Binormal.normalize();
- }
- }
- else
- {
- core::vector3df localNormal;
- for (uint32_t 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;
- }
- }
-}
-}
-
-
-//! Recalculates tangents for a tangent mesh buffer
-void CMeshManipulator::recalculateTangents(IMeshBuffer* buffer, bool recalculateNormals, bool smooth, bool angleWeighted) const
-{
- if (buffer && (buffer->getVertexType() == video::EVT_TANGENTS))
- {
- if (buffer->getIndexType() == EIT_16BIT)
- recalculateTangentsT<uint16_t>(buffer, recalculateNormals, smooth, angleWeighted);
- else
- recalculateTangentsT<uint32_t>(buffer, recalculateNormals, smooth, angleWeighted);
- }
-}
-
-
-//! Recalculates tangents for all tangent mesh buffers
-void CMeshManipulator::recalculateTangents(IMesh* mesh, bool recalculateNormals, bool smooth, bool angleWeighted) const
-{
- if (!mesh)
- return;
-
- const uint32_t meshBufferCount = mesh->getMeshBufferCount();
- for (uint32_t b=0; b<meshBufferCount; ++b)
- {
- recalculateTangents(mesh->getMeshBuffer(b), recalculateNormals, smooth, angleWeighted);
- }
-}
-#endif // NEW_MESHES
-
asset::ICPUMeshBuffer* CMeshManipulator::createMeshBufferFetchOptimized(const asset::ICPUMeshBuffer* _inbuffer) const
{
if (!_inbuffer || !_inbuffer->getMeshDataAndFormat() || !_inbuffer->getIndices())

MODIFY
src/irr/asset/CMeshManipulator.h
src/irr/asset/CMeshManipulator.h
@@ -42,32 +42,14 @@ public:
\param mesh: Mesh on which the operation is performed. */
virtual void flipSurfaces(asset::ICPUMeshBuffer* inbuffer) const;
-#ifndef NEW_MESHES
- //! Recalculates all normals of the mesh.
- /** \param mesh: Mesh on which the operation is performed.
- \param smooth: Whether to use smoothed normals. */
- virtual void recalculateNormals(scene::IMesh* mesh, bool smooth = false, bool angleWeighted = false) const;
-
- //! Recalculates all normals of the mesh buffer.
- /** \param buffer: Mesh buffer on which the operation is performed.
- \param smooth: Whether to use smoothed normals. */
- virtual void recalculateNormals(IMeshBuffer* buffer, bool smooth = false, bool angleWeighted = false) 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
- virtual void recalculateTangents(IMesh* mesh, bool recalculateNormals=false, bool smooth=false, bool angleWeighted=false) const;
-#endif // NEW_MESHES
-
virtual asset::ICPUMeshBuffer* createMeshBufferFetchOptimized(const asset::ICPUMeshBuffer* _inbuffer) const;
//! Creates a copy of the mesh, which will only consist of unique triangles, i.e. no vertices are shared.
virtual asset::ICPUMeshBuffer* createMeshBufferUniquePrimitives(asset::ICPUMeshBuffer* inbuffer) const;
//
- virtual asset::ICPUMeshBuffer* calculateSmoothNormals(asset::ICPUMeshBuffer* inbuffer, float epsilon = 1.525e-5f,
- asset::E_VERTEX_ATTRIBUTE_ID normalAttrID = asset::E_VERTEX_ATTRIBUTE_ID::EVAI_ATTR3, VxCmpFunction vxcmp = defaultVxCmpFunction) const override;
+ virtual asset::ICPUMeshBuffer* calculateSmoothNormals(asset::ICPUMeshBuffer* inbuffer, float epsilon,
+ asset::E_VERTEX_ATTRIBUTE_ID normalAttrID, VxCmpFunction vxcmp) const override;
//! Creates a copy of the mesh, which will have all duplicated vertices removed, i.e. maximal amount of vertices are shared via indexing.
virtual asset::ICPUMeshBuffer* createMeshBufferWelded(asset::ICPUMeshBuffer *inbuffer, const SErrorMetric* _errMetrics, const bool& optimIndexType = true, const bool& makeNewMesh=false) const;

MODIFY
src/irr/asset/CSmoothNormalGenerator.cpp
src/irr/asset/CSmoothNormalGenerator.cpp
@@ -8,20 +8,12 @@ namespace irr
{
namespace asset
{
-
-bool defaultVxCmpFunction(const SSNGVertexData& v0, const SSNGVertexData& v1, asset::ICPUMeshBuffer* triangleSoupMeshBuffer)
-{
- static constexpr float cosOf45Deg = 0.70710678118f;
- return v0.parentTriangleFaceNormal.dotProductAsFloat(v1.parentTriangleFaceNormal) > cosOf45Deg;
-}
-
-//needed for upper_bound vertex search
-static inline bool operator<(uint32_t lhs, const SSNGVertexData& rhs)
+static inline bool operator<(uint32_t lhs, const IMeshManipulator::SSNGVertexData& rhs)
{
return lhs < rhs.hash;
}
-static inline bool operator<(const SSNGVertexData& lhs, uint32_t rhs)
+static inline bool operator<(const IMeshManipulator::SSNGVertexData& lhs, uint32_t rhs)
{
return lhs.hash < rhs;
}
@@ -52,7 +44,7 @@ static inline core::vector3df_SIMD getAngleWeight(const core::vector3df_SIMD & v
acosf((b - c + a) / (2.f * bsqrt * asqrt)));
}
-asset::ICPUMeshBuffer* irr::asset::CSmoothNormalGenerator::calculateNormals(asset::ICPUMeshBuffer* buffer, float epsilon, asset::E_VERTEX_ATTRIBUTE_ID normalAttrID, VxCmpFunction vxcmp)
+asset::ICPUMeshBuffer* irr::asset::CSmoothNormalGenerator::calculateNormals(asset::ICPUMeshBuffer* buffer, float epsilon, asset::E_VERTEX_ATTRIBUTE_ID normalAttrID, IMeshManipulator::VxCmpFunction vxcmp)
{
VertexHashMap vertexArray = setupData(buffer, epsilon);
processConnectedVertices(buffer, vertexArray, epsilon, normalAttrID, vxcmp);
@@ -70,7 +62,7 @@ CSmoothNormalGenerator::VertexHashMap::VertexHashMap(size_t _vertexCount, uint32
buckets.reserve(_hashTableMaxSize+1);
}
-uint32_t CSmoothNormalGenerator::VertexHashMap::hash(const SSNGVertexData& vertex) const
+uint32_t CSmoothNormalGenerator::VertexHashMap::hash(const IMeshManipulator::SSNGVertexData& vertex) const
{
static constexpr uint32_t primeNumber1 = 73856093;
static constexpr uint32_t primeNumber2 = 19349663;
@@ -94,7 +86,7 @@ uint32_t CSmoothNormalGenerator::VertexHashMap::hash(const core::vector3du32_SIM
(position.z * primeNumber3)) & (hashTableMaxSize - 1);
}
-void CSmoothNormalGenerator::VertexHashMap::add(SSNGVertexData&& vertex)
+void CSmoothNormalGenerator::VertexHashMap::add(IMeshManipulator::SSNGVertexData&& vertex)
{
vertex.hash = hash(vertex);
vertices.push_back(vertex);
@@ -105,8 +97,8 @@ CSmoothNormalGenerator::VertexHashMap::BucketBounds CSmoothNormalGenerator::Vert
if (hash == invalidHash)
return { vertices.end(), vertices.end() };
- core::vector<SSNGVertexData>::iterator begin = std::lower_bound(vertices.begin(), vertices.end(), hash);
- core::vector<SSNGVertexData>::iterator end = std::upper_bound(vertices.begin(), vertices.end(), hash);
+ core::vector<IMeshManipulator::SSNGVertexData>::iterator begin = std::lower_bound(vertices.begin(), vertices.end(), hash);
+ core::vector<IMeshManipulator::SSNGVertexData>::iterator end = std::upper_bound(vertices.begin(), vertices.end(), hash);
//bucket missing
if(begin == vertices.end())
@@ -121,15 +113,15 @@ CSmoothNormalGenerator::VertexHashMap::BucketBounds CSmoothNormalGenerator::Vert
void CSmoothNormalGenerator::VertexHashMap::validate()
{
- std::sort(vertices.begin(), vertices.end(), [](SSNGVertexData& a, SSNGVertexData& b) { return a.hash < b.hash; });
+ std::sort(vertices.begin(), vertices.end(), [](IMeshManipulator::SSNGVertexData& a, IMeshManipulator::SSNGVertexData& b) { return a.hash < b.hash; });
uint16_t prevHash = vertices[0].hash;
- core::vector<SSNGVertexData>::iterator prevBegin = vertices.begin();
+ core::vector<IMeshManipulator::SSNGVertexData>::iterator prevBegin = vertices.begin();
buckets.push_back(prevBegin);
while (true)
{
- core::vector<SSNGVertexData>::iterator next = std::upper_bound(prevBegin, vertices.end(), prevHash);
+ core::vector<IMeshManipulator::SSNGVertexData>::iterator next = std::upper_bound(prevBegin, vertices.end(), prevHash);
buckets.push_back(next);
if (next == vertices.end())
@@ -143,12 +135,10 @@ void CSmoothNormalGenerator::VertexHashMap::validate()
CSmoothNormalGenerator::VertexHashMap CSmoothNormalGenerator::setupData(asset::ICPUMeshBuffer * buffer, float epsilon)
{
const size_t idxCount = buffer->getIndexCount();
- const size_t vxCount = buffer->calcVertexCount();
_IRR_DEBUG_BREAK_IF((idxCount % 3));
- _IRR_DEBUG_BREAK_IF((idxCount != vxCount));
- VertexHashMap vertices(vxCount, std::min(16u * 1024u, core::roundUpToPoT<unsigned int>(idxCount * 1.0f/32.0f)), epsilon * 1.00001f);
+ VertexHashMap vertices(idxCount, std::min(16u * 1024u, core::roundUpToPoT<unsigned int>(idxCount * 1.0f/32.0f)), epsilon == 0.0f ? 0.00001f : epsilon * 1.00001f);
core::vector3df_SIMD faceNormal;
@@ -175,13 +165,13 @@ CSmoothNormalGenerator::VertexHashMap CSmoothNormalGenerator::setupData(asset::I
return vertices;
}
-void CSmoothNormalGenerator::processConnectedVertices(asset::ICPUMeshBuffer * buffer, VertexHashMap & vertexHashMap, float epsilon, asset::E_VERTEX_ATTRIBUTE_ID normalAttrID, VxCmpFunction vxcmp)
+void CSmoothNormalGenerator::processConnectedVertices(asset::ICPUMeshBuffer * buffer, VertexHashMap & vertexHashMap, float epsilon, asset::E_VERTEX_ATTRIBUTE_ID normalAttrID, IMeshManipulator::VxCmpFunction vxcmp)
{
for (uint32_t cell = 0; cell < vertexHashMap.getBucketCount() - 1; cell++)
{
VertexHashMap::BucketBounds processedBucket = vertexHashMap.getBucketBoundsById(cell);
- for (core::vector<SSNGVertexData>::iterator processedVertex = processedBucket.begin; processedVertex != processedBucket.end; processedVertex++)
+ for (core::vector<IMeshManipulator::SSNGVertexData>::iterator processedVertex = processedBucket.begin; processedVertex != processedBucket.end; processedVertex++)
{
std::array<uint32_t, 8> neighboringCells = vertexHashMap.getNeighboringCellHashes(*processedVertex);
core::vector3df_SIMD normal(0.0f);
@@ -209,7 +199,7 @@ void CSmoothNormalGenerator::processConnectedVertices(asset::ICPUMeshBuffer * bu
}
-std::array<uint32_t, 8> CSmoothNormalGenerator::VertexHashMap::getNeighboringCellHashes(const SSNGVertexData& vertex)
+std::array<uint32_t, 8> CSmoothNormalGenerator::VertexHashMap::getNeighboringCellHashes(const IMeshManipulator::SSNGVertexData& vertex)
{
std::array<uint32_t, 8> neighbourhood;

MODIFY
src/irr/asset/CSmoothNormalGenerator.h
src/irr/asset/CSmoothNormalGenerator.h
#include "irr/asset/IMeshManipulator.h"
#include "irr/core/math/irrMath.h"
-
namespace irr
{
namespace asset
@@ -16,7 +15,7 @@ namespace asset
class CSmoothNormalGenerator
{
public:
- static asset::ICPUMeshBuffer* calculateNormals(asset::ICPUMeshBuffer* buffer, float epsilon, asset::E_VERTEX_ATTRIBUTE_ID normalAttrID, VxCmpFunction function);
+ static asset::ICPUMeshBuffer* calculateNormals(asset::ICPUMeshBuffer* buffer, float epsilon, asset::E_VERTEX_ATTRIBUTE_ID normalAttrID, IMeshManipulator::VxCmpFunction function);
CSmoothNormalGenerator() = delete;
~CSmoothNormalGenerator() = delete;
@@ -27,21 +26,21 @@ private:
public:
struct BucketBounds
{
- core::vector<SSNGVertexData>::iterator begin;
- core::vector<SSNGVertexData>::iterator end;
+ core::vector<IMeshManipulator::SSNGVertexData>::iterator begin;
+ core::vector<IMeshManipulator::SSNGVertexData>::iterator end;
};
public:
VertexHashMap(size_t _vertexCount, uint32_t _hashTableMaxSize, float _cellSize);
//inserts vertex into hash table
- void add(SSNGVertexData&& vertex);
+ void add(IMeshManipulator::SSNGVertexData&& vertex);
//sorts hashtable and sets iterators at beginnings of bucktes
void validate();
//
- std::array<uint32_t, 8> getNeighboringCellHashes(const SSNGVertexData& vertex);
+ std::array<uint32_t, 8> getNeighboringCellHashes(const IMeshManipulator::SSNGVertexData& vertex);
inline uint32_t getBucketCount() const { return buckets.size(); }
inline BucketBounds getBucketBoundsById(uint32_t index) { return { buckets[index], buckets[index + 1] }; }
@@ -52,20 +51,20 @@ private:
private:
//holds iterators pointing to beginning of each bucket, last iterator points to vertices.end()
- core::vector<core::vector<SSNGVertexData>::iterator> buckets;
- core::vector<SSNGVertexData> vertices;
+ core::vector<core::vector<IMeshManipulator::SSNGVertexData>::iterator> buckets;
+ core::vector<IMeshManipulator::SSNGVertexData> vertices;
const uint32_t hashTableMaxSize;
const float cellSize;
private:
- uint32_t hash(const SSNGVertexData& vertex) const;
+ uint32_t hash(const IMeshManipulator::SSNGVertexData& vertex) const;
uint32_t hash(const core::vector3du32_SIMD& position) const;
};
private:
static VertexHashMap setupData(asset::ICPUMeshBuffer* buffer, float epsilon);
- static void processConnectedVertices(asset::ICPUMeshBuffer* buffer, VertexHashMap& vertices, float epsilon, asset::E_VERTEX_ATTRIBUTE_ID normalAttrID, VxCmpFunction vxcmp);
+ static void processConnectedVertices(asset::ICPUMeshBuffer* buffer, VertexHashMap& vertices, float epsilon, asset::E_VERTEX_ATTRIBUTE_ID normalAttrID, IMeshManipulator::VxCmpFunction vxcmp);
};

small changes and code rearrangement