|
@@ -1,8 +1,6 @@
|
|
|
import { Observer, Observable } from "../Misc/observable";
|
|
|
import { PerformanceMonitor } from "../Misc/performanceMonitor";
|
|
|
import { StringDictionary } from "../Misc/stringDictionary";
|
|
|
-import { PromisePolyfill } from "../Misc/promise";
|
|
|
-import { Tools, ICustomAnimationFrameRequester, IFileRequest } from "../Misc/tools";
|
|
|
import { Nullable, FloatArray, DataArray, IndicesArray, float } from "../types";
|
|
|
import { Scene } from "../scene";
|
|
|
import { VertexBuffer } from "../Meshes/buffer";
|
|
@@ -30,6 +28,9 @@ import { WebGLDataBuffer } from '../Meshes/WebGL/webGLDataBuffer';
|
|
|
import { IShaderProcessor } from './Processors/iShaderProcessor';
|
|
|
import { WebGL2ShaderProcessor } from './WebGL/webGL2ShaderProcessors';
|
|
|
import { PerfCounter } from '../Misc/perfCounter';
|
|
|
+import { IFileRequest } from '../Misc/fileRequest';
|
|
|
+import { ICustomAnimationFrameRequester } from '../Misc/customAnimationFrameRequester';
|
|
|
+import { FileTools } from '../Misc/fileTools';
|
|
|
|
|
|
declare type Material = import("../Materials/material").Material;
|
|
|
declare type PostProcess = import("../PostProcesses/postProcess").PostProcess;
|
|
@@ -996,9 +997,6 @@ export class Engine {
|
|
|
*/
|
|
|
constructor(canvasOrContext: Nullable<HTMLCanvasElement | WebGLRenderingContext>, antialias?: boolean, options?: EngineOptions, adaptToDeviceRatio: boolean = false) {
|
|
|
|
|
|
- // Register promises
|
|
|
- PromisePolyfill.Apply();
|
|
|
-
|
|
|
let canvas: Nullable<HTMLCanvasElement> = null;
|
|
|
Engine.Instances.push(this);
|
|
|
|
|
@@ -1238,7 +1236,7 @@ export class Engine {
|
|
|
|
|
|
// Pointer lock
|
|
|
if (this.isFullscreen && this._pointerLockRequested && canvas) {
|
|
|
- Tools.RequestPointerlock(canvas);
|
|
|
+ Engine._RequestPointerlock(canvas);
|
|
|
}
|
|
|
};
|
|
|
|
|
@@ -2038,12 +2036,12 @@ export class Engine {
|
|
|
if (this._activeRenderLoops.length > 0) {
|
|
|
// Register new frame
|
|
|
if (this.customAnimationFrameRequester) {
|
|
|
- this.customAnimationFrameRequester.requestID = Tools.QueueNewFrame(this.customAnimationFrameRequester.renderFunction || this._bindedRenderFunction, this.customAnimationFrameRequester);
|
|
|
+ this.customAnimationFrameRequester.requestID = Engine.QueueNewFrame(this.customAnimationFrameRequester.renderFunction || this._bindedRenderFunction, this.customAnimationFrameRequester);
|
|
|
this._frameHandler = this.customAnimationFrameRequester.requestID;
|
|
|
} else if (this.isVRPresenting()) {
|
|
|
this._requestVRFrame();
|
|
|
} else {
|
|
|
- this._frameHandler = Tools.QueueNewFrame(this._bindedRenderFunction);
|
|
|
+ this._frameHandler = Engine.QueueNewFrame(this._bindedRenderFunction);
|
|
|
}
|
|
|
} else {
|
|
|
this._renderingQueueLaunched = false;
|
|
@@ -2064,7 +2062,7 @@ export class Engine {
|
|
|
if (!this._renderingQueueLaunched) {
|
|
|
this._renderingQueueLaunched = true;
|
|
|
this._bindedRenderFunction = this._renderLoop.bind(this);
|
|
|
- this._frameHandler = Tools.QueueNewFrame(this._bindedRenderFunction);
|
|
|
+ this._frameHandler = Engine.QueueNewFrame(this._bindedRenderFunction);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -2088,7 +2086,7 @@ export class Engine {
|
|
|
if (!this.isFullscreen) {
|
|
|
this._pointerLockRequested = requestPointerLock;
|
|
|
if (this._renderingCanvas) {
|
|
|
- Tools.RequestFullscreen(this._renderingCanvas);
|
|
|
+ Engine._RequestFullscreen(this._renderingCanvas);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -2098,7 +2096,7 @@ export class Engine {
|
|
|
*/
|
|
|
public exitFullscreen(): void {
|
|
|
if (this.isFullscreen) {
|
|
|
- Tools.ExitFullscreen();
|
|
|
+ Engine._ExitFullscreen();
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -2107,7 +2105,7 @@ export class Engine {
|
|
|
*/
|
|
|
public enterPointerlock(): void {
|
|
|
if (this._renderingCanvas) {
|
|
|
- Tools.RequestPointerlock(this._renderingCanvas);
|
|
|
+ Engine._RequestPointerlock(this._renderingCanvas);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -2115,7 +2113,7 @@ export class Engine {
|
|
|
* Exits Pointerlock mode
|
|
|
*/
|
|
|
public exitPointerlock(): void {
|
|
|
- Tools.ExitPointerlock();
|
|
|
+ Engine._ExitPointerlock();
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -4235,7 +4233,6 @@ export class Engine {
|
|
|
// Add Back
|
|
|
customFallback = true;
|
|
|
excludeLoaders.push(loader);
|
|
|
- Tools.Warn((loader.constructor as any).name + " failed when trying to load " + texture.url + ", falling back to the next supported loader");
|
|
|
this.createTexture(urlArg, noMipmap, texture.invertY, scene, samplingMode, null, onError, buffer, texture, undefined, undefined, excludeLoaders);
|
|
|
return;
|
|
|
}
|
|
@@ -4245,8 +4242,8 @@ export class Engine {
|
|
|
if (onLoadObserver) {
|
|
|
texture.onLoadedObservable.remove(onLoadObserver);
|
|
|
}
|
|
|
- if (Tools.UseFallbackTexture) {
|
|
|
- this.createTexture(Tools.fallbackTexture, noMipmap, texture.invertY, scene, samplingMode, null, onError, buffer, texture);
|
|
|
+ if (EngineStore.UseFallbackTexture) {
|
|
|
+ this.createTexture(EngineStore.FallbackTexture, noMipmap, texture.invertY, scene, samplingMode, null, onError, buffer, texture);
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
@@ -4336,11 +4333,11 @@ export class Engine {
|
|
|
if (buffer instanceof HTMLImageElement) {
|
|
|
onload(buffer);
|
|
|
} else {
|
|
|
- Tools.LoadImage(url, onload, onInternalError, scene ? scene.offlineProvider : null);
|
|
|
+ FileTools.LoadImage(url, onload, onInternalError, scene ? scene.offlineProvider : null);
|
|
|
}
|
|
|
}
|
|
|
else if (typeof buffer === "string" || buffer instanceof ArrayBuffer || buffer instanceof Blob) {
|
|
|
- Tools.LoadImage(buffer, onload, onInternalError, scene ? scene.offlineProvider : null);
|
|
|
+ FileTools.LoadImage(buffer, onload, onInternalError, scene ? scene.offlineProvider : null);
|
|
|
}
|
|
|
else {
|
|
|
onload(<HTMLImageElement>buffer);
|
|
@@ -4461,8 +4458,8 @@ export class Engine {
|
|
|
texture.baseHeight = height;
|
|
|
|
|
|
if (generateMipMaps) {
|
|
|
- width = this.needPOTTextures ? Tools.GetExponentOfTwo(width, this._caps.maxTextureSize) : width;
|
|
|
- height = this.needPOTTextures ? Tools.GetExponentOfTwo(height, this._caps.maxTextureSize) : height;
|
|
|
+ width = this.needPOTTextures ? Engine.GetExponentOfTwo(width, this._caps.maxTextureSize) : width;
|
|
|
+ height = this.needPOTTextures ? Engine.GetExponentOfTwo(height, this._caps.maxTextureSize) : height;
|
|
|
}
|
|
|
|
|
|
// this.resetTextureCache();
|
|
@@ -5126,8 +5123,8 @@ export class Engine {
|
|
|
private _prepareWebGLTexture(texture: InternalTexture, scene: Nullable<Scene>, width: number, height: number, invertY: boolean, noMipmap: boolean, isCompressed: boolean,
|
|
|
processFunction: (width: number, height: number, continuationCallback: () => void) => boolean, samplingMode: number = Engine.TEXTURE_TRILINEAR_SAMPLINGMODE): void {
|
|
|
var maxTextureSize = this.getCaps().maxTextureSize;
|
|
|
- var potWidth = Math.min(maxTextureSize, this.needPOTTextures ? Tools.GetExponentOfTwo(width, maxTextureSize) : width);
|
|
|
- var potHeight = Math.min(maxTextureSize, this.needPOTTextures ? Tools.GetExponentOfTwo(height, maxTextureSize) : height);
|
|
|
+ var potWidth = Math.min(maxTextureSize, this.needPOTTextures ? Engine.GetExponentOfTwo(width, maxTextureSize) : width);
|
|
|
+ var potHeight = Math.min(maxTextureSize, this.needPOTTextures ? Engine.GetExponentOfTwo(height, maxTextureSize) : height);
|
|
|
|
|
|
var gl = this._gl;
|
|
|
if (!gl) {
|
|
@@ -6380,7 +6377,7 @@ export class Engine {
|
|
|
|
|
|
/** @hidden */
|
|
|
public _loadFile(url: string, onSuccess: (data: string | ArrayBuffer, responseURL?: string) => void, onProgress?: (data: any) => void, offlineProvider?: IOfflineProvider, useArrayBuffer?: boolean, onError?: (request?: WebRequest, exception?: any) => void): IFileRequest {
|
|
|
- let request = Tools.LoadFile(url, onSuccess, onProgress, offlineProvider, useArrayBuffer, onError);
|
|
|
+ let request = FileTools.LoadFile(url, onSuccess, onProgress, offlineProvider, useArrayBuffer, onError);
|
|
|
this._activeRequests.push(request);
|
|
|
request.onCompleteObservable.add((request) => {
|
|
|
this._activeRequests.splice(this._activeRequests.indexOf(request), 1);
|
|
@@ -6416,4 +6413,159 @@ export class Engine {
|
|
|
return false;
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Find the next highest power of two.
|
|
|
+ * @param x Number to start search from.
|
|
|
+ * @return Next highest power of two.
|
|
|
+ */
|
|
|
+ public static CeilingPOT(x: number): number {
|
|
|
+ x--;
|
|
|
+ x |= x >> 1;
|
|
|
+ x |= x >> 2;
|
|
|
+ x |= x >> 4;
|
|
|
+ x |= x >> 8;
|
|
|
+ x |= x >> 16;
|
|
|
+ x++;
|
|
|
+ return x;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Find the next lowest power of two.
|
|
|
+ * @param x Number to start search from.
|
|
|
+ * @return Next lowest power of two.
|
|
|
+ */
|
|
|
+ public static FloorPOT(x: number): number {
|
|
|
+ x = x | (x >> 1);
|
|
|
+ x = x | (x >> 2);
|
|
|
+ x = x | (x >> 4);
|
|
|
+ x = x | (x >> 8);
|
|
|
+ x = x | (x >> 16);
|
|
|
+ return x - (x >> 1);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Find the nearest power of two.
|
|
|
+ * @param x Number to start search from.
|
|
|
+ * @return Next nearest power of two.
|
|
|
+ */
|
|
|
+ public static NearestPOT(x: number): number {
|
|
|
+ var c = Engine.CeilingPOT(x);
|
|
|
+ var f = Engine.FloorPOT(x);
|
|
|
+ return (c - x) > (x - f) ? f : c;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Get the closest exponent of two
|
|
|
+ * @param value defines the value to approximate
|
|
|
+ * @param max defines the maximum value to return
|
|
|
+ * @param mode defines how to define the closest value
|
|
|
+ * @returns closest exponent of two of the given value
|
|
|
+ */
|
|
|
+ public static GetExponentOfTwo(value: number, max: number, mode = Constants.SCALEMODE_NEAREST): number {
|
|
|
+ let pot;
|
|
|
+
|
|
|
+ switch (mode) {
|
|
|
+ case Constants.SCALEMODE_FLOOR:
|
|
|
+ pot = Engine.FloorPOT(value);
|
|
|
+ break;
|
|
|
+ case Constants.SCALEMODE_NEAREST:
|
|
|
+ pot = Engine.NearestPOT(value);
|
|
|
+ break;
|
|
|
+ case Constants.SCALEMODE_CEILING:
|
|
|
+ default:
|
|
|
+ pot = Engine.CeilingPOT(value);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ return Math.min(pot, max);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Queue a new function into the requested animation frame pool (ie. this function will be executed byt the browser for the next frame)
|
|
|
+ * @param func - the function to be called
|
|
|
+ * @param requester - the object that will request the next frame. Falls back to window.
|
|
|
+ * @returns frame number
|
|
|
+ */
|
|
|
+ public static QueueNewFrame(func: () => void, requester?: any): number {
|
|
|
+ if (!DomManagement.IsWindowObjectExist()) {
|
|
|
+ return setTimeout(func, 16);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!requester) {
|
|
|
+ requester = window;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (requester.requestAnimationFrame) {
|
|
|
+ return requester.requestAnimationFrame(func);
|
|
|
+ }
|
|
|
+ else if (requester.msRequestAnimationFrame) {
|
|
|
+ return requester.msRequestAnimationFrame(func);
|
|
|
+ }
|
|
|
+ else if (requester.webkitRequestAnimationFrame) {
|
|
|
+ return requester.webkitRequestAnimationFrame(func);
|
|
|
+ }
|
|
|
+ else if (requester.mozRequestAnimationFrame) {
|
|
|
+ return requester.mozRequestAnimationFrame(func);
|
|
|
+ }
|
|
|
+ else if (requester.oRequestAnimationFrame) {
|
|
|
+ return requester.oRequestAnimationFrame(func);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ return window.setTimeout(func, 16);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Ask the browser to promote the current element to pointerlock mode
|
|
|
+ * @param element defines the DOM element to promote
|
|
|
+ */
|
|
|
+ static _RequestPointerlock(element: HTMLElement): void {
|
|
|
+ element.requestPointerLock = element.requestPointerLock || (<any>element).msRequestPointerLock || (<any>element).mozRequestPointerLock || (<any>element).webkitRequestPointerLock;
|
|
|
+ if (element.requestPointerLock) {
|
|
|
+ element.requestPointerLock();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Asks the browser to exit pointerlock mode
|
|
|
+ */
|
|
|
+ static _ExitPointerlock(): void {
|
|
|
+ let anyDoc = document as any;
|
|
|
+ document.exitPointerLock = document.exitPointerLock || anyDoc.msExitPointerLock || anyDoc.mozExitPointerLock || anyDoc.webkitExitPointerLock;
|
|
|
+
|
|
|
+ if (document.exitPointerLock) {
|
|
|
+ document.exitPointerLock();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Ask the browser to promote the current element to fullscreen rendering mode
|
|
|
+ * @param element defines the DOM element to promote
|
|
|
+ */
|
|
|
+ static _RequestFullscreen(element: HTMLElement): void {
|
|
|
+ var requestFunction = element.requestFullscreen || (<any>element).msRequestFullscreen || (<any>element).webkitRequestFullscreen || (<any>element).mozRequestFullScreen;
|
|
|
+ if (!requestFunction) { return; }
|
|
|
+ requestFunction.call(element);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Asks the browser to exit fullscreen mode
|
|
|
+ */
|
|
|
+ static _ExitFullscreen(): void {
|
|
|
+ let anyDoc = document as any;
|
|
|
+
|
|
|
+ if (document.exitFullscreen) {
|
|
|
+ document.exitFullscreen();
|
|
|
+ }
|
|
|
+ else if (anyDoc.mozCancelFullScreen) {
|
|
|
+ anyDoc.mozCancelFullScreen();
|
|
|
+ }
|
|
|
+ else if (anyDoc.webkitCancelFullScreen) {
|
|
|
+ anyDoc.webkitCancelFullScreen();
|
|
|
+ }
|
|
|
+ else if (anyDoc.msCancelFullScreen) {
|
|
|
+ anyDoc.msCancelFullScreen();
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|