UNPKG

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.

142 lines 6.08 kB
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 { AViewerPluginSync } from '../../viewer'; import { onChange, serialize } from 'ts-browser-helpers'; import { GLTFMaterialsVariantsExtensionImport, khrMaterialsVariantsGLTF, } from './helpers/GLTFMaterialsVariantsExtensionImport'; import { gltfExporterMaterialsVariantsExtensionExport } from './helpers/GLTFMaterialsVariantsExtensionExport'; /** * GLTF khr_material_variants plugin * * This plugin allows to import and export gltf files with KHR_materials_variants extension. * The material data is stored in the object userData. The plugin also provides a UI to select the variant. * * @category Plugins */ export class GLTFKHRMaterialVariantsPlugin extends AViewerPluginSync { constructor() { super(); this.enabled = true; this.variants = {}; // dont serialize this /** * The selected variant. Changing this will automatically apply the variant to the objects. */ this.selectedVariant = ''; /** * If true, the first variant will be applied to the objects when object is added and nothing is selected. */ this.applyFirstVariantOnLoad = true; this._objectAdded = (ev) => { const object = ev.object; if (!object?.isObject3D) return; if (!this._viewer) return; object.traverse((obj) => { if (obj.userData._variantMaterials) { for (const val of Object.values(obj.userData._variantMaterials)) { if (val?.material) val.material = this._viewer?.materialManager.convertToIMaterial(val.material, {}) || val.material; } } const d = obj.userData?.__importData?.[khrMaterialsVariantsGLTF]; if (!d) return; const names = d.names || []; for (const name of names) { if (!this.variants[name]) this.variants[name] = []; this.variants[name].push(obj); } delete obj.userData.__importData[khrMaterialsVariantsGLTF]; }); if (!this.selectedVariant && this.applyFirstVariantOnLoad) { this.selectedVariant = Object.keys(this.variants)[0] || ''; } this.uiConfig.uiRefresh?.(); return; }; this.uiConfig = { type: 'folder', label: 'KHR Material Variants', children: [ () => ({ children: [null, ...Object.keys(this.variants)].map((label) => !label ? { label: 'none', value: '' } : { label }), type: 'dropdown', label: 'Variant', property: [this, 'selectedVariant'], }), ], }; } onAdded(v) { super.onAdded(v); // v.addEventListener('preRender', this._preRender) v.scene.addEventListener('addSceneObject', this._objectAdded); v.assetManager.registerGltfExtension(khrMaterialVariantsGLTFExtension); } onRemove(v) { v.scene.removeEventListener('addSceneObject', this._objectAdded); v.assetManager.unregisterGltfExtension(khrMaterialVariantsGLTFExtension.name); this.variants = {}; return super.onRemove(v); } _variantChanged() { this.applyVariant(this.selectedVariant || '', true); } /** * Apply the variant to objects. * It will also change the `selectedVariant` if `root` is not provided. * @param name * @param force * @param root * @param doTraverse */ applyVariant(name, force = false, root, doTraverse = true) { if (!force && !root && this.selectedVariant === name) return; if (!name) return; if (!root) this.selectedVariant = name; const objects = root ? Array.isArray(root) ? root : [root] : name ? this.variants[name] || [] : Object.values(this.variants).flat(); for (const object of objects) { const done = new Set(); const apply = (obj) => { if (!obj.userData._variantMaterials || done.has(obj)) return; const va = name ? obj.userData._variantMaterials[name]?.material : obj.userData._originalMaterial; if (va) { if (!obj.userData._originalMaterial) obj.userData._originalMaterial = obj.material; obj.material = va; } done.add(obj); }; if (doTraverse) object.traverse(apply); else apply(object); } } } GLTFKHRMaterialVariantsPlugin.PluginType = 'GLTFKHRMaterialVariantsPlugin'; __decorate([ onChange(GLTFKHRMaterialVariantsPlugin.prototype._variantChanged), serialize() ], GLTFKHRMaterialVariantsPlugin.prototype, "selectedVariant", void 0); __decorate([ serialize() ], GLTFKHRMaterialVariantsPlugin.prototype, "applyFirstVariantOnLoad", void 0); export const khrMaterialVariantsGLTFExtension = { name: khrMaterialsVariantsGLTF, import: (p) => new GLTFMaterialsVariantsExtensionImport(p), export: gltfExporterMaterialsVariantsExtensionExport, // textures: undefined, }; //# sourceMappingURL=GLTFKHRMaterialVariantsPlugin.js.map