Embedded texture handling.

This commit is contained in:
kovacsv 2021-08-06 22:17:33 +02:00
parent d03c67ce1f
commit a5561c6f1a
3 changed files with 87 additions and 57 deletions

View File

@ -19,7 +19,7 @@ OV.ThreeImporter = class extends OV.ImporterBase
GetUpDirection () GetUpDirection ()
{ {
return OV.Direction.Z; return OV.Direction.Y;
} }
ClearContent () ClearContent ()
@ -40,9 +40,7 @@ OV.ThreeImporter = class extends OV.ImporterBase
return; return;
} }
Promise.all (libraries).then (() => { Promise.all (libraries).then (() => {
const mainFileUrl = OV.CreateObjectUrl (fileContent); this.LoadModel (fileContent, onFinish);
const loader = this.CreateLoader (mainFileUrl);
this.LoadModel (mainFileUrl, loader, onFinish);
}).catch (() => { }).catch (() => {
onFinish (); onFinish ();
}); });
@ -59,10 +57,23 @@ OV.ThreeImporter = class extends OV.ImporterBase
return null; return null;
} }
CreateLoader (mainFileUrl) CreateLoader (manager)
{ {
const manager = new THREE.LoadingManager (); let loader = null;
manager.setURLModifier ((url) => { if (this.extension === 'fbx') {
loader = new THREE.FBXLoader (manager);
}
return loader;
}
LoadModel (fileContent, onFinish)
{
let loadedScene = null;
let loadingManager = new THREE.LoadingManager (() => {
this.OnThreeObjectsLoaded (loadedScene, onFinish);
});
loadingManager.setURLModifier ((url) => {
if (url === mainFileUrl) { if (url === mainFileUrl) {
return url; return url;
} }
@ -73,24 +84,9 @@ OV.ThreeImporter = class extends OV.ImporterBase
const fileUrl = OV.CreateObjectUrl (fileBuffer); const fileUrl = OV.CreateObjectUrl (fileBuffer);
return fileUrl; return fileUrl;
}); });
let loader = null;
if (this.extension === 'fbx') {
loader = new THREE.FBXLoader (manager);
}
return loader;
}
LoadModel (mainFileUrl, loader, onFinish)
{
function SetColor (color, threeColor)
{
color.Set (
parseInt (threeColor.r * 255.0, 10),
parseInt (threeColor.g * 255.0, 10),
parseInt (threeColor.b * 255.0, 10)
);
}
const mainFileUrl = OV.CreateObjectUrl (fileContent);
const loader = this.CreateLoader (loadingManager);
if (loader === null) { if (loader === null) {
onFinish (); onFinish ();
return; return;
@ -99,38 +95,9 @@ OV.ThreeImporter = class extends OV.ImporterBase
// TODO: error handling // TODO: error handling
loader.load (mainFileUrl, loader.load (mainFileUrl,
(object) => { (object) => {
object.traverse ((child) => { loadedScene = object;
if (child.isMesh) {
// TODO: merge same materials
// TODO: PBR materials
console.log (child);
let threeMaterial = child.material;
let material = new OV.Material (OV.MaterialType.Phong);
material.name = threeMaterial.name;
SetColor (material.color, threeMaterial.color);
if (threeMaterial.type === 'MeshPhongMaterial') {
SetColor (material.specular, threeMaterial.specular);
material.shininess = threeMaterial.shininess / 100.0;
}
const materialIndex = this.model.AddMaterial (material);
let mesh = OV.ConvertThreeGeometryToMesh (child.geometry, materialIndex);
if (child.matrixWorld !== undefined && child.matrixWorld !== null) {
const matrix = new OV.Matrix (child.matrixWorld.elements);
const transformation = new OV.Transformation (matrix);
const determinant = matrix.Determinant ();
const mirrorByX = OV.IsNegative (determinant);
OV.TransformMesh (mesh, transformation);
if (mirrorByX) {
OV.FlipMeshTrianglesOrientation (mesh);
}
}
this.model.AddMesh (mesh);
}
});
onFinish ();
}, },
() => { () => {
}, },
(err) => { (err) => {
this.SetError (); this.SetError ();
@ -139,4 +106,30 @@ OV.ThreeImporter = class extends OV.ImporterBase
} }
); );
} }
OnThreeObjectsLoaded (scene, onFinish)
{
scene.traverse ((child) => {
if (child.isMesh) {
// TODO: merge same materials
// TODO: PBR materials
console.log (child);
let material = OV.ConvertThreeMaterialToMaterial (child.material);
const materialIndex = this.model.AddMaterial (material);
let mesh = OV.ConvertThreeGeometryToMesh (child.geometry, materialIndex);
if (child.matrixWorld !== undefined && child.matrixWorld !== null) {
const matrix = new OV.Matrix (child.matrixWorld.elements);
const transformation = new OV.Transformation (matrix);
const determinant = matrix.Determinant ();
const mirrorByX = OV.IsNegative (determinant);
OV.TransformMesh (mesh, transformation);
if (mirrorByX) {
OV.FlipMeshTrianglesOrientation (mesh);
}
}
this.model.AddMesh (mesh);
}
});
onFinish ();
}
}; };

View File

@ -55,6 +55,43 @@ OV.HasHighpDriverIssue = function ()
return false; return false;
}; };
OV.ConvertThreeMaterialToMaterial = function (threeMaterial)
{
function SetColor (color, threeColor)
{
color.Set (
parseInt (threeColor.r * 255.0, 10),
parseInt (threeColor.g * 255.0, 10),
parseInt (threeColor.b * 255.0, 10)
);
}
function CreateTexture (threeMap)
{
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 material = new OV.Material (OV.MaterialType.Phong);
material.name = threeMaterial.name;
SetColor (material.color, threeMaterial.color);
if (threeMaterial.type === 'MeshPhongMaterial') {
SetColor (material.specular, threeMaterial.specular);
material.shininess = threeMaterial.shininess / 100.0;
}
if (threeMaterial.map !== undefined && threeMaterial.map !== null) {
material.diffuseMap = CreateTexture (threeMaterial.map);
}
return material;
};
OV.ConvertThreeGeometryToMesh = function (threeGeometry, materialIndex) OV.ConvertThreeGeometryToMesh = function (threeGeometry, materialIndex)
{ {
// TODO: check if buffergeometry // TODO: check if buffergeometry