UNPKG

mylingo3d

Version:

Lingo3D is a React/Vue 3d game development framework that ships with a complete visual editor

117 lines 4.5 kB
import fit from "./utils/fit"; import Loaded from "./core/Loaded"; import AnimationManager from "./core/AnimatedObjectManager/AnimationManager"; import { modelDefaults, modelSchema } from "../interface/IModel"; import { Resolvable } from "@lincode/promiselikes"; import { Reactive } from "@lincode/reactivity"; import measure from "./utils/measure"; import { getExtensionIncludingObjectURL } from "./core/utils/objectURL"; import { decreaseLoadingCount, increaseLoadingCount } from "../states/useLoadingCount"; export default class Model extends Loaded { unmounted; static componentName = "model"; static defaults = modelDefaults; static schema = modelSchema; constructor(unmounted) { super(unmounted); this.unmounted = unmounted; } loadingState = new Reactive(0); playAnimation(name, o) { setTimeout(() => this.cancelHandle("playAnimation", () => this.loadingState.get((count, handle) => { if (count) return; handle.cancel(); super.playAnimation(name, o); }))); } stopAnimation() { setTimeout(() => this.cancelHandle("stopAnimation", () => this.loadingState.get((count, handle) => { if (count) return; handle.cancel(); super.stopAnimation(); }))); } serializeAnimations; async loadAnimation(url, name = url) { ; (this.serializeAnimations ??= {})[name] = url; const clip = (await this.load(url)).animations[0]; if (!clip) return; this.animations[name] = this.watch(new AnimationManager(clip, await this.loaded)); } get animations() { return super.animations; } set animations(val) { for (const [key, value] of Object.entries(val)) if (typeof value === "string") this.loadAnimation(value, key); else this.animations[key] = value; } async load(url) { increaseLoadingCount(); const resolvable = new Resolvable(); this.loadingState.set(this.loadingState.get() + 1); const extension = getExtensionIncludingObjectURL(url); if (!extension || !["fbx", "glb", "gltf"].includes(extension)) { resolvable.resolve(); setTimeout(() => this.loadingState.set(this.loadingState.get() - 1)); decreaseLoadingCount(); throw new Error("Unsupported file extension " + extension); } const module = extension === "fbx" ? await import("./utils/loaders/loadFBX") : await import("./utils/loaders/loadGLTF"); let result; try { result = await module.default(url, !this.unmounted); } catch { resolvable.resolve(); setTimeout(() => this.loadingState.set(this.loadingState.get() - 1)); decreaseLoadingCount(); throw new Error("Failed to load model, check if src is correct"); } resolvable.resolve(); setTimeout(() => this.loadingState.set(this.loadingState.get() - 1)); decreaseLoadingCount(); return result; } _resize; get resize() { return this._resize ?? true; } set resize(val) { this._resize = val; this.loaded.done && (this.src = this._src); } resolveLoaded(loadedObject3d, src) { if (this.unmounted) return loadedObject3d; for (const clip of loadedObject3d.animations) this.animations[clip.name] = this.watch(new AnimationManager(clip, loadedObject3d)); const measuredSize = this._resize === false ? measure(loadedObject3d, src) : fit(loadedObject3d, src); !this.widthSet && (this.object3d.scale.x = measuredSize.x); !this.heightSet && (this.object3d.scale.y = measuredSize.y); !this.depthSet && (this.object3d.scale.z = measuredSize.z); return loadedObject3d; } find(name, hiddenFromSceneGraph) { const child = super.find(name, hiddenFromSceneGraph); child && (child.model = this); return child; } findAll(name) { const children = super.findAll(name); for (const child of children) child.model = this; return children; } } //# sourceMappingURL=Model.js.map