@threepipe/plugin-assimpjs
Version:
Assimp.js Plugin for ThreePipe
1 lines • 8.35 kB
Source Map (JSON)
{"version":3,"file":"index.mjs","sources":["../src/AssimpJsPlugin.ts"],"sourcesContent":["import {\n AViewerPluginSync,\n ThreeViewer,\n getUrlQueryParam,\n createScriptFromURL,\n IObject3D,\n ExportFileOptions, uiButton, uiToggle, PickingPlugin, uiFolderContainer,\n} from 'threepipe'\n\ninterface AssimpJsInterface{\n [key: string]: any\n}\n\n/**\n * AssimpJsPlugin\n *\n * Helper plugin to load the assimp.js library from a CDN and provide a method to convert files using Assimp.js.\n *\n * Assimpjs - https://github.com/kovacsv/assimpjs\n * Fork with a custom build to support fbx export - https://github.com/repalash/assimpjs\n */\n@uiFolderContainer('Assimp')\nexport class AssimpJsPlugin extends AViewerPluginSync {\n public static readonly PluginType: string = 'SamplePlugin'\n enabled = true\n dependencies = []\n\n initOnAdd: boolean\n\n // public static LIBRARY_PATH = `https://cdn.jsdelivr.net/npm/assimpjs@${getUrlQueryParam('assimpjs', '0.0.10')}/`\n // adds fbx export support\n public static LIBRARY_PATH = `https://cdn.jsdelivr.net/gh/repalash/assimpjs@${getUrlQueryParam('assimpjs', 'main')}/`\n\n constructor(initOnAdd = true) {\n super()\n this.initOnAdd = initOnAdd\n }\n\n protected _scriptElement?: HTMLScriptElement\n private _initing: Promise<void>|undefined\n\n async init() {\n if (!this._initing) this._initing = this._init()\n await this._initing\n return this.ajs\n }\n private async _init() {\n if (!(window as any).assimpjs) {\n this._scriptElement = await createScriptFromURL(AssimpJsPlugin.LIBRARY_PATH + 'dist/assimpjs.js')\n }\n const ctor = (window as any).assimpjs\n const ajs = ctor ? await ctor({\n locateFile: (file: string) => AssimpJsPlugin.LIBRARY_PATH + 'dist/' + file,\n // print: (text: string) => console.log(text),\n // printErr: (text: string) => console.error(text),\n // onRuntimeInitialized: () => {\n // console.log('Assimp.js initialized')\n // this.viewer?.emit('assimpjs-initialized', ajs)\n // },\n // noExitRuntime: true,\n }) : null\n if (!ajs) {\n this._initing = undefined\n this._scriptElement?.remove()\n throw new Error('Failed to load Assimp.js library')\n }\n this.ajs = ajs\n\n }\n ajs?: AssimpJsInterface\n\n onAdded(viewer: ThreeViewer) {\n super.onAdded(viewer)\n if (this.initOnAdd) this.init()\n }\n\n // todo add ui config to export the scene, selected object as fbx or glb2 etc. or interface with the AssetExporter.\n\n convertFiles(files: Record<string, ArrayBuffer>, format: 'fbx'|'gltf2'|'glb2'|'assjson' = 'glb2') {\n const ajs = this.ajs\n if (!ajs) {\n console.error('Assimp.js is not initialized, wait for the promise like - `await assimpPlugin.init()`')\n return\n }\n const fileList = new ajs.FileList()\n for (const [name, content] of Object.entries(files)) {\n fileList.AddFile(name, new Uint8Array(content))\n }\n\n // convert file list to assimp json\n const result = ajs.ConvertFileList(fileList, format)\n\n // check if the conversion succeeded\n if (!result.IsSuccess() || result.FileCount() == 0) {\n // resultDiv.innerHTML = result.GetErrorCode()\n console.error(result.GetErrorCode())\n console.error(result)\n return\n }\n\n // get the result file, and convert to blob\n const resultFile = result.GetFile(0)\n const blob = new Blob([resultFile.GetContent()], {type: 'application/octet-stream'})\n return blob\n }\n\n async exportModel(format: 'fbx'|'gltf2'|'glb2'|'assjson' = 'glb2', object?: IObject3D, options: ExportFileOptions = {embedUrlImages: true}) {\n if (!this._viewer) {\n console.error('AssimpJsPlugin - No viewer attached, please add the plugin to a viewer instance.')\n return\n }\n const initing = this.init()\n const selected = this.exportSelected ? this._viewer.getPlugin(PickingPlugin)?.getSelectedObject<IObject3D>() : undefined\n object = object || (selected?.isObject3D ? selected : this._viewer.scene.modelRoot)\n\n // export to glb\n const blob = await this._viewer.export(object, options)\n if (!blob || blob.ext !== 'glb') {\n console.error('AssimpJsPlugin - Unable to export model, no blob returned.')\n return\n }\n await initing // wait for assimp.js to be initialized\n const blob2 = this.convertFiles({['file.glb']: await blob.arrayBuffer()}, format)\n if (!blob2) {\n console.error('AssimpJsPlugin - Unable to convert model to format:', format)\n return\n }\n // convert to ArrayBuffer\n return new File([blob2], 'model.' + format.replace(/2$/, ''), {type: 'application/octet-stream'})\n }\n\n @uiToggle('Export Selected')\n exportSelected = true\n\n @uiButton('Download FBX')\n async exportAsFbx(object?: IObject3D) {\n if (!object?.isObject3D) object = undefined\n const blob = await this.exportModel('fbx', object)\n if (blob) {\n await this._viewer?.exportBlob(blob, blob.name)\n }\n }\n @uiButton('Download Assimp JSON')\n async exportAsGlb(object?: IObject3D) {\n if (!object?.isObject3D) object = undefined\n const blob = await this.exportModel('assjson', object)\n if (blob) {\n await this._viewer?.exportBlob(blob, blob.name)\n }\n }\n}\n"],"names":[],"mappings":"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"}