@threepipe/plugin-assimpjs
Version:
Assimp.js Plugin for ThreePipe
137 lines (136 loc) • 5.17 kB
JavaScript
/**
* @license
* @threepipe/plugin-assimpjs v0.2.0
* Copyright 2022-2025 repalash <palash@shaders.app>
* Apache-2.0 License
* See ./dependencies.txt for any bundled third-party dependencies and licenses.
*/
import { getUrlQueryParam, uiToggle, uiButton, uiFolderContainer, AViewerPluginSync, createScriptFromURL, PickingPlugin } from "threepipe";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __decorateClass = (decorators, target, key, kind) => {
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
for (var i = decorators.length - 1, decorator; i >= 0; i--)
if (decorator = decorators[i])
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
if (kind && result) __defProp(target, key, result);
return result;
};
let AssimpJsPlugin = class extends AViewerPluginSync {
constructor(initOnAdd = true) {
super();
this.enabled = true;
this.dependencies = [];
this.exportSelected = true;
this.initOnAdd = initOnAdd;
}
async init() {
if (!this._initing) this._initing = this._init();
await this._initing;
return this.ajs;
}
async _init() {
var _a;
if (!window.assimpjs) {
this._scriptElement = await createScriptFromURL(AssimpJsPlugin.LIBRARY_PATH + "dist/assimpjs.js");
}
const ctor = window.assimpjs;
const ajs = ctor ? await ctor({
locateFile: (file) => AssimpJsPlugin.LIBRARY_PATH + "dist/" + file
// print: (text: string) => console.log(text),
// printErr: (text: string) => console.error(text),
// onRuntimeInitialized: () => {
// console.log('Assimp.js initialized')
// this.viewer?.emit('assimpjs-initialized', ajs)
// },
// noExitRuntime: true,
}) : null;
if (!ajs) {
this._initing = void 0;
(_a = this._scriptElement) == null ? void 0 : _a.remove();
throw new Error("Failed to load Assimp.js library");
}
this.ajs = ajs;
}
onAdded(viewer) {
super.onAdded(viewer);
if (this.initOnAdd) this.init();
}
// todo add ui config to export the scene, selected object as fbx or glb2 etc. or interface with the AssetExporter.
convertFiles(files, format = "glb2") {
const ajs = this.ajs;
if (!ajs) {
console.error("Assimp.js is not initialized, wait for the promise like - `await assimpPlugin.init()`");
return;
}
const fileList = new ajs.FileList();
for (const [name, content] of Object.entries(files)) {
fileList.AddFile(name, new Uint8Array(content));
}
const result = ajs.ConvertFileList(fileList, format);
if (!result.IsSuccess() || result.FileCount() == 0) {
console.error(result.GetErrorCode());
console.error(result);
return;
}
const resultFile = result.GetFile(0);
const blob = new Blob([resultFile.GetContent()], { type: "application/octet-stream" });
return blob;
}
async exportModel(format = "glb2", object, options = { embedUrlImages: true }) {
var _a;
if (!this._viewer) {
console.error("AssimpJsPlugin - No viewer attached, please add the plugin to a viewer instance.");
return;
}
const initing = this.init();
const selected = this.exportSelected ? (_a = this._viewer.getPlugin(PickingPlugin)) == null ? void 0 : _a.getSelectedObject() : void 0;
object = object || selected || this._viewer.scene.modelRoot;
const blob = await this._viewer.export(object, options);
if (!blob || blob.ext !== "glb") {
console.error("AssimpJsPlugin - Unable to export model, no blob returned.");
return;
}
await initing;
const blob2 = this.convertFiles({ ["file.glb"]: await blob.arrayBuffer() }, format);
if (!blob2) {
console.error("AssimpJsPlugin - Unable to convert model to format:", format);
return;
}
return new File([blob2], "model." + format.replace(/2$/, ""), { type: "application/octet-stream" });
}
async exportAsFbx(object) {
var _a;
if (!(object == null ? void 0 : object.isObject3D)) object = void 0;
const blob = await this.exportModel("fbx", object);
if (blob) {
await ((_a = this._viewer) == null ? void 0 : _a.exportBlob(blob, blob.name));
}
}
async exportAsGlb(object) {
var _a;
if (!(object == null ? void 0 : object.isObject3D)) object = void 0;
const blob = await this.exportModel("assjson", object);
if (blob) {
await ((_a = this._viewer) == null ? void 0 : _a.exportBlob(blob, blob.name));
}
}
};
AssimpJsPlugin.PluginType = "SamplePlugin";
AssimpJsPlugin.LIBRARY_PATH = `https://cdn.jsdelivr.net/gh/repalash/assimpjs@${getUrlQueryParam("assimpjs", "main")}/`;
__decorateClass([
uiToggle("Export Selected")
], AssimpJsPlugin.prototype, "exportSelected", 2);
__decorateClass([
uiButton("Download FBX")
], AssimpJsPlugin.prototype, "exportAsFbx", 1);
__decorateClass([
uiButton("Download Assimp JSON")
], AssimpJsPlugin.prototype, "exportAsGlb", 1);
AssimpJsPlugin = __decorateClass([
uiFolderContainer("Assimp")
], AssimpJsPlugin);
export {
AssimpJsPlugin
};
//# sourceMappingURL=index.mjs.map