From 251b42ad0611824b12bb5df36f3512b6bdebd4f0 Mon Sep 17 00:00:00 2001 From: Viktor Kovacs Date: Mon, 24 May 2021 20:40:34 +0200 Subject: [PATCH] Do not calculate same normal multiple times so triangulation won't effect curved normal calculation. --- source/model/modelfinalization.js | 30 ++++++++++++++++++++-------- test/tests/model_test.js | 33 +++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 8 deletions(-) diff --git a/source/model/modelfinalization.js b/source/model/modelfinalization.js index ac62b10..0306bd5 100644 --- a/source/model/modelfinalization.js +++ b/source/model/modelfinalization.js @@ -6,22 +6,36 @@ OV.FinalizeModel = function (model, getDefaultMaterial) { function AddAverageNormal (mesh, triangle, vertexIndex, triangleNormals, vertexToTriangles) { - // TODO: do not calculate the same normal multiple times - - let averageNormal = new OV.Coord3D (0.0, 0.0, 0.0); - let averageCount = 0; - + function IsNormalInArray (array, normal) + { + for (let i = 0; i < array.length; i++) { + let current = array[i]; + if (OV.CoordIsEqual3D (current, normal)) { + return true; + } + } + return false; + } + + let averageNormals = []; let neigTriangles = vertexToTriangles[vertexIndex]; for (let i = 0; i < neigTriangles.length; i++) { let neigIndex = neigTriangles[i]; let neigTriangle = mesh.GetTriangle (neigIndex); if (triangle.curve === neigTriangle.curve) { - averageNormal = OV.AddCoord3D (averageNormal, triangleNormals[neigIndex]); - averageCount = averageCount + 1; + let triangleNormal = triangleNormals[neigIndex]; + if (!IsNormalInArray (averageNormals, triangleNormal)) { + averageNormals.push (triangleNormal); + } } } + + let averageNormal = new OV.Coord3D (0.0, 0.0, 0.0); + for (let i = 0; i < averageNormals.length; i++) { + averageNormal = OV.AddCoord3D (averageNormal, averageNormals[i]); + } - averageNormal.MultiplyScalar (1.0 / averageCount); + averageNormal.MultiplyScalar (1.0 / averageNormals.length); averageNormal.Normalize (); return mesh.AddNormal (averageNormal); } diff --git a/test/tests/model_test.js b/test/tests/model_test.js index 5031851..6189302 100644 --- a/test/tests/model_test.js +++ b/test/tests/model_test.js @@ -149,6 +149,39 @@ describe ('Model Finalization', function() { assert.strictEqual (normal.y, -0.7071067811865475); assert.strictEqual (normal.z, 0.7071067811865475); }); + + it ('Calculate Curved Normal 2', function () { + var mesh = new OV.Mesh (); + var v0 = mesh.AddVertex (new OV.Coord3D (0.0, 0.0, 0.0)); + var v1 = mesh.AddVertex (new OV.Coord3D (1.0, 0.0, 0.0)); + var v2 = mesh.AddVertex (new OV.Coord3D (1.0, 1.0, 0.0)); + var v3 = mesh.AddVertex (new OV.Coord3D (0.0, 0.0, -1.0)); + var v4 = mesh.AddVertex (new OV.Coord3D (0.0, 1.0, 0.0)); + + var triangle1 = new OV.Triangle (v0, v1, v2); + triangle1.curve = 1; + var triangle2 = new OV.Triangle (v0, v2, v4); + triangle2.curve = 1; + var triangle3 = new OV.Triangle (v0, v3, v1); + triangle3.curve = 1; + + mesh.AddTriangle (triangle1); + mesh.AddTriangle (triangle2); + mesh.AddTriangle (triangle3); + + var model = new OV.Model () + var meshIndex = model.AddMesh (mesh); + + OV.FinalizeModel (model, function () { new OV.Material () }); + + var theMesh = model.GetMesh (meshIndex); + assert.strictEqual (theMesh.NormalCount (), 9); + + var normal = theMesh.GetNormal (0); + assert.strictEqual (normal.x, 0.0); + assert.strictEqual (normal.y, -0.7071067811865475); + assert.strictEqual (normal.z, 0.7071067811865475); + }); }); describe ('Color Conversion', function() {