Browse Source

Merge pull request #3192 from benaadams/cube.dds

Allow multiple dds files for CubeMap
David Catuhe 7 năm trước cách đây
mục cha
commit
1daa89c241

+ 3 - 3
inspector/src/helpers/Helpers.ts

@@ -153,17 +153,17 @@ module INSPECTOR {
         public static LoadScript() {
             BABYLON.Tools.LoadFile("https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.7.0/highlight.min.js", (elem) => {
                 let script = Helpers.CreateElement('script', '', Inspector.DOCUMENT.body);
-                script.textContent = elem;
+                script.textContent = elem as string;
 
                 // Load glsl detection
                 BABYLON.Tools.LoadFile("https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.7.0/languages/glsl.min.js", (elem) => {
                     let script = Helpers.CreateElement('script', '', Inspector.DOCUMENT.body);
-                    script.textContent = elem;
+                    script.textContent = elem as string;
 
                     // Load css style
                     BABYLON.Tools.LoadFile("https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.7.0/styles/zenburn.min.css", (elem) => {
                         let style = Helpers.CreateElement('style', '', Inspector.DOCUMENT.body);
-                        style.textContent = elem;
+                        style.textContent = elem as string;
                     });
                 }, undefined, undefined, undefined, () => {
                     console.log("erreur");

+ 2 - 2
loaders/src/glTF/1.0/babylon.glTFLoader.ts

@@ -1282,7 +1282,7 @@ module BABYLON.GLTF1 {
                 setTimeout(() => onSuccess(new Uint8Array(GLTFUtils.DecodeBase64(buffer.uri))));
             }
             else {
-                Tools.LoadFile(gltfRuntime.rootUrl + buffer.uri, data => onSuccess(new Uint8Array(data)), onProgress, undefined, true, request => {
+                Tools.LoadFile(gltfRuntime.rootUrl + buffer.uri, data => onSuccess(new Uint8Array(data as ArrayBuffer)), onProgress, undefined, true, request => {
                     if (request) {
                         onError(request.status + " " + request.statusText);
                     }
@@ -1309,7 +1309,7 @@ module BABYLON.GLTF1 {
                 setTimeout(() => onSuccess(new Uint8Array(GLTFUtils.DecodeBase64(source.uri))));
             }
             else {
-                Tools.LoadFile(gltfRuntime.rootUrl + source.uri, data => onSuccess(new Uint8Array(data)), undefined, undefined, true, request => {
+                Tools.LoadFile(gltfRuntime.rootUrl + source.uri, data => onSuccess(new Uint8Array(data as ArrayBuffer)), undefined, undefined, true, request => {
                     if (request) {
                         onError(request.status + " " + request.statusText);
                     }

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

@@ -1558,7 +1558,7 @@ module BABYLON.GLTF2 {
 
             let request = Tools.LoadFile(this._rootUrl + uri, data => {
                 this._tryCatchOnError(() => {
-                    onSuccess(new Uint8Array(data));
+                    onSuccess(new Uint8Array(data as ArrayBuffer));
                 });
             }, event => {
                 this._tryCatchOnError(() => {

+ 1 - 1
src/Audio/babylon.sound.ts

@@ -129,7 +129,7 @@ module BABYLON {
                                 if (codecSupportedFound) {
                                     // Loading sound using XHR2
                                     if (!this._streaming) {
-                                        Tools.LoadFile(url, (data) => { this._soundLoaded(data); }, undefined, this._scene.database, true);
+                                        Tools.LoadFile(url, (data) => { this._soundLoaded(data as ArrayBuffer); }, undefined, this._scene.database, true);
                                     }
                                     // Streaming sound using HTML5 Audio tag
                                     else {

+ 117 - 50
src/Engine/babylon.engine.ts

@@ -116,20 +116,20 @@
         }
     }
 
-    var partialLoad = (url: string, index: number, loadedImages: any, scene: Nullable<Scene>,
+    var partialLoadImg = (url: string, index: number, loadedImages: HTMLImageElement[], scene: Nullable<Scene>,
         onfinish: (images: HTMLImageElement[]) => void, onErrorCallBack: Nullable<(message?: string, exception?: any) => void> = null) => {
 
         var img: HTMLImageElement;
 
         var onload = () => {
             loadedImages[index] = img;
-            loadedImages._internalCount++;
+            (<any>loadedImages)._internalCount++;
 
             if (scene) {
                 scene._removePendingData(img);
             }
 
-            if (loadedImages._internalCount === 6) {
+            if ((<any>loadedImages)._internalCount === 6) {
                 onfinish(loadedImages);
             }
         };
@@ -150,14 +150,46 @@
         }
     }
 
-    var cascadeLoad = (rootUrl: string, scene: Nullable<Scene>,
+    var cascadeLoadImgs = (rootUrl: string, scene: Nullable<Scene>,
         onfinish: (images: HTMLImageElement[]) => void, files: string[], onError: Nullable<(message?: string, exception?: any) => void> = null) => {
 
-        var loadedImages: any = [];
-        loadedImages._internalCount = 0;
+        var loadedImages: HTMLImageElement[] = [];
+        (<any>loadedImages)._internalCount = 0;
 
-        for (var index = 0; index < 6; index++) {
-            partialLoad(files[index], index, loadedImages, scene, onfinish, onError);
+        for (let index = 0; index < 6; index++) {
+            partialLoadImg(files[index], index, loadedImages, scene, onfinish, onError);
+        }
+    };
+
+    var partialLoadFile = (url: string, index: number, loadedFiles: (string | ArrayBuffer)[], scene: Nullable<Scene>,
+        onfinish: (files: (string | ArrayBuffer)[]) => void, onErrorCallBack: Nullable<(message?: string, exception?: any) => void> = null) => {
+
+        var onload = (data: string | ArrayBuffer) => {
+            loadedFiles[index] = data;
+            (<any>loadedFiles)._internalCount++;
+
+            if ((<any>loadedFiles)._internalCount === 6) {
+                onfinish(loadedFiles);
+            }
+        };
+
+        const onerror = (request: XMLHttpRequest, exception: any) => {
+            if (onErrorCallBack) {
+                onErrorCallBack(request.status + " " + request.statusText, exception);
+            }
+        };
+
+        Tools.LoadFile(url, onload, undefined, undefined, true, onerror);
+    }
+
+    var cascadeLoadFiles = (rootUrl: string, scene: Nullable<Scene>,
+        onfinish: (images: (string | ArrayBuffer)[]) => void, files: string[], onError: Nullable<(message?: string, exception?: any) => void> = null) => {
+
+        var loadedFiles: (string | ArrayBuffer)[] = [];
+        (<any>loadedFiles)._internalCount = 0;
+
+        for (let index = 0; index < 6; index++) {
+            partialLoadFile(files[index], index, loadedFiles, scene, onfinish, onError);
         }
     };
 
@@ -3901,7 +3933,7 @@
 
             let onerror = (request: XMLHttpRequest, exception: any) => {
                 if (onError) {
-                    onError(request.status + " " + request.statusText, exception)
+                    onError(request.status + " " + request.statusText, exception);
                 }
             }
 
@@ -3916,58 +3948,89 @@
 
                     ktx.uploadLevels(this._gl, !noMipmap);
 
-                    gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
-                    gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, loadMipmap ? gl.LINEAR_MIPMAP_LINEAR : gl.LINEAR);
-                    gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
-                    gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
-
-                    this._bindTextureDirectly(gl.TEXTURE_CUBE_MAP, null);
-
-                    this.resetTextureCache();
+                    this.setCubeMapTextureParams(gl, loadMipmap);
 
                     texture.width = ktx.pixelWidth;
                     texture.height = ktx.pixelHeight;
                     texture.isReady = true;
                 }, undefined, undefined, true, onerror);
             } else if (isDDS) {
-                Tools.LoadFile(rootUrl, data => {
-                    var info = Internals.DDSTools.GetDDSInfo(data);
+                if (files && files.length === 6) {
+                    cascadeLoadFiles(rootUrl,
+                        scene,
+                        imgs => {
+                            var info: Internals.DDSInfo | undefined;
+                            var loadMipmap: boolean = false;
+                            var width: number = 0;
+                            for (let index = 0; index < imgs.length; index++) {
+                                let data = imgs[index];
+                                info = Internals.DDSTools.GetDDSInfo(data);
+
+                                loadMipmap = (info.isRGB || info.isLuminance || info.mipmapCount > 1) && !noMipmap;
+
+                                this._bindTextureDirectly(gl.TEXTURE_CUBE_MAP, texture);
+                                gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, info.isCompressed ? 1 : 0);
+
+                                Internals.DDSTools.UploadDDSLevels(this, this._gl, data, info, loadMipmap, 6, -1, index);
+
+                                if (!noMipmap && !info.isFourCC && info.mipmapCount === 1) {
+                                    gl.generateMipmap(gl.TEXTURE_CUBE_MAP);
+                                }
+
+                                texture.width = info.width;
+                                texture.height = info.height;
+                                texture.type = info.textureType;
+                                width = info.width;
+                            }
 
-                    var loadMipmap = (info.isRGB || info.isLuminance || info.mipmapCount > 1) && !noMipmap;
+                            this.setCubeMapTextureParams(gl, loadMipmap);
+                            texture.isReady = true;
 
-                    this._bindTextureDirectly(gl.TEXTURE_CUBE_MAP, texture);
-                    gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, info.isCompressed ? 1 : 0);
+                            if (onLoad) {
+                                onLoad({ isDDS: true, width: width, info, imgs, texture });
+                            }
+                        },
+                        files,
+                        onError);
 
-                    Internals.DDSTools.UploadDDSLevels(this, this._gl, data, info, loadMipmap, 6);
+                } else {
+                    Tools.LoadFile(rootUrl,
+                        data => {
+                            var info = Internals.DDSTools.GetDDSInfo(data);
 
-                    if (!noMipmap && !info.isFourCC && info.mipmapCount === 1) {
-                        gl.generateMipmap(gl.TEXTURE_CUBE_MAP);
-                    }
+                            var loadMipmap = (info.isRGB || info.isLuminance || info.mipmapCount > 1) && !noMipmap;
 
-                    gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
-                    gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, loadMipmap ? gl.LINEAR_MIPMAP_LINEAR : gl.LINEAR);
-                    gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
-                    gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+                            this._bindTextureDirectly(gl.TEXTURE_CUBE_MAP, texture);
+                            gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, info.isCompressed ? 1 : 0);
 
-                    this._bindTextureDirectly(gl.TEXTURE_CUBE_MAP, null);
+                            Internals.DDSTools.UploadDDSLevels(this, this._gl, data, info, loadMipmap, 6);
 
-                    this.resetTextureCache();
+                            if (!noMipmap && !info.isFourCC && info.mipmapCount === 1) {
+                                gl.generateMipmap(gl.TEXTURE_CUBE_MAP);
+                            }
 
-                    texture.width = info.width;
-                    texture.height = info.height;
-                    texture.isReady = true;
-                    texture.type = info.textureType;
+                            this.setCubeMapTextureParams(gl, loadMipmap);
 
-                    if (onLoad) {
-                        onLoad({ isDDS: true, width: info.width, info, data, texture });
-                    }
-                }, undefined, undefined, true, onerror);
+                            texture.width = info.width;
+                            texture.height = info.height;
+                            texture.isReady = true;
+                            texture.type = info.textureType;
+
+                            if (onLoad) {
+                                onLoad({ isDDS: true, width: info.width, info, data, texture });
+                            }
+                        },
+                        undefined,
+                        undefined,
+                        true,
+                        onerror);
+                }
             } else {
                 if (!files) {
                     throw new Error("Cannot load cubemap because files were not defined");
                 }
 
-                cascadeLoad(rootUrl, scene, imgs => {
+                cascadeLoadImgs(rootUrl, scene, imgs => {
                     var width = this.needPOTTextures ? Tools.GetExponentOfTwo(imgs[0].width, this._caps.maxCubemapTextureSize) : imgs[0].width;
                     var height = width;
 
@@ -3995,15 +4058,8 @@
                     if (!noMipmap) {
                         gl.generateMipmap(gl.TEXTURE_CUBE_MAP);
                     }
-
-                    gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
-                    gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, noMipmap ? gl.LINEAR : gl.LINEAR_MIPMAP_LINEAR);
-                    gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
-                    gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
-
-                    this._bindTextureDirectly(gl.TEXTURE_CUBE_MAP, null);
-
-                    this.resetTextureCache();
+                    
+                    this.setCubeMapTextureParams(gl, !noMipmap);
 
                     texture.width = width;
                     texture.height = height;
@@ -4026,6 +4082,17 @@
             return texture;
         }
 
+        private setCubeMapTextureParams(gl: WebGLRenderingContext, loadMipmap: boolean) {
+            gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
+            gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, loadMipmap ? gl.LINEAR_MIPMAP_LINEAR : gl.LINEAR);
+            gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+            gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+
+            this._bindTextureDirectly(gl.TEXTURE_CUBE_MAP, null);
+
+            this.resetTextureCache();
+        }
+
         public updateRawCubeTexture(texture: InternalTexture, data: ArrayBufferView[], format: number, type: number, invertY: boolean, compression: Nullable<string> = null, level = 0): void {
             texture._bufferViewArray = data;
             texture.format = format;

+ 10 - 8
src/Materials/Textures/babylon.cubeTexture.ts

@@ -40,23 +40,25 @@
 
             this._texture = this._getFromCache(rootUrl, noMipmap);
 
-            if (!files) {
+            const lastDot = rootUrl.lastIndexOf(".");
+            const extension = forcedExtension ? forcedExtension : (lastDot > -1 ? rootUrl.substring(lastDot).toLowerCase() : "");
+            const isDDS = (extension === ".dds");
 
-                if (!extensions) {
+            if (!files) {
+                if (!isDDS && !extensions) {
                     extensions = ["_px.jpg", "_py.jpg", "_pz.jpg", "_nx.jpg", "_ny.jpg", "_nz.jpg"];
                 }
 
                 files = [];
 
-                for (var index = 0; index < extensions.length; index++) {
-                    files.push(rootUrl + extensions[index]);
+                if (extensions) {
+                    
+                    for (var index = 0; index < extensions.length; index++) {
+                        files.push(rootUrl + extensions[index]);
+                    }
                 }
-
-                this._extensions = extensions;
             }
 
-            this._files = files;
-
             if (!this._texture) {
                 if (!scene.useDelayedTextureLoading) {
                     if (prefiltered) {

+ 1 - 1
src/Materials/babylon.effect.ts

@@ -492,7 +492,7 @@
                     var includeShaderUrl = Engine.ShadersRepository + "ShadersInclude/" + includeFile + ".fx";
 
                     Tools.LoadFile(includeShaderUrl, (fileContent) => {
-                        Effect.IncludesShadersStore[includeFile] = fileContent;
+                        Effect.IncludesShadersStore[includeFile] = fileContent as string;
                         this._processIncludes(<string>returnValue, callback);
                     });
                     return;

+ 1 - 1
src/Mesh/babylon.geometry.ts

@@ -562,7 +562,7 @@
                     return;
                 }
 
-                this._delayLoadingFunction(JSON.parse(data), this);
+                this._delayLoadingFunction(JSON.parse(data as string), this);
 
                 this.delayLoadState = Engine.DELAYLOADSTATE_LOADED;
                 this._delayInfo = [];

+ 2 - 2
src/Tools/babylon.assetsManager.ts

@@ -130,7 +130,7 @@ module BABYLON {
 
         public runTask(scene: Scene, onSuccess: () => void, onError: (message?: string, exception?: any) => void) {
             Tools.LoadFile(this.url, (data) => {
-                this.text = data;
+                this.text = data as string;
                 onSuccess();
             }, undefined, scene.database, false, (request, exception) => {
                 if (request) {
@@ -150,7 +150,7 @@ module BABYLON {
         public runTask(scene: Scene, onSuccess: () => void, onError: (message?: string, exception?: any) => void) {
             Tools.LoadFile(this.url, (data) => {
 
-                this.data = data;
+                this.data = data as ArrayBuffer;
                 onSuccess();
             }, undefined, scene.database, true, (request, exception) => {
                 if (request) {

+ 22 - 17
src/Tools/babylon.dds.ts

@@ -361,17 +361,17 @@
             return byteArray;
         }
 
-        public static UploadDDSLevels(engine: Engine, gl:WebGLRenderingContext, arrayBuffer: any, info: DDSInfo, loadMipmaps: boolean, faces: number, lodIndex = -1): void {
+        public static UploadDDSLevels(engine: Engine, gl:WebGLRenderingContext, arrayBuffer: any, info: DDSInfo, loadMipmaps: boolean, faces: number, lodIndex = -1, currentFace?: number): void {
             var ext = engine.getCaps().s3tc;
 
-            var header = new Int32Array(arrayBuffer, 0, headerLengthInt),
-                fourCC, width, height, dataLength, dataOffset,
-                byteArray, mipmapCount, mip;
+            var header = new Int32Array(arrayBuffer, 0, headerLengthInt);
+            var fourCC: number, width: number, height: number, dataLength: number = 0, dataOffset: number;
+            var byteArray: Uint8Array, mipmapCount: number, mip: number;
             let internalFormat = 0;
             let format = 0;
             let blockBytes = 1;
 
-            if (header[off_magic] != DDS_MAGIC) {
+            if (header[off_magic] !== DDS_MAGIC) {
                 Tools.Error("Invalid magic number in DDS header");
                 return;
             }
@@ -411,7 +411,7 @@
                     break;
                 case FOURCC_D3DFMT_R32G32B32A32F:
                     computeFormats = true;
-                    break;                    
+                    break;
                 case FOURCC_DX10:
                     // There is an additionnal header so dataOffset need to be changed
                     dataOffset += 5 * 4; // 5 uints
@@ -427,7 +427,7 @@
                             info.isFourCC = false;
                             bpp = 32;
                             supported = true;
-                            break;                        
+                            break;
                     }
 
                     if (supported) {
@@ -450,7 +450,7 @@
             }
             
             for (var face = 0; face < faces; face++) {
-                var sampler = faces === 1 ? gl.TEXTURE_2D : (gl.TEXTURE_CUBE_MAP_POSITIVE_X + face);
+                var sampler = faces === 1 ? gl.TEXTURE_2D : (gl.TEXTURE_CUBE_MAP_POSITIVE_X + face + (currentFace ? currentFace : 0));
 
                 width = header[off_width];
                 height = header[off_height];
@@ -462,14 +462,14 @@
 
                         if (!info.isCompressed && info.isFourCC) {
                             dataLength = width * height * 4;
-                            var FloatArray: Nullable<ArrayBufferView> = null;
+                            var floatArray: Nullable<ArrayBufferView> = null;
 
                             if (engine.badOS || engine.badDesktopOS || (!engine.getCaps().textureHalfFloat && !engine.getCaps().textureFloat)) { // Required because iOS has many issues with float and half float generation
                                 if (bpp === 128) {
-                                    FloatArray = DDSTools._GetFloatAsUIntRGBAArrayBuffer(width, height, dataOffset, dataLength, arrayBuffer, i);                                    
+                                    floatArray = DDSTools._GetFloatAsUIntRGBAArrayBuffer(width, height, dataOffset, dataLength, arrayBuffer, i);                                    
                                 }
                                 else if (bpp === 64) {
-                                    FloatArray = DDSTools._GetHalfFloatAsUIntRGBAArrayBuffer(width, height, dataOffset, dataLength, arrayBuffer, i);
+                                    floatArray = DDSTools._GetHalfFloatAsUIntRGBAArrayBuffer(width, height, dataOffset, dataLength, arrayBuffer, i);
                                 }
 
                                 info.textureType = Engine.TEXTURETYPE_UNSIGNED_INT;
@@ -478,20 +478,20 @@
                             }
                             else {
                                 if (bpp === 128) {
-                                    FloatArray = DDSTools._GetFloatRGBAArrayBuffer(width, height, dataOffset, dataLength, arrayBuffer, i);
+                                    floatArray = DDSTools._GetFloatRGBAArrayBuffer(width, height, dataOffset, dataLength, arrayBuffer, i);
                                 } else if (bpp === 64 && !engine.getCaps().textureHalfFloat) {
-                                    FloatArray = DDSTools._GetHalfFloatAsFloatRGBAArrayBuffer(width, height, dataOffset, dataLength, arrayBuffer, i);
+                                    floatArray = DDSTools._GetHalfFloatAsFloatRGBAArrayBuffer(width, height, dataOffset, dataLength, arrayBuffer, i);
 
                                     info.textureType = Engine.TEXTURETYPE_FLOAT;
                                     format = engine._getWebGLTextureType(info.textureType);    
                                     internalFormat = engine._getRGBABufferInternalSizedFormat(info.textureType);                            
                                 } else { // 64
-                                    FloatArray = DDSTools._GetHalfFloatRGBAArrayBuffer(width, height, dataOffset, dataLength, arrayBuffer, i);
+                                    floatArray = DDSTools._GetHalfFloatRGBAArrayBuffer(width, height, dataOffset, dataLength, arrayBuffer, i);
                                 }
                             }
 
-                            if (FloatArray) {
-                                engine._uploadDataToTexture(sampler, i, internalFormat, width, height, gl.RGBA, format, FloatArray);
+                            if (floatArray) {
+                                engine._uploadDataToTexture(sampler, i, internalFormat, width, height, gl.RGBA, format, floatArray);
                             }
                         } else if (info.isRGB) {
                             if (bpp === 24) {
@@ -517,13 +517,18 @@
                             engine._uploadCompressedDataToTexture(sampler, i, internalFormat, width, height, byteArray);
                         }
                     }
-                    dataOffset += width * height * (bpp / 8);
+                    dataOffset += dataLength;
                     width *= 0.5;
                     height *= 0.5;
 
                     width = Math.max(1.0, width);
                     height = Math.max(1.0, height);
                 }
+
+                if (currentFace !== undefined) {
+                    // Loading a single face
+                    break;
+                }
             }
         }
     }

+ 2 - 2
src/Tools/babylon.tools.ts

@@ -484,7 +484,7 @@
             return img;
         }
 
-        public static LoadFile(url: string, callback: (data: any, responseURL?: string) => void, progressCallBack?: (data: any) => void, database?: Database, useArrayBuffer?: boolean, onError?: (request?: XMLHttpRequest, exception?: any) => void): Nullable<XMLHttpRequest> {
+        public static LoadFile(url: string, callback: (data: string | ArrayBuffer, responseURL?: string) => void, progressCallBack?: (data: any) => void, database?: Database, useArrayBuffer?: boolean, onError?: (request?: XMLHttpRequest, exception?: any) => void): Nullable<XMLHttpRequest> {
             url = Tools.CleanUrl(url);
 
             url = Tools.PreprocessUrl(url);
@@ -511,7 +511,7 @@
                         req.onreadystatechange = () => { };//some browsers have issues where onreadystatechange can be called multiple times with the same value
 
                         if (req.status >= 200 && req.status < 300 || (!Tools.IsWindowObjectExist() && (req.status === 0))) {
-                            callback(!useArrayBuffer ? req.responseText : req.response, req.responseURL);
+                            callback(!useArrayBuffer ? req.responseText : <ArrayBuffer>req.response, req.responseURL);
                         } else { // Failed
                             let e = new Error("Error status: " + req.status + " - Unable to load " + loadUrl);
                             if (onError) {