diff --git a/assets/images/3dviewer_net_start_page.png b/assets/images/3dviewer_net_start_page.png index 9a85c60..3f1843f 100644 Binary files a/assets/images/3dviewer_net_start_page.png and b/assets/images/3dviewer_net_start_page.png differ diff --git a/source/import/importergltf.js b/source/import/importergltf.js index 8384fa5..7bda2a6 100644 --- a/source/import/importergltf.js +++ b/source/import/importergltf.js @@ -37,50 +37,6 @@ OV.GltfConstants = BINARY_CHUNK_TYPE : 0x004E4942 }; -OV.GltfNodeTree = class -{ - constructor () - { - this.nodes = []; - this.nodeToParent = {}; - this.nodeMatrices = {}; - } - - AddMeshNode (nodeIndex) - { - this.nodes.push (nodeIndex); - return this.nodes.length - 1; - } - - AddNodeParent (nodeIndex, parentIndex) - { - this.nodeToParent[nodeIndex] = parentIndex; - } - - GetNodeParent (nodeIndex) - { - let parentIndex = this.nodeToParent[nodeIndex]; - if (parentIndex === undefined || parentIndex === -1) { - return null; - } - return parentIndex; - } - - AddNodeMatrix (nodeIndex, matrix) - { - this.nodeMatrices[nodeIndex] = matrix; - } - - GetNodeMatrix (nodeIndex) - { - let matrix = this.nodeMatrices[nodeIndex]; - if (matrix === undefined) { - return null; - } - return matrix; - } -}; - OV.GltfBufferReader = class { constructor (buffer) @@ -614,26 +570,22 @@ OV.ImporterGltf = class extends OV.ImporterBase ImportModel (gltf) { - let defaultScene = this.GetDefaultScene (gltf); - if (defaultScene === null) { - this.SetError ('No default scene found.'); - return; - } - - this.ImportModelProperties (gltf); - let materials = gltf.materials; if (materials !== undefined) { - for (let i = 0; i < materials.length; i++) { - this.ImportMaterial (gltf, i); + for (let material of materials) { + this.ImportMaterial (gltf, material); } } - let nodeTree = this.CollectMeshNodesForScene (gltf, defaultScene); - for (let i = 0; i < nodeTree.nodes.length; i++) { - let nodeIndex = nodeTree.nodes[i]; - this.ImportMeshNode (gltf, nodeIndex, nodeTree); + let meshes = gltf.meshes; + if (meshes !== undefined) { + for (let mesh of meshes) { + this.ImportMesh (gltf, mesh); + } } + + this.ImportNodes (gltf); + this.ImportModelProperties (gltf); } ImportModelProperties (gltf) @@ -670,39 +622,13 @@ OV.ImporterGltf = class extends OV.ImporterBase return gltf.scenes[defaultSceneIndex]; } - CollectMeshNodesForScene (gltf, scene) - { - function CollectMeshNodeIndices (gltf, parentIndex, nodeIndex, nodeTree) - { - let node = gltf.nodes[nodeIndex]; - if (node.mesh !== undefined) { - nodeTree.AddMeshNode (nodeIndex); - } - nodeTree.AddNodeParent (nodeIndex, parentIndex); - if (node.children !== undefined) { - for (let i = 0; i < node.children.length; i++) { - let childNodeIndex = node.children[i]; - CollectMeshNodeIndices (gltf, nodeIndex, childNodeIndex, nodeTree); - } - } - } - - let nodeTree = new OV.GltfNodeTree (); - for (let i = 0; i < scene.nodes.length; i++) { - let nodeIndex = scene.nodes[i]; - CollectMeshNodeIndices (gltf, -1, nodeIndex, nodeTree); - } - return nodeTree; - } - - ImportMaterial (gltf, materialIndex) + ImportMaterial (gltf, gltfMaterial) { function GetMaterialComponent (component) { return parseInt (Math.round (OV.LinearToSRGB (component) * 255.0), 10); } - let gltfMaterial = gltf.materials[materialIndex]; let material = new OV.Material (OV.MaterialType.Physical); if (gltfMaterial.name !== undefined) { material.name = gltfMaterial.name; @@ -819,76 +745,18 @@ OV.ImporterGltf = class extends OV.ImporterBase return texture; } - ImportMeshNode (gltf, nodeIndex, nodeTree) + ImportMesh (gltf, gltfMesh) { - function GetNodeTransformation (gltf, nodeIndex, nodeTree) - { - let node = gltf.nodes[nodeIndex]; - let matrix = nodeTree.GetNodeMatrix (nodeIndex); - if (matrix !== null) { - return matrix; - } - - matrix = new OV.Matrix ().CreateIdentity (); - if (node.matrix !== undefined) { - matrix.Set (node.matrix); - } else { - let hasTransformation = false; - let translation = [0.0, 0.0, 0.0]; - let rotation = [0.0, 0.0, 0.0, 1.0]; - let scale = [1.0, 1.0, 1.0]; - if (node.translation !== undefined) { - translation = node.translation; - hasTransformation = true; - } - if (node.rotation !== undefined) { - rotation = node.rotation; - hasTransformation = true; - } - if (node.scale !== undefined) { - scale = node.scale; - hasTransformation = true; - } - - if (hasTransformation) { - matrix.ComposeTRS ( - OV.ArrayToCoord3D (translation), - OV.ArrayToQuaternion (rotation), - OV.ArrayToCoord3D (scale) - ); - } - } - - let parentNodeIndex = nodeTree.GetNodeParent (nodeIndex); - if (parentNodeIndex !== null) { - let parentMatrix = GetNodeTransformation (gltf, parentNodeIndex, nodeTree); - matrix = matrix.MultiplyMatrix (parentMatrix); - } - - nodeTree.AddNodeMatrix (nodeIndex, matrix); - return matrix; - } - - let gltfNode = gltf.nodes[nodeIndex]; - let gltfMeshIndex = gltfNode.mesh; - let gltfMesh = gltf.meshes[gltfMeshIndex]; - let mesh = new OV.Mesh (); - this.model.AddMeshToRootNode (mesh); + this.model.AddMesh (mesh); if (gltfMesh.name !== undefined) { mesh.SetName (gltfMesh.name); - } else if (gltfNode.name !== undefined) { - mesh.SetName (gltfNode.name); } for (let i = 0; i < gltfMesh.primitives.length; i++) { let primitive = gltfMesh.primitives[i]; this.ImportPrimitive (gltf, primitive, mesh); } - - let matrix = GetNodeTransformation (gltf, nodeIndex, nodeTree); - let transformation = new OV.Transformation (matrix); - OV.TransformMesh (mesh, transformation); } ImportPrimitive (gltf, primitive, mesh) @@ -1022,6 +890,71 @@ OV.ImporterGltf = class extends OV.ImporterBase mesh.AddTriangle (triangle); } + ImportNodes (gltf) + { + let scene = this.GetDefaultScene (gltf); + if (scene === null) { + return; + } + let rootNode = this.model.GetRootNode (); + for (let nodeIndex of scene.nodes) { + let gltfNode = gltf.nodes[nodeIndex]; + this.ImportNode (gltf, gltfNode, rootNode); + } + } + + ImportNode (gltf, gltfNode, parentNode) + { + function GetNodeTransformation (gltfNode) + { + let matrix = new OV.Matrix ().CreateIdentity (); + if (gltfNode.matrix !== undefined) { + matrix.Set (gltfNode.matrix); + } else { + let translation = [0.0, 0.0, 0.0]; + let rotation = [0.0, 0.0, 0.0, 1.0]; + let scale = [1.0, 1.0, 1.0]; + if (gltfNode.translation !== undefined) { + translation = gltfNode.translation; + } + if (gltfNode.rotation !== undefined) { + rotation = gltfNode.rotation; + } + if (gltfNode.scale !== undefined) { + scale = gltfNode.scale; + } + matrix.ComposeTRS ( + OV.ArrayToCoord3D (translation), + OV.ArrayToQuaternion (rotation), + OV.ArrayToCoord3D (scale) + ); + } + return new OV.Transformation (matrix); + } + + if (gltfNode.children === undefined && gltfNode.mesh === undefined) { + return; + } + + let node = new OV.Node (); + if (gltfNode.name !== undefined) { + node.SetName (gltfNode.name); + } + node.SetTransformation (GetNodeTransformation (gltfNode)); + parentNode.AddChildNode (node); + + if (gltfNode.children !== undefined) { + for (let childIndex of gltfNode.children) { + let childGltfNode = gltf.nodes[childIndex]; + this.ImportNode (gltf, childGltfNode, node); + } + } + + if (gltfNode.mesh !== undefined) { + node.AddMeshIndex (gltfNode.mesh); + } + } + GetReaderFromBufferView (bufferView) { let bufferIndex = bufferView.buffer || 0; diff --git a/test/tests/importergltf_test.js b/test/tests/importergltf_test.js index aa62d90..046d2c9 100644 --- a/test/tests/importergltf_test.js +++ b/test/tests/importergltf_test.js @@ -18,6 +18,17 @@ describe ('Gltf Importer', function () { let testFile = testFileList[i]; testFiles.ImportGltfFile (testFile[0], testFile[1], function (model) { assert (OV.CheckModel (model)); + assert.deepStrictEqual (testUtils.ModelNodesToTree (model), { + name : '', + childNodes : [ + { + name : '', + childNodes : [], + meshNames : [''] + } + ], + meshNames : [] + }); assert.deepStrictEqual (testUtils.ModelToObjectSimple (model), { name : '', materials : [ @@ -57,6 +68,23 @@ describe ('Gltf Importer', function () { let testFile = testFileList[i]; testFiles.ImportGltfFile (testFile[0], testFile[1], function (model) { assert (OV.CheckModel (model)); + assert.deepStrictEqual (testUtils.ModelNodesToTree (model), { + name : '', + childNodes : [ + { + name : '', + childNodes : [ + { + name : '', + childNodes : [], + meshNames : ['Mesh'] + } + ], + meshNames : [] + } + ], + meshNames : [] + }); assert.deepStrictEqual (testUtils.ModelToObjectSimple (model), { name : '', materials : [ @@ -75,15 +103,15 @@ describe ('Gltf Importer', function () { } } ] - }); + }); processed += 1; if (processed == testFileList.length) { done (); } - }); + }); } }); - + it ('BoxInterleaved', function (done) { let testFileList = [ ['BoxInterleaved/glTF', 'BoxInterleaved.gltf'], @@ -95,6 +123,23 @@ describe ('Gltf Importer', function () { let testFile = testFileList[i]; testFiles.ImportGltfFile (testFile[0], testFile[1], function (model) { assert (OV.CheckModel (model)); + assert.deepStrictEqual (testUtils.ModelNodesToTree (model), { + name : '', + childNodes : [ + { + name : '', + childNodes : [ + { + name : '', + childNodes : [], + meshNames : ['Mesh'] + } + ], + meshNames : [] + } + ], + meshNames : [] + }); assert.deepStrictEqual (testUtils.ModelToObjectSimple (model), { name : '', materials : [ @@ -113,12 +158,12 @@ describe ('Gltf Importer', function () { } } ] - }); + }); processed += 1; if (processed == testFileList.length) { done (); } - }); + }); } }); @@ -133,6 +178,23 @@ describe ('Gltf Importer', function () { let testFile = testFileList[i]; testFiles.ImportGltfFile (testFile[0], testFile[1], function (model) { assert (OV.CheckModel (model)); + assert.deepStrictEqual (testUtils.ModelNodesToTree (model), { + name : '', + childNodes : [ + { + name : '', + childNodes : [ + { + name : '', + childNodes : [], + meshNames : ['Mesh'] + } + ], + meshNames : [] + } + ], + meshNames : [] + }); assert.deepStrictEqual (testUtils.ModelToObjectSimple (model), { name : '', materials : [ @@ -151,7 +213,7 @@ describe ('Gltf Importer', function () { } } ] - }); + }); processed += 1; if (processed == testFileList.length) { done (); @@ -170,6 +232,22 @@ describe ('Gltf Importer', function () { let testFile = testFileList[i]; testFiles.ImportGltfFile (testFile[0], testFile[1], function (model) { assert (OV.CheckModel (model)); + assert.deepStrictEqual (testUtils.ModelNodesToTree (model), { + name : '', + childNodes : [ + { + name : '', + childNodes : [], + meshNames : [''] + }, + { + name : '', + childNodes : [], + meshNames : [''] + } + ], + meshNames : [] + }); assert.deepStrictEqual (testUtils.ModelToObjectSimple (model), { name : '', materials : [ @@ -199,7 +277,7 @@ describe ('Gltf Importer', function () { } } ] - }); + }); processed += 1; if (processed == testFileList.length) { done (); @@ -207,7 +285,7 @@ describe ('Gltf Importer', function () { }); } }); - + it ('OrientationTest', function (done) { let testFileList = [ ['OrientationTest/glTF', 'OrientationTest.gltf'], @@ -380,7 +458,7 @@ describe ('Gltf Importer', function () { if (processed == testFileList.length) { done (); } - }); + }); } }); @@ -415,7 +493,7 @@ describe ('Gltf Importer', function () { } } ] - }); + }); processed += 1; if (processed == testFileList.length) { done (); @@ -451,7 +529,7 @@ describe ('Gltf Importer', function () { } } ] - }); + }); processed += 1; if (processed == testFileList.length) { done (); @@ -495,5 +573,5 @@ describe ('Gltf Importer', function () { } }); } - }); + }); }); diff --git a/test/tests/importero3dv_test.js b/test/tests/importero3dv_test.js index dfaa593..3845119 100644 --- a/test/tests/importero3dv_test.js +++ b/test/tests/importero3dv_test.js @@ -29,26 +29,6 @@ describe ('O3dv Importer', function () { meshNames : ['Cube'] }); - assert.deepStrictEqual (testUtils.ModelToObjectSimple (model), { - name : '', - materials : [ - { name : 'Green' } - ], - meshes : [ - { - name : 'Cube', - vertexCount : 8, - normalCount : 12, - uvCount : 0, - triangleCount : 12, - boundingBox : { - min : [0, 0, 0], - max : [1, 1, 1] - } - } - ] - }); - assert.strictEqual (model.MeshInstanceCount (), 3); let boundingBox = OV.GetBoundingBox (model); assert (OV.CoordIsEqual3D (boundingBox.min, new OV.Coord3D (-1.0, 0.0, 0.0))); diff --git a/test/utils/testutils.js b/test/utils/testutils.js index 9fa3486..3e2a8f2 100644 --- a/test/utils/testutils.js +++ b/test/utils/testutils.js @@ -139,11 +139,9 @@ module.exports = }); } - var mesh, meshObj, boundingBox; - for (i = 0; i < model.MeshCount (); i++) { - mesh = model.GetMesh (i); - boundingBox = OV.GetBoundingBox (mesh); - meshObj = { + model.EnumerateTransformedMeshInstances ((mesh) => { + let boundingBox = OV.GetBoundingBox (mesh); + let meshObj = { name : mesh.GetName (), vertexCount : mesh.VertexCount (), normalCount : mesh.NormalCount (), @@ -155,7 +153,7 @@ module.exports = } }; obj.meshes.push (meshObj); - } + }); return obj; }, diff --git a/website/o3dv/js/featureset.js b/website/o3dv/js/featureset.js index 6763ad9..5e65cc5 100644 --- a/website/o3dv/js/featureset.js +++ b/website/o3dv/js/featureset.js @@ -1,4 +1,4 @@ OV.FeatureSet = { - NavigatorTree : true + NavigatorTree : false };