144 lines
3.9 KiB
JavaScript
144 lines
3.9 KiB
JavaScript
OV.ThreeImporter = class extends OV.ImporterBase
|
|
{
|
|
constructor ()
|
|
{
|
|
super ();
|
|
}
|
|
|
|
CanImportExtension (extension)
|
|
{
|
|
return extension === 'fbx';
|
|
}
|
|
|
|
GetKnownFileFormats ()
|
|
{
|
|
return {
|
|
'fbx' : OV.FileFormat.Binary
|
|
};
|
|
}
|
|
|
|
GetUpDirection ()
|
|
{
|
|
return OV.Direction.Y;
|
|
}
|
|
|
|
ClearContent ()
|
|
{
|
|
if (this.loadedScene !== undefined && this.loadedScene !== null) {
|
|
this.loadedScene.traverse ((child) => {
|
|
if (child.isMesh) {
|
|
child.geometry.dispose ();
|
|
}
|
|
});
|
|
this.loadedScene = null;
|
|
}
|
|
}
|
|
|
|
ResetContent ()
|
|
{
|
|
this.loadedScene = null;
|
|
}
|
|
|
|
ImportContent (fileContent, onFinish)
|
|
{
|
|
const libraries = this.GetExternalLibraries ();
|
|
if (libraries === null) {
|
|
onFinish ();
|
|
return;
|
|
}
|
|
Promise.all (libraries).then (() => {
|
|
this.LoadModel (fileContent, onFinish);
|
|
}).catch (() => {
|
|
onFinish ();
|
|
});
|
|
}
|
|
|
|
GetExternalLibraries ()
|
|
{
|
|
if (this.extension === 'fbx') {
|
|
return [
|
|
OV.LoadExternalLibrary ('three_loaders/FBXLoader.js'),
|
|
OV.LoadExternalLibrary ('three_loaders/fflate.min.js')
|
|
];
|
|
}
|
|
return null;
|
|
}
|
|
|
|
CreateLoader (manager)
|
|
{
|
|
let loader = null;
|
|
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) {
|
|
return url;
|
|
}
|
|
if (url.startsWith ('data:')) {
|
|
return url;
|
|
}
|
|
const fileBuffer = this.callbacks.getFileBuffer (url);
|
|
const fileUrl = OV.CreateObjectUrl (fileBuffer);
|
|
return fileUrl;
|
|
});
|
|
|
|
const mainFileUrl = OV.CreateObjectUrl (fileContent);
|
|
const loader = this.CreateLoader (loadingManager);
|
|
if (loader === null) {
|
|
onFinish ();
|
|
return;
|
|
}
|
|
|
|
// TODO: error handling
|
|
loader.load (mainFileUrl,
|
|
(object) => {
|
|
loadedScene = object;
|
|
},
|
|
() => {
|
|
},
|
|
(err) => {
|
|
this.SetError ();
|
|
this.SetMessage (err);
|
|
onFinish ();
|
|
}
|
|
);
|
|
}
|
|
|
|
OnThreeObjectsLoaded (scene, onFinish)
|
|
{
|
|
this.loadedScene = scene;
|
|
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 ();
|
|
}
|
|
};
|