polygonjs-engine
Version:
node-based webgl 3D engine https://polygonjs.com
278 lines (277 loc) • 9.79 kB
JavaScript
import {ObjectLoader as ObjectLoader2} from "three/src/loaders/ObjectLoader";
import {Object3D as Object3D2} from "three/src/core/Object3D";
import {BufferGeometry as BufferGeometry2} from "three/src/core/BufferGeometry";
import {Poly as Poly2} from "../../engine/Poly";
import {ModuleName} from "../../engine/poly/registers/modules/_BaseRegister";
import {LineSegments as LineSegments2} from "three/src/objects/LineSegments";
import {Mesh as Mesh2} from "three/src/objects/Mesh";
import {Points as Points2} from "three/src/objects/Points";
import {LineBasicMaterial as LineBasicMaterial2} from "three/src/materials/LineBasicMaterial";
import {MeshLambertMaterial as MeshLambertMaterial2} from "three/src/materials/MeshLambertMaterial";
import {PointsMaterial as PointsMaterial2} from "three/src/materials/PointsMaterial";
import {CoreUserAgent} from "../UserAgent";
var GeometryExtension;
(function(GeometryExtension2) {
GeometryExtension2["DRC"] = "drc";
GeometryExtension2["FBX"] = "fbx";
GeometryExtension2["GLTF"] = "gltf";
GeometryExtension2["GLB"] = "glb";
GeometryExtension2["OBJ"] = "obj";
GeometryExtension2["PDB"] = "pdb";
GeometryExtension2["PLY"] = "ply";
})(GeometryExtension || (GeometryExtension = {}));
const CoreLoaderGeometry2 = class {
constructor(url, scene) {
this.url = url;
this.scene = scene;
this.ext = CoreLoaderGeometry2.get_extension(url);
}
static get_extension(url) {
let _url;
let ext = null;
try {
_url = new URL(url);
ext = _url.searchParams.get("ext");
} catch (e) {
}
if (!ext) {
const url_without_params = url.split("?")[0];
const elements = url_without_params.split(".");
ext = elements[elements.length - 1].toLowerCase();
}
return ext;
}
load(on_success, on_error) {
this.load_auto().then((object) => {
on_success(object);
}).catch((error) => {
on_error(error);
});
}
load_auto() {
return new Promise(async (resolve, reject) => {
let url = this.url;
if (url[0] != "h") {
const assets_root = this.scene.assets.root();
if (assets_root) {
url = `${assets_root}${url}`;
}
}
if (this.ext == "json") {
CoreLoaderGeometry2.increment_in_progress_loads_count();
await CoreLoaderGeometry2.wait_for_max_concurrent_loads_queue_freed();
fetch(url).then(async (response) => {
const data = await response.json();
const obj_loader = new ObjectLoader2();
obj_loader.parse(data, (obj) => {
CoreLoaderGeometry2.decrement_in_progress_loads_count();
resolve(this.on_load_success(obj.children[0]));
});
}).catch((error) => {
CoreLoaderGeometry2.decrement_in_progress_loads_count();
reject(error);
});
} else {
const loader = await this.loader_for_ext();
if (loader) {
CoreLoaderGeometry2.increment_in_progress_loads_count();
await CoreLoaderGeometry2.wait_for_max_concurrent_loads_queue_freed();
loader.load(url, (object) => {
this.on_load_success(object).then((object2) => {
CoreLoaderGeometry2.decrement_in_progress_loads_count();
resolve(object2);
});
}, void 0, (error_message) => {
Poly2.warn("error loading", url, error_message);
CoreLoaderGeometry2.decrement_in_progress_loads_count();
reject(error_message);
});
} else {
const error_message = `format not supported (${this.ext})`;
reject(error_message);
}
}
});
}
async on_load_success(object) {
if (object instanceof Object3D2) {
switch (this.ext) {
case GeometryExtension.GLTF:
return this.on_load_succes_gltf(object);
case GeometryExtension.GLB:
return this.on_load_succes_gltf(object);
case GeometryExtension.OBJ:
return [object];
case "json":
return [object];
default:
return [object];
}
}
if (object instanceof BufferGeometry2) {
switch (this.ext) {
case GeometryExtension.DRC:
return this.on_load_succes_drc(object);
default:
return [new Mesh2(object)];
}
}
switch (this.ext) {
case GeometryExtension.GLTF:
return this.on_load_succes_gltf(object);
case GeometryExtension.GLB:
return this.on_load_succes_gltf(object);
case GeometryExtension.PDB:
return this.on_load_succes_pdb(object);
default:
return [];
}
return [];
}
on_load_succes_drc(geometry) {
const mesh = new Mesh2(geometry, CoreLoaderGeometry2._default_mat_mesh);
return [mesh];
}
on_load_succes_gltf(gltf) {
const scene = gltf["scene"];
scene.animations = gltf.animations;
return [scene];
}
on_load_succes_pdb(pdb_object) {
const atoms = new Points2(pdb_object.geometryAtoms, CoreLoaderGeometry2._default_mat_point);
const bonds = new LineSegments2(pdb_object.geometryBonds, CoreLoaderGeometry2._default_mat_line);
return [atoms, bonds];
}
static module_names(ext) {
switch (ext) {
case GeometryExtension.DRC:
return [ModuleName.DRACOLoader];
case GeometryExtension.FBX:
return [ModuleName.FBXLoader];
case GeometryExtension.GLTF:
return [ModuleName.GLTFLoader];
case GeometryExtension.GLB:
return [ModuleName.GLTFLoader, ModuleName.DRACOLoader];
case GeometryExtension.OBJ:
return [ModuleName.OBJLoader2];
case GeometryExtension.PDB:
return [ModuleName.PDBLoader];
case GeometryExtension.PLY:
return [ModuleName.PLYLoader];
}
}
async loader_for_ext() {
switch (this.ext.toLowerCase()) {
case GeometryExtension.DRC:
return this.loader_for_drc();
case GeometryExtension.FBX:
return this.loader_for_fbx();
case GeometryExtension.GLTF:
return this.loader_for_gltf();
case GeometryExtension.GLB:
return this.loader_for_glb();
case GeometryExtension.OBJ:
return this.loader_for_obj();
case GeometryExtension.PDB:
return this.loader_for_pdb();
case GeometryExtension.PLY:
return this.loader_for_ply();
}
}
async loader_for_drc() {
const module = await Poly2.modulesRegister.module(ModuleName.DRACOLoader);
if (module) {
const draco_loader = new module.DRACOLoader();
const root = Poly2.libs.root();
const decoder_path = `${root}/draco/`;
draco_loader.setDecoderPath(decoder_path);
draco_loader.setDecoderConfig({type: "js"});
return draco_loader;
}
}
async loader_for_fbx() {
const module = await Poly2.modulesRegister.module(ModuleName.FBXLoader);
if (module) {
return new module.FBXLoader();
}
}
async loader_for_gltf() {
const module = await Poly2.modulesRegister.module(ModuleName.GLTFLoader);
if (module) {
return new module.GLTFLoader();
}
}
static async loader_for_glb(scene) {
const gltf_module = await Poly2.modulesRegister.module(ModuleName.GLTFLoader);
const draco_module = await Poly2.modulesRegister.module(ModuleName.DRACOLoader);
if (gltf_module && draco_module) {
this.gltf_loader = this.gltf_loader || new gltf_module.GLTFLoader();
this.draco_loader = this.draco_loader || new draco_module.DRACOLoader();
const root = Poly2.libs.root();
const decoder_path = `${root}/draco/gltf/`;
this.draco_loader.setDecoderPath(decoder_path);
this.gltf_loader.setDRACOLoader(this.draco_loader);
return this.gltf_loader;
}
}
async loader_for_glb() {
return CoreLoaderGeometry2.loader_for_glb(this.scene);
}
async loader_for_obj() {
const module = await Poly2.modulesRegister.module(ModuleName.OBJLoader2);
if (module) {
return new module.OBJLoader2();
}
}
async loader_for_pdb() {
const module = await Poly2.modulesRegister.module(ModuleName.PDBLoader);
if (module) {
return new module.PDBLoader();
}
}
async loader_for_ply() {
const module = await Poly2.modulesRegister.module(ModuleName.PLYLoader);
if (module) {
return new module.PLYLoader();
}
}
static _init_max_concurrent_loads_count() {
return CoreUserAgent.is_chrome() ? 4 : 1;
}
static _init_concurrent_loads_delay() {
return CoreUserAgent.is_chrome() ? 1 : 10;
}
static override_max_concurrent_loads_count(count) {
this.MAX_CONCURRENT_LOADS_COUNT = count;
}
static increment_in_progress_loads_count() {
this.in_progress_loads_count++;
}
static decrement_in_progress_loads_count() {
this.in_progress_loads_count--;
const queued_resolve = this._queue.pop();
if (queued_resolve) {
const delay = this.CONCURRENT_LOADS_DELAY;
setTimeout(() => {
queued_resolve();
}, delay);
}
}
static async wait_for_max_concurrent_loads_queue_freed() {
if (this.in_progress_loads_count <= this.MAX_CONCURRENT_LOADS_COUNT) {
return;
} else {
return new Promise((resolve) => {
this._queue.push(resolve);
});
}
}
};
export let CoreLoaderGeometry = CoreLoaderGeometry2;
CoreLoaderGeometry._default_mat_mesh = new MeshLambertMaterial2();
CoreLoaderGeometry._default_mat_point = new PointsMaterial2();
CoreLoaderGeometry._default_mat_line = new LineBasicMaterial2();
CoreLoaderGeometry.MAX_CONCURRENT_LOADS_COUNT = CoreLoaderGeometry2._init_max_concurrent_loads_count();
CoreLoaderGeometry.CONCURRENT_LOADS_DELAY = CoreLoaderGeometry2._init_concurrent_loads_delay();
CoreLoaderGeometry.in_progress_loads_count = 0;
CoreLoaderGeometry._queue = [];