Selaa lähdekoodia

Simplified code by disabling InstancedMesh when gpu instancing extension is used

Popov72 5 vuotta sitten
vanhempi
commit
e9449c2b25

+ 13 - 63
loaders/src/glTF/2.0/Extensions/EXT_mesh_gpu_instancing.ts

@@ -1,13 +1,10 @@
 import { Vector3, Quaternion, Matrix } from 'babylonjs/Maths/math.vector';
-import { InstancedMesh } from 'babylonjs/Meshes/instancedMesh';
 import { Mesh } from 'babylonjs/Meshes/mesh';
 import { TransformNode } from "babylonjs/Meshes/transformNode";
-import { StringTools } from 'babylonjs/Misc/stringTools';
 import { Nullable } from "babylonjs/types";
 import { GLTFLoader, ArrayItem } from "../glTFLoader";
 import { IGLTFLoaderExtension } from "../glTFLoaderExtension";
 import { INode } from "../glTFLoaderInterfaces";
-import { AbstractMesh } from 'babylonjs/Meshes/abstractMesh';
 import { TmpVectors } from 'babylonjs/Maths/math.vector';
 
 const NAME = "EXT_mesh_gpu_instancing";
@@ -39,6 +36,9 @@ export class EXT_mesh_gpu_instancing implements IGLTFLoaderExtension {
     constructor(loader: GLTFLoader) {
         this._loader = loader;
         this.enabled = this._loader.isExtensionUsed(NAME);
+        if (this.enabled) {
+            loader._disableInstancedMesh = true;
+        }
     }
 
     /** @hidden */
@@ -55,21 +55,6 @@ export class EXT_mesh_gpu_instancing implements IGLTFLoaderExtension {
                 return promise;
             }
 
-            let useThinInstancesForAllMeshes = true;
-            let canUseThinInstances = false;
-
-            // Hide the source meshes.
-            for (const babylonMesh of node._primitiveBabylonMeshes) {
-                if (!(babylonMesh as Mesh).thinInstanceSetBuffer) {
-                    babylonMesh.isVisible = false;
-                    useThinInstancesForAllMeshes = false;
-                } else {
-                    canUseThinInstances = true;
-                    (babylonMesh as Mesh)._thinInstanceDataStorage.instancesCount = 1;  // make sure mesh.hasThinInstances returns true from now on (else async loading of the thin instance data will lead to problems
-                                                                                        // as the mesh won't be considered as having thin instances until thinInstanceSetBuffer is called)
-                }
-            }
-
             const promises = new Array<Promise<Nullable<Float32Array>>>();
             let instanceCount = 0;
 
@@ -93,61 +78,26 @@ export class EXT_mesh_gpu_instancing implements IGLTFLoaderExtension {
             loadAttribute("ROTATION");
             loadAttribute("SCALE");
 
-            if (instanceCount == 0) {
-                for (const babylonMesh of node._primitiveBabylonMeshes) {
-                    if ((babylonMesh as any).thinInstanceSetBuffer) {
-                        (babylonMesh as Mesh)._thinInstanceDataStorage.instancesCount = 0;
-                    }
-                }
-                return promise;
-            }
-
-            if (!useThinInstancesForAllMeshes) {
-                const digitLength = instanceCount.toString().length;
-                for (let i = 0; i < instanceCount; ++i) {
-                    for (const babylonMesh of node._primitiveBabylonMeshes!) {
-                        if (!(babylonMesh as Mesh).thinInstanceSetBuffer) {
-                            const instanceName = `${babylonMesh.name || babylonMesh.id}_${StringTools.PadNumber(i, digitLength)}`;
-                            const babylonInstancedMesh = (babylonMesh as (InstancedMesh | Mesh)).createInstance(instanceName);
-                            babylonInstancedMesh.setParent(babylonMesh);
-                        }
-                    }
-                }
-            }
-
             return promise.then((babylonTransformNode) => {
                 return Promise.all(promises).then(([translationBuffer, rotationBuffer, scaleBuffer]) => {
-                    const matrices = canUseThinInstances ? new Float32Array(instanceCount * 16) : null;
+                    const matrices = new Float32Array(instanceCount * 16);
 
-                    if (matrices) {
-                        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
+                    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]);
+                    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]);
+                        Matrix.ComposeToRef(TmpVectors.Vector3[1], TmpVectors.Quaternion[0], TmpVectors.Vector3[0], TmpVectors.Matrix[0]);
 
-                            TmpVectors.Matrix[0].copyToArray(matrices, i * 16);
-                        }
+                        TmpVectors.Matrix[0].copyToArray(matrices, i * 16);
                     }
 
                     for (const babylonMesh of node._primitiveBabylonMeshes!) {
-                        if (!(babylonMesh as Mesh).thinInstanceSetBuffer) {
-                            const babylonInstancedMeshes = babylonMesh.getChildMeshes(true, (node) => (node as AbstractMesh).isAnInstance);
-                            for (let i = 0; i < instanceCount; ++i) {
-                                const babylonInstancedMesh = babylonInstancedMeshes[i];
-                                translationBuffer && Vector3.FromArrayToRef(translationBuffer, i * 3, babylonInstancedMesh.position);
-                                rotationBuffer && Quaternion.FromArrayToRef(rotationBuffer, i * 4, babylonInstancedMesh.rotationQuaternion!);
-                                scaleBuffer && Vector3.FromArrayToRef(scaleBuffer, i * 3, babylonInstancedMesh.scaling);
-                                babylonInstancedMesh.refreshBoundingInfo();
-                            }
-                        } else {
                             (babylonMesh as Mesh).thinInstanceSetBuffer("matrix", matrices, 16, true);
-                        }
                     }
 
                     return babylonTransformNode;

+ 4 - 1
loaders/src/glTF/2.0/glTFLoader.ts

@@ -106,6 +106,9 @@ export class GLTFLoader implements IGLTFLoader {
     /** Storage */
     public _babylonLights: Light[] = [];
 
+    /** @hidden */
+    public _disableInstancedMesh = false;
+
     private _disposed = false;
     private _parent: GLTFFileLoader;
     private _state: Nullable<GLTFLoaderState> = null;
@@ -777,7 +780,7 @@ export class GLTFLoader implements IGLTFLoader {
 
         this.logOpen(`${context}`);
 
-        const shouldInstance = d && !mesh.primitives[0].targets) && (!primitive._instanceData || !primitive._instanceData.babylonSourceMesh.hasThinInstances);
+        const shouldInstance = !this._disableInstancedMesh && d && !mesh.primitives[0].targets);
 
         let babylonAbstractMesh: AbstractMesh;
         let promise: Promise<any>;