UNPKG

cione-comp-lib

Version:

`$ yarn add cione-comp-lib` 或者 `$ npm i cione-comp-lib -S`

121 lines (120 loc) 3.9 kB
import { Texture } from "../../../../_three@0.150.1@three/build/three.module.mjs"; import { clone } from "../../../../_three@0.150.1@three/examples/jsm/utils/SkeletonUtils.mjs"; /* @license * Copyright 2020 Google LLC. All Rights Reserved. * Licensed under the Apache License, Version 2.0 (the 'License'); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an 'AS IS' BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ const $prepared = Symbol("prepared"); const $prepare = Symbol("prepare"); const $preparedGLTF = Symbol("preparedGLTF"); const $clone = Symbol("clone"); class GLTFInstance { constructor(preparedGLTF) { this[$preparedGLTF] = preparedGLTF; } static prepare(source) { if (source.scene == null) { throw new Error("Model does not have a scene"); } if (source[$prepared]) { return source; } const prepared = this[$prepare](source); prepared[$prepared] = true; return prepared; } static [$prepare](source) { const { scene } = source; const scenes = [scene]; return Object.assign(Object.assign({}, source), { scene, scenes }); } get parser() { return this[$preparedGLTF].parser; } get animations() { return this[$preparedGLTF].animations; } get scene() { return this[$preparedGLTF].scene; } get scenes() { return this[$preparedGLTF].scenes; } get cameras() { return this[$preparedGLTF].cameras; } get asset() { return this[$preparedGLTF].asset; } get userData() { return this[$preparedGLTF].userData; } clone() { const GLTFInstanceConstructor = this.constructor; const clonedGLTF = this[$clone](); return new GLTFInstanceConstructor(clonedGLTF); } dispose() { this.scenes.forEach((scene) => { scene.traverse((object) => { if (!object.isMesh) { return; } const mesh = object; const materials = Array.isArray(mesh.material) ? mesh.material : [mesh.material]; materials.forEach((material) => { for (const propertyName in material) { const texture = material[propertyName]; if (texture instanceof Texture) { const image = texture.source.data; if (image.close != null) { image.close(); } texture.dispose(); } } material.dispose(); }); mesh.geometry.dispose(); }); }); } [$clone]() { const source = this[$preparedGLTF]; const scene = clone(this.scene); cloneVariantMaterials(scene, this.scene); const scenes = [scene]; const userData = source.userData ? Object.assign({}, source.userData) : {}; return Object.assign(Object.assign({}, source), { scene, scenes, userData }); } } const cloneVariantMaterials = (dst, src) => { traversePair(dst, src, (dst2, src2) => { if (src2.userData.variantMaterials !== void 0) { dst2.userData.variantMaterials = new Map(src2.userData.variantMaterials); } if (src2.userData.variantData !== void 0) { dst2.userData.variantData = src2.userData.variantData; } if (src2.userData.originalMaterial !== void 0) { dst2.userData.originalMaterial = src2.userData.originalMaterial; } }); }; const traversePair = (obj1, obj2, callback) => { callback(obj1, obj2); for (let i = 0; i < obj1.children.length; i++) { traversePair(obj1.children[i], obj2.children[i], callback); } }; export { $clone, $prepare, $prepared, $preparedGLTF, GLTFInstance };