Add mesh instance object that represents a mesh with transformation.

This commit is contained in:
kovacsv 2021-10-24 16:46:49 +02:00
parent f045d214c7
commit 4250ab3b58
20 changed files with 147 additions and 68 deletions

View File

@ -30,7 +30,7 @@
<script type="text/javascript" src="../source/model/material.js"></script> <script type="text/javascript" src="../source/model/material.js"></script>
<script type="text/javascript" src="../source/model/triangle.js"></script> <script type="text/javascript" src="../source/model/triangle.js"></script>
<script type="text/javascript" src="../source/model/property.js"></script> <script type="text/javascript" src="../source/model/property.js"></script>
<script type="text/javascript" src="../source/model/element.js"></script> <script type="text/javascript" src="../source/model/object.js"></script>
<script type="text/javascript" src="../source/model/mesh.js"></script> <script type="text/javascript" src="../source/model/mesh.js"></script>
<script type="text/javascript" src="../source/model/meshbuffer.js"></script> <script type="text/javascript" src="../source/model/meshbuffer.js"></script>
<script type="text/javascript" src="../source/model/node.js"></script> <script type="text/javascript" src="../source/model/node.js"></script>

View File

@ -30,7 +30,7 @@
<script type="text/javascript" src="../source/model/material.js"></script> <script type="text/javascript" src="../source/model/material.js"></script>
<script type="text/javascript" src="../source/model/triangle.js"></script> <script type="text/javascript" src="../source/model/triangle.js"></script>
<script type="text/javascript" src="../source/model/property.js"></script> <script type="text/javascript" src="../source/model/property.js"></script>
<script type="text/javascript" src="../source/model/element.js"></script> <script type="text/javascript" src="../source/model/object.js"></script>
<script type="text/javascript" src="../source/model/mesh.js"></script> <script type="text/javascript" src="../source/model/mesh.js"></script>
<script type="text/javascript" src="../source/model/meshbuffer.js"></script> <script type="text/javascript" src="../source/model/meshbuffer.js"></script>
<script type="text/javascript" src="../source/model/node.js"></script> <script type="text/javascript" src="../source/model/node.js"></script>

View File

@ -29,7 +29,7 @@
<script type="text/javascript" src="../source/model/material.js"></script> <script type="text/javascript" src="../source/model/material.js"></script>
<script type="text/javascript" src="../source/model/triangle.js"></script> <script type="text/javascript" src="../source/model/triangle.js"></script>
<script type="text/javascript" src="../source/model/property.js"></script> <script type="text/javascript" src="../source/model/property.js"></script>
<script type="text/javascript" src="../source/model/element.js"></script> <script type="text/javascript" src="../source/model/object.js"></script>
<script type="text/javascript" src="../source/model/mesh.js"></script> <script type="text/javascript" src="../source/model/mesh.js"></script>
<script type="text/javascript" src="../source/model/meshbuffer.js"></script> <script type="text/javascript" src="../source/model/meshbuffer.js"></script>
<script type="text/javascript" src="../source/model/node.js"></script> <script type="text/javascript" src="../source/model/node.js"></script>

View File

@ -30,7 +30,7 @@
<script type="text/javascript" src="../source/model/material.js"></script> <script type="text/javascript" src="../source/model/material.js"></script>
<script type="text/javascript" src="../source/model/triangle.js"></script> <script type="text/javascript" src="../source/model/triangle.js"></script>
<script type="text/javascript" src="../source/model/property.js"></script> <script type="text/javascript" src="../source/model/property.js"></script>
<script type="text/javascript" src="../source/model/element.js"></script> <script type="text/javascript" src="../source/model/object.js"></script>
<script type="text/javascript" src="../source/model/mesh.js"></script> <script type="text/javascript" src="../source/model/mesh.js"></script>
<script type="text/javascript" src="../source/model/meshbuffer.js"></script> <script type="text/javascript" src="../source/model/meshbuffer.js"></script>
<script type="text/javascript" src="../source/model/node.js"></script> <script type="text/javascript" src="../source/model/node.js"></script>

View File

@ -30,7 +30,7 @@
<script type="text/javascript" src="../source/model/material.js"></script> <script type="text/javascript" src="../source/model/material.js"></script>
<script type="text/javascript" src="../source/model/triangle.js"></script> <script type="text/javascript" src="../source/model/triangle.js"></script>
<script type="text/javascript" src="../source/model/property.js"></script> <script type="text/javascript" src="../source/model/property.js"></script>
<script type="text/javascript" src="../source/model/element.js"></script> <script type="text/javascript" src="../source/model/object.js"></script>
<script type="text/javascript" src="../source/model/mesh.js"></script> <script type="text/javascript" src="../source/model/mesh.js"></script>
<script type="text/javascript" src="../source/model/meshbuffer.js"></script> <script type="text/javascript" src="../source/model/meshbuffer.js"></script>
<script type="text/javascript" src="../source/model/node.js"></script> <script type="text/javascript" src="../source/model/node.js"></script>

View File

@ -29,7 +29,7 @@
<script type="text/javascript" src="../source/model/material.js"></script> <script type="text/javascript" src="../source/model/material.js"></script>
<script type="text/javascript" src="../source/model/triangle.js"></script> <script type="text/javascript" src="../source/model/triangle.js"></script>
<script type="text/javascript" src="../source/model/property.js"></script> <script type="text/javascript" src="../source/model/property.js"></script>
<script type="text/javascript" src="../source/model/element.js"></script> <script type="text/javascript" src="../source/model/object.js"></script>
<script type="text/javascript" src="../source/model/mesh.js"></script> <script type="text/javascript" src="../source/model/mesh.js"></script>
<script type="text/javascript" src="../source/model/meshbuffer.js"></script> <script type="text/javascript" src="../source/model/meshbuffer.js"></script>
<script type="text/javascript" src="../source/model/node.js"></script> <script type="text/javascript" src="../source/model/node.js"></script>

View File

@ -29,7 +29,7 @@
<script type="text/javascript" src="../source/model/material.js"></script> <script type="text/javascript" src="../source/model/material.js"></script>
<script type="text/javascript" src="../source/model/triangle.js"></script> <script type="text/javascript" src="../source/model/triangle.js"></script>
<script type="text/javascript" src="../source/model/property.js"></script> <script type="text/javascript" src="../source/model/property.js"></script>
<script type="text/javascript" src="../source/model/element.js"></script> <script type="text/javascript" src="../source/model/object.js"></script>
<script type="text/javascript" src="../source/model/mesh.js"></script> <script type="text/javascript" src="../source/model/mesh.js"></script>
<script type="text/javascript" src="../source/model/meshbuffer.js"></script> <script type="text/javascript" src="../source/model/meshbuffer.js"></script>
<script type="text/javascript" src="../source/model/node.js"></script> <script type="text/javascript" src="../source/model/node.js"></script>

View File

@ -1,4 +1,4 @@
OV.Mesh = class extends OV.Element OV.Mesh = class extends OV.ModelObject3D
{ {
constructor () constructor ()
{ {

View File

@ -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);
});
}
};

View File

@ -12,7 +12,7 @@ OV.MeshInstanceId = class
} }
}; };
OV.Model = class extends OV.Element OV.Model = class extends OV.ModelObject3D
{ {
constructor () constructor ()
{ {

View File

@ -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); let normal = OV.CalculateTriangleNormal (v0, v1, v2);
onTriangle (v0, v1, v2, normal); onTriangle (v0, v1, v2, normal);
}); });
}; };
OV.GetBoundingBox = function (element) OV.GetBoundingBox = function (object3D)
{ {
let calculator = new OV.BoundingBoxCalculator3D (); let calculator = new OV.BoundingBoxCalculator3D ();
element.EnumerateVertices ((vertex) => { object3D.EnumerateVertices ((vertex) => {
calculator.AddPoint (vertex); calculator.AddPoint (vertex);
}); });
return calculator.GetBox (); return calculator.GetBox ();
}; };
OV.GetTopology = function (element) OV.GetTopology = function (object3D)
{ {
function GetVertexIndex (vertex, octree, topology) function GetVertexIndex (vertex, octree, topology)
{ {
@ -194,11 +194,11 @@ OV.GetTopology = function (element)
return index; return index;
} }
let boundingBox = OV.GetBoundingBox (element); let boundingBox = OV.GetBoundingBox (object3D);
let octree = new OV.Octree (boundingBox); let octree = new OV.Octree (boundingBox);
let topology = new OV.Topology (); let topology = new OV.Topology ();
element.EnumerateTriangleVertices ((v0, v1, v2) => { object3D.EnumerateTriangleVertices ((v0, v1, v2) => {
let v0Index = GetVertexIndex (v0, octree, topology); let v0Index = GetVertexIndex (v0, octree, topology);
let v1Index = GetVertexIndex (v1, octree, topology); let v1Index = GetVertexIndex (v1, octree, topology);
let v2Index = GetVertexIndex (v2, octree, topology); let v2Index = GetVertexIndex (v2, octree, topology);
@ -207,7 +207,7 @@ OV.GetTopology = function (element)
return topology; return topology;
}; };
OV.IsSolid = function (element) OV.IsSolid = function (object3D)
{ {
function GetEdgeOrientationInTriangle (topology, triangleIndex, edgeIndex) function GetEdgeOrientationInTriangle (topology, triangleIndex, edgeIndex)
{ {
@ -227,7 +227,7 @@ OV.IsSolid = function (element)
return null; return null;
} }
const topology = OV.GetTopology (element); const topology = OV.GetTopology (object3D);
for (let edgeIndex = 0; edgeIndex < topology.edges.length; edgeIndex++) { for (let edgeIndex = 0; edgeIndex < topology.edges.length; edgeIndex++) {
const edge = topology.edges[edgeIndex]; const edge = topology.edges[edgeIndex];
let triCount = edge.triangles.length; let triCount = edge.triangles.length;

View File

@ -1,19 +1,8 @@
OV.Element = class OV.Object3D = class
{ {
constructor () constructor ()
{ {
this.name = '';
this.propertyGroups = [];
}
GetName ()
{
return this.name;
}
SetName (name)
{
this.name = name;
} }
VertexCount () VertexCount ()
@ -36,22 +25,6 @@ OV.Element = class
return 0; 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) 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];
}
};

View File

@ -16,22 +16,22 @@ OV.GetTetrahedronSignedVolume = function (v0, v1, v2)
return OV.DotVector3D (v0, OV.CrossVector3D (v1, v2)) / 6.0; 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; return null;
} }
let volume = 0.0; let volume = 0.0;
element.EnumerateTriangleVertices ((v0, v1, v2) => { object3D.EnumerateTriangleVertices ((v0, v1, v2) => {
volume += OV.GetTetrahedronSignedVolume (v0, v1, v2); volume += OV.GetTetrahedronSignedVolume (v0, v1, v2);
}); });
return volume; return volume;
}; };
OV.CalculateSurfaceArea = function (element) OV.CalculateSurfaceArea = function (object3D)
{ {
let surface = 0.0; let surface = 0.0;
element.EnumerateTriangleVertices ((v0, v1, v2) => { object3D.EnumerateTriangleVertices ((v0, v1, v2) => {
surface += OV.GetTriangleArea (v0, v1, v2); surface += OV.GetTriangleArea (v0, v1, v2);
}); });
return surface; return surface;

View File

@ -86,6 +86,15 @@ describe ('Model Utils', function () {
assert (OV.CoordIsEqual3D (cubeBounds.max, new OV.Coord3D (1.0, 1.0, 1.0))); 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 () { it ('Model Bounding Box', function () {
var model = new OV.Model (); var model = new OV.Model ();

View File

@ -72,7 +72,7 @@ describe ('Quantities', function () {
}); });
it ('Tetrahedron Volume Calculation', 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 mesh = testUtils.GetTetrahedronMesh ();
const model = testUtils.GetModelWithOneMesh (mesh); const model = testUtils.GetModelWithOneMesh (mesh);
assert (OV.IsEqual (OV.CalculateVolume (mesh), Math.pow (edgeLength, 3.0) / (6.0 * Math.sqrt (2)))); 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 () { 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 mesh = testUtils.GetTetrahedronMesh ();
const model = testUtils.GetModelWithOneMesh (mesh); const model = testUtils.GetModelWithOneMesh (mesh);
assert (OV.IsEqual (OV.CalculateSurfaceArea (mesh), Math.sqrt (3) * Math.pow (edgeLength, 2.0))); 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))); 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));
});
}); });

View File

@ -26,8 +26,9 @@
"source/model/material.js", "source/model/material.js",
"source/model/triangle.js", "source/model/triangle.js",
"source/model/property.js", "source/model/property.js",
"source/model/element.js", "source/model/object.js",
"source/model/mesh.js", "source/model/mesh.js",
"source/model/meshinstance.js",
"source/model/meshbuffer.js", "source/model/meshbuffer.js",
"source/model/node.js", "source/model/node.js",
"source/model/model.js", "source/model/model.js",

View File

@ -39,7 +39,7 @@
<script type="text/javascript" src="../source/model/material.js"></script> <script type="text/javascript" src="../source/model/material.js"></script>
<script type="text/javascript" src="../source/model/triangle.js"></script> <script type="text/javascript" src="../source/model/triangle.js"></script>
<script type="text/javascript" src="../source/model/property.js"></script> <script type="text/javascript" src="../source/model/property.js"></script>
<script type="text/javascript" src="../source/model/element.js"></script> <script type="text/javascript" src="../source/model/object.js"></script>
<script type="text/javascript" src="../source/model/mesh.js"></script> <script type="text/javascript" src="../source/model/mesh.js"></script>
<script type="text/javascript" src="../source/model/meshbuffer.js"></script> <script type="text/javascript" src="../source/model/meshbuffer.js"></script>
<script type="text/javascript" src="../source/model/node.js"></script> <script type="text/javascript" src="../source/model/node.js"></script>

View File

@ -39,7 +39,7 @@
<script type="text/javascript" src="../source/model/material.js"></script> <script type="text/javascript" src="../source/model/material.js"></script>
<script type="text/javascript" src="../source/model/triangle.js"></script> <script type="text/javascript" src="../source/model/triangle.js"></script>
<script type="text/javascript" src="../source/model/property.js"></script> <script type="text/javascript" src="../source/model/property.js"></script>
<script type="text/javascript" src="../source/model/element.js"></script> <script type="text/javascript" src="../source/model/object.js"></script>
<script type="text/javascript" src="../source/model/mesh.js"></script> <script type="text/javascript" src="../source/model/mesh.js"></script>
<script type="text/javascript" src="../source/model/meshbuffer.js"></script> <script type="text/javascript" src="../source/model/meshbuffer.js"></script>
<script type="text/javascript" src="../source/model/node.js"></script> <script type="text/javascript" src="../source/model/node.js"></script>

View File

@ -10,35 +10,35 @@ OV.DetailsSidebarPanel = class extends OV.SidebarPanel
return 'Details'; return 'Details';
} }
AddElementProperties (element) AddObject3DProperties (object3D)
{ {
this.Clear (); this.Clear ();
let table = $('<div>').addClass ('ov_property_table').appendTo (this.contentDiv); let table = $('<div>').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); 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, 'Vertex Count', object3D.VertexCount ()));
this.AddProperty (table, new OV.Property (OV.PropertyType.Integer, 'Triangle Count', element.TriangleCount ())); 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 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 Y', size.y));
this.AddProperty (table, new OV.Property (OV.PropertyType.Number, 'Size Z', size.z)); this.AddProperty (table, new OV.Property (OV.PropertyType.Number, 'Size Z', size.z));
this.AddCalculatedProperty (table, 'Volume', () => { this.AddCalculatedProperty (table, 'Volume', () => {
const volume = OV.CalculateVolume (element); const volume = OV.CalculateVolume (object3D);
if (volume === null) { if (volume === null) {
return null; return null;
} }
return new OV.Property (OV.PropertyType.Number, null, volume); return new OV.Property (OV.PropertyType.Number, null, volume);
}); });
this.AddCalculatedProperty (table, 'Surface Area', () => { this.AddCalculatedProperty (table, 'Surface Area', () => {
const volume = OV.CalculateSurfaceArea (element); const volume = OV.CalculateSurfaceArea (object3D);
if (volume === null) { if (volume === null) {
return null; return null;
} }
return new OV.Property (OV.PropertyType.Number, null, volume); return new OV.Property (OV.PropertyType.Number, null, volume);
}); });
if (element.PropertyGroupCount () > 0) { if (object3D.PropertyGroupCount () > 0) {
let customTable = $('<div>').addClass ('ov_property_table ov_property_table_custom').appendTo (this.contentDiv); let customTable = $('<div>').addClass ('ov_property_table ov_property_table_custom').appendTo (this.contentDiv);
for (let i = 0; i < element.PropertyGroupCount (); i++) { for (let i = 0; i < object3D.PropertyGroupCount (); i++) {
const propertyGroup = element.GetPropertyGroup (i); const propertyGroup = object3D.GetPropertyGroup (i);
this.AddPropertyGroup (customTable, propertyGroup); this.AddPropertyGroup (customTable, propertyGroup);
for (let j = 0; j < propertyGroup.PropertyCount (); j++) { for (let j = 0; j < propertyGroup.PropertyCount (); j++) {
const property = propertyGroup.GetProperty (j); const property = propertyGroup.GetProperty (j);

View File

@ -695,10 +695,10 @@ OV.Website = class
return GetMaterialsForModel (this.model); return GetMaterialsForModel (this.model);
}, },
onModelSelected : () => { onModelSelected : () => {
this.detailsPanel.AddElementProperties (this.model); this.detailsPanel.AddObject3DProperties (this.model);
}, },
onMeshSelected : (meshIndex) => { onMeshSelected : (meshIndex) => {
this.detailsPanel.AddElementProperties (this.model.GetMesh (meshIndex)); this.detailsPanel.AddObject3DProperties (this.model.GetMesh (meshIndex));
}, },
onMaterialSelected : (materialIndex) => { onMaterialSelected : (materialIndex) => {
this.detailsPanel.AddMaterialProperties (this.model.GetMaterial (materialIndex)); this.detailsPanel.AddMaterialProperties (this.model.GetMaterial (materialIndex));