From 4250ab3b58a2f83abbe61350d530e21c72815d8c Mon Sep 17 00:00:00 2001 From: kovacsv Date: Sun, 24 Oct 2021 16:46:49 +0200 Subject: [PATCH] Add mesh instance object that represents a mesh with transformation. --- sandbox/embed_selfhost_errors.html | 2 +- sandbox/embed_selfhost_externallibs.html | 2 +- sandbox/embed_selfhost_fullscreen.html | 2 +- sandbox/embed_selfhost_manual.html | 2 +- sandbox/embed_selfhost_multiple.html | 2 +- sandbox/embed_selfhost_single.html | 2 +- sandbox/embed_selfhost_single_scroll.html | 2 +- source/model/mesh.js | 2 +- source/model/meshinstance.js | 52 ++++++++++++++++++ source/model/model.js | 2 +- source/model/modelutils.js | 18 +++--- source/model/{element.js => object.js} | 67 +++++++++++++---------- source/model/quantities.js | 10 ++-- test/tests/modelutils_test.js | 9 +++ test/tests/quantities_test.js | 12 +++- tools/config.json | 3 +- website/embed.html | 2 +- website/index.html | 2 +- website/o3dv/js/detailssidebarpanel.js | 18 +++--- website/o3dv/js/website.js | 4 +- 20 files changed, 147 insertions(+), 68 deletions(-) create mode 100644 source/model/meshinstance.js rename source/model/{element.js => object.js} (88%) diff --git a/sandbox/embed_selfhost_errors.html b/sandbox/embed_selfhost_errors.html index 85acc1f..d1614ea 100644 --- a/sandbox/embed_selfhost_errors.html +++ b/sandbox/embed_selfhost_errors.html @@ -30,7 +30,7 @@ - + diff --git a/sandbox/embed_selfhost_externallibs.html b/sandbox/embed_selfhost_externallibs.html index 2f2af70..e7c3a17 100644 --- a/sandbox/embed_selfhost_externallibs.html +++ b/sandbox/embed_selfhost_externallibs.html @@ -30,7 +30,7 @@ - + diff --git a/sandbox/embed_selfhost_fullscreen.html b/sandbox/embed_selfhost_fullscreen.html index b02b445..6683967 100644 --- a/sandbox/embed_selfhost_fullscreen.html +++ b/sandbox/embed_selfhost_fullscreen.html @@ -29,7 +29,7 @@ - + diff --git a/sandbox/embed_selfhost_manual.html b/sandbox/embed_selfhost_manual.html index 9a5cd75..8c0f98e 100644 --- a/sandbox/embed_selfhost_manual.html +++ b/sandbox/embed_selfhost_manual.html @@ -30,7 +30,7 @@ - + diff --git a/sandbox/embed_selfhost_multiple.html b/sandbox/embed_selfhost_multiple.html index 0b90d10..8f9ca55 100644 --- a/sandbox/embed_selfhost_multiple.html +++ b/sandbox/embed_selfhost_multiple.html @@ -30,7 +30,7 @@ - + diff --git a/sandbox/embed_selfhost_single.html b/sandbox/embed_selfhost_single.html index f981cec..ce60632 100644 --- a/sandbox/embed_selfhost_single.html +++ b/sandbox/embed_selfhost_single.html @@ -29,7 +29,7 @@ - + diff --git a/sandbox/embed_selfhost_single_scroll.html b/sandbox/embed_selfhost_single_scroll.html index 02aad68..fe5ad7b 100644 --- a/sandbox/embed_selfhost_single_scroll.html +++ b/sandbox/embed_selfhost_single_scroll.html @@ -29,7 +29,7 @@ - + diff --git a/source/model/mesh.js b/source/model/mesh.js index 067a980..7da4b51 100644 --- a/source/model/mesh.js +++ b/source/model/mesh.js @@ -1,4 +1,4 @@ -OV.Mesh = class extends OV.Element +OV.Mesh = class extends OV.ModelObject3D { constructor () { diff --git a/source/model/meshinstance.js b/source/model/meshinstance.js new file mode 100644 index 0000000..f4c96f4 --- /dev/null +++ b/source/model/meshinstance.js @@ -0,0 +1,52 @@ +OV.MeshInstance = class extends OV.Object3D +{ + constructor (mesh, transformation) + { + super (); + this.mesh = mesh; + this.transformation = transformation; + } + + VertexCount () + { + return this.mesh.VertexCount (); + } + + NormalCount () + { + return this.mesh.NormalCount (); + } + + TextureUVCount () + { + return this.mesh.TextureUVCount (); + } + + TriangleCount () + { + return this.mesh.TriangleCount (); + } + + EnumerateVertices (onVertex) + { + this.mesh.EnumerateVertices ((vertex) => { + const transformed = this.transformation.TransformCoord3D (vertex); + onVertex (transformed); + }); + } + + EnumerateTriangles (onTriangle) + { + this.mesh.EnumerateTriangles (onTriangle); + } + + EnumerateTriangleVertices (onTriangleVertices) + { + this.mesh.EnumerateTriangleVertices ((v0, v1, v2) => { + const v0Transformed = this.transformation.TransformCoord3D (v0); + const v1Transformed = this.transformation.TransformCoord3D (v1); + const v2Transformed = this.transformation.TransformCoord3D (v2); + onTriangleVertices (v0Transformed, v1Transformed, v2Transformed); + }); + } +}; diff --git a/source/model/model.js b/source/model/model.js index e6d8f28..c968bf5 100644 --- a/source/model/model.js +++ b/source/model/model.js @@ -12,7 +12,7 @@ OV.MeshInstanceId = class } }; -OV.Model = class extends OV.Element +OV.Model = class extends OV.ModelObject3D { constructor () { diff --git a/source/model/modelutils.js b/source/model/modelutils.js index de781ee..e36bfb3 100644 --- a/source/model/modelutils.js +++ b/source/model/modelutils.js @@ -165,24 +165,24 @@ OV.EnumerateModelVerticesAndTriangles = function (model, callbacks) }); }; -OV.EnumerateTrianglesWithNormals = function (element, onTriangle) +OV.EnumerateTrianglesWithNormals = function (object3D, onTriangle) { - element.EnumerateTriangleVertices ((v0, v1, v2) => { + object3D.EnumerateTriangleVertices ((v0, v1, v2) => { let normal = OV.CalculateTriangleNormal (v0, v1, v2); onTriangle (v0, v1, v2, normal); }); }; -OV.GetBoundingBox = function (element) +OV.GetBoundingBox = function (object3D) { let calculator = new OV.BoundingBoxCalculator3D (); - element.EnumerateVertices ((vertex) => { + object3D.EnumerateVertices ((vertex) => { calculator.AddPoint (vertex); }); return calculator.GetBox (); }; -OV.GetTopology = function (element) +OV.GetTopology = function (object3D) { function GetVertexIndex (vertex, octree, topology) { @@ -194,11 +194,11 @@ OV.GetTopology = function (element) return index; } - let boundingBox = OV.GetBoundingBox (element); + let boundingBox = OV.GetBoundingBox (object3D); let octree = new OV.Octree (boundingBox); let topology = new OV.Topology (); - element.EnumerateTriangleVertices ((v0, v1, v2) => { + object3D.EnumerateTriangleVertices ((v0, v1, v2) => { let v0Index = GetVertexIndex (v0, octree, topology); let v1Index = GetVertexIndex (v1, octree, topology); let v2Index = GetVertexIndex (v2, octree, topology); @@ -207,7 +207,7 @@ OV.GetTopology = function (element) return topology; }; -OV.IsSolid = function (element) +OV.IsSolid = function (object3D) { function GetEdgeOrientationInTriangle (topology, triangleIndex, edgeIndex) { @@ -227,7 +227,7 @@ OV.IsSolid = function (element) return null; } - const topology = OV.GetTopology (element); + const topology = OV.GetTopology (object3D); for (let edgeIndex = 0; edgeIndex < topology.edges.length; edgeIndex++) { const edge = topology.edges[edgeIndex]; let triCount = edge.triangles.length; diff --git a/source/model/element.js b/source/model/object.js similarity index 88% rename from source/model/element.js rename to source/model/object.js index 7762472..7b213a3 100644 --- a/source/model/element.js +++ b/source/model/object.js @@ -1,21 +1,10 @@ -OV.Element = class +OV.Object3D = class { constructor () { - this.name = ''; - this.propertyGroups = []; + } - GetName () - { - return this.name; - } - - SetName (name) - { - this.name = name; - } - VertexCount () { return 0; @@ -36,22 +25,6 @@ OV.Element = class return 0; } - PropertyGroupCount () - { - return this.propertyGroups.length; - } - - AddPropertyGroup (propertyGroup) - { - this.propertyGroups.push (propertyGroup); - return this.propertyGroups.length - 1; - } - - GetPropertyGroup (index) - { - return this.propertyGroups[index]; - } - EnumerateVertices (onVertex) { @@ -67,3 +40,39 @@ OV.Element = class } }; + +OV.ModelObject3D = class extends OV.Object3D +{ + constructor () + { + super (); + this.name = ''; + this.propertyGroups = []; + } + + GetName () + { + return this.name; + } + + SetName (name) + { + this.name = name; + } + + PropertyGroupCount () + { + return this.propertyGroups.length; + } + + AddPropertyGroup (propertyGroup) + { + this.propertyGroups.push (propertyGroup); + return this.propertyGroups.length - 1; + } + + GetPropertyGroup (index) + { + return this.propertyGroups[index]; + } +}; diff --git a/source/model/quantities.js b/source/model/quantities.js index 14be1f3..c7fdf05 100644 --- a/source/model/quantities.js +++ b/source/model/quantities.js @@ -16,22 +16,22 @@ OV.GetTetrahedronSignedVolume = function (v0, v1, v2) return OV.DotVector3D (v0, OV.CrossVector3D (v1, v2)) / 6.0; }; -OV.CalculateVolume = function (element) +OV.CalculateVolume = function (object3D) { - if (!OV.IsSolid (element)) { + if (!OV.IsSolid (object3D)) { return null; } let volume = 0.0; - element.EnumerateTriangleVertices ((v0, v1, v2) => { + object3D.EnumerateTriangleVertices ((v0, v1, v2) => { volume += OV.GetTetrahedronSignedVolume (v0, v1, v2); }); return volume; }; -OV.CalculateSurfaceArea = function (element) +OV.CalculateSurfaceArea = function (object3D) { let surface = 0.0; - element.EnumerateTriangleVertices ((v0, v1, v2) => { + object3D.EnumerateTriangleVertices ((v0, v1, v2) => { surface += OV.GetTriangleArea (v0, v1, v2); }); return surface; diff --git a/test/tests/modelutils_test.js b/test/tests/modelutils_test.js index 24f2b3e..9e02b74 100644 --- a/test/tests/modelutils_test.js +++ b/test/tests/modelutils_test.js @@ -86,6 +86,15 @@ describe ('Model Utils', function () { assert (OV.CoordIsEqual3D (cubeBounds.max, new OV.Coord3D (1.0, 1.0, 1.0))); }); + it ('Mesh Instance Bounding Box', function () { + let cube = OV.GenerateCuboid (null, 1.0, 1.0, 1.0); + let transformation = new OV.Transformation (new OV.Matrix ().CreateTranslation (2.0, 0.0, 0.0)); + let cubeInstance = new OV.MeshInstance (cube, transformation); + let cubeInstanceBounds = OV.GetBoundingBox (cubeInstance); + assert (OV.CoordIsEqual3D (cubeInstanceBounds.min, new OV.Coord3D (2.0, 0.0, 0.0))); + assert (OV.CoordIsEqual3D (cubeInstanceBounds.max, new OV.Coord3D (3.0, 1.0, 1.0))); + }); + it ('Model Bounding Box', function () { var model = new OV.Model (); diff --git a/test/tests/quantities_test.js b/test/tests/quantities_test.js index ebfa03c..417d939 100644 --- a/test/tests/quantities_test.js +++ b/test/tests/quantities_test.js @@ -72,7 +72,7 @@ describe ('Quantities', function () { }); it ('Tetrahedron Volume Calculation', function () { - let edgeLength = OV.CoordDistance3D (new OV.Coord3D (1.0, 1.0, 1.0), new OV.Coord3D (-1.0, -1.0, 1.0)); + const edgeLength = OV.CoordDistance3D (new OV.Coord3D (1.0, 1.0, 1.0), new OV.Coord3D (-1.0, -1.0, 1.0)); const mesh = testUtils.GetTetrahedronMesh (); const model = testUtils.GetModelWithOneMesh (mesh); assert (OV.IsEqual (OV.CalculateVolume (mesh), Math.pow (edgeLength, 3.0) / (6.0 * Math.sqrt (2)))); @@ -80,10 +80,18 @@ describe ('Quantities', function () { }); it ('Tetrahedron Surface Area Calculation', function () { - let edgeLength = OV.CoordDistance3D (new OV.Coord3D (1.0, 1.0, 1.0), new OV.Coord3D (-1.0, -1.0, 1.0)); + const edgeLength = OV.CoordDistance3D (new OV.Coord3D (1.0, 1.0, 1.0), new OV.Coord3D (-1.0, -1.0, 1.0)); const mesh = testUtils.GetTetrahedronMesh (); const model = testUtils.GetModelWithOneMesh (mesh); assert (OV.IsEqual (OV.CalculateSurfaceArea (mesh), Math.sqrt (3) * Math.pow (edgeLength, 2.0))); assert (OV.IsEqual (OV.CalculateSurfaceArea (model), Math.sqrt (3) * Math.pow (edgeLength, 2.0))); }); + + it ('Cube Scaled Volume and Area Calculation', function () { + const mesh = OV.GenerateCuboid (null, 1.0, 1.0, 1.0); + const transformation = new OV.Transformation (new OV.Matrix ().CreateScale (2.0, 2.0, 2.0)); + const meshInstance = new OV.MeshInstance (mesh, transformation); + assert (OV.IsEqual (OV.CalculateVolume (meshInstance), 8.0)); + assert (OV.IsEqual (OV.CalculateSurfaceArea (meshInstance), 24.0)); + }); }); diff --git a/tools/config.json b/tools/config.json index 6162121..6c4fcc8 100644 --- a/tools/config.json +++ b/tools/config.json @@ -26,8 +26,9 @@ "source/model/material.js", "source/model/triangle.js", "source/model/property.js", - "source/model/element.js", + "source/model/object.js", "source/model/mesh.js", + "source/model/meshinstance.js", "source/model/meshbuffer.js", "source/model/node.js", "source/model/model.js", diff --git a/website/embed.html b/website/embed.html index c74252e..8607cde 100644 --- a/website/embed.html +++ b/website/embed.html @@ -39,7 +39,7 @@ - + diff --git a/website/index.html b/website/index.html index 291ab02..361fc80 100644 --- a/website/index.html +++ b/website/index.html @@ -39,7 +39,7 @@ - + diff --git a/website/o3dv/js/detailssidebarpanel.js b/website/o3dv/js/detailssidebarpanel.js index b0da02a..b1ddaf0 100644 --- a/website/o3dv/js/detailssidebarpanel.js +++ b/website/o3dv/js/detailssidebarpanel.js @@ -10,35 +10,35 @@ OV.DetailsSidebarPanel = class extends OV.SidebarPanel return 'Details'; } - AddElementProperties (element) + AddObject3DProperties (object3D) { this.Clear (); let table = $('
').addClass ('ov_property_table').appendTo (this.contentDiv); - let boundingBox = OV.GetBoundingBox (element); + let boundingBox = OV.GetBoundingBox (object3D); let size = OV.SubCoord3D (boundingBox.max, boundingBox.min); - this.AddProperty (table, new OV.Property (OV.PropertyType.Integer, 'Vertex Count', element.VertexCount ())); - this.AddProperty (table, new OV.Property (OV.PropertyType.Integer, 'Triangle Count', element.TriangleCount ())); + this.AddProperty (table, new OV.Property (OV.PropertyType.Integer, 'Vertex Count', object3D.VertexCount ())); + this.AddProperty (table, new OV.Property (OV.PropertyType.Integer, 'Triangle Count', object3D.TriangleCount ())); this.AddProperty (table, new OV.Property (OV.PropertyType.Number, 'Size X', size.x)); this.AddProperty (table, new OV.Property (OV.PropertyType.Number, 'Size Y', size.y)); this.AddProperty (table, new OV.Property (OV.PropertyType.Number, 'Size Z', size.z)); this.AddCalculatedProperty (table, 'Volume', () => { - const volume = OV.CalculateVolume (element); + const volume = OV.CalculateVolume (object3D); if (volume === null) { return null; } return new OV.Property (OV.PropertyType.Number, null, volume); }); this.AddCalculatedProperty (table, 'Surface Area', () => { - const volume = OV.CalculateSurfaceArea (element); + const volume = OV.CalculateSurfaceArea (object3D); if (volume === null) { return null; } return new OV.Property (OV.PropertyType.Number, null, volume); }); - if (element.PropertyGroupCount () > 0) { + if (object3D.PropertyGroupCount () > 0) { let customTable = $('
').addClass ('ov_property_table ov_property_table_custom').appendTo (this.contentDiv); - for (let i = 0; i < element.PropertyGroupCount (); i++) { - const propertyGroup = element.GetPropertyGroup (i); + for (let i = 0; i < object3D.PropertyGroupCount (); i++) { + const propertyGroup = object3D.GetPropertyGroup (i); this.AddPropertyGroup (customTable, propertyGroup); for (let j = 0; j < propertyGroup.PropertyCount (); j++) { const property = propertyGroup.GetProperty (j); diff --git a/website/o3dv/js/website.js b/website/o3dv/js/website.js index 7368ec2..491c09b 100644 --- a/website/o3dv/js/website.js +++ b/website/o3dv/js/website.js @@ -695,10 +695,10 @@ OV.Website = class return GetMaterialsForModel (this.model); }, onModelSelected : () => { - this.detailsPanel.AddElementProperties (this.model); + this.detailsPanel.AddObject3DProperties (this.model); }, onMeshSelected : (meshIndex) => { - this.detailsPanel.AddElementProperties (this.model.GetMesh (meshIndex)); + this.detailsPanel.AddObject3DProperties (this.model.GetMesh (meshIndex)); }, onMaterialSelected : (materialIndex) => { this.detailsPanel.AddMaterialProperties (this.model.GetMaterial (materialIndex));