diff --git a/source/threejs/threeimporter.js b/source/threejs/threeimporter.js index dfd1f77..4c09a8d 100644 --- a/source/threejs/threeimporter.js +++ b/source/threejs/threeimporter.js @@ -76,8 +76,9 @@ OV.ThreeImporter = class extends OV.ImporterBase LoadModel (fileContent, onFinish) { let loadedScene = null; + let blobToBuffer = {}; let loadingManager = new THREE.LoadingManager (() => { - this.OnThreeObjectsLoaded (loadedScene, onFinish); + this.OnThreeObjectsLoaded (loadedScene, blobToBuffer, onFinish); }); const mainFileUrl = OV.CreateObjectUrl (fileContent); @@ -90,6 +91,10 @@ OV.ThreeImporter = class extends OV.ImporterBase } const fileBuffer = this.callbacks.getFileBuffer (url); const fileUrl = OV.CreateObjectUrl (fileBuffer); + blobToBuffer[fileUrl] = { + name : OV.GetFileName (url), + buffer : fileBuffer + }; return fileUrl; }); @@ -114,9 +119,9 @@ OV.ThreeImporter = class extends OV.ImporterBase ); } - OnThreeObjectsLoaded (scene, onFinish) + OnThreeObjectsLoaded (scene, blobToBuffer, onFinish) { - function ConvertThreeMaterialToMaterial (threeMaterial) + function ConvertThreeMaterialToMaterial (threeMaterial, blobToBuffer) { function SetColor (color, threeColor) { @@ -127,19 +132,34 @@ OV.ThreeImporter = class extends OV.ImporterBase ); } - function CreateTexture (threeMap) + function CreateTexture (threeMap, blobToBuffer) { if (threeMap.image === undefined || threeMap.image === null) { return null; } - let base64Buffer = OV.Base64DataURIToArrayBuffer (threeMap.image.currentSrc); - let texture = new OV.TextureMap (); - texture.name = 'Embedded.' + OV.GetFileExtensionFromMimeType (base64Buffer.mimeType); - texture.url = OV.CreateObjectUrlWithMimeType (base64Buffer.buffer, base64Buffer.mimeType); - texture.buffer = base64Buffer.buffer; - return texture; + let imageSrc = threeMap.image.currentSrc; + if (imageSrc.startsWith ('data:')) { + let base64Buffer = OV.Base64DataURIToArrayBuffer (threeMap.image.currentSrc); + let texture = new OV.TextureMap (); + texture.name = 'Embedded.' + OV.GetFileExtensionFromMimeType (base64Buffer.mimeType); + texture.url = OV.CreateObjectUrlWithMimeType (base64Buffer.buffer, base64Buffer.mimeType); + texture.buffer = base64Buffer.buffer; + return texture; + } else if (imageSrc.startsWith ('blob:')) { + let buffer = blobToBuffer[imageSrc]; + if (buffer === undefined) { + return null; + } + let texture = new OV.TextureMap (); + texture.name = buffer.name; + texture.url = imageSrc; + texture.buffer = buffer.buffer; + return texture; + } + return null; } + // TODO: PBR materials let material = new OV.Material (OV.MaterialType.Phong); material.name = threeMaterial.name; SetColor (material.color, threeMaterial.color); @@ -148,19 +168,28 @@ OV.ThreeImporter = class extends OV.ImporterBase material.shininess = threeMaterial.shininess / 100.0; } if (threeMaterial.map !== undefined && threeMaterial.map !== null) { - material.diffuseMap = CreateTexture (threeMaterial.map); + material.diffuseMap = CreateTexture (threeMaterial.map, blobToBuffer); } return material; - } + } + + function FindMatchingMaterialIndex (model, material) + { + for (let i = 0; i < model.MaterialCount (); i++) { + let modelMaterial = model.GetMaterial (i); + if (OV.MaterialIsEqual (modelMaterial, material)) { + return i; + } + } + return model.AddMaterial (material); + } this.loadedScene = scene; scene.traverse ((child) => { if (child.isMesh) { - // TODO: merge same materials - // TODO: PBR materials - console.log (child); - let material = ConvertThreeMaterialToMaterial (child.material); - const materialIndex = this.model.AddMaterial (material); + // TODO: array of materials + let material = ConvertThreeMaterialToMaterial (child.material, blobToBuffer); + const materialIndex = FindMatchingMaterialIndex (this.model, material); let mesh = OV.ConvertThreeGeometryToMesh (child.geometry, materialIndex); if (child.matrixWorld !== undefined && child.matrixWorld !== null) { const matrix = new OV.Matrix (child.matrixWorld.elements);