浏览代码

Merge pull request #6948 from bghgary/gltf-fixes

glTF loader fixes
David Catuhe 5 年之前
父节点
当前提交
05ad333070

+ 1 - 0
dist/preview release/what's new.md

@@ -85,6 +85,7 @@
 - Load glTF extras into BJS metadata ([pjoe](https://github.com/pjoe))
 - Added support for morph target names via `mesh.extras.targetNames` when loading a glTF ([zeux](https://github.com/zeux))
 - Added support for using HTTP range requests when loading `MSFT_lod` extension from a glTF binary. ([bghgary](https://github.com/bghgary))
+- Added a flag to enable/disable creation of instances for glTF loader. ([bghgary](https://github.com/bghgary))
 
 ### Materials
 - Added `ShaderMaterial.setColor4Array` ([JonathanTron](https://github.com/JonathanTron/))

+ 6 - 7
loaders/src/glTF/2.0/glTFLoader.ts

@@ -744,15 +744,14 @@ export class GLTFLoader implements IGLTFLoader {
 
         this.logOpen(`${context}`);
 
-        const canInstance = (node.skin == undefined && !mesh.primitives[0].targets);
+        const shouldInstance = this._parent.createInstances && (node.skin == undefined && !mesh.primitives[0].targets);
 
         let babylonAbstractMesh: AbstractMesh;
         let promise: Promise<any>;
 
-        const instanceData = primitive._instanceData;
-        if (canInstance && instanceData) {
-            babylonAbstractMesh = instanceData.babylonSourceMesh.createInstance(name);
-            promise = instanceData.promise;
+        if (shouldInstance && primitive._instanceData) {
+            babylonAbstractMesh = primitive._instanceData.babylonSourceMesh.createInstance(name);
+            promise = primitive._instanceData.promise;
         }
         else {
             const promises = new Array<Promise<any>>();
@@ -786,7 +785,7 @@ export class GLTFLoader implements IGLTFLoader {
 
             promise = Promise.all(promises);
 
-            if (canInstance) {
+            if (shouldInstance) {
                 primitive._instanceData = {
                     babylonSourceMesh: babylonMesh,
                     promise: promise
@@ -1898,7 +1897,7 @@ export class GLTFLoader implements IGLTFLoader {
             if (!this._disposed) {
                 deferred.reject(new Error(`${context}: ${(exception && exception.message) ? exception.message : message || "Failed to load texture"}`));
             }
-        });
+        }, undefined, undefined, undefined, image.mimeType);
         promises.push(deferred.promise);
 
         if (!url) {

+ 5 - 0
loaders/src/glTF/glTFFileLoader.ts

@@ -208,6 +208,11 @@ export class GLTFFileLoader implements IDisposable, ISceneLoaderPluginAsync, ISc
     public useRangeRequests = false;
 
     /**
+     * Defines if the loader should create instances when multiple glTF nodes point to the same glTF mesh. Defaults to true.
+     */
+    public createInstances = true;
+
+    /**
      * Function called before loading a url referenced by the asset.
      */
     public preprocessUrlAsync = (url: string) => Promise.resolve(url);

+ 2 - 16
src/Misc/fileTools.ts

@@ -7,6 +7,7 @@ import { Observable } from './observable';
 import { FilesInputStore } from './filesInputStore';
 import { RetryStrategy } from './retryStrategy';
 import { BaseError } from './baseError';
+import { StringTools } from './stringTools';
 
 /** @ignore */
 export class LoadFileError extends BaseError {
@@ -123,21 +124,6 @@ export class FileTools {
     }
 
     /**
-     * Encode an array buffer into a base64 string
-     * @param buffer defines the buffer to encode
-     * @returns a string containing the base64 version of the buffer
-     */
-    public static ArrayBufferToBase64(buffer: ArrayBuffer | ArrayBufferView) {
-        var binary = '';
-        var bytes = (buffer as ArrayBufferView).buffer ? new Uint8Array((buffer as ArrayBufferView).buffer) : new Uint8Array(buffer as ArrayBuffer);
-        var len = bytes.byteLength;
-        for (var i = 0; i < len; i++) {
-            binary += String.fromCharCode(bytes[i]);
-        }
-        return window.btoa(binary);
-    }
-
-    /**
      * Loads an image as an HTMLImageElement.
      * @param input url string, ArrayBuffer, or Blob to load
      * @param onLoad callback called when the image successfully loads
@@ -155,7 +141,7 @@ export class FileTools {
                 url = URL.createObjectURL(new Blob([input]));
                 usingObjectURL = true;
             } else {
-                url = `data:${mimeType || "image/jpg"};base64,` + this.ArrayBufferToBase64(input);
+                url = `data:${mimeType || "image/jpg"};base64,` + StringTools.EncodeArrayBufferToBase64(input);
             }
         }
         else if (input instanceof Blob) {

+ 34 - 0
src/Misc/stringTools.ts

@@ -39,4 +39,38 @@ export class StringTools {
 
         return result;
     }
+
+    /**
+     * Encode a buffer to a base64 string
+     * @param buffer defines the buffer to encode
+     * @returns the encoded string
+     */
+    public static EncodeArrayBufferToBase64(buffer: ArrayBuffer | ArrayBufferView): string {
+        var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
+        var output = "";
+        var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
+        var i = 0;
+        var bytes = ArrayBuffer.isView(buffer) ? new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.byteLength) : new Uint8Array(buffer);
+
+        while (i < bytes.length) {
+            chr1 = bytes[i++];
+            chr2 = i < bytes.length ? bytes[i++] : Number.NaN;
+            chr3 = i < bytes.length ? bytes[i++] : Number.NaN;
+
+            enc1 = chr1 >> 2;
+            enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
+            enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
+            enc4 = chr3 & 63;
+
+            if (isNaN(chr2)) {
+                enc3 = enc4 = 64;
+            } else if (isNaN(chr3)) {
+                enc4 = 64;
+            }
+            output += keyStr.charAt(enc1) + keyStr.charAt(enc2) +
+                keyStr.charAt(enc3) + keyStr.charAt(enc4);
+        }
+
+        return output;
+    }
 }