@@ -29,13 +29,18 @@ static bool compareVertexPosition(const hlsl::float32_t3& a, const hlsl::float32
2929 return (difference.x <= epsilon && difference.y <= epsilon && difference.z <= epsilon);
3030}
3131
32- CSmoothNormalGenerator::Result CSmoothNormalGenerator::calculateNormals (const asset::ICPUPolygonGeometry* polygon, float epsilon, VxCmpFunction vxcmp)
32+ CSmoothNormalGenerator::Result CSmoothNormalGenerator::calculateNormals (const asset::ICPUPolygonGeometry* polygon, float epsilon, VxCmpFunction vxcmp, const bool recomputeHash )
3333{
3434 assert (polygon->getIndexingCallback ()->degree () == 3 );
35+
3536 static constexpr auto MinEpsilon = 0 .00001f ;
3637 const auto patchedEpsilon = epsilon < MinEpsilon ? MinEpsilon : epsilon;
3738 VertexHashMap vertexHashMap = setupData (polygon, patchedEpsilon);
39+
3840 const auto smoothPolygon = processConnectedVertices (polygon, vertexHashMap, patchedEpsilon,vxcmp);
41+ if (recomputeHash)
42+ CPolygonGeometryManipulator::recomputeContentHashes (smoothPolygon.get ());
43+
3944 return { vertexHashMap, smoothPolygon };
4045}
4146
@@ -51,33 +56,42 @@ CSmoothNormalGenerator::VertexHashMap CSmoothNormalGenerator::setupData(const as
5156 {
5257 // calculate face normal of parent triangle
5358 hlsl::float32_t3 v0, v1, v2;
59+ // TODO: could iterate over an index buffer properly
5460 polygon->getPositionView ().decodeElement <hlsl::float32_t3>(i, v0);
5561 polygon->getPositionView ().decodeElement <hlsl::float32_t3>(i + 1 , v1);
5662 polygon->getPositionView ().decodeElement <hlsl::float32_t3>(i + 2 , v2);
5763
58- const auto faceNormal = normalize (cross (v1 - v0, v2 - v0));
64+ auto faceNormal = cross (v1 - v0, v2 - v0);
65+ // if any triangle edge is 0 length, the cross product will be 0 length too
66+ const float normLen2 = dot (faceNormal,faceNormal);
67+ // need to filter invalid triangles while we're at it
68+ if (normLen2<hlsl::numeric_limits<float >::min)
69+ continue ;
70+ faceNormal *= hlsl::rsqrt (normLen2);
5971
6072 // set data for m_vertices
61- const auto angleWages = hlsl::shapes::util::anglesFromTriangleEdges (v2 - v1, v0 - v2, v1 - v2);
73+ const auto angleWeights = hlsl::shapes::util::anglesFromTriangleEdges (v2 - v1, v0 - v2, v1 - v2);
6274
63- vertices.add ({ i, 0 , faceNormal * angleWages .x , v0});
64- vertices.add ({ i + 1 , 0 , faceNormal * angleWages .y ,v1});
65- vertices.add ({ i + 2 , 0 , faceNormal * angleWages .z , v2});
75+ vertices.add ({ i, 0 , faceNormal * angleWeights .x , v0});
76+ vertices.add ({ i + 1 , 0 , faceNormal * angleWeights .y ,v1});
77+ vertices.add ({ i + 2 , 0 , faceNormal * angleWeights .z , v2});
6678 }
6779
6880 vertices.bake ();
6981
7082 return vertices;
7183}
7284
73- core::smart_refctd_ptr<ICPUPolygonGeometry> CSmoothNormalGenerator::processConnectedVertices (const asset::ICPUPolygonGeometry* polygon, VertexHashMap& vertexHashMap, float epsilon, VxCmpFunction vxcmp)
85+ core::smart_refctd_ptr<ICPUPolygonGeometry> CSmoothNormalGenerator::processConnectedVertices (const asset::ICPUPolygonGeometry* polygon, VertexHashMap& vertexHashMap, const float epsilon, VxCmpFunction vxcmp)
7486{
87+ // TODO: its semi doable to defer unwelding/rewelding until later an just work on a duplicated normal buffer only
7588 auto outPolygon = core::move_and_static_cast<ICPUPolygonGeometry>(polygon->clone (0u ));
7689 static constexpr auto NormalFormat = EF_R32G32B32_SFLOAT;
7790 const auto normalFormatBytesize = asset::getTexelOrBlockBytesize (NormalFormat);
7891 auto normalBuf = ICPUBuffer::create ({ normalFormatBytesize * outPolygon->getPositionView ().getElementCount ()});
7992 auto normalView = polygon->getNormalView ();
8093
94+ // TODO: compute actual range
8195 hlsl::shapes::AABB<4 ,hlsl::float32_t > aabb;
8296 aabb.maxVx = hlsl::float32_t4 (1 , 1 , 1 , 0 .f );
8397 aabb.minVx = -aabb.maxVx ;
@@ -118,8 +132,6 @@ core::smart_refctd_ptr<ICPUPolygonGeometry> CSmoothNormalGenerator::processConne
118132 memcpy (normalPtr + (normalStride * processedVertex.index ), &normal, sizeof (normal));
119133 }
120134
121- CPolygonGeometryManipulator::recomputeContentHashes (outPolygon.get ());
122-
123135 return outPolygon;
124136}
125137
0 commit comments