Import all models as hierarchical model, but put all the meshes under the root node.

This commit is contained in:
kovacsv 2021-10-27 08:25:47 +02:00
parent e6eff40543
commit 7abc6efc93
21 changed files with 305 additions and 307 deletions

View File

@ -10,7 +10,7 @@ OV.Exporter3dm = class extends OV.ExporterBase
{ {
return format === OV.FileFormat.Binary && extension === '3dm'; return format === OV.FileFormat.Binary && extension === '3dm';
} }
ExportContent (model, format, files, onFinish) ExportContent (model, format, files, onFinish)
{ {
if (this.rhino === null) { if (this.rhino === null) {
@ -43,8 +43,7 @@ OV.Exporter3dm = class extends OV.ExporterBase
files.push (rhinoFile); files.push (rhinoFile);
let rhinoDoc = new this.rhino.File3dm (); let rhinoDoc = new this.rhino.File3dm ();
for (let meshIndex = 0; meshIndex < model.MeshCount (); meshIndex++) { model.EnumerateTransformedMeshInstances ((mesh) => {
let mesh = model.GetMesh (meshIndex);
let meshBuffer = OV.ConvertMeshToMeshBuffer (mesh); let meshBuffer = OV.ConvertMeshToMeshBuffer (mesh);
for (let primitiveIndex = 0; primitiveIndex < meshBuffer.PrimitiveCount (); primitiveIndex++) { for (let primitiveIndex = 0; primitiveIndex < meshBuffer.PrimitiveCount (); primitiveIndex++) {
let primitive = meshBuffer.GetPrimitive (primitiveIndex); let primitive = meshBuffer.GetPrimitive (primitiveIndex);
@ -87,7 +86,7 @@ OV.Exporter3dm = class extends OV.ExporterBase
rhinoAttributes.materialIndex = rhinoMaterialIndex; rhinoAttributes.materialIndex = rhinoMaterialIndex;
rhinoDoc.objects ().add (rhinoMesh, rhinoAttributes); rhinoDoc.objects ().add (rhinoMesh, rhinoAttributes);
} }
} });
let writeOptions = new this.rhino.File3dmWriteOptions (); let writeOptions = new this.rhino.File3dmWriteOptions ();
writeOptions.version = 6; writeOptions.version = 6;

View File

@ -19,7 +19,7 @@ OV.ExporterGltf = class extends OV.ExporterBase
{ {
return (format === OV.FileFormat.Text && extension === 'gltf') || (format === OV.FileFormat.Binary && extension === 'glb'); return (format === OV.FileFormat.Text && extension === 'gltf') || (format === OV.FileFormat.Binary && extension === 'glb');
} }
ExportContent (model, format, files, onFinish) ExportContent (model, format, files, onFinish)
{ {
if (format === OV.FileFormat.Text) { if (format === OV.FileFormat.Text) {
@ -56,7 +56,7 @@ OV.ExporterGltf = class extends OV.ExporterBase
textureIndex = mainJson.textures.length; textureIndex = mainJson.textures.length;
fileNameToIndex[fileName] = textureIndex; fileNameToIndex[fileName] = textureIndex;
mainJson.images.push ({ mainJson.images.push ({
uri : fileName uri : fileName
}); });
@ -68,7 +68,7 @@ OV.ExporterGltf = class extends OV.ExporterBase
}); });
gltfFile.SetTextContent (JSON.stringify (mainJson, null, 4)); gltfFile.SetTextContent (JSON.stringify (mainJson, null, 4));
binFile.SetBufferContent (mainBuffer); binFile.SetBufferContent (mainBuffer);
} }
ExportBinaryContent (model, files) ExportBinaryContent (model, files)
@ -88,7 +88,7 @@ OV.ExporterGltf = class extends OV.ExporterBase
writer.WriteUnsignedCharacter8 (char); writer.WriteUnsignedCharacter8 (char);
} }
} }
let glbFile = new OV.ExportedFile ('model.glb'); let glbFile = new OV.ExportedFile ('model.glb');
files.push (glbFile); files.push (glbFile);
@ -144,7 +144,7 @@ OV.ExporterGltf = class extends OV.ExporterBase
let glbSize = 12 + 8 + mainJsonBufferAlignedLength + 8 + mainBinaryBufferAlignedLength; let glbSize = 12 + 8 + mainJsonBufferAlignedLength + 8 + mainBinaryBufferAlignedLength;
let glbWriter = new OV.BinaryWriter (glbSize, true); let glbWriter = new OV.BinaryWriter (glbSize, true);
glbWriter.WriteUnsignedInteger32 (0x46546C67); glbWriter.WriteUnsignedInteger32 (0x46546C67);
glbWriter.WriteUnsignedInteger32 (2); glbWriter.WriteUnsignedInteger32 (2);
glbWriter.WriteUnsignedInteger32 (glbSize); glbWriter.WriteUnsignedInteger32 (glbSize);
@ -171,8 +171,7 @@ OV.ExporterGltf = class extends OV.ExporterBase
{ {
let meshDataArr = []; let meshDataArr = [];
for (let meshIndex = 0; meshIndex < model.MeshCount (); meshIndex++) { model.EnumerateTransformedMeshInstances ((mesh) => {
let mesh = model.GetMesh (meshIndex);
let buffer = OV.ConvertMeshToMeshBuffer (mesh); let buffer = OV.ConvertMeshToMeshBuffer (mesh);
meshDataArr.push ({ meshDataArr.push ({
name : mesh.GetName (), name : mesh.GetName (),
@ -180,7 +179,7 @@ OV.ExporterGltf = class extends OV.ExporterBase
offsets : [], offsets : [],
sizes : [] sizes : []
}); });
} });
return meshDataArr; return meshDataArr;
} }
@ -294,7 +293,7 @@ OV.ExporterGltf = class extends OV.ExporterBase
mode : 4, mode : 4,
material : primitive.material material : primitive.material
}; };
let bounds = primitive.GetBounds (); let bounds = primitive.GetBounds ();
mainJson.accessors.push ({ mainJson.accessors.push ({
bufferView : bufferViewIndex, bufferView : bufferViewIndex,
@ -424,18 +423,18 @@ OV.ExporterGltf = class extends OV.ExporterBase
} }
let metallicTexture = GetTextureParams (mainJson, material.metalnessMap, addTexture); let metallicTexture = GetTextureParams (mainJson, material.metalnessMap, addTexture);
if (metallicTexture !== null) { if (metallicTexture !== null) {
jsonMaterial.pbrMetallicRoughness.metallicRoughnessTexture = metallicTexture; jsonMaterial.pbrMetallicRoughness.metallicRoughnessTexture = metallicTexture;
} else { } else {
jsonMaterial.pbrMetallicRoughness.metallicFactor = material.metalness; jsonMaterial.pbrMetallicRoughness.metallicFactor = material.metalness;
jsonMaterial.pbrMetallicRoughness.roughnessFactor = material.roughness; jsonMaterial.pbrMetallicRoughness.roughnessFactor = material.roughness;
} }
let normalTexture = GetTextureParams (mainJson, material.normalMap, addTexture); let normalTexture = GetTextureParams (mainJson, material.normalMap, addTexture);
if (normalTexture !== null) { if (normalTexture !== null) {
jsonMaterial.normalTexture = normalTexture; jsonMaterial.normalTexture = normalTexture;
} }
let emissiveTexture = GetTextureParams (mainJson, material.emissiveMap, addTexture); let emissiveTexture = GetTextureParams (mainJson, material.emissiveMap, addTexture);
if (emissiveTexture !== null) { if (emissiveTexture !== null) {
jsonMaterial.emissiveTexture = emissiveTexture; jsonMaterial.emissiveTexture = emissiveTexture;
} }
mainJson.materials.push (jsonMaterial); mainJson.materials.push (jsonMaterial);

View File

@ -9,7 +9,7 @@ OV.ExporterObj = class extends OV.ExporterBase
{ {
return format === OV.FileFormat.Text && extension === 'obj'; return format === OV.FileFormat.Text && extension === 'obj';
} }
ExportContent (model, format, files, onFinish) ExportContent (model, format, files, onFinish)
{ {
function WriteTexture (mtlWriter, keyword, texture, files) function WriteTexture (mtlWriter, keyword, texture, files)
@ -59,7 +59,7 @@ OV.ExporterObj = class extends OV.ExporterBase
let normalOffset = 0; let normalOffset = 0;
let uvOffset = 0; let uvOffset = 0;
let usedMaterialName = null; let usedMaterialName = null;
model.EnumerateMeshes ((mesh) => { model.EnumerateTransformedMeshInstances ((mesh) => {
objWriter.WriteArrayLine (['g', this.GetExportedMeshName (mesh.GetName ())]); objWriter.WriteArrayLine (['g', this.GetExportedMeshName (mesh.GetName ())]);
for (let vertexIndex = 0; vertexIndex < mesh.VertexCount (); vertexIndex++) { for (let vertexIndex = 0; vertexIndex < mesh.VertexCount (); vertexIndex++) {
let vertex = mesh.GetVertex (vertexIndex); let vertex = mesh.GetVertex (vertexIndex);
@ -95,7 +95,7 @@ OV.ExporterObj = class extends OV.ExporterBase
if (triangle.HasTextureUVs ()) { if (triangle.HasTextureUVs ()) {
u0 = triangle.u0 + uvOffset + 1; u0 = triangle.u0 + uvOffset + 1;
u1 = triangle.u1 + uvOffset + 1; u1 = triangle.u1 + uvOffset + 1;
u2 = triangle.u2 + uvOffset + 1; u2 = triangle.u2 + uvOffset + 1;
} }
objWriter.WriteArrayLine (['f', [v0, u0, n0].join ('/'), [v1, u1, n1].join ('/'), [v2, u2, n2].join ('/')]); objWriter.WriteArrayLine (['f', [v0, u0, n0].join ('/'), [v1, u1, n1].join ('/'), [v2, u2, n2].join ('/')]);
} }
@ -105,11 +105,11 @@ OV.ExporterObj = class extends OV.ExporterBase
}); });
objFile.SetTextContent (objWriter.GetText ()); objFile.SetTextContent (objWriter.GetText ());
onFinish (); onFinish ();
} }
GetHeaderText () GetHeaderText ()
{ {
return '# exported by https://3dviewer.net'; return '# exported by https://3dviewer.net';
} }
}; };

View File

@ -5,7 +5,7 @@ OV.Importer3dm = class extends OV.ImporterBase
super (); super ();
this.rhino = null; this.rhino = null;
} }
CanImportExtension (extension) CanImportExtension (extension)
{ {
return extension === '3dm'; return extension === '3dm';
@ -101,7 +101,7 @@ OV.Importer3dm = class extends OV.ImporterBase
let rhinoObjects = rhinoDoc.objects (); let rhinoObjects = rhinoDoc.objects ();
for (let i = 0; i < rhinoObjects.count; i++) { for (let i = 0; i < rhinoObjects.count; i++) {
let rhinoObject = rhinoObjects.get (i); let rhinoObject = rhinoObjects.get (i);
this.ImportRhinoGeometryObject (rhinoDoc, rhinoObject, []); this.ImportRhinoGeometryObject (rhinoDoc, rhinoObject, []);
} }
} }
@ -113,8 +113,8 @@ OV.Importer3dm = class extends OV.ImporterBase
let objectType = rhinoGeometry.objectType; let objectType = rhinoGeometry.objectType;
if (rhinoAttributes.isInstanceDefinitionObject && rhinoInstanceReferences.length === 0) { if (rhinoAttributes.isInstanceDefinitionObject && rhinoInstanceReferences.length === 0) {
return; return;
} }
let rhinoMesh = null; let rhinoMesh = null;
let deleteMesh = false; let deleteMesh = false;
@ -145,7 +145,7 @@ OV.Importer3dm = class extends OV.ImporterBase
deleteMesh = true; deleteMesh = true;
} else if (objectType === this.rhino.ObjectType.InstanceReference) { } else if (objectType === this.rhino.ObjectType.InstanceReference) {
let parentDefinitionId = rhinoGeometry.parentIdefId; let parentDefinitionId = rhinoGeometry.parentIdefId;
let instanceDefinition = this.instanceDefinitions[parentDefinitionId]; let instanceDefinition = this.instanceDefinitions[parentDefinitionId];
if (instanceDefinition !== undefined) { if (instanceDefinition !== undefined) {
let instanceObjectIds = instanceDefinition.getObjectIds (); let instanceObjectIds = instanceDefinition.getObjectIds ();
for (let i = 0; i < instanceObjectIds.length; i++) { for (let i = 0; i < instanceObjectIds.length; i++) {
@ -199,7 +199,7 @@ OV.Importer3dm = class extends OV.ImporterBase
let transformation = new OV.Transformation (matrix); let transformation = new OV.Transformation (matrix);
OV.TransformMesh (mesh, transformation); OV.TransformMesh (mesh, transformation);
} }
this.model.AddMesh (mesh); this.model.AddMeshToRootNode (mesh);
} }
GetMaterialIndex (rhinoDoc, rhinoObject, rhinoInstanceReferences) GetMaterialIndex (rhinoDoc, rhinoObject, rhinoInstanceReferences)

View File

@ -293,7 +293,7 @@ OV.Importer3ds = class extends OV.ImporterBase
} }
} }
let meshIndex = this.model.AddMesh (mesh); let meshIndex = this.model.AddMeshToRootNode (mesh);
this.meshNameToIndex[mesh.GetName ()] = meshIndex; this.meshNameToIndex[mesh.GetName ()] = meshIndex;
this.meshTransformations.push (new OV.Matrix (transformation)); this.meshTransformations.push (new OV.Matrix (transformation));
} }
@ -519,6 +519,7 @@ OV.Importer3ds = class extends OV.ImporterBase
let mesh = model.GetMesh (meshIndex); let mesh = model.GetMesh (meshIndex);
let clonedMesh = OV.CloneMesh (mesh); let clonedMesh = OV.CloneMesh (mesh);
let clonedMeshIndex = model.AddMeshToIndex (clonedMesh, toIndex); let clonedMeshIndex = model.AddMeshToIndex (clonedMesh, toIndex);
model.GetRootNode ().AddMeshIndexToIndex (clonedMeshIndex, toIndex);
return clonedMeshIndex; return clonedMeshIndex;
} }

View File

@ -78,7 +78,7 @@ OV.GltfNodeTree = class
return null; return null;
} }
return matrix; return matrix;
} }
}; };
OV.GltfBufferReader = class OV.GltfBufferReader = class
@ -139,7 +139,7 @@ OV.GltfBufferReader = class
{ {
return this.reader.ReadArrayBuffer (byteLength); return this.reader.ReadArrayBuffer (byteLength);
} }
GetDataCount () GetDataCount ()
{ {
return this.dataCount; return this.dataCount;
@ -249,7 +249,7 @@ OV.GltfBufferReader = class
return 4; return 4;
} }
return 0; return 0;
} }
}; };
OV.GltfExtensions = class OV.GltfExtensions = class
@ -269,7 +269,7 @@ OV.GltfExtensions = class
if (extensionsRequired === undefined) { if (extensionsRequired === undefined) {
callbacks.onSuccess (); callbacks.onSuccess ();
return; return;
} }
if (this.draco === null && extensionsRequired.indexOf ('KHR_draco_mesh_compression') !== -1) { if (this.draco === null && extensionsRequired.indexOf ('KHR_draco_mesh_compression') !== -1) {
OV.LoadExternalLibrary ('loaders/draco_decoder.js').then (() => { OV.LoadExternalLibrary ('loaders/draco_decoder.js').then (() => {
DracoDecoderModule ().then ((draco) => { DracoDecoderModule ().then ((draco) => {
@ -336,7 +336,7 @@ OV.GltfExtensions = class
let specularTexture = khrSpecularGlossiness.specularGlossinessTexture; let specularTexture = khrSpecularGlossiness.specularGlossinessTexture;
if (specularTexture !== undefined) { if (specularTexture !== undefined) {
material.specularMap = imporTextureFn (specularTexture); material.specularMap = imporTextureFn (specularTexture);
} }
let glossiness = khrSpecularGlossiness.glossinessFactor; let glossiness = khrSpecularGlossiness.glossinessFactor;
if (glossiness !== undefined) { if (glossiness !== undefined) {
material.shininess = glossiness; material.shininess = glossiness;
@ -487,7 +487,7 @@ OV.ImporterGltf = class extends OV.ImporterBase
{ {
return OV.Direction.Y; return OV.Direction.Y;
} }
ClearContent () ClearContent ()
{ {
this.bufferContents = null; this.bufferContents = null;
@ -626,7 +626,7 @@ OV.ImporterGltf = class extends OV.ImporterBase
if (materials !== undefined) { if (materials !== undefined) {
for (let i = 0; i < materials.length; i++) { for (let i = 0; i < materials.length; i++) {
this.ImportMaterial (gltf, i); this.ImportMaterial (gltf, i);
} }
} }
let nodeTree = this.CollectMeshNodesForScene (gltf, defaultScene); let nodeTree = this.CollectMeshNodesForScene (gltf, defaultScene);
@ -814,7 +814,7 @@ OV.ImporterGltf = class extends OV.ImporterBase
texture.name = textureParams.name; texture.name = textureParams.name;
texture.url = textureParams.url; texture.url = textureParams.url;
texture.buffer = textureParams.buffer; texture.buffer = textureParams.buffer;
this.gltfExtensions.ProcessTexture (gltfTextureRef, texture); this.gltfExtensions.ProcessTexture (gltfTextureRef, texture);
return texture; return texture;
} }
@ -849,7 +849,7 @@ OV.ImporterGltf = class extends OV.ImporterBase
scale = node.scale; scale = node.scale;
hasTransformation = true; hasTransformation = true;
} }
if (hasTransformation) { if (hasTransformation) {
matrix.ComposeTRS ( matrix.ComposeTRS (
OV.ArrayToCoord3D (translation), OV.ArrayToCoord3D (translation),
@ -866,7 +866,7 @@ OV.ImporterGltf = class extends OV.ImporterBase
} }
nodeTree.AddNodeMatrix (nodeIndex, matrix); nodeTree.AddNodeMatrix (nodeIndex, matrix);
return matrix; return matrix;
} }
let gltfNode = gltf.nodes[nodeIndex]; let gltfNode = gltf.nodes[nodeIndex];
@ -874,7 +874,7 @@ OV.ImporterGltf = class extends OV.ImporterBase
let gltfMesh = gltf.meshes[gltfMeshIndex]; let gltfMesh = gltf.meshes[gltfMeshIndex];
let mesh = new OV.Mesh (); let mesh = new OV.Mesh ();
this.model.AddMesh (mesh); this.model.AddMeshToRootNode (mesh);
if (gltfMesh.name !== undefined) { if (gltfMesh.name !== undefined) {
mesh.SetName (gltfMesh.name); mesh.SetName (gltfMesh.name);
} else if (gltfNode.name !== undefined) { } else if (gltfNode.name !== undefined) {
@ -889,7 +889,7 @@ OV.ImporterGltf = class extends OV.ImporterBase
let matrix = GetNodeTransformation (gltf, nodeIndex, nodeTree); let matrix = GetNodeTransformation (gltf, nodeIndex, nodeTree);
let transformation = new OV.Transformation (matrix); let transformation = new OV.Transformation (matrix);
OV.TransformMesh (mesh, transformation); OV.TransformMesh (mesh, transformation);
} }
ImportPrimitive (gltf, primitive, mesh) ImportPrimitive (gltf, primitive, mesh)
{ {
@ -963,7 +963,7 @@ OV.ImporterGltf = class extends OV.ImporterBase
} }
reader.EnumerateData ((data) => { reader.EnumerateData ((data) => {
vertexIndices.push (data); vertexIndices.push (data);
}); });
} else { } else {
for (let i = 0; i < mesh.VertexCount (); i++) { for (let i = 0; i < mesh.VertexCount (); i++) {
vertexIndices.push (i); vertexIndices.push (i);
@ -1020,7 +1020,7 @@ OV.ImporterGltf = class extends OV.ImporterBase
triangle.mat = primitive.material; triangle.mat = primitive.material;
} }
mesh.AddTriangle (triangle); mesh.AddTriangle (triangle);
} }
GetReaderFromBufferView (bufferView) GetReaderFromBufferView (bufferView)
{ {
@ -1075,7 +1075,7 @@ OV.ImporterGltf = class extends OV.ImporterBase
if (reader === null) { if (reader === null) {
return null; return null;
} }
reader.SetComponentType (componentType); reader.SetComponentType (componentType);
reader.SetDataType (type); reader.SetDataType (type);
reader.SetDataCount (count); reader.SetDataCount (count);

View File

@ -104,7 +104,7 @@ OV.ImporterIfc = class extends OV.ImporterBase
} }
this.expressIDToMesh[ifcMesh.expressID] = mesh; this.expressIDToMesh[ifcMesh.expressID] = mesh;
this.model.AddMesh (mesh); this.model.AddMeshToRootNode (mesh);
} }
ImportProperties (modelID) ImportProperties (modelID)

View File

@ -14,18 +14,18 @@ OV.ImporterObj = class extends OV.ImporterBase
{ {
return OV.Direction.Y; return OV.Direction.Y;
} }
ClearContent () ClearContent ()
{ {
this.globalVertices = null; this.globalVertices = null;
this.globalNormals = null; this.globalNormals = null;
this.globalUvs = null; this.globalUvs = null;
this.currentMesh = null; this.currentMesh = null;
this.currentMeshData = null; this.currentMeshData = null;
this.currentMaterial = null; this.currentMaterial = null;
this.currentMaterialIndex = null; this.currentMaterialIndex = null;
this.meshNameToMeshData = null; this.meshNameToMeshData = null;
this.materialNameToIndex = null; this.materialNameToIndex = null;
} }
@ -39,12 +39,12 @@ OV.ImporterObj = class extends OV.ImporterBase
this.currentMesh = null; this.currentMesh = null;
this.currentMeshData = null; this.currentMeshData = null;
this.currentMaterial = null; this.currentMaterial = null;
this.currentMaterialIndex = null; this.currentMaterialIndex = null;
this.meshNameToMeshData = {}; this.meshNameToMeshData = {};
this.materialNameToIndex = {}; this.materialNameToIndex = {};
} }
ImportContent (fileContent, onFinish) ImportContent (fileContent, onFinish)
{ {
let textContent = OV.ArrayBufferToUtf8String (fileContent); let textContent = OV.ArrayBufferToUtf8String (fileContent);
@ -55,7 +55,7 @@ OV.ImporterObj = class extends OV.ImporterBase
}); });
onFinish (); onFinish ();
} }
ProcessLine (line) ProcessLine (line)
{ {
if (line[0] === '#') { if (line[0] === '#') {
@ -66,7 +66,7 @@ OV.ImporterObj = class extends OV.ImporterBase
if (parameters.length === 0) { if (parameters.length === 0) {
return; return;
} }
let keyword = parameters[0].toLowerCase (); let keyword = parameters[0].toLowerCase ();
parameters.shift (); parameters.shift ();
@ -78,7 +78,7 @@ OV.ImporterObj = class extends OV.ImporterBase
return; return;
} }
} }
AddNewMesh (name) AddNewMesh (name)
{ {
let meshData = this.meshNameToMeshData[name]; let meshData = this.meshNameToMeshData[name];
@ -87,7 +87,7 @@ OV.ImporterObj = class extends OV.ImporterBase
if (name !== null) { if (name !== null) {
mesh.SetName (name); mesh.SetName (name);
} }
this.model.AddMesh (mesh); this.model.AddMeshToRootNode (mesh);
meshData = { meshData = {
mesh : mesh, mesh : mesh,
data : { data : {
@ -179,7 +179,7 @@ OV.ImporterObj = class extends OV.ImporterBase
if (parameters.length === 0) { if (parameters.length === 0) {
return true; return true;
} }
let material = new OV.Material (OV.MaterialType.Phong); let material = new OV.Material (OV.MaterialType.Phong);
let materialName = OV.NameFromLine (line, keyword.length, '#'); let materialName = OV.NameFromLine (line, keyword.length, '#');
let materialIndex = this.model.AddMaterial (material); let materialIndex = this.model.AddMaterial (material);
@ -191,7 +191,7 @@ OV.ImporterObj = class extends OV.ImporterBase
if (parameters.length === 0) { if (parameters.length === 0) {
return true; return true;
} }
let materialName = OV.NameFromLine (line, keyword.length, '#'); let materialName = OV.NameFromLine (line, keyword.length, '#');
let materialIndex = this.materialNameToIndex[materialName]; let materialIndex = this.materialNameToIndex[materialName];
if (materialIndex !== undefined) { if (materialIndex !== undefined) {
@ -272,7 +272,7 @@ OV.ImporterObj = class extends OV.ImporterBase
return true; return true;
} }
return false; return false;
} }
ProcessFace (parameters) ProcessFace (parameters)
@ -285,7 +285,7 @@ OV.ImporterObj = class extends OV.ImporterBase
return count + index; return count + index;
} }
} }
function GetLocalIndex (globalValueArray, globalToCurrentIndices, globalIndex, valueAdderFunc) function GetLocalIndex (globalValueArray, globalToCurrentIndices, globalIndex, valueAdderFunc)
{ {
if (isNaN (globalIndex) || globalIndex < 0 || globalIndex >= globalValueArray.length) { if (isNaN (globalIndex) || globalIndex < 0 || globalIndex >= globalValueArray.length) {
@ -302,32 +302,32 @@ OV.ImporterObj = class extends OV.ImporterBase
} }
return result; return result;
} }
function GetLocalVertexIndex (obj, mesh, globalIndex) function GetLocalVertexIndex (obj, mesh, globalIndex)
{ {
return GetLocalIndex (obj.globalVertices, obj.currentMeshData.globalToCurrentVertices, globalIndex, (val) => { return GetLocalIndex (obj.globalVertices, obj.currentMeshData.globalToCurrentVertices, globalIndex, (val) => {
return mesh.AddVertex (new OV.Coord3D (val.x, val.y, val.z)); return mesh.AddVertex (new OV.Coord3D (val.x, val.y, val.z));
}); });
} }
function GetLocalNormalIndex (obj, mesh, globalIndex) function GetLocalNormalIndex (obj, mesh, globalIndex)
{ {
return GetLocalIndex (obj.globalNormals, obj.currentMeshData.globalToCurrentNormals, globalIndex, (val) => { return GetLocalIndex (obj.globalNormals, obj.currentMeshData.globalToCurrentNormals, globalIndex, (val) => {
return mesh.AddNormal (new OV.Coord3D (val.x, val.y, val.z)); return mesh.AddNormal (new OV.Coord3D (val.x, val.y, val.z));
}); });
} }
function GetLocalUVIndex (obj, mesh, globalIndex) function GetLocalUVIndex (obj, mesh, globalIndex)
{ {
return GetLocalIndex (obj.globalUvs, obj.currentMeshData.globalToCurrentUvs, globalIndex, (val) => { return GetLocalIndex (obj.globalUvs, obj.currentMeshData.globalToCurrentUvs, globalIndex, (val) => {
return mesh.AddTextureUV (new OV.Coord2D (val.x, val.y)); return mesh.AddTextureUV (new OV.Coord2D (val.x, val.y));
}); });
} }
let vertices = []; let vertices = [];
let normals = []; let normals = [];
let uvs = []; let uvs = [];
for (let i = 0; i < parameters.length; i++) { for (let i = 0; i < parameters.length; i++) {
let vertexParams = parameters[i].split ('/'); let vertexParams = parameters[i].split ('/');
vertices.push (GetRelativeIndex (parseInt (vertexParams[0], 10), this.globalVertices.length)); vertices.push (GetRelativeIndex (parseInt (vertexParams[0], 10), this.globalVertices.length));
@ -338,11 +338,11 @@ OV.ImporterObj = class extends OV.ImporterBase
normals.push (GetRelativeIndex (parseInt (vertexParams[2], 10), this.globalNormals.length)); normals.push (GetRelativeIndex (parseInt (vertexParams[2], 10), this.globalNormals.length));
} }
} }
if (this.currentMesh === null) { if (this.currentMesh === null) {
this.AddNewMesh (''); this.AddNewMesh ('');
} }
for (let i = 0; i < vertices.length - 2; i++) { for (let i = 0; i < vertices.length - 2; i++) {
let v0 = GetLocalVertexIndex (this, this.currentMesh, vertices[0]); let v0 = GetLocalVertexIndex (this, this.currentMesh, vertices[0]);
let v1 = GetLocalVertexIndex (this, this.currentMesh, vertices[i + 1]); let v1 = GetLocalVertexIndex (this, this.currentMesh, vertices[i + 1]);

View File

@ -4,7 +4,7 @@ OV.ImporterOff = class extends OV.ImporterBase
{ {
super (); super ();
} }
CanImportExtension (extension) CanImportExtension (extension)
{ {
return extension === 'off'; return extension === 'off';
@ -14,7 +14,7 @@ OV.ImporterOff = class extends OV.ImporterBase
{ {
return OV.Direction.Y; return OV.Direction.Y;
} }
ClearContent () ClearContent ()
{ {
this.mesh = null; this.mesh = null;
@ -24,7 +24,7 @@ OV.ImporterOff = class extends OV.ImporterBase
ResetContent () ResetContent ()
{ {
this.mesh = new OV.Mesh (); this.mesh = new OV.Mesh ();
this.model.AddMesh (this.mesh); this.model.AddMeshToRootNode (this.mesh);
this.status = { this.status = {
vertexCount : 0, vertexCount : 0,
faceCount : 0, faceCount : 0,
@ -43,7 +43,7 @@ OV.ImporterOff = class extends OV.ImporterBase
}); });
onFinish (); onFinish ();
} }
ProcessLine (line) ProcessLine (line)
{ {
if (line[0] === '#') { if (line[0] === '#') {
@ -54,7 +54,7 @@ OV.ImporterOff = class extends OV.ImporterBase
if (parameters.length === 0) { if (parameters.length === 0) {
return; return;
} }
if (parameters[0] === 'OFF') { if (parameters[0] === 'OFF') {
return; return;
} }
@ -72,7 +72,7 @@ OV.ImporterOff = class extends OV.ImporterBase
this.mesh.AddVertex (new OV.Coord3D ( this.mesh.AddVertex (new OV.Coord3D (
parseFloat (parameters[0]), parseFloat (parameters[0]),
parseFloat (parameters[1]), parseFloat (parameters[1]),
parseFloat (parameters[2]) parseFloat (parameters[2])
)); ));
this.status.foundVertex += 1; this.status.foundVertex += 1;
} }

View File

@ -177,7 +177,7 @@ OV.ImporterPly = class extends OV.ImporterBase
ResetContent () ResetContent ()
{ {
this.mesh = new OV.Mesh (); this.mesh = new OV.Mesh ();
this.model.AddMesh (this.mesh); this.model.AddMeshToRootNode (this.mesh);
} }
ImportContent (fileContent, onFinish) ImportContent (fileContent, onFinish)

View File

@ -24,7 +24,7 @@ OV.ImporterStl = class extends OV.ImporterBase
ResetContent () ResetContent ()
{ {
this.mesh = new OV.Mesh (); this.mesh = new OV.Mesh ();
this.model.AddMesh (this.mesh); this.model.AddMeshToRootNode (this.mesh);
this.triangle = null; this.triangle = null;
} }

View File

@ -465,7 +465,7 @@ OV.ImporterThree = class extends OV.ImporterBase
OV.FlipMeshTrianglesOrientation (mesh); OV.FlipMeshTrianglesOrientation (mesh);
} }
} }
this.model.AddMesh (mesh); this.model.AddMeshToRootNode (mesh);
child.geometry.dispose (); child.geometry.dispose ();
}); });

View File

@ -23,39 +23,48 @@ OV.Model = class extends OV.ModelObject3D
return this.meshes.length; return this.meshes.length;
} }
MeshInstanceCount ()
{
let count = 0;
this.EnumerateMeshInstances ((meshInstance) => {
count += 1;
});
return count;
}
VertexCount () VertexCount ()
{ {
let count = 0; let count = 0;
for (let i = 0; i < this.meshes.length; i++) { this.EnumerateMeshInstances ((meshInstance) => {
count += this.meshes[i].VertexCount (); count += meshInstance.VertexCount ();
} });
return count; return count;
} }
NormalCount () NormalCount ()
{ {
let count = 0; let count = 0;
for (let i = 0; i < this.meshes.length; i++) { this.EnumerateMeshInstances ((meshInstance) => {
count += this.meshes[i].NormalCount (); count += meshInstance.NormalCount ();
} });
return count; return count;
} }
TextureUVCount () TextureUVCount ()
{ {
let count = 0; let count = 0;
for (let i = 0; i < this.meshes.length; i++) { this.EnumerateMeshInstances ((meshInstance) => {
count += this.meshes[i].TextureUVCount (); count += meshInstance.TextureUVCount ();
} });
return count; return count;
} }
TriangleCount () TriangleCount ()
{ {
let count = 0; let count = 0;
for (let i = 0; i < this.meshes.length; i++) { this.EnumerateMeshInstances ((meshInstance) => {
count += this.meshes[i].TriangleCount (); count += meshInstance.TriangleCount ();
} });
return count; return count;
} }
@ -127,11 +136,10 @@ OV.Model = class extends OV.ModelObject3D
if (foundNode === null) { if (foundNode === null) {
return null; return null;
} }
// TODO: check it when every model is hierarchical const nodeMeshIndices = foundNode.GetMeshIndices ();
// const nodeMeshIndices = foundNode.GetMeshIndices (); if (nodeMeshIndices.indexOf (instanceId.meshIndex) === -1) {
// if (nodeMeshIndices.indexOf (instanceId.meshIndex) === -1) { return null;
// return null; }
// }
let foundMesh = this.GetMesh (instanceId.meshIndex); let foundMesh = this.GetMesh (instanceId.meshIndex);
return new OV.MeshInstance (foundNode, foundMesh); return new OV.MeshInstance (foundNode, foundMesh);
} }
@ -164,22 +172,22 @@ OV.Model = class extends OV.ModelObject3D
EnumerateVertices (onVertex) EnumerateVertices (onVertex)
{ {
for (const mesh of this.meshes) { this.EnumerateMeshInstances ((meshInstance) => {
mesh.EnumerateVertices (onVertex); meshInstance.EnumerateVertices (onVertex);
} });
} }
EnumerateTriangleVertexIndices (onTriangleVertexIndices) EnumerateTriangleVertexIndices (onTriangleVertexIndices)
{ {
for (const mesh of this.meshes) { this.EnumerateMeshInstances ((meshInstance) => {
mesh.EnumerateTriangleVertexIndices (onTriangleVertexIndices); meshInstance.EnumerateTriangleVertexIndices (onTriangleVertexIndices);
} });
} }
EnumerateTriangleVertices (onTriangleVertices) EnumerateTriangleVertices (onTriangleVertices)
{ {
for (const mesh of this.meshes) { this.EnumerateMeshInstances ((meshInstance) => {
mesh.EnumerateTriangleVertices (onTriangleVertices); meshInstance.EnumerateTriangleVertices (onTriangleVertices);
} });
} }
}; };

View File

@ -87,18 +87,17 @@ OV.CloneMesh = function (mesh)
OV.EnumerateModelVerticesAndTriangles = function (model, callbacks) OV.EnumerateModelVerticesAndTriangles = function (model, callbacks)
{ {
model.EnumerateMeshes ((mesh) => { model.EnumerateMeshInstances ((meshInstance) => {
for (let vertexIndex = 0; vertexIndex < mesh.VertexCount (); vertexIndex++) { meshInstance.EnumerateVertices ((vertex) => {
let vertex = mesh.GetVertex (vertexIndex);
callbacks.onVertex (vertex.x, vertex.y, vertex.z); callbacks.onVertex (vertex.x, vertex.y, vertex.z);
} });
}); });
let vertexOffset = 0; let vertexOffset = 0;
model.EnumerateMeshes ((mesh) => { model.EnumerateMeshInstances ((meshInstance) => {
mesh.EnumerateTriangleVertexIndices ((v0, v1, v2) => { meshInstance.EnumerateTriangleVertexIndices ((v0, v1, v2) => {
callbacks.onTriangle (v0 + vertexOffset, v1 + vertexOffset, v2 + vertexOffset); callbacks.onTriangle (v0 + vertexOffset, v1 + vertexOffset, v2 + vertexOffset);
}); });
vertexOffset += mesh.VertexCount (); vertexOffset += meshInstance.VertexCount ();
}); });
}; };

View File

@ -117,6 +117,11 @@ OV.Node = class
return this.meshIndices.length - 1; return this.meshIndices.length - 1;
} }
AddMeshIndexToIndex (index, toIndex)
{
this.meshIndices.splice (toIndex, 0, index);
}
MeshIndexCount () MeshIndexCount ()
{ {
return this.meshIndices.length; return this.meshIndices.length;

View File

@ -318,22 +318,6 @@ OV.ConvertModelToThreeObject = function (model, params, output, callbacks)
}); });
} }
function ConvertMeshList (threeObject, model, modelThreeMaterials, stateHandler)
{
OV.RunTasksBatch (model.MeshCount (), 100, {
runTask : (firstIndex, lastIndex, ready) => {
for (let meshIndex = firstIndex; meshIndex <= lastIndex; meshIndex++) {
let meshInstanceId = new OV.MeshInstanceId (model.GetRootNode ().GetId (), meshIndex);
ConvertMesh (threeObject, model, meshInstanceId, modelThreeMaterials);
}
ready ();
},
onReady : () => {
stateHandler.OnModelLoaded (threeObject);
}
});
}
let stateHandler = new OV.ThreeConversionStateHandler (callbacks); let stateHandler = new OV.ThreeConversionStateHandler (callbacks);
let modelThreeMaterials = []; let modelThreeMaterials = [];
@ -343,11 +327,5 @@ OV.ConvertModelToThreeObject = function (model, params, output, callbacks)
} }
let threeObject = new THREE.Object3D (); let threeObject = new THREE.Object3D ();
let rootNode = model.GetRootNode (); ConvertNodeHierarchy (threeObject, model, modelThreeMaterials, stateHandler);
if (!rootNode.IsEmpty ()) {
ConvertNodeHierarchy (threeObject, model, modelThreeMaterials, stateHandler);
} else {
// TODO: remove
ConvertMeshList (threeObject, model, modelThreeMaterials, stateHandler);
}
}; };

View File

@ -38,7 +38,7 @@ function CreateTestModel ()
let triangle1 = new OV.Triangle (0, 1, 2); let triangle1 = new OV.Triangle (0, 1, 2);
triangle1.mat = 0; triangle1.mat = 0;
mesh1.AddTriangle (triangle1); mesh1.AddTriangle (triangle1);
model.AddMesh (mesh1); model.AddMeshToRootNode (mesh1);
let mesh2 = new OV.Mesh (); let mesh2 = new OV.Mesh ();
mesh2.SetName ('TestMesh2'); mesh2.SetName ('TestMesh2');
@ -56,8 +56,8 @@ function CreateTestModel ()
mesh2.AddTriangle (triangle2); mesh2.AddTriangle (triangle2);
mesh2.AddTriangle (triangle3); mesh2.AddTriangle (triangle3);
mesh2.AddTriangle (triangle4); mesh2.AddTriangle (triangle4);
model.AddMesh (mesh2); model.AddMeshToRootNode (mesh2);
OV.FinalizeModel (model, null); OV.FinalizeModel (model, null);
return model; return model;
} }
@ -138,19 +138,19 @@ describe ('Exporter', function () {
'f 4//4 8//4 6//4', 'f 4//4 8//4 6//4',
'' ''
].join ('\n')); ].join ('\n'));
let textureFile1 = result[2]; let textureFile1 = result[2];
assert.strictEqual (textureFile1.GetName (), 'texture1.png'); assert.strictEqual (textureFile1.GetName (), 'texture1.png');
assert.strictEqual (textureFile1.GetBufferContent ().byteLength, 1); assert.strictEqual (textureFile1.GetBufferContent ().byteLength, 1);
let textureFile2 = result[3]; let textureFile2 = result[3];
assert.strictEqual (textureFile2.GetName (), 'texture2.png'); assert.strictEqual (textureFile2.GetName (), 'texture2.png');
assert.strictEqual (textureFile2.GetBufferContent ().byteLength, 2); assert.strictEqual (textureFile2.GetBufferContent ().byteLength, 2);
let textureFile3 = result[4]; let textureFile3 = result[4];
assert.strictEqual (textureFile3.GetName (), 'texture3.png'); assert.strictEqual (textureFile3.GetName (), 'texture3.png');
assert.strictEqual (textureFile3.GetBufferContent ().byteLength, 3); assert.strictEqual (textureFile3.GetBufferContent ().byteLength, 3);
done (); done ();
}); });
}); });
@ -197,7 +197,7 @@ describe ('Exporter', function () {
'' ''
].join ('\n')); ].join ('\n'));
done (); done ();
}); });
}); });
@ -209,7 +209,7 @@ describe ('Exporter', function () {
let stlFile = result[0]; let stlFile = result[0];
assert.strictEqual (stlFile.GetName (), 'model.stl'); assert.strictEqual (stlFile.GetName (), 'model.stl');
assert.strictEqual (stlFile.GetBufferContent ().byteLength, 284); assert.strictEqual (stlFile.GetBufferContent ().byteLength, 284);
let contentBuffer = stlFile.GetBufferContent (); let contentBuffer = stlFile.GetBufferContent ();
let importer = new OV.ImporterStl (); let importer = new OV.ImporterStl ();
importer.Import (stlFile.GetName (), 'stl', contentBuffer, { importer.Import (stlFile.GetName (), 'stl', contentBuffer, {
@ -223,7 +223,7 @@ describe ('Exporter', function () {
done (); done ();
} }
}); });
done (); done ();
}); });
}); });
@ -253,7 +253,7 @@ describe ('Exporter', function () {
'3 3 7 5', '3 3 7 5',
'' ''
].join ('\n')); ].join ('\n'));
done (); done ();
}); });
}); });
@ -290,7 +290,7 @@ describe ('Exporter', function () {
'3 3 7 5', '3 3 7 5',
'' ''
].join ('\n')); ].join ('\n'));
done (); done ();
}); });
}); });
@ -303,7 +303,7 @@ describe ('Exporter', function () {
let plyFile = result[0]; let plyFile = result[0];
assert.strictEqual (plyFile.GetName (), 'model.ply'); assert.strictEqual (plyFile.GetName (), 'model.ply');
assert.strictEqual (plyFile.GetBufferContent ().byteLength, 315); assert.strictEqual (plyFile.GetBufferContent ().byteLength, 315);
let contentBuffer = plyFile.GetBufferContent (); let contentBuffer = plyFile.GetBufferContent ();
let importer = new OV.ImporterPly (); let importer = new OV.ImporterPly ();
importer.Import (plyFile.GetName (), 'ply', contentBuffer, { importer.Import (plyFile.GetName (), 'ply', contentBuffer, {
@ -316,7 +316,7 @@ describe ('Exporter', function () {
assert.strictEqual (importedModel.TriangleCount (), 4); assert.strictEqual (importedModel.TriangleCount (), 4);
done (); done ();
} }
}); });
}); });
}); });
@ -324,16 +324,16 @@ describe ('Exporter', function () {
let model = CreateTestModel (); let model = CreateTestModel ();
Export (model, OV.FileFormat.Text, 'gltf', function (result) { Export (model, OV.FileFormat.Text, 'gltf', function (result) {
assert.strictEqual (result.length, 3); assert.strictEqual (result.length, 3);
let gltfFile = result[0]; let gltfFile = result[0];
let binFile = result[1]; let binFile = result[1];
let textureFile = result[2]; let textureFile = result[2];
assert.strictEqual (gltfFile.GetName (), 'model.gltf'); assert.strictEqual (gltfFile.GetName (), 'model.gltf');
assert.strictEqual (binFile.GetName (), 'model.bin'); assert.strictEqual (binFile.GetName (), 'model.bin');
assert.strictEqual (textureFile.GetName (), 'texture1.png'); assert.strictEqual (textureFile.GetName (), 'texture1.png');
assert.strictEqual (textureFile.GetBufferContent ().byteLength, 1); assert.strictEqual (textureFile.GetBufferContent ().byteLength, 1);
let contentBuffer = gltfFile.GetBufferContent (); let contentBuffer = gltfFile.GetBufferContent ();
let importer = new OV.ImporterGltf (); let importer = new OV.ImporterGltf ();
importer.Import (gltfFile.GetName (), 'gltf', contentBuffer, { importer.Import (gltfFile.GetName (), 'gltf', contentBuffer, {
@ -360,7 +360,7 @@ describe ('Exporter', function () {
assert.strictEqual (importedModel.TriangleCount (), 4); assert.strictEqual (importedModel.TriangleCount (), 4);
done (); done ();
} }
}); });
}); });
}); });
@ -397,5 +397,5 @@ describe ('Exporter', function () {
} }
}); });
}); });
}); });
}); });

View File

@ -1,4 +1,5 @@
var assert = require ('assert'); var assert = require ('assert');
var testUtils = require ('../utils/testutils.js');
describe ('Model', function () { describe ('Model', function () {
it ('Default Initialization', function () { it ('Default Initialization', function () {
@ -60,7 +61,7 @@ describe ('Model', function () {
mesh.AddTriangle (new OV.Triangle (0, 1, 2)); mesh.AddTriangle (new OV.Triangle (0, 1, 2));
mesh.AddTriangle (new OV.Triangle (0, 1, 2)); mesh.AddTriangle (new OV.Triangle (0, 1, 2));
mesh.AddTriangle (new OV.Triangle (0, 1, 2)); mesh.AddTriangle (new OV.Triangle (0, 1, 2));
model.AddMesh (mesh); model.AddMeshToRootNode (mesh);
assert.strictEqual (model.VertexCount (), 3); assert.strictEqual (model.VertexCount (), 3);
assert.strictEqual (model.NormalCount (), 2); assert.strictEqual (model.NormalCount (), 2);
assert.strictEqual (model.TextureUVCount (), 1); assert.strictEqual (model.TextureUVCount (), 1);
@ -75,14 +76,14 @@ describe ('Model', function () {
mesh1.AddVertex (new OV.Coord3D (1.0, 0.0, 0.0)); mesh1.AddVertex (new OV.Coord3D (1.0, 0.0, 0.0));
mesh1.AddVertex (new OV.Coord3D (1.0, 1.0, 0.0)); mesh1.AddVertex (new OV.Coord3D (1.0, 1.0, 0.0));
mesh1.AddTriangle (new OV.Triangle (0, 1, 2)); mesh1.AddTriangle (new OV.Triangle (0, 1, 2));
model.AddMesh (mesh1); model.AddMeshToRootNode (mesh1);
let mesh2 = new OV.Mesh (); let mesh2 = new OV.Mesh ();
mesh2.AddVertex (new OV.Coord3D (0.0, 0.0, 1.0)); mesh2.AddVertex (new OV.Coord3D (0.0, 0.0, 1.0));
mesh2.AddVertex (new OV.Coord3D (1.0, 0.0, 1.0)); mesh2.AddVertex (new OV.Coord3D (1.0, 0.0, 1.0));
mesh2.AddVertex (new OV.Coord3D (1.0, 1.0, 1.0)); mesh2.AddVertex (new OV.Coord3D (1.0, 1.0, 1.0));
mesh2.AddTriangle (new OV.Triangle (0, 1, 2)); mesh2.AddTriangle (new OV.Triangle (0, 1, 2));
model.AddMesh (mesh2); model.AddMeshToRootNode (mesh2);
assert.strictEqual (model.MeshCount (), 2); assert.strictEqual (model.MeshCount (), 2);
assert.strictEqual (model.VertexCount (), 6); assert.strictEqual (model.VertexCount (), 6);
@ -244,129 +245,6 @@ describe ('Color Conversion', function () {
}); });
}); });
function CreateHierarchicalModel ()
{
/*
+ <Root>
+ Node 1
+ Node 3
Mesh 5
Mesh 6
Mesh 7
+ Node 4
Mesh 7
Mesh 3
Mesh 4
+ Node 2
Mesh 1
Mesh 2
*/
let model = new OV.Model ();
let root = model.GetRootNode ();
let node1 = new OV.Node ();
node1.SetName ('Node 1');
let node2 = new OV.Node ();
node2.SetName ('Node 2');
let node3 = new OV.Node ();
node3.SetName ('Node 3');
let node4 = new OV.Node ();
node4.SetName ('Node 4');
root.AddChildNode (node1);
root.AddChildNode (node2);
node1.AddChildNode (node3);
node1.AddChildNode (node4);
let mesh1 = new OV.Mesh ();
mesh1.SetName ('Mesh 1');
let mesh2 = new OV.Mesh ();
mesh2.SetName ('Mesh 2');
let mesh3 = new OV.Mesh ();
mesh3.SetName ('Mesh 3');
let mesh4 = new OV.Mesh ();
mesh4.SetName ('Mesh 4');
let mesh5 = new OV.Mesh ();
mesh5.SetName ('Mesh 5');
let mesh6 = new OV.Mesh ();
mesh6.SetName ('Mesh 6');
let mesh7 = new OV.Mesh ();
mesh7.SetName ('Mesh 7');
let mesh1Ind = model.AddMesh (mesh1);
let mesh2Ind = model.AddMesh (mesh2);
let mesh3Ind = model.AddMesh (mesh3);
let mesh4Ind = model.AddMesh (mesh4);
let mesh5Ind = model.AddMesh (mesh5);
let mesh6Ind = model.AddMesh (mesh6);
let mesh7Ind = model.AddMesh (mesh7);
root.AddMeshIndex (mesh1Ind);
root.AddMeshIndex (mesh2Ind);
node1.AddMeshIndex (mesh3Ind);
node1.AddMeshIndex (mesh4Ind);
node3.AddMeshIndex (mesh5Ind);
node3.AddMeshIndex (mesh6Ind);
node3.AddMeshIndex (mesh7Ind);
node4.AddMeshIndex (mesh7Ind);
return model;
}
function CreateTranslatedRotatedCubesModel ()
{
/*
+ <Root>
+ Translated
Cube
+ Rotated
+ Translated and Rotated
Cube
Cube
*/
let model = new OV.Model ();
let mesh = OV.GenerateCuboid (null, 1.0, 1.0, 1.0);
mesh.SetName ('Cube');
let meshIndex = model.AddMesh (mesh);
let root = model.GetRootNode ();
root.AddMeshIndex (0);
let translatedNode = new OV.Node ();
translatedNode.SetName ('Translated');
translatedNode.SetTransformation (new OV.Transformation (new OV.Matrix ().CreateTranslation (2.0, 0.0, 0.0)));
translatedNode.AddMeshIndex (0);
let rotatedNode = new OV.Node ();
rotatedNode.SetName ('Rotated');
let rotation = OV.QuaternionFromAxisAngle (new OV.Coord3D (0.0, 0.0, 1.0), Math.PI / 2.0);
rotatedNode.SetTransformation (new OV.Transformation (new OV.Matrix ().CreateRotation (0.0, 0.0, 0.7071067811865475, 0.7071067811865476)));
let translatedRotatedNode = new OV.Node ();
translatedRotatedNode.SetName ('Translated and Rotated');
translatedRotatedNode.SetTransformation (new OV.Transformation (new OV.Matrix ().CreateTranslation (2.0, 0.0, 0.0)));
translatedRotatedNode.AddMeshIndex (0);
root.AddChildNode (translatedNode);
root.AddChildNode (rotatedNode);
rotatedNode.AddChildNode (translatedRotatedNode);
return model;
}
function GetModelTree (model) function GetModelTree (model)
{ {
function AddNodeToModelTree (model, node, modelTree) function AddNodeToModelTree (model, node, modelTree)
@ -392,7 +270,7 @@ function GetModelTree (model)
describe ('Node Hierarchy', function () { describe ('Node Hierarchy', function () {
it ('Enumerate hierarchy', function () { it ('Enumerate hierarchy', function () {
let model = CreateHierarchicalModel (); let model = testUtils.GetHierarchicalModel ();
let modelTree = GetModelTree (model); let modelTree = GetModelTree (model);
assert.deepStrictEqual (modelTree, { assert.deepStrictEqual (modelTree, {
name : '<Root>', name : '<Root>',
@ -424,7 +302,7 @@ describe ('Node Hierarchy', function () {
}); });
it ('Remove mesh', function () { it ('Remove mesh', function () {
let model = CreateHierarchicalModel (); let model = testUtils.GetHierarchicalModel ();
model.RemoveMesh (2); model.RemoveMesh (2);
let modelTree = GetModelTree (model); let modelTree = GetModelTree (model);
assert.deepStrictEqual (modelTree, { assert.deepStrictEqual (modelTree, {
@ -457,7 +335,7 @@ describe ('Node Hierarchy', function () {
}); });
it ('Add mesh to index', function () { it ('Add mesh to index', function () {
let model = CreateHierarchicalModel (); let model = testUtils.GetHierarchicalModel ();
let mesh = new OV.Mesh (); let mesh = new OV.Mesh ();
mesh.SetName ('Mesh 8'); mesh.SetName ('Mesh 8');
model.AddMeshToIndex (mesh, 3); model.AddMeshToIndex (mesh, 3);
@ -492,7 +370,7 @@ describe ('Node Hierarchy', function () {
}); });
it ('Enumerate mesh instances', function () { it ('Enumerate mesh instances', function () {
let model = CreateTranslatedRotatedCubesModel (); let model = testUtils.GetTranslatedRotatedCubesModel ();
let modelTree = GetModelTree (model); let modelTree = GetModelTree (model);
assert.deepStrictEqual (modelTree, { assert.deepStrictEqual (modelTree, {
name : '<Root>', name : '<Root>',
@ -539,7 +417,7 @@ describe ('Node Hierarchy', function () {
}); });
it ('Enumerate transformed mesh instances', function () { it ('Enumerate transformed mesh instances', function () {
let model = CreateTranslatedRotatedCubesModel (); let model = testUtils.GetTranslatedRotatedCubesModel ();
let modelTree = GetModelTree (model); let modelTree = GetModelTree (model);
assert.deepStrictEqual (modelTree, { assert.deepStrictEqual (modelTree, {
name : '<Root>', name : '<Root>',
@ -584,4 +462,15 @@ describe ('Node Hierarchy', function () {
assert (OV.CoordIsEqual3D (boundingBox3.min, new OV.Coord3D (-1.0, 2.0, 0.0))); assert (OV.CoordIsEqual3D (boundingBox3.min, new OV.Coord3D (-1.0, 2.0, 0.0)));
assert (OV.CoordIsEqual3D (boundingBox3.max, new OV.Coord3D (0.0, 3.0, 1.0))); assert (OV.CoordIsEqual3D (boundingBox3.max, new OV.Coord3D (0.0, 3.0, 1.0)));
}); });
it ('Instance counters', function () {
let model = testUtils.GetTranslatedRotatedCubesModel ();
OV.FinalizeModel (model, function () { return new OV.Material (OV.MaterialType.Phong) });
assert.strictEqual (model.MeshCount (), 1);
assert.strictEqual (model.MeshInstanceCount (), 3);
assert.strictEqual (model.VertexCount (), 8 * 3);
assert.strictEqual (model.NormalCount (), 12 * 3);
assert.strictEqual (model.TextureUVCount (), 0);
assert.strictEqual (model.TriangleCount (), 12 * 3);
});
}); });

View File

@ -28,14 +28,14 @@ describe ('Model Utils', function () {
mesh1.AddVertex (new OV.Coord3D (1.0, 0.0, 0.0)); mesh1.AddVertex (new OV.Coord3D (1.0, 0.0, 0.0));
mesh1.AddVertex (new OV.Coord3D (1.0, 1.0, 0.0)); mesh1.AddVertex (new OV.Coord3D (1.0, 1.0, 0.0));
mesh1.AddTriangle (new OV.Triangle (0, 1, 2)); mesh1.AddTriangle (new OV.Triangle (0, 1, 2));
model.AddMesh (mesh1); model.AddMeshToRootNode (mesh1);
var mesh2 = new OV.Mesh (); var mesh2 = new OV.Mesh ();
mesh2.AddVertex (new OV.Coord3D (0.0, 0.0, 1.0)); mesh2.AddVertex (new OV.Coord3D (0.0, 0.0, 1.0));
mesh2.AddVertex (new OV.Coord3D (1.0, 0.0, 1.0)); mesh2.AddVertex (new OV.Coord3D (1.0, 0.0, 1.0));
mesh2.AddVertex (new OV.Coord3D (1.0, 1.0, 1.0)); mesh2.AddVertex (new OV.Coord3D (1.0, 1.0, 1.0));
mesh2.AddTriangle (new OV.Triangle (0, 1, 2)); mesh2.AddTriangle (new OV.Triangle (0, 1, 2));
model.AddMesh (mesh2); model.AddMeshToRootNode (mesh2);
OV.FinalizeModel (model, function () { return new OV.Material (OV.MaterialType.Phong); }); OV.FinalizeModel (model, function () { return new OV.Material (OV.MaterialType.Phong); });
@ -46,6 +46,10 @@ describe ('Model Utils', function () {
let mesh2Bounds = OV.GetBoundingBox (model.GetMesh (1)); let mesh2Bounds = OV.GetBoundingBox (model.GetMesh (1));
assert (OV.CoordIsEqual3D (mesh2Bounds.min, new OV.Coord3D (0.0, 0.0, 1.0))); assert (OV.CoordIsEqual3D (mesh2Bounds.min, new OV.Coord3D (0.0, 0.0, 1.0)));
assert (OV.CoordIsEqual3D (mesh2Bounds.max, new OV.Coord3D (1.0, 1.0, 1.0))); assert (OV.CoordIsEqual3D (mesh2Bounds.max, new OV.Coord3D (1.0, 1.0, 1.0)));
let modelBounds = OV.GetBoundingBox (model);
assert (OV.CoordIsEqual3D (modelBounds.min, new OV.Coord3D (0.0, 0.0, 0.0)));
assert (OV.CoordIsEqual3D (modelBounds.max, new OV.Coord3D (1.0, 1.0, 1.0)));
}); });
it ('Tetrahedron Topology Calculation', function () { it ('Tetrahedron Topology Calculation', function () {

View File

@ -22,7 +22,7 @@ module.exports =
for (i = 0; i < buffer.length; ++i) { for (i = 0; i < buffer.length; ++i) {
uint8Array[i] = buffer[i]; uint8Array[i] = buffer[i];
} }
return arrayBuffer return arrayBuffer
}, },
ModelToObject : function (model) ModelToObject : function (model)
@ -88,7 +88,7 @@ module.exports =
mesh.GetTextureUV (triangle.u1).y, mesh.GetTextureUV (triangle.u1).y,
mesh.GetTextureUV (triangle.u2).x, mesh.GetTextureUV (triangle.u2).x,
mesh.GetTextureUV (triangle.u2).y mesh.GetTextureUV (triangle.u2).y
); );
} }
meshObj.triangles.push (triangleObj); meshObj.triangles.push (triangleObj);
} }
@ -142,11 +142,11 @@ module.exports =
let model = new OV.Model (); let model = new OV.Model ();
let cube1 = OV.GenerateCuboid (null, 1.0, 1.0, 1.0); let cube1 = OV.GenerateCuboid (null, 1.0, 1.0, 1.0);
model.AddMesh (cube1); model.AddMeshToRootNode (cube1);
let matrix = new OV.Matrix ().CreateTranslation (1.0, 1.0, 1.0); let matrix = new OV.Matrix ().CreateTranslation (1.0, 1.0, 1.0);
let cube2 = OV.GenerateCuboid (new OV.GeneratorParams ().SetTransformationMatrix (matrix), 1.0, 1.0, 1.0); let cube2 = OV.GenerateCuboid (new OV.GeneratorParams ().SetTransformationMatrix (matrix), 1.0, 1.0, 1.0);
model.AddMesh (cube2); model.AddMeshToRootNode (cube2);
OV.FinalizeModel (model, function () { return new OV.Material (OV.MaterialType.Phong) }); OV.FinalizeModel (model, function () { return new OV.Material (OV.MaterialType.Phong) });
return model; return model;
@ -157,11 +157,11 @@ module.exports =
let model = new OV.Model (); let model = new OV.Model ();
let cube1 = OV.GenerateCuboid (null, 1.0, 1.0, 1.0); let cube1 = OV.GenerateCuboid (null, 1.0, 1.0, 1.0);
model.AddMesh (cube1); model.AddMeshToRootNode (cube1);
let matrix = new OV.Matrix ().CreateTranslation (1.0, 0.0, 1.0); let matrix = new OV.Matrix ().CreateTranslation (1.0, 0.0, 1.0);
let cube2 = OV.GenerateCuboid (new OV.GeneratorParams ().SetTransformationMatrix (matrix), 1.0, 1.0, 1.0); let cube2 = OV.GenerateCuboid (new OV.GeneratorParams ().SetTransformationMatrix (matrix), 1.0, 1.0, 1.0);
model.AddMesh (cube2); model.AddMeshToRootNode (cube2);
OV.FinalizeModel (model, function () { return new OV.Material (OV.MaterialType.Phong) }); OV.FinalizeModel (model, function () { return new OV.Material (OV.MaterialType.Phong) });
return model; return model;
@ -172,16 +172,16 @@ module.exports =
let model = new OV.Model (); let model = new OV.Model ();
let cube1 = OV.GenerateCuboid (null, 1.0, 1.0, 1.0); let cube1 = OV.GenerateCuboid (null, 1.0, 1.0, 1.0);
model.AddMesh (cube1); model.AddMeshToRootNode (cube1);
let matrix = new OV.Matrix ().CreateTranslation (1.0, 0.0, 0.0); let matrix = new OV.Matrix ().CreateTranslation (1.0, 0.0, 0.0);
let cube2 = OV.GenerateCuboid (new OV.GeneratorParams ().SetTransformationMatrix (matrix), 1.0, 1.0, 1.0); let cube2 = OV.GenerateCuboid (new OV.GeneratorParams ().SetTransformationMatrix (matrix), 1.0, 1.0, 1.0);
model.AddMesh (cube2); model.AddMeshToRootNode (cube2);
OV.FinalizeModel (model, function () { return new OV.Material (OV.MaterialType.Phong) }); OV.FinalizeModel (model, function () { return new OV.Material (OV.MaterialType.Phong) });
return model; return model;
}, },
GetCubeWithOneMissingFaceMesh () GetCubeWithOneMissingFaceMesh ()
{ {
var cube = new OV.Mesh (); var cube = new OV.Mesh ();
@ -204,12 +204,12 @@ module.exports =
cube.AddTriangle (new OV.Triangle (0, 3, 2)); cube.AddTriangle (new OV.Triangle (0, 3, 2));
cube.AddTriangle (new OV.Triangle (0, 2, 1)); cube.AddTriangle (new OV.Triangle (0, 2, 1));
return cube; return cube;
}, },
GetTetrahedronMesh () GetTetrahedronMesh ()
{ {
var tetrahedron = new OV.Mesh (); var tetrahedron = new OV.Mesh ();
let a = 1.0; let a = 1.0;
tetrahedron.AddVertex (new OV.Coord3D (+a, +a, +a)); tetrahedron.AddVertex (new OV.Coord3D (+a, +a, +a));
tetrahedron.AddVertex (new OV.Coord3D (-a, -a, +a)); tetrahedron.AddVertex (new OV.Coord3D (-a, -a, +a));
@ -221,13 +221,136 @@ module.exports =
tetrahedron.AddTriangle (new OV.Triangle (1, 2, 3)); tetrahedron.AddTriangle (new OV.Triangle (1, 2, 3));
return tetrahedron; return tetrahedron;
}, },
GetModelWithOneMesh (mesh) GetModelWithOneMesh (mesh)
{ {
var model = new OV.Model (); var model = new OV.Model ();
model.AddMesh (mesh); model.AddMeshToRootNode (mesh);
OV.FinalizeModel (model, function () { return new OV.Material (OV.MaterialType.Phong) }); OV.FinalizeModel (model, function () { return new OV.Material (OV.MaterialType.Phong) });
return model; return model;
} },
GetHierarchicalModel ()
{
/*
+ <Root>
+ Node 1
+ Node 3
Mesh 5
Mesh 6
Mesh 7
+ Node 4
Mesh 7
Mesh 3
Mesh 4
+ Node 2
Mesh 1
Mesh 2
*/
let model = new OV.Model ();
let root = model.GetRootNode ();
let node1 = new OV.Node ();
node1.SetName ('Node 1');
let node2 = new OV.Node ();
node2.SetName ('Node 2');
let node3 = new OV.Node ();
node3.SetName ('Node 3');
let node4 = new OV.Node ();
node4.SetName ('Node 4');
root.AddChildNode (node1);
root.AddChildNode (node2);
node1.AddChildNode (node3);
node1.AddChildNode (node4);
let mesh1 = new OV.Mesh ();
mesh1.SetName ('Mesh 1');
let mesh2 = new OV.Mesh ();
mesh2.SetName ('Mesh 2');
let mesh3 = new OV.Mesh ();
mesh3.SetName ('Mesh 3');
let mesh4 = new OV.Mesh ();
mesh4.SetName ('Mesh 4');
let mesh5 = new OV.Mesh ();
mesh5.SetName ('Mesh 5');
let mesh6 = new OV.Mesh ();
mesh6.SetName ('Mesh 6');
let mesh7 = new OV.Mesh ();
mesh7.SetName ('Mesh 7');
let mesh1Ind = model.AddMesh (mesh1);
let mesh2Ind = model.AddMesh (mesh2);
let mesh3Ind = model.AddMesh (mesh3);
let mesh4Ind = model.AddMesh (mesh4);
let mesh5Ind = model.AddMesh (mesh5);
let mesh6Ind = model.AddMesh (mesh6);
let mesh7Ind = model.AddMesh (mesh7);
root.AddMeshIndex (mesh1Ind);
root.AddMeshIndex (mesh2Ind);
node1.AddMeshIndex (mesh3Ind);
node1.AddMeshIndex (mesh4Ind);
node3.AddMeshIndex (mesh5Ind);
node3.AddMeshIndex (mesh6Ind);
node3.AddMeshIndex (mesh7Ind);
node4.AddMeshIndex (mesh7Ind);
return model;
},
GetTranslatedRotatedCubesModel ()
{
/*
+ <Root>
+ Translated
Cube
+ Rotated
+ Translated and Rotated
Cube
Cube
*/
let model = new OV.Model ();
let mesh = OV.GenerateCuboid (null, 1.0, 1.0, 1.0);
mesh.SetName ('Cube');
let meshIndex = model.AddMesh (mesh);
let root = model.GetRootNode ();
root.AddMeshIndex (0);
let translatedNode = new OV.Node ();
translatedNode.SetName ('Translated');
translatedNode.SetTransformation (new OV.Transformation (new OV.Matrix ().CreateTranslation (2.0, 0.0, 0.0)));
translatedNode.AddMeshIndex (0);
let rotatedNode = new OV.Node ();
rotatedNode.SetName ('Rotated');
let rotation = OV.QuaternionFromAxisAngle (new OV.Coord3D (0.0, 0.0, 1.0), Math.PI / 2.0);
rotatedNode.SetTransformation (new OV.Transformation (new OV.Matrix ().CreateRotation (rotation.x, rotation.y, rotation.z, rotation.w)));
let translatedRotatedNode = new OV.Node ();
translatedRotatedNode.SetName ('Translated and Rotated');
translatedRotatedNode.SetTransformation (new OV.Transformation (new OV.Matrix ().CreateTranslation (2.0, 0.0, 0.0)));
translatedRotatedNode.AddMeshIndex (0);
root.AddChildNode (translatedNode);
root.AddChildNode (rotatedNode);
rotatedNode.AddChildNode (translatedRotatedNode);
return model;
}
} }

View File

@ -250,14 +250,7 @@ OV.Navigator = class
meshesItem.ShowChildren (true, null); meshesItem.ShowChildren (true, null);
let rootNode = model.GetRootNode (); let rootNode = model.GetRootNode ();
if (!rootNode.IsEmpty ()) { AddModelNodeToTree (this, model, rootNode, meshesItem);
AddModelNodeToTree (this, model, rootNode, meshesItem);
} else {
// TODO: remove
for (let meshIndex = 0; meshIndex < model.MeshCount (); meshIndex++) {
AddMeshToNodeTree (this, model, rootNode, meshIndex, meshesItem);
}
}
} }
MeshItemCount () MeshItemCount ()