UNPKG

@babylonjs/viewer

Version:

The Babylon Viewer aims to simplify a specific but common Babylon.js use case: loading, viewing, and interacting with a 3D model.

90 lines (87 loc) 4.31 kB
import { aS as TmpVectors, V as Vector3, Q as Quaternion, M as Matrix, bJ as unregisterGLTFExtension, bI as registerGLTFExtension } from './index-FzOfPXLV.esm.js'; import { GLTFLoader, ArrayItem } from './glTFLoader-VVyk3AwX.esm.js'; import './thinInstanceMesh-BeyNtce0.esm.js'; import './bone--mL3H5cQ.esm.js'; import './skeleton-B7-ffRm_.esm.js'; import './rawTexture-B2DimmQ5.esm.js'; import './assetContainer-8JZnoDWQ.esm.js'; import './objectModelMapping-CJnQ6at_.esm.js'; const NAME = "EXT_mesh_gpu_instancing"; /** * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Vendor/EXT_mesh_gpu_instancing/README.md) * [Playground Sample](https://playground.babylonjs.com/#QFIGLW#9) */ // eslint-disable-next-line @typescript-eslint/naming-convention class EXT_mesh_gpu_instancing { /** * @internal */ constructor(loader) { /** * The name of this extension. */ this.name = NAME; this._loader = loader; this.enabled = this._loader.isExtensionUsed(NAME); } /** @internal */ dispose() { this._loader = null; } /** * @internal */ // eslint-disable-next-line no-restricted-syntax loadNodeAsync(context, node, assign) { return GLTFLoader.LoadExtensionAsync(context, node, this.name, async (extensionContext, extension) => { this._loader._disableInstancedMesh++; const promise = this._loader.loadNodeAsync(`/nodes/${node.index}`, node, assign); this._loader._disableInstancedMesh--; if (!node._primitiveBabylonMeshes) { return await promise; } const promises = new Array(); let instanceCount = 0; const loadAttribute = (attribute) => { if (extension.attributes[attribute] == undefined) { promises.push(Promise.resolve(null)); return; } const accessor = ArrayItem.Get(`${extensionContext}/attributes/${attribute}`, this._loader.gltf.accessors, extension.attributes[attribute]); promises.push(this._loader._loadFloatAccessorAsync(`/accessors/${accessor.bufferView}`, accessor)); if (instanceCount === 0) { instanceCount = accessor.count; } else if (instanceCount !== accessor.count) { throw new Error(`${extensionContext}/attributes: Instance buffer accessors do not have the same count.`); } }; loadAttribute("TRANSLATION"); loadAttribute("ROTATION"); loadAttribute("SCALE"); // eslint-disable-next-line github/no-then return await promise.then(async (babylonTransformNode) => { const [translationBuffer, rotationBuffer, scaleBuffer] = await Promise.all(promises); const matrices = new Float32Array(instanceCount * 16); TmpVectors.Vector3[0].copyFromFloats(0, 0, 0); // translation TmpVectors.Quaternion[0].copyFromFloats(0, 0, 0, 1); // rotation TmpVectors.Vector3[1].copyFromFloats(1, 1, 1); // scale for (let i = 0; i < instanceCount; ++i) { translationBuffer && Vector3.FromArrayToRef(translationBuffer, i * 3, TmpVectors.Vector3[0]); rotationBuffer && Quaternion.FromArrayToRef(rotationBuffer, i * 4, TmpVectors.Quaternion[0]); scaleBuffer && Vector3.FromArrayToRef(scaleBuffer, i * 3, TmpVectors.Vector3[1]); Matrix.ComposeToRef(TmpVectors.Vector3[1], TmpVectors.Quaternion[0], TmpVectors.Vector3[0], TmpVectors.Matrix[0]); TmpVectors.Matrix[0].copyToArray(matrices, i * 16); } for (const babylonMesh of node._primitiveBabylonMeshes) { babylonMesh.thinInstanceSetBuffer("matrix", matrices, 16, true); } return babylonTransformNode; }); }); } } unregisterGLTFExtension(NAME); registerGLTFExtension(NAME, true, (loader) => new EXT_mesh_gpu_instancing(loader)); export { EXT_mesh_gpu_instancing }; //# sourceMappingURL=EXT_mesh_gpu_instancing-2qjracey.esm.js.map