threepipe
Version:
A 3D viewer framework built on top of three.js in TypeScript with a focus on quality rendering, modularity and extensibility.
145 lines • 6.54 kB
JavaScript
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
import { serialize } from 'ts-browser-helpers';
import { AViewerPluginSync, ThreeViewer } from '../../viewer';
// todo deprecate the plugin and add functionality to AssetManager maybe
/**
* Asset Exporter Plugin
* Provides options and methods to export the scene, object GLB or Viewer Config.
* All the functionality is available in the viewer directly, this provides only a ui-config and maintains state of the options.
*/
export class AssetExporterPlugin extends AViewerPluginSync {
constructor() {
super();
this.enabled = true;
// readonly because bound to ui
this.exportOptions = {
name: 'scene',
viewerConfig: true,
encodeUint16Rgbe: false,
convertMeshToIndexed: false,
embedUrlImagePreviews: false,
embedUrlImages: false,
encrypt: false,
encryptKey: '',
};
this.uiConfig = {
type: 'folder',
label: 'Asset Export',
children: [
{
type: 'input',
property: [this.exportOptions, 'name'],
},
{
type: 'folder',
label: 'GLB Export',
children: [
{
type: 'checkbox',
label: 'Viewer Config (All Settings)',
property: [this.exportOptions, 'viewerConfig'],
onChange: () => this.uiConfig.uiRefresh?.(true),
},
{
type: 'checkbox',
label: 'Embed Image Previews',
property: [this.exportOptions, 'embedUrlImagePreviews'],
},
{
type: 'checkbox',
label: 'Encrypt',
property: [this.exportOptions, 'encrypt'],
onChange: () => this.uiConfig.uiRefresh?.(true),
},
{
type: 'input',
label: 'Encrypt Password',
hidden: () => !this.exportOptions.encrypt,
property: [this.exportOptions, 'encryptKey'],
},
{
type: 'checkbox',
label: 'Compress hdr env maps',
hidden: () => !this.exportOptions.viewerConfig,
property: [this.exportOptions, 'encodeUint16Rgbe'],
},
// { // todo
// type: 'checkbox',
// label: 'Convert to indexed',
// property: [this.exportOptions, 'convertMeshToIndexed'],
// },
{
type: 'button',
label: 'Export GLB',
property: [this, 'downloadSceneGlb'],
},
],
},
{
type: 'button',
label: 'Export Config',
value: async () => {
const blob = new Blob([JSON.stringify(this._viewer?.exportConfig(false), null, 2)], { type: 'application/json' });
if (blob)
await this._viewer?.exportBlob(blob, this.exportOptions.name + '.' + ThreeViewer.ConfigTypeSlug);
},
},
{
type: 'button',
label: 'Export Selected',
hidden: () => !this._viewer?.getPlugin('PickingPlugin'),
value: async () => this.exportSelected(this.exportOptions, true),
},
],
};
this.exportScene = this.exportScene.bind(this);
}
onAdded(viewer) {
super.onAdded(viewer);
// todo Convert all non-indexed geometries to indexed geometries, because DRACO compression requires indexed geometry.
// this.exporter.processors.add('model', {
// forAssetType: 'model',
// processAsync: async(obj: IObject3D, options) => {
// if (options.convertMeshToIndexed)
// obj?.traverse((o: IObject3D)=>{
// if (!o.geometry) return
// if (o.geometry.attributes.index) return
// o.geometry = toIndexedGeometry(o.geometry)
// })
// return obj
// },
// })
}
onRemove(viewer) {
return super.onRemove(viewer);
}
async exportScene(options) {
return this._viewer?.assetManager.exporter?.exportObject(this._viewer?.scene.modelRoot, options || { ...this.exportOptions });
}
async downloadSceneGlb() {
const blob = await this.exportScene(this.exportOptions);
if (blob)
await this._viewer?.exportBlob(blob, this.exportOptions.name + '.' + blob.ext);
}
async exportSelected(options, download = true) {
const selected = this._viewer?.getPlugin('PickingPlugin')?.getSelectedObject();
if (!selected) {
alert('Nothing selected');
return;
}
const blob = await this._viewer.assetManager.exporter.exportObject(selected, options ?? this.exportOptions);
if (blob && download)
await this._viewer?.exportBlob(blob, 'object.' + blob.ext);
return blob;
}
}
AssetExporterPlugin.PluginType = 'AssetExporterPlugin';
__decorate([
serialize()
], AssetExporterPlugin.prototype, "exportOptions", void 0);
//# sourceMappingURL=AssetExporterPlugin.js.map