threepipe
Version:
A modern 3D viewer framework built on top of three.js, written in TypeScript, designed to make creating high-quality, modular, and extensible 3D experiences on the web simple and enjoyable.
133 lines • 6.25 kB
JavaScript
import { GLTFExporter } from 'three/examples/jsm/exporters/GLTFExporter.js';
import { GLTFWriter2 } from './GLTFWriter2';
import { glbEncryptionProcessor, GLTFLightExtrasExtension, GLTFMaterialExtrasExtension, GLTFMaterialsAlphaMapExtension, GLTFMaterialsBumpMapExtension, GLTFMaterialsDisplacementMapExtension, GLTFMaterialsLightMapExtension, GLTFObject3DExtrasExtension, GLTFViewerConfigExtension, } from '../gltf';
export class GLTFExporter2 extends GLTFExporter {
constructor() {
super();
this.processors = [];
this.processors.push(glbEncryptionProcessor);
}
register(callback) {
return super.register(callback);
}
async parseAsync(obj, options) {
if (!obj)
throw new Error('No object to export');
let gltf = !obj.__isGLTFOutput && (Array.isArray(obj) || obj.isObject3D) ? await new Promise((resolve, reject) => this.parse(obj, resolve, reject, options)) : obj;
for (const processor of this.processors) {
gltf = await processor(gltf, options);
}
if (gltf && gltf instanceof Blob)
return gltf;
if (gltf && typeof gltf === 'object' && !gltf.byteLength) { // byteLength is for ArrayBuffer
return new Blob([JSON.stringify(gltf, (k, v) => k.startsWith('__') ? undefined : v, options.jsonSpaces ?? 2)], { type: 'model/gltf+json' });
}
else if (gltf) {
return new Blob([gltf], { type: 'model/gltf+binary' });
}
else {
throw new Error('GLTFExporter2.parse() failed');
}
}
parse(input, onDone, onError, options = {}) {
const gltfOptions = {
// default options
binary: false,
trs: options.trs ?? false,
onlyVisible: options.onlyVisible ?? false,
truncateDrawRange: options.truncateDrawRange ?? true,
externalImagesInExtras: !options.embedUrlImages && options.externalImagesInExtras || false, // this is handled in gltfMaterialExtrasWriter, also see GLTFDracoExporter
maxTextureSize: options.maxTextureSize ?? Infinity,
animations: options.animations ?? [],
includeCustomExtensions: options.includeCustomExtensions ?? true,
forceIndices: options.forceIndices ?? false, // todo implement
exporterOptions: options,
ignoreInvalidMorphTargetTracks: options.ignoreInvalidMorphTargetTracks,
ignoreEmptyTextures: options.ignoreEmptyTextures,
};
if (options.exportExt === 'glb') {
gltfOptions.binary = true;
}
// collect animations and preserveUUID(default true)
(Array.isArray(input) ? input : [input]).forEach((obj) => obj.traverse((obj1) => {
if (options.preserveUUIDs !== false && obj1.uuid)
obj1.userData.gltfUUID = obj1.uuid;
if (obj1.animations) {
for (const animation of obj1.animations) {
if (animation.__gltfExport !== false) {
const rootRefs = animation.userData.rootRefs || [];
if (options.preserveUUIDs !== false && obj1.uuid) {
if (!rootRefs.includes(obj1.uuid)) {
rootRefs.push(obj1.uuid);
}
}
else if (obj1.name) {
if (!rootRefs.includes(obj1.name)) {
rootRefs.push(obj1.name);
}
}
animation.userData.rootRefs = rootRefs;
if (!gltfOptions.animations.includes(animation))
gltfOptions.animations.push(animation);
}
}
}
// todo move this to asset exporter?
if (obj1.children && obj1._sChildren) {
// @ts-expect-error temp
obj1._tChildren = obj1.children;
obj1.children = obj1._sChildren;
}
}));
console.log(gltfOptions.animations);
return super.parse(input, (o) => {
if (options.preserveUUIDs !== false) { // default true
(Array.isArray(input) ? input : [input]).forEach((obj) => obj.traverse((obj1) => {
delete obj1.userData.gltfUUID;
// @ts-expect-error temp
if (obj1._tChildren) {
// @ts-expect-error temp
obj1.children = obj1._tChildren;
// @ts-expect-error temp
delete obj1._tChildren;
}
}));
}
// eslint-disable-next-line @typescript-eslint/naming-convention
onDone(Object.assign(o, { __isGLTFOutput: true }));
}, onError, gltfOptions, new GLTFWriter2());
}
setup(viewer, extraExtensions) {
for (const ext of GLTFExporter2.ExportExtensions)
this.register(ext);
if (extraExtensions)
for (const ext of extraExtensions)
this.register(ext);
// should be last
this.register(this.gltfViewerWriter(viewer));
return this;
}
gltfViewerWriter(viewer) {
return (writer) => ({
afterParse: (input) => {
input = Array.isArray(input) ? input[0] : input;
if (!input?.userData?.rootSceneModelRoot ||
writer.options?.exporterOptions?.viewerConfig === false ||
input?.userData?.__exportViewerConfig === false)
return;
GLTFViewerConfigExtension.ExportViewerConfig(viewer, writer);
},
});
}
}
GLTFExporter2.ExportExtensions = [
GLTFMaterialExtrasExtension.Export,
GLTFObject3DExtrasExtension.Export,
GLTFLightExtrasExtension.Export,
GLTFMaterialsBumpMapExtension.Export,
GLTFMaterialsDisplacementMapExtension.Export,
GLTFMaterialsLightMapExtension.Export,
GLTFMaterialsAlphaMapExtension.Export,
// (w)=>new GLTFMeshGpuInstancingExporter(w),
];
//# sourceMappingURL=GLTFExporter2.js.map