import { Object3D, Material } from "three"; import { GLTF, GLTFLoaderPlugin, GLTFParser } from "three/examples/jsm/loaders/GLTFLoader"; import { addCustomExtension } from "@needle-tools/engine"; import { $editorKey } from "./types"; import { Registry } from "./registry"; import { notifySceneChanged } from "./editor"; export const EXTENSION_NAME = "NEEDLE_editor"; declare type ExtensibleProperty = { extensions: [] } declare type ExtensionDefinition = { id: string } let isLoading = 0; export class NEEDLE_editor implements GLTFLoaderPlugin { static get isLoading(): boolean { return isLoading > 0; } get name(): string { return EXTENSION_NAME; } private parser: GLTFParser; constructor(parser: GLTFParser) { this.parser = parser; } beforeRoot() { isLoading += 1; return null; } afterRoot(_result: GLTF): Promise | null { const promises: Promise[] = []; this.applyToObjects("material", this.parser.json.materials, promises); this.applyToObjects("node", this.parser.json.nodes, promises); return Promise.all(promises).then(() => { isLoading -= 1; }); } private applyToObjects(dependencyName: string, array: ExtensibleProperty[], promises: Array>) { if (!array) return; for (let i = 0; i < array.length; i++) { const definition = array[i]; if (definition && definition.extensions) { const ext = definition.extensions[EXTENSION_NAME] as ExtensionDefinition; if (ext) { const prom = this.parser.getDependency(dependencyName, i).then(obj => { obj[$editorKey] = ext.id; Registry.add(ext.id, obj); }) promises.push(prom); } } } } } addCustomExtension(NEEDLE_editor);