David Catuhe 8 vuotta sitten
vanhempi
commit
3818803c03

+ 1 - 1
Playground/css/index.css

@@ -60,7 +60,7 @@ body {
 #fpsLabel {
     position: absolute;
     right: 10px;
-    top: 80px;
+    top: 50px;
     cursor: default;
     z-index:10;
     background-color: #7283a0;

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 22 - 22
dist/preview release/babylon.core.js


+ 354 - 352
dist/preview release/babylon.d.ts

@@ -514,6 +514,7 @@ declare module BABYLON {
         removeExternalData(key: any): boolean;
         releaseInternalTexture(texture: WebGLTexture): void;
         unbindAllAttributes(): void;
+        releaseEffects(): void;
         dispose(): void;
         displayLoadingUI(): void;
         hideLoadingUI(): void;
@@ -3887,6 +3888,111 @@ declare module BABYLON {
     }
 }
 
+declare module BABYLON.Debug {
+    class AxesViewer {
+        private _xline;
+        private _yline;
+        private _zline;
+        private _xmesh;
+        private _ymesh;
+        private _zmesh;
+        scene: Scene;
+        scaleLines: number;
+        constructor(scene: Scene, scaleLines?: number);
+        update(position: Vector3, xaxis: Vector3, yaxis: Vector3, zaxis: Vector3): void;
+        dispose(): void;
+    }
+}
+
+declare module BABYLON.Debug {
+    class BoneAxesViewer extends Debug.AxesViewer {
+        mesh: Mesh;
+        bone: Bone;
+        pos: Vector3;
+        xaxis: Vector3;
+        yaxis: Vector3;
+        zaxis: Vector3;
+        constructor(scene: Scene, bone: Bone, mesh: Mesh, scaleLines?: number);
+        update(): void;
+        dispose(): void;
+    }
+}
+
+declare module BABYLON {
+    class DebugLayer {
+        private _scene;
+        static InspectorURL: string;
+        private _inspector;
+        constructor(scene: Scene);
+        /** Creates the inspector window. */
+        private _createInspector(config?);
+        isVisible(): boolean;
+        hide(): void;
+        show(config?: {
+            popup?: boolean;
+            initialTab?: number;
+            parentElement?: HTMLElement;
+            newColors?: {
+                backgroundColor?: string;
+                backgroundColorLighter?: string;
+                backgroundColorLighter2?: string;
+                backgroundColorLighter3?: string;
+                color?: string;
+                colorTop?: string;
+                colorBot?: string;
+            };
+        }): void;
+    }
+}
+
+declare module BABYLON {
+    class RayHelper {
+        ray: Ray;
+        private _renderPoints;
+        private _renderLine;
+        private _renderFunction;
+        private _scene;
+        private _updateToMeshFunction;
+        private _attachedToMesh;
+        private _meshSpaceDirection;
+        private _meshSpaceOrigin;
+        static CreateAndShow(ray: Ray, scene: Scene, color: Color3): RayHelper;
+        constructor(ray: Ray);
+        show(scene: Scene, color: Color3): void;
+        hide(): void;
+        private _render();
+        attachToMesh(mesh: AbstractMesh, meshSpaceDirection?: Vector3, meshSpaceOrigin?: Vector3, length?: number): void;
+        detachFromMesh(): void;
+        private _updateToMesh();
+        dispose(): void;
+    }
+}
+
+declare module BABYLON.Debug {
+    /**
+    * Demo available here: http://www.babylonjs-playground.com/#1BZJVJ#8
+    */
+    class SkeletonViewer {
+        skeleton: Skeleton;
+        mesh: AbstractMesh;
+        autoUpdateBonesMatrices: boolean;
+        renderingGroupId: number;
+        color: Color3;
+        private _scene;
+        private _debugLines;
+        private _debugMesh;
+        private _isEnabled;
+        private _renderFunction;
+        constructor(skeleton: Skeleton, mesh: AbstractMesh, scene: Scene, autoUpdateBonesMatrices?: boolean, renderingGroupId?: number);
+        isEnabled: boolean;
+        private _getBonePosition(position, bone, meshMat, x?, y?, z?);
+        private _getLinesForBonesWithLength(bones, meshMat);
+        private _getLinesForBonesNoLength(bones, meshMat);
+        update(): void;
+        dispose(): void;
+    }
+}
+
 declare module BABYLON {
     class BoundingBox implements ICullable {
         minimum: Vector3;
@@ -4001,111 +4107,6 @@ declare module BABYLON {
     }
 }
 
-declare module BABYLON.Debug {
-    class AxesViewer {
-        private _xline;
-        private _yline;
-        private _zline;
-        private _xmesh;
-        private _ymesh;
-        private _zmesh;
-        scene: Scene;
-        scaleLines: number;
-        constructor(scene: Scene, scaleLines?: number);
-        update(position: Vector3, xaxis: Vector3, yaxis: Vector3, zaxis: Vector3): void;
-        dispose(): void;
-    }
-}
-
-declare module BABYLON.Debug {
-    class BoneAxesViewer extends Debug.AxesViewer {
-        mesh: Mesh;
-        bone: Bone;
-        pos: Vector3;
-        xaxis: Vector3;
-        yaxis: Vector3;
-        zaxis: Vector3;
-        constructor(scene: Scene, bone: Bone, mesh: Mesh, scaleLines?: number);
-        update(): void;
-        dispose(): void;
-    }
-}
-
-declare module BABYLON {
-    class DebugLayer {
-        private _scene;
-        static InspectorURL: string;
-        private _inspector;
-        constructor(scene: Scene);
-        /** Creates the inspector window. */
-        private _createInspector(config?);
-        isVisible(): boolean;
-        hide(): void;
-        show(config?: {
-            popup?: boolean;
-            initialTab?: number;
-            parentElement?: HTMLElement;
-            newColors?: {
-                backgroundColor?: string;
-                backgroundColorLighter?: string;
-                backgroundColorLighter2?: string;
-                backgroundColorLighter3?: string;
-                color?: string;
-                colorTop?: string;
-                colorBot?: string;
-            };
-        }): void;
-    }
-}
-
-declare module BABYLON {
-    class RayHelper {
-        ray: Ray;
-        private _renderPoints;
-        private _renderLine;
-        private _renderFunction;
-        private _scene;
-        private _updateToMeshFunction;
-        private _attachedToMesh;
-        private _meshSpaceDirection;
-        private _meshSpaceOrigin;
-        static CreateAndShow(ray: Ray, scene: Scene, color: Color3): RayHelper;
-        constructor(ray: Ray);
-        show(scene: Scene, color: Color3): void;
-        hide(): void;
-        private _render();
-        attachToMesh(mesh: AbstractMesh, meshSpaceDirection?: Vector3, meshSpaceOrigin?: Vector3, length?: number): void;
-        detachFromMesh(): void;
-        private _updateToMesh();
-        dispose(): void;
-    }
-}
-
-declare module BABYLON.Debug {
-    /**
-    * Demo available here: http://www.babylonjs-playground.com/#1BZJVJ#8
-    */
-    class SkeletonViewer {
-        skeleton: Skeleton;
-        mesh: AbstractMesh;
-        autoUpdateBonesMatrices: boolean;
-        renderingGroupId: number;
-        color: Color3;
-        private _scene;
-        private _debugLines;
-        private _debugMesh;
-        private _isEnabled;
-        private _renderFunction;
-        constructor(skeleton: Skeleton, mesh: AbstractMesh, scene: Scene, autoUpdateBonesMatrices?: boolean, renderingGroupId?: number);
-        isEnabled: boolean;
-        private _getBonePosition(position, bone, meshMat, x?, y?, z?);
-        private _getLinesForBonesWithLength(bones, meshMat);
-        private _getLinesForBonesNoLength(bones, meshMat);
-        update(): void;
-        dispose(): void;
-    }
-}
-
 declare module BABYLON {
     /**
      * Highlight layer options. This helps customizing the behaviour
@@ -4362,103 +4363,6 @@ declare module BABYLON {
 }
 
 declare module BABYLON {
-    class LensFlare {
-        size: number;
-        position: number;
-        color: Color3;
-        texture: Texture;
-        alphaMode: number;
-        private _system;
-        constructor(size: number, position: number, color: any, imgUrl: string, system: LensFlareSystem);
-        dispose: () => void;
-    }
-}
-
-declare module BABYLON {
-    class LensFlareSystem {
-        name: string;
-        lensFlares: LensFlare[];
-        borderLimit: number;
-        viewportBorder: number;
-        meshesSelectionPredicate: (mesh: Mesh) => boolean;
-        layerMask: number;
-        id: string;
-        private _scene;
-        private _emitter;
-        private _vertexBuffers;
-        private _indexBuffer;
-        private _effect;
-        private _positionX;
-        private _positionY;
-        private _isEnabled;
-        constructor(name: string, emitter: any, scene: Scene);
-        isEnabled: boolean;
-        getScene(): Scene;
-        getEmitter(): any;
-        setEmitter(newEmitter: any): void;
-        getEmitterPosition(): Vector3;
-        computeEffectivePosition(globalViewport: Viewport): boolean;
-        _isVisible(): boolean;
-        render(): boolean;
-        dispose(): void;
-        static Parse(parsedLensFlareSystem: any, scene: Scene, rootUrl: string): LensFlareSystem;
-        serialize(): any;
-    }
-}
-
-declare module BABYLON {
-    interface ISceneLoaderPluginExtensions {
-        [extension: string]: {
-            isBinary: boolean;
-        };
-    }
-    interface ISceneLoaderPlugin {
-        extensions: string | ISceneLoaderPluginExtensions;
-        importMesh: (meshesNames: any, scene: Scene, data: any, rootUrl: string, meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]) => boolean;
-        load: (scene: Scene, data: string, rootUrl: string) => boolean;
-    }
-    interface ISceneLoaderPluginAsync {
-        extensions: string | ISceneLoaderPluginExtensions;
-        importMeshAsync: (meshesNames: any, scene: Scene, data: any, rootUrl: string, onsuccess?: (meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]) => void, onerror?: () => void) => void;
-        loadAsync: (scene: Scene, data: string, rootUrl: string, onsuccess: () => void, onerror: () => void) => boolean;
-    }
-    class SceneLoader {
-        private static _ForceFullSceneLoadingForIncremental;
-        private static _ShowLoadingScreen;
-        static readonly NO_LOGGING: number;
-        static readonly MINIMAL_LOGGING: number;
-        static readonly SUMMARY_LOGGING: number;
-        static readonly DETAILED_LOGGING: number;
-        private static _loggingLevel;
-        static ForceFullSceneLoadingForIncremental: boolean;
-        static ShowLoadingScreen: boolean;
-        static loggingLevel: number;
-        private static _registeredPlugins;
-        private static _getDefaultPlugin();
-        private static _getPluginForExtension(extension);
-        private static _getPluginForFilename(sceneFilename);
-        private static _getDirectLoad(sceneFilename);
-        static GetPluginForExtension(extension: string): ISceneLoaderPlugin | ISceneLoaderPluginAsync;
-        static RegisterPlugin(plugin: ISceneLoaderPlugin | ISceneLoaderPluginAsync): void;
-        static ImportMesh(meshesNames: any, rootUrl: string, sceneFilename: string, scene: Scene, onsuccess?: (meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]) => void, progressCallBack?: () => void, onerror?: (scene: Scene, message: string, exception?: any) => void): void;
-        /**
-        * Load a scene
-        * @param rootUrl a string that defines the root url for scene and resources
-        * @param sceneFilename a string that defines the name of the scene file. can start with "data:" following by the stringified version of the scene
-        * @param engine is the instance of BABYLON.Engine to use to create the scene
-        */
-        static Load(rootUrl: string, sceneFilename: any, engine: Engine, onsuccess?: (scene: Scene) => void, progressCallBack?: any, onerror?: (scene: Scene) => void): void;
-        /**
-        * Append a scene
-        * @param rootUrl a string that defines the root url for scene and resources
-        * @param sceneFilename a string that defines the name of the scene file. can start with "data:" following by the stringified version of the scene
-        * @param scene is the instance of BABYLON.Scene to append to
-        */
-        static Append(rootUrl: string, sceneFilename: any, scene: Scene, onsuccess?: (scene: Scene) => void, progressCallBack?: any, onerror?: (scene: Scene) => void): void;
-    }
-}
-
-declare module BABYLON {
     class DirectionalLight extends Light implements IShadowLight {
         position: Vector3;
         direction: Vector3;
@@ -4844,6 +4748,103 @@ declare module BABYLON {
 }
 
 declare module BABYLON {
+    class LensFlare {
+        size: number;
+        position: number;
+        color: Color3;
+        texture: Texture;
+        alphaMode: number;
+        private _system;
+        constructor(size: number, position: number, color: any, imgUrl: string, system: LensFlareSystem);
+        dispose: () => void;
+    }
+}
+
+declare module BABYLON {
+    class LensFlareSystem {
+        name: string;
+        lensFlares: LensFlare[];
+        borderLimit: number;
+        viewportBorder: number;
+        meshesSelectionPredicate: (mesh: Mesh) => boolean;
+        layerMask: number;
+        id: string;
+        private _scene;
+        private _emitter;
+        private _vertexBuffers;
+        private _indexBuffer;
+        private _effect;
+        private _positionX;
+        private _positionY;
+        private _isEnabled;
+        constructor(name: string, emitter: any, scene: Scene);
+        isEnabled: boolean;
+        getScene(): Scene;
+        getEmitter(): any;
+        setEmitter(newEmitter: any): void;
+        getEmitterPosition(): Vector3;
+        computeEffectivePosition(globalViewport: Viewport): boolean;
+        _isVisible(): boolean;
+        render(): boolean;
+        dispose(): void;
+        static Parse(parsedLensFlareSystem: any, scene: Scene, rootUrl: string): LensFlareSystem;
+        serialize(): any;
+    }
+}
+
+declare module BABYLON {
+    interface ISceneLoaderPluginExtensions {
+        [extension: string]: {
+            isBinary: boolean;
+        };
+    }
+    interface ISceneLoaderPlugin {
+        extensions: string | ISceneLoaderPluginExtensions;
+        importMesh: (meshesNames: any, scene: Scene, data: any, rootUrl: string, meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]) => boolean;
+        load: (scene: Scene, data: string, rootUrl: string) => boolean;
+    }
+    interface ISceneLoaderPluginAsync {
+        extensions: string | ISceneLoaderPluginExtensions;
+        importMeshAsync: (meshesNames: any, scene: Scene, data: any, rootUrl: string, onsuccess: (meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]) => void, onerror: () => void) => void;
+        loadAsync: (scene: Scene, data: string, rootUrl: string, onsuccess: () => void, onerror: () => void) => void;
+    }
+    class SceneLoader {
+        private static _ForceFullSceneLoadingForIncremental;
+        private static _ShowLoadingScreen;
+        static readonly NO_LOGGING: number;
+        static readonly MINIMAL_LOGGING: number;
+        static readonly SUMMARY_LOGGING: number;
+        static readonly DETAILED_LOGGING: number;
+        private static _loggingLevel;
+        static ForceFullSceneLoadingForIncremental: boolean;
+        static ShowLoadingScreen: boolean;
+        static loggingLevel: number;
+        private static _registeredPlugins;
+        private static _getDefaultPlugin();
+        private static _getPluginForExtension(extension);
+        private static _getPluginForFilename(sceneFilename);
+        private static _getDirectLoad(sceneFilename);
+        static GetPluginForExtension(extension: string): ISceneLoaderPlugin | ISceneLoaderPluginAsync;
+        static RegisterPlugin(plugin: ISceneLoaderPlugin | ISceneLoaderPluginAsync): void;
+        static ImportMesh(meshesNames: any, rootUrl: string, sceneFilename: string, scene: Scene, onsuccess?: (meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]) => void, progressCallBack?: () => void, onerror?: (scene: Scene, message: string, exception?: any) => void): void;
+        /**
+        * Load a scene
+        * @param rootUrl a string that defines the root url for scene and resources
+        * @param sceneFilename a string that defines the name of the scene file. can start with "data:" following by the stringified version of the scene
+        * @param engine is the instance of BABYLON.Engine to use to create the scene
+        */
+        static Load(rootUrl: string, sceneFilename: any, engine: Engine, onsuccess?: (scene: Scene) => void, progressCallBack?: any, onerror?: (scene: Scene) => void): void;
+        /**
+        * Append a scene
+        * @param rootUrl a string that defines the root url for scene and resources
+        * @param sceneFilename a string that defines the name of the scene file. can start with "data:" following by the stringified version of the scene
+        * @param scene is the instance of BABYLON.Scene to append to
+        */
+        static Append(rootUrl: string, sceneFilename: any, scene: Scene, onsuccess?: (scene: Scene) => void, progressCallBack?: any, onerror?: (scene: Scene) => void): void;
+    }
+}
+
+declare module BABYLON {
     /**
      * The color grading curves provide additional color adjustmnent that is applied after any color grading transform (3D LUT).
      * They allow basic adjustment of saturation and small exposure adjustments, along with color filter tinting to provide white balance adjustment or more stylistic effects.
@@ -8778,6 +8779,7 @@ declare module BABYLON {
         getTotalIndices(): number;
         getIndices(copyWhenShared?: boolean): IndicesArray;
         getIndexBuffer(): WebGLBuffer;
+        _releaseVertexArrayObject(effect: Effect): void;
         releaseForMesh(mesh: Mesh, shouldDispose?: boolean): void;
         applyToMesh(mesh: Mesh): void;
         private updateExtend(data?, stride?);
@@ -11036,7 +11038,7 @@ declare module BABYLON {
         _distanceToCamera: number;
         _id: number;
         _materialDefines: MaterialDefines;
-        private _materialEffect;
+        _materialEffect: Effect;
         private _currentMaterial;
         readonly effect: Effect;
         setEffect(effect: Effect, defines?: MaterialDefines): void;
@@ -12087,29 +12089,6 @@ declare module BABYLON {
 }
 
 declare module BABYLON {
-    class ReflectionProbe {
-        name: string;
-        private _scene;
-        private _renderTargetTexture;
-        private _projectionMatrix;
-        private _viewMatrix;
-        private _target;
-        private _add;
-        private _attachedMesh;
-        invertYAxis: boolean;
-        position: Vector3;
-        constructor(name: string, size: number, scene: Scene, generateMipMaps?: boolean);
-        samples: number;
-        refreshRate: number;
-        getScene(): Scene;
-        readonly cubeTexture: RenderTargetTexture;
-        readonly renderList: AbstractMesh[];
-        attachToMesh(mesh: AbstractMesh): void;
-        dispose(): void;
-    }
-}
-
-declare module BABYLON {
     class AnaglyphPostProcess extends PostProcess {
         private _passedProcess;
         constructor(name: string, options: number | PostProcessOptions, rigCameras: Camera[], samplingMode?: number, engine?: Engine, reusable?: boolean);
@@ -12783,6 +12762,29 @@ declare module BABYLON {
 }
 
 declare module BABYLON {
+    class ReflectionProbe {
+        name: string;
+        private _scene;
+        private _renderTargetTexture;
+        private _projectionMatrix;
+        private _viewMatrix;
+        private _target;
+        private _add;
+        private _attachedMesh;
+        invertYAxis: boolean;
+        position: Vector3;
+        constructor(name: string, size: number, scene: Scene, generateMipMaps?: boolean);
+        samples: number;
+        refreshRate: number;
+        getScene(): Scene;
+        readonly cubeTexture: RenderTargetTexture;
+        readonly renderList: AbstractMesh[];
+        attachToMesh(mesh: AbstractMesh): void;
+        dispose(): void;
+    }
+}
+
+declare module BABYLON {
     class BoundingBoxRenderer {
         frontColor: Color3;
         backColor: Color3;
@@ -14484,6 +14486,129 @@ declare module BABYLON {
 }
 
 declare module BABYLON {
+    class VRCameraMetrics {
+        hResolution: number;
+        vResolution: number;
+        hScreenSize: number;
+        vScreenSize: number;
+        vScreenCenter: number;
+        eyeToScreenDistance: number;
+        lensSeparationDistance: number;
+        interpupillaryDistance: number;
+        distortionK: number[];
+        chromaAbCorrection: number[];
+        postProcessScaleFactor: number;
+        lensCenterOffset: number;
+        compensateDistortion: boolean;
+        readonly aspectRatio: number;
+        readonly aspectRatioFov: number;
+        readonly leftHMatrix: Matrix;
+        readonly rightHMatrix: Matrix;
+        readonly leftPreViewMatrix: Matrix;
+        readonly rightPreViewMatrix: Matrix;
+        static GetDefault(): VRCameraMetrics;
+    }
+}
+
+declare module BABYLON {
+    class VRDeviceOrientationFreeCamera extends DeviceOrientationCamera {
+        constructor(name: string, position: Vector3, scene: Scene, compensateDistortion?: boolean, vrCameraMetrics?: VRCameraMetrics);
+        getClassName(): string;
+    }
+    class VRDeviceOrientationGamepadCamera extends VRDeviceOrientationFreeCamera {
+        constructor(name: string, position: Vector3, scene: Scene, compensateDistortion?: boolean, vrCameraMetrics?: VRCameraMetrics);
+        getClassName(): string;
+    }
+    class VRDeviceOrientationArcRotateCamera extends ArcRotateCamera {
+        constructor(name: string, alpha: number, beta: number, radius: number, target: Vector3, scene: Scene, compensateDistortion?: boolean, vrCameraMetrics?: VRCameraMetrics);
+        getClassName(): string;
+    }
+}
+
+declare var HMDVRDevice: any;
+declare var VRDisplay: any;
+declare var VRFrameData: any;
+declare module BABYLON {
+    /**
+     * This is a copy of VRPose.
+     * IMPORTANT!! The data is right-hand data.
+     * @export
+     * @interface DevicePose
+     */
+    interface DevicePose {
+        readonly position?: Float32Array;
+        readonly linearVelocity?: Float32Array;
+        readonly linearAcceleration?: Float32Array;
+        readonly orientation?: Float32Array;
+        readonly angularVelocity?: Float32Array;
+        readonly angularAcceleration?: Float32Array;
+    }
+    interface PoseControlled {
+        position: Vector3;
+        rotationQuaternion: Quaternion;
+        devicePosition?: Vector3;
+        deviceRotationQuaternion: Quaternion;
+        rawPose: DevicePose;
+        deviceScaleFactor: number;
+        updateFromDevice(poseData: DevicePose): any;
+    }
+    interface WebVROptions {
+        trackPosition?: boolean;
+        positionScale?: number;
+        displayName?: string;
+        controllerMeshes?: boolean;
+        defaultLightningOnControllers?: boolean;
+    }
+    class WebVRFreeCamera extends FreeCamera implements PoseControlled {
+        private webVROptions;
+        _vrDevice: any;
+        rawPose: DevicePose;
+        private _vrEnabled;
+        private _specsVersion;
+        private _attached;
+        private _oldSize;
+        private _oldHardwareScaleFactor;
+        private _frameData;
+        private _quaternionCache;
+        private _positionOffset;
+        protected _descendants: Array<Node>;
+        devicePosition: Vector3;
+        deviceRotationQuaternion: any;
+        deviceScaleFactor: number;
+        controllers: Array<WebVRController>;
+        onControllersAttached: (controllers: Array<WebVRController>) => void;
+        rigParenting: boolean;
+        private _lightOnControllers;
+        constructor(name: string, position: Vector3, scene: Scene, webVROptions?: WebVROptions);
+        _checkInputs(): void;
+        updateFromDevice(poseData: DevicePose): void;
+        /**
+         * WebVR's attach control will start broadcasting frames to the device.
+         * Note that in certain browsers (chrome for example) this function must be called
+         * within a user-interaction callback. Example:
+         * <pre> scene.onPointerDown = function() { camera.attachControl(canvas); }</pre>
+         *
+         * @param {HTMLElement} element
+         * @param {boolean} [noPreventDefault]
+         *
+         * @memberOf WebVRFreeCamera
+         */
+        attachControl(element: HTMLElement, noPreventDefault?: boolean): void;
+        detachControl(element: HTMLElement): void;
+        getClassName(): string;
+        resetToCurrentRotation(): void;
+        _updateRigCameras(): void;
+        /**
+         * This function is called by the two RIG cameras.
+         * 'this' is the left or right camera (and NOT (!!!) the WebVRFreeCamera instance)
+         */
+        protected _getWebVRViewMatrix(): Matrix;
+        protected _getWebVRProjectionMatrix(): Matrix;
+        initControllers(): void;
+    }
+}
+
+declare module BABYLON {
     class ArcRotateCameraGamepadInput implements ICameraInput<ArcRotateCamera> {
         camera: ArcRotateCamera;
         gamepad: Gamepad;
@@ -14694,129 +14819,6 @@ declare module BABYLON {
 }
 
 declare module BABYLON {
-    class VRCameraMetrics {
-        hResolution: number;
-        vResolution: number;
-        hScreenSize: number;
-        vScreenSize: number;
-        vScreenCenter: number;
-        eyeToScreenDistance: number;
-        lensSeparationDistance: number;
-        interpupillaryDistance: number;
-        distortionK: number[];
-        chromaAbCorrection: number[];
-        postProcessScaleFactor: number;
-        lensCenterOffset: number;
-        compensateDistortion: boolean;
-        readonly aspectRatio: number;
-        readonly aspectRatioFov: number;
-        readonly leftHMatrix: Matrix;
-        readonly rightHMatrix: Matrix;
-        readonly leftPreViewMatrix: Matrix;
-        readonly rightPreViewMatrix: Matrix;
-        static GetDefault(): VRCameraMetrics;
-    }
-}
-
-declare module BABYLON {
-    class VRDeviceOrientationFreeCamera extends DeviceOrientationCamera {
-        constructor(name: string, position: Vector3, scene: Scene, compensateDistortion?: boolean, vrCameraMetrics?: VRCameraMetrics);
-        getClassName(): string;
-    }
-    class VRDeviceOrientationGamepadCamera extends VRDeviceOrientationFreeCamera {
-        constructor(name: string, position: Vector3, scene: Scene, compensateDistortion?: boolean, vrCameraMetrics?: VRCameraMetrics);
-        getClassName(): string;
-    }
-    class VRDeviceOrientationArcRotateCamera extends ArcRotateCamera {
-        constructor(name: string, alpha: number, beta: number, radius: number, target: Vector3, scene: Scene, compensateDistortion?: boolean, vrCameraMetrics?: VRCameraMetrics);
-        getClassName(): string;
-    }
-}
-
-declare var HMDVRDevice: any;
-declare var VRDisplay: any;
-declare var VRFrameData: any;
-declare module BABYLON {
-    /**
-     * This is a copy of VRPose.
-     * IMPORTANT!! The data is right-hand data.
-     * @export
-     * @interface DevicePose
-     */
-    interface DevicePose {
-        readonly position?: Float32Array;
-        readonly linearVelocity?: Float32Array;
-        readonly linearAcceleration?: Float32Array;
-        readonly orientation?: Float32Array;
-        readonly angularVelocity?: Float32Array;
-        readonly angularAcceleration?: Float32Array;
-    }
-    interface PoseControlled {
-        position: Vector3;
-        rotationQuaternion: Quaternion;
-        devicePosition?: Vector3;
-        deviceRotationQuaternion: Quaternion;
-        rawPose: DevicePose;
-        deviceScaleFactor: number;
-        updateFromDevice(poseData: DevicePose): any;
-    }
-    interface WebVROptions {
-        trackPosition?: boolean;
-        positionScale?: number;
-        displayName?: string;
-        controllerMeshes?: boolean;
-        defaultLightningOnControllers?: boolean;
-    }
-    class WebVRFreeCamera extends FreeCamera implements PoseControlled {
-        private webVROptions;
-        _vrDevice: any;
-        rawPose: DevicePose;
-        private _vrEnabled;
-        private _specsVersion;
-        private _attached;
-        private _oldSize;
-        private _oldHardwareScaleFactor;
-        private _frameData;
-        private _quaternionCache;
-        private _positionOffset;
-        protected _descendants: Array<Node>;
-        devicePosition: Vector3;
-        deviceRotationQuaternion: any;
-        deviceScaleFactor: number;
-        controllers: Array<WebVRController>;
-        onControllersAttached: (controllers: Array<WebVRController>) => void;
-        rigParenting: boolean;
-        private _lightOnControllers;
-        constructor(name: string, position: Vector3, scene: Scene, webVROptions?: WebVROptions);
-        _checkInputs(): void;
-        updateFromDevice(poseData: DevicePose): void;
-        /**
-         * WebVR's attach control will start broadcasting frames to the device.
-         * Note that in certain browsers (chrome for example) this function must be called
-         * within a user-interaction callback. Example:
-         * <pre> scene.onPointerDown = function() { camera.attachControl(canvas); }</pre>
-         *
-         * @param {HTMLElement} element
-         * @param {boolean} [noPreventDefault]
-         *
-         * @memberOf WebVRFreeCamera
-         */
-        attachControl(element: HTMLElement, noPreventDefault?: boolean): void;
-        detachControl(element: HTMLElement): void;
-        getClassName(): string;
-        resetToCurrentRotation(): void;
-        _updateRigCameras(): void;
-        /**
-         * This function is called by the two RIG cameras.
-         * 'this' is the left or right camera (and NOT (!!!) the WebVRFreeCamera instance)
-         */
-        protected _getWebVRViewMatrix(): Matrix;
-        protected _getWebVRProjectionMatrix(): Matrix;
-        initControllers(): void;
-    }
-}
-
-declare module BABYLON {
     interface IOctreeContainer<T> {
         blocks: Array<OctreeBlock<T>>;
     }
@@ -14863,9 +14865,6 @@ declare module BABYLON {
     }
 }
 
-declare module BABYLON.Internals {
-}
-
 declare module BABYLON {
     interface IShadowGenerator {
         getShadowMap(): RenderTargetTexture;
@@ -14979,6 +14978,9 @@ declare module BABYLON {
     }
 }
 
+declare module BABYLON.Internals {
+}
+
 declare module BABYLON {
     class BaseTexture {
         name: string;

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 37 - 37
dist/preview release/babylon.js


+ 48 - 39
dist/preview release/babylon.max.js

@@ -10757,6 +10757,12 @@ var BABYLON;
                 this._currentBufferPointers[i] = null;
             }
         };
+        Engine.prototype.releaseEffects = function () {
+            for (var name in this._compiledEffects) {
+                this._gl.deleteProgram(this._compiledEffects[name]._program);
+            }
+            this._compiledEffects = {};
+        };
         // Dispose
         Engine.prototype.dispose = function () {
             this.hideLoadingUI();
@@ -10768,9 +10774,7 @@ var BABYLON;
             // Release audio engine
             Engine.audioEngine.dispose();
             // Release effects
-            for (var name in this._compiledEffects) {
-                this._gl.deleteProgram(this._compiledEffects[name]._program);
-            }
+            this.releaseEffects();
             // Unbind
             this.unbindAllAttributes();
             this._gl = null;
@@ -21699,12 +21703,14 @@ var BABYLON;
                 return false;
             }
             var index;
+            // Geometries
             for (index = 0; index < this._geometries.length; index++) {
                 var geometry = this._geometries[index];
                 if (geometry.delayLoadState === BABYLON.Engine.DELAYLOADSTATE_LOADING) {
                     return false;
                 }
             }
+            // Meshes
             for (index = 0; index < this.meshes.length; index++) {
                 var mesh = this.meshes[index];
                 if (!mesh.isEnabled()) {
@@ -31595,17 +31601,37 @@ var BABYLON;
             if (index >= 0) {
                 this._scene.materials.splice(index, 1);
             }
-            // Shader are kept in cache for further use but we can get rid of this by using forceDisposeEffect
-            if (forceDisposeEffect && this._effect) {
-                this._scene.getEngine()._releaseEffect(this._effect);
-                this._effect = null;
-            }
             // Remove from meshes
             for (index = 0; index < this._scene.meshes.length; index++) {
                 var mesh = this._scene.meshes[index];
                 if (mesh.material === this) {
                     mesh.material = null;
                 }
+                if (mesh.geometry) {
+                    var geometry = mesh.geometry;
+                    if (this.storeEffectOnSubMeshes) {
+                        for (var _i = 0, _a = mesh.subMeshes; _i < _a.length; _i++) {
+                            var subMesh = _a[_i];
+                            geometry._releaseVertexArrayObject(subMesh._materialEffect);
+                        }
+                    }
+                    else {
+                        geometry._releaseVertexArrayObject(this._effect);
+                    }
+                }
+            }
+            // Shader are kept in cache for further use but we can get rid of this by using forceDisposeEffect
+            if (forceDisposeEffect && this._effect) {
+                if (this.storeEffectOnSubMeshes) {
+                    for (var _b = 0, _c = mesh.subMeshes; _b < _c.length; _b++) {
+                        var subMesh = _c[_b];
+                        this._scene.getEngine()._releaseEffect(subMesh._materialEffect);
+                    }
+                }
+                else {
+                    this._scene.getEngine()._releaseEffect(this._effect);
+                }
+                this._effect = null;
             }
             // Callback
             this.onDisposeObservable.notifyObservers(this);
@@ -43009,6 +43035,12 @@ var BABYLON;
             }
             return this._indexBuffer;
         };
+        Geometry.prototype._releaseVertexArrayObject = function (effect) {
+            if (this._vertexArrayObjects[effect.key]) {
+                this._engine.releaseVertexArrayObject(this._vertexArrayObjects[effect.key]);
+                delete this._vertexArrayObjects[effect.key];
+            }
+        };
         Geometry.prototype.releaseForMesh = function (mesh, shouldDispose) {
             var meshes = this._meshes;
             var index = meshes.indexOf(mesh);
@@ -53484,12 +53516,6 @@ var BABYLON;
         }
         PoseEnabledController.prototype.update = function () {
             _super.prototype.update.call(this);
-            // update this device's offset position from the attached camera, if provided
-            //if (this._poseControlledCamera && this._poseControlledCamera.deviceScaleFactor) {
-            //this.position.copyFrom(this._poseControlledCamera.position);
-            //this.rotationQuaternion.copyFrom(this._poseControlledCamera.rotationQuaternion);
-            //this.deviceScaleFactor = this._poseControlledCamera.deviceScaleFactor;
-            //}
             var pose = this.vrGamepad.pose;
             this.updateFromDevice(pose);
             if (this._mesh) {
@@ -53507,11 +53533,6 @@ var BABYLON;
                     }
                     this.devicePosition.scaleToRef(this.deviceScaleFactor, this._calculatedPosition);
                     this._calculatedPosition.addInPlace(this.position);
-                    // scale the position using the scale factor, add the device's position
-                    /*if (this._poseControlledCamera) {
-                        // this allows total positioning freedom - the device, the camera and the mesh can be individually controlled.
-                        this._calculatedPosition.addInPlace(this._poseControlledCamera.position);
-                    }*/
                 }
                 if (poseData.orientation) {
                     this.deviceRotationQuaternion.copyFromFloats(this.rawPose.orientation[0], this.rawPose.orientation[1], -this.rawPose.orientation[2], -this.rawPose.orientation[3]);
@@ -53526,23 +53547,6 @@ var BABYLON;
                     }
                     // if the camera is set, rotate to the camera's rotation
                     this.deviceRotationQuaternion.multiplyToRef(this.rotationQuaternion, this._calculatedRotation);
-                    /*if (this._poseControlledCamera) {
-                        Matrix.ScalingToRef(1, 1, 1, Tmp.Matrix[1]);
-                        this._calculatedRotation.toRotationMatrix(Tmp.Matrix[0]);
-                        Matrix.TranslationToRef(this._calculatedPosition.x, this._calculatedPosition.y, this._calculatedPosition.z, Tmp.Matrix[2]);
-
-                        //Matrix.Identity().multiplyToRef(Tmp.Matrix[1], Tmp.Matrix[4]);
-                        Tmp.Matrix[1].multiplyToRef(Tmp.Matrix[0], Tmp.Matrix[5]);
-
-                        this._poseControlledCamera.getWorldMatrix().getTranslationToRef(Tmp.Vector3[0])
-
-                        Matrix.ComposeToRef(new Vector3(this.deviceScaleFactor, this.deviceScaleFactor, this.deviceScaleFactor), this._poseControlledCamera.rotationQuaternion, Tmp.Vector3[0], Tmp.Matrix[4]);
-                        Tmp.Matrix[5].multiplyToRef(Tmp.Matrix[2], Tmp.Matrix[1]);
-
-                        Tmp.Matrix[1].multiplyToRef(Tmp.Matrix[4], Tmp.Matrix[2]);
-                        Tmp.Matrix[2].decompose(Tmp.Vector3[0], this._calculatedRotation, this._calculatedPosition);
-
-                    }*/
                 }
             }
         };
@@ -61042,8 +61046,8 @@ var BABYLON;
                 // Colors
                 this._myScene.ambientColor.multiplyToRef(this.ambientColor, this._globalAmbientColor);
                 if (this._defines.METALLICWORKFLOW) {
-                    PBRMaterial._scaledReflectivity.r = this.metallic === undefined ? 1 : this.metallic;
-                    PBRMaterial._scaledReflectivity.g = this.roughness === undefined ? 1 : this.roughness;
+                    PBRMaterial._scaledReflectivity.r = (this.metallic === undefined || this.metallic === null) ? 1 : this.metallic;
+                    PBRMaterial._scaledReflectivity.g = (this.roughness === undefined || this.roughness === null) ? 1 : this.roughness;
                     this._effect.setColor4("vReflectivityColor", PBRMaterial._scaledReflectivity, 0);
                 }
                 else {
@@ -61456,7 +61460,12 @@ var BABYLON;
         };
         DebugLayer.prototype.hide = function () {
             if (this._inspector) {
-                this._inspector.dispose();
+                try {
+                    this._inspector.dispose();
+                }
+                catch (e) {
+                    // If the inspector has been removed directly from the inspector tool
+                }
                 this._inspector = null;
             }
         };

+ 354 - 352
dist/preview release/babylon.module.d.ts

@@ -514,6 +514,7 @@ declare module BABYLON {
         removeExternalData(key: any): boolean;
         releaseInternalTexture(texture: WebGLTexture): void;
         unbindAllAttributes(): void;
+        releaseEffects(): void;
         dispose(): void;
         displayLoadingUI(): void;
         hideLoadingUI(): void;
@@ -3887,6 +3888,111 @@ declare module BABYLON {
     }
 }
 
+declare module BABYLON.Debug {
+    class AxesViewer {
+        private _xline;
+        private _yline;
+        private _zline;
+        private _xmesh;
+        private _ymesh;
+        private _zmesh;
+        scene: Scene;
+        scaleLines: number;
+        constructor(scene: Scene, scaleLines?: number);
+        update(position: Vector3, xaxis: Vector3, yaxis: Vector3, zaxis: Vector3): void;
+        dispose(): void;
+    }
+}
+
+declare module BABYLON.Debug {
+    class BoneAxesViewer extends Debug.AxesViewer {
+        mesh: Mesh;
+        bone: Bone;
+        pos: Vector3;
+        xaxis: Vector3;
+        yaxis: Vector3;
+        zaxis: Vector3;
+        constructor(scene: Scene, bone: Bone, mesh: Mesh, scaleLines?: number);
+        update(): void;
+        dispose(): void;
+    }
+}
+
+declare module BABYLON {
+    class DebugLayer {
+        private _scene;
+        static InspectorURL: string;
+        private _inspector;
+        constructor(scene: Scene);
+        /** Creates the inspector window. */
+        private _createInspector(config?);
+        isVisible(): boolean;
+        hide(): void;
+        show(config?: {
+            popup?: boolean;
+            initialTab?: number;
+            parentElement?: HTMLElement;
+            newColors?: {
+                backgroundColor?: string;
+                backgroundColorLighter?: string;
+                backgroundColorLighter2?: string;
+                backgroundColorLighter3?: string;
+                color?: string;
+                colorTop?: string;
+                colorBot?: string;
+            };
+        }): void;
+    }
+}
+
+declare module BABYLON {
+    class RayHelper {
+        ray: Ray;
+        private _renderPoints;
+        private _renderLine;
+        private _renderFunction;
+        private _scene;
+        private _updateToMeshFunction;
+        private _attachedToMesh;
+        private _meshSpaceDirection;
+        private _meshSpaceOrigin;
+        static CreateAndShow(ray: Ray, scene: Scene, color: Color3): RayHelper;
+        constructor(ray: Ray);
+        show(scene: Scene, color: Color3): void;
+        hide(): void;
+        private _render();
+        attachToMesh(mesh: AbstractMesh, meshSpaceDirection?: Vector3, meshSpaceOrigin?: Vector3, length?: number): void;
+        detachFromMesh(): void;
+        private _updateToMesh();
+        dispose(): void;
+    }
+}
+
+declare module BABYLON.Debug {
+    /**
+    * Demo available here: http://www.babylonjs-playground.com/#1BZJVJ#8
+    */
+    class SkeletonViewer {
+        skeleton: Skeleton;
+        mesh: AbstractMesh;
+        autoUpdateBonesMatrices: boolean;
+        renderingGroupId: number;
+        color: Color3;
+        private _scene;
+        private _debugLines;
+        private _debugMesh;
+        private _isEnabled;
+        private _renderFunction;
+        constructor(skeleton: Skeleton, mesh: AbstractMesh, scene: Scene, autoUpdateBonesMatrices?: boolean, renderingGroupId?: number);
+        isEnabled: boolean;
+        private _getBonePosition(position, bone, meshMat, x?, y?, z?);
+        private _getLinesForBonesWithLength(bones, meshMat);
+        private _getLinesForBonesNoLength(bones, meshMat);
+        update(): void;
+        dispose(): void;
+    }
+}
+
 declare module BABYLON {
     class BoundingBox implements ICullable {
         minimum: Vector3;
@@ -4001,111 +4107,6 @@ declare module BABYLON {
     }
 }
 
-declare module BABYLON.Debug {
-    class AxesViewer {
-        private _xline;
-        private _yline;
-        private _zline;
-        private _xmesh;
-        private _ymesh;
-        private _zmesh;
-        scene: Scene;
-        scaleLines: number;
-        constructor(scene: Scene, scaleLines?: number);
-        update(position: Vector3, xaxis: Vector3, yaxis: Vector3, zaxis: Vector3): void;
-        dispose(): void;
-    }
-}
-
-declare module BABYLON.Debug {
-    class BoneAxesViewer extends Debug.AxesViewer {
-        mesh: Mesh;
-        bone: Bone;
-        pos: Vector3;
-        xaxis: Vector3;
-        yaxis: Vector3;
-        zaxis: Vector3;
-        constructor(scene: Scene, bone: Bone, mesh: Mesh, scaleLines?: number);
-        update(): void;
-        dispose(): void;
-    }
-}
-
-declare module BABYLON {
-    class DebugLayer {
-        private _scene;
-        static InspectorURL: string;
-        private _inspector;
-        constructor(scene: Scene);
-        /** Creates the inspector window. */
-        private _createInspector(config?);
-        isVisible(): boolean;
-        hide(): void;
-        show(config?: {
-            popup?: boolean;
-            initialTab?: number;
-            parentElement?: HTMLElement;
-            newColors?: {
-                backgroundColor?: string;
-                backgroundColorLighter?: string;
-                backgroundColorLighter2?: string;
-                backgroundColorLighter3?: string;
-                color?: string;
-                colorTop?: string;
-                colorBot?: string;
-            };
-        }): void;
-    }
-}
-
-declare module BABYLON {
-    class RayHelper {
-        ray: Ray;
-        private _renderPoints;
-        private _renderLine;
-        private _renderFunction;
-        private _scene;
-        private _updateToMeshFunction;
-        private _attachedToMesh;
-        private _meshSpaceDirection;
-        private _meshSpaceOrigin;
-        static CreateAndShow(ray: Ray, scene: Scene, color: Color3): RayHelper;
-        constructor(ray: Ray);
-        show(scene: Scene, color: Color3): void;
-        hide(): void;
-        private _render();
-        attachToMesh(mesh: AbstractMesh, meshSpaceDirection?: Vector3, meshSpaceOrigin?: Vector3, length?: number): void;
-        detachFromMesh(): void;
-        private _updateToMesh();
-        dispose(): void;
-    }
-}
-
-declare module BABYLON.Debug {
-    /**
-    * Demo available here: http://www.babylonjs-playground.com/#1BZJVJ#8
-    */
-    class SkeletonViewer {
-        skeleton: Skeleton;
-        mesh: AbstractMesh;
-        autoUpdateBonesMatrices: boolean;
-        renderingGroupId: number;
-        color: Color3;
-        private _scene;
-        private _debugLines;
-        private _debugMesh;
-        private _isEnabled;
-        private _renderFunction;
-        constructor(skeleton: Skeleton, mesh: AbstractMesh, scene: Scene, autoUpdateBonesMatrices?: boolean, renderingGroupId?: number);
-        isEnabled: boolean;
-        private _getBonePosition(position, bone, meshMat, x?, y?, z?);
-        private _getLinesForBonesWithLength(bones, meshMat);
-        private _getLinesForBonesNoLength(bones, meshMat);
-        update(): void;
-        dispose(): void;
-    }
-}
-
 declare module BABYLON {
     /**
      * Highlight layer options. This helps customizing the behaviour
@@ -4362,103 +4363,6 @@ declare module BABYLON {
 }
 
 declare module BABYLON {
-    class LensFlare {
-        size: number;
-        position: number;
-        color: Color3;
-        texture: Texture;
-        alphaMode: number;
-        private _system;
-        constructor(size: number, position: number, color: any, imgUrl: string, system: LensFlareSystem);
-        dispose: () => void;
-    }
-}
-
-declare module BABYLON {
-    class LensFlareSystem {
-        name: string;
-        lensFlares: LensFlare[];
-        borderLimit: number;
-        viewportBorder: number;
-        meshesSelectionPredicate: (mesh: Mesh) => boolean;
-        layerMask: number;
-        id: string;
-        private _scene;
-        private _emitter;
-        private _vertexBuffers;
-        private _indexBuffer;
-        private _effect;
-        private _positionX;
-        private _positionY;
-        private _isEnabled;
-        constructor(name: string, emitter: any, scene: Scene);
-        isEnabled: boolean;
-        getScene(): Scene;
-        getEmitter(): any;
-        setEmitter(newEmitter: any): void;
-        getEmitterPosition(): Vector3;
-        computeEffectivePosition(globalViewport: Viewport): boolean;
-        _isVisible(): boolean;
-        render(): boolean;
-        dispose(): void;
-        static Parse(parsedLensFlareSystem: any, scene: Scene, rootUrl: string): LensFlareSystem;
-        serialize(): any;
-    }
-}
-
-declare module BABYLON {
-    interface ISceneLoaderPluginExtensions {
-        [extension: string]: {
-            isBinary: boolean;
-        };
-    }
-    interface ISceneLoaderPlugin {
-        extensions: string | ISceneLoaderPluginExtensions;
-        importMesh: (meshesNames: any, scene: Scene, data: any, rootUrl: string, meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]) => boolean;
-        load: (scene: Scene, data: string, rootUrl: string) => boolean;
-    }
-    interface ISceneLoaderPluginAsync {
-        extensions: string | ISceneLoaderPluginExtensions;
-        importMeshAsync: (meshesNames: any, scene: Scene, data: any, rootUrl: string, onsuccess?: (meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]) => void, onerror?: () => void) => void;
-        loadAsync: (scene: Scene, data: string, rootUrl: string, onsuccess: () => void, onerror: () => void) => boolean;
-    }
-    class SceneLoader {
-        private static _ForceFullSceneLoadingForIncremental;
-        private static _ShowLoadingScreen;
-        static readonly NO_LOGGING: number;
-        static readonly MINIMAL_LOGGING: number;
-        static readonly SUMMARY_LOGGING: number;
-        static readonly DETAILED_LOGGING: number;
-        private static _loggingLevel;
-        static ForceFullSceneLoadingForIncremental: boolean;
-        static ShowLoadingScreen: boolean;
-        static loggingLevel: number;
-        private static _registeredPlugins;
-        private static _getDefaultPlugin();
-        private static _getPluginForExtension(extension);
-        private static _getPluginForFilename(sceneFilename);
-        private static _getDirectLoad(sceneFilename);
-        static GetPluginForExtension(extension: string): ISceneLoaderPlugin | ISceneLoaderPluginAsync;
-        static RegisterPlugin(plugin: ISceneLoaderPlugin | ISceneLoaderPluginAsync): void;
-        static ImportMesh(meshesNames: any, rootUrl: string, sceneFilename: string, scene: Scene, onsuccess?: (meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]) => void, progressCallBack?: () => void, onerror?: (scene: Scene, message: string, exception?: any) => void): void;
-        /**
-        * Load a scene
-        * @param rootUrl a string that defines the root url for scene and resources
-        * @param sceneFilename a string that defines the name of the scene file. can start with "data:" following by the stringified version of the scene
-        * @param engine is the instance of BABYLON.Engine to use to create the scene
-        */
-        static Load(rootUrl: string, sceneFilename: any, engine: Engine, onsuccess?: (scene: Scene) => void, progressCallBack?: any, onerror?: (scene: Scene) => void): void;
-        /**
-        * Append a scene
-        * @param rootUrl a string that defines the root url for scene and resources
-        * @param sceneFilename a string that defines the name of the scene file. can start with "data:" following by the stringified version of the scene
-        * @param scene is the instance of BABYLON.Scene to append to
-        */
-        static Append(rootUrl: string, sceneFilename: any, scene: Scene, onsuccess?: (scene: Scene) => void, progressCallBack?: any, onerror?: (scene: Scene) => void): void;
-    }
-}
-
-declare module BABYLON {
     class DirectionalLight extends Light implements IShadowLight {
         position: Vector3;
         direction: Vector3;
@@ -4844,6 +4748,103 @@ declare module BABYLON {
 }
 
 declare module BABYLON {
+    class LensFlare {
+        size: number;
+        position: number;
+        color: Color3;
+        texture: Texture;
+        alphaMode: number;
+        private _system;
+        constructor(size: number, position: number, color: any, imgUrl: string, system: LensFlareSystem);
+        dispose: () => void;
+    }
+}
+
+declare module BABYLON {
+    class LensFlareSystem {
+        name: string;
+        lensFlares: LensFlare[];
+        borderLimit: number;
+        viewportBorder: number;
+        meshesSelectionPredicate: (mesh: Mesh) => boolean;
+        layerMask: number;
+        id: string;
+        private _scene;
+        private _emitter;
+        private _vertexBuffers;
+        private _indexBuffer;
+        private _effect;
+        private _positionX;
+        private _positionY;
+        private _isEnabled;
+        constructor(name: string, emitter: any, scene: Scene);
+        isEnabled: boolean;
+        getScene(): Scene;
+        getEmitter(): any;
+        setEmitter(newEmitter: any): void;
+        getEmitterPosition(): Vector3;
+        computeEffectivePosition(globalViewport: Viewport): boolean;
+        _isVisible(): boolean;
+        render(): boolean;
+        dispose(): void;
+        static Parse(parsedLensFlareSystem: any, scene: Scene, rootUrl: string): LensFlareSystem;
+        serialize(): any;
+    }
+}
+
+declare module BABYLON {
+    interface ISceneLoaderPluginExtensions {
+        [extension: string]: {
+            isBinary: boolean;
+        };
+    }
+    interface ISceneLoaderPlugin {
+        extensions: string | ISceneLoaderPluginExtensions;
+        importMesh: (meshesNames: any, scene: Scene, data: any, rootUrl: string, meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]) => boolean;
+        load: (scene: Scene, data: string, rootUrl: string) => boolean;
+    }
+    interface ISceneLoaderPluginAsync {
+        extensions: string | ISceneLoaderPluginExtensions;
+        importMeshAsync: (meshesNames: any, scene: Scene, data: any, rootUrl: string, onsuccess: (meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]) => void, onerror: () => void) => void;
+        loadAsync: (scene: Scene, data: string, rootUrl: string, onsuccess: () => void, onerror: () => void) => void;
+    }
+    class SceneLoader {
+        private static _ForceFullSceneLoadingForIncremental;
+        private static _ShowLoadingScreen;
+        static readonly NO_LOGGING: number;
+        static readonly MINIMAL_LOGGING: number;
+        static readonly SUMMARY_LOGGING: number;
+        static readonly DETAILED_LOGGING: number;
+        private static _loggingLevel;
+        static ForceFullSceneLoadingForIncremental: boolean;
+        static ShowLoadingScreen: boolean;
+        static loggingLevel: number;
+        private static _registeredPlugins;
+        private static _getDefaultPlugin();
+        private static _getPluginForExtension(extension);
+        private static _getPluginForFilename(sceneFilename);
+        private static _getDirectLoad(sceneFilename);
+        static GetPluginForExtension(extension: string): ISceneLoaderPlugin | ISceneLoaderPluginAsync;
+        static RegisterPlugin(plugin: ISceneLoaderPlugin | ISceneLoaderPluginAsync): void;
+        static ImportMesh(meshesNames: any, rootUrl: string, sceneFilename: string, scene: Scene, onsuccess?: (meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]) => void, progressCallBack?: () => void, onerror?: (scene: Scene, message: string, exception?: any) => void): void;
+        /**
+        * Load a scene
+        * @param rootUrl a string that defines the root url for scene and resources
+        * @param sceneFilename a string that defines the name of the scene file. can start with "data:" following by the stringified version of the scene
+        * @param engine is the instance of BABYLON.Engine to use to create the scene
+        */
+        static Load(rootUrl: string, sceneFilename: any, engine: Engine, onsuccess?: (scene: Scene) => void, progressCallBack?: any, onerror?: (scene: Scene) => void): void;
+        /**
+        * Append a scene
+        * @param rootUrl a string that defines the root url for scene and resources
+        * @param sceneFilename a string that defines the name of the scene file. can start with "data:" following by the stringified version of the scene
+        * @param scene is the instance of BABYLON.Scene to append to
+        */
+        static Append(rootUrl: string, sceneFilename: any, scene: Scene, onsuccess?: (scene: Scene) => void, progressCallBack?: any, onerror?: (scene: Scene) => void): void;
+    }
+}
+
+declare module BABYLON {
     /**
      * The color grading curves provide additional color adjustmnent that is applied after any color grading transform (3D LUT).
      * They allow basic adjustment of saturation and small exposure adjustments, along with color filter tinting to provide white balance adjustment or more stylistic effects.
@@ -8778,6 +8779,7 @@ declare module BABYLON {
         getTotalIndices(): number;
         getIndices(copyWhenShared?: boolean): IndicesArray;
         getIndexBuffer(): WebGLBuffer;
+        _releaseVertexArrayObject(effect: Effect): void;
         releaseForMesh(mesh: Mesh, shouldDispose?: boolean): void;
         applyToMesh(mesh: Mesh): void;
         private updateExtend(data?, stride?);
@@ -11036,7 +11038,7 @@ declare module BABYLON {
         _distanceToCamera: number;
         _id: number;
         _materialDefines: MaterialDefines;
-        private _materialEffect;
+        _materialEffect: Effect;
         private _currentMaterial;
         readonly effect: Effect;
         setEffect(effect: Effect, defines?: MaterialDefines): void;
@@ -12087,29 +12089,6 @@ declare module BABYLON {
 }
 
 declare module BABYLON {
-    class ReflectionProbe {
-        name: string;
-        private _scene;
-        private _renderTargetTexture;
-        private _projectionMatrix;
-        private _viewMatrix;
-        private _target;
-        private _add;
-        private _attachedMesh;
-        invertYAxis: boolean;
-        position: Vector3;
-        constructor(name: string, size: number, scene: Scene, generateMipMaps?: boolean);
-        samples: number;
-        refreshRate: number;
-        getScene(): Scene;
-        readonly cubeTexture: RenderTargetTexture;
-        readonly renderList: AbstractMesh[];
-        attachToMesh(mesh: AbstractMesh): void;
-        dispose(): void;
-    }
-}
-
-declare module BABYLON {
     class AnaglyphPostProcess extends PostProcess {
         private _passedProcess;
         constructor(name: string, options: number | PostProcessOptions, rigCameras: Camera[], samplingMode?: number, engine?: Engine, reusable?: boolean);
@@ -12783,6 +12762,29 @@ declare module BABYLON {
 }
 
 declare module BABYLON {
+    class ReflectionProbe {
+        name: string;
+        private _scene;
+        private _renderTargetTexture;
+        private _projectionMatrix;
+        private _viewMatrix;
+        private _target;
+        private _add;
+        private _attachedMesh;
+        invertYAxis: boolean;
+        position: Vector3;
+        constructor(name: string, size: number, scene: Scene, generateMipMaps?: boolean);
+        samples: number;
+        refreshRate: number;
+        getScene(): Scene;
+        readonly cubeTexture: RenderTargetTexture;
+        readonly renderList: AbstractMesh[];
+        attachToMesh(mesh: AbstractMesh): void;
+        dispose(): void;
+    }
+}
+
+declare module BABYLON {
     class BoundingBoxRenderer {
         frontColor: Color3;
         backColor: Color3;
@@ -14484,6 +14486,129 @@ declare module BABYLON {
 }
 
 declare module BABYLON {
+    class VRCameraMetrics {
+        hResolution: number;
+        vResolution: number;
+        hScreenSize: number;
+        vScreenSize: number;
+        vScreenCenter: number;
+        eyeToScreenDistance: number;
+        lensSeparationDistance: number;
+        interpupillaryDistance: number;
+        distortionK: number[];
+        chromaAbCorrection: number[];
+        postProcessScaleFactor: number;
+        lensCenterOffset: number;
+        compensateDistortion: boolean;
+        readonly aspectRatio: number;
+        readonly aspectRatioFov: number;
+        readonly leftHMatrix: Matrix;
+        readonly rightHMatrix: Matrix;
+        readonly leftPreViewMatrix: Matrix;
+        readonly rightPreViewMatrix: Matrix;
+        static GetDefault(): VRCameraMetrics;
+    }
+}
+
+declare module BABYLON {
+    class VRDeviceOrientationFreeCamera extends DeviceOrientationCamera {
+        constructor(name: string, position: Vector3, scene: Scene, compensateDistortion?: boolean, vrCameraMetrics?: VRCameraMetrics);
+        getClassName(): string;
+    }
+    class VRDeviceOrientationGamepadCamera extends VRDeviceOrientationFreeCamera {
+        constructor(name: string, position: Vector3, scene: Scene, compensateDistortion?: boolean, vrCameraMetrics?: VRCameraMetrics);
+        getClassName(): string;
+    }
+    class VRDeviceOrientationArcRotateCamera extends ArcRotateCamera {
+        constructor(name: string, alpha: number, beta: number, radius: number, target: Vector3, scene: Scene, compensateDistortion?: boolean, vrCameraMetrics?: VRCameraMetrics);
+        getClassName(): string;
+    }
+}
+
+declare var HMDVRDevice: any;
+declare var VRDisplay: any;
+declare var VRFrameData: any;
+declare module BABYLON {
+    /**
+     * This is a copy of VRPose.
+     * IMPORTANT!! The data is right-hand data.
+     * @export
+     * @interface DevicePose
+     */
+    interface DevicePose {
+        readonly position?: Float32Array;
+        readonly linearVelocity?: Float32Array;
+        readonly linearAcceleration?: Float32Array;
+        readonly orientation?: Float32Array;
+        readonly angularVelocity?: Float32Array;
+        readonly angularAcceleration?: Float32Array;
+    }
+    interface PoseControlled {
+        position: Vector3;
+        rotationQuaternion: Quaternion;
+        devicePosition?: Vector3;
+        deviceRotationQuaternion: Quaternion;
+        rawPose: DevicePose;
+        deviceScaleFactor: number;
+        updateFromDevice(poseData: DevicePose): any;
+    }
+    interface WebVROptions {
+        trackPosition?: boolean;
+        positionScale?: number;
+        displayName?: string;
+        controllerMeshes?: boolean;
+        defaultLightningOnControllers?: boolean;
+    }
+    class WebVRFreeCamera extends FreeCamera implements PoseControlled {
+        private webVROptions;
+        _vrDevice: any;
+        rawPose: DevicePose;
+        private _vrEnabled;
+        private _specsVersion;
+        private _attached;
+        private _oldSize;
+        private _oldHardwareScaleFactor;
+        private _frameData;
+        private _quaternionCache;
+        private _positionOffset;
+        protected _descendants: Array<Node>;
+        devicePosition: Vector3;
+        deviceRotationQuaternion: any;
+        deviceScaleFactor: number;
+        controllers: Array<WebVRController>;
+        onControllersAttached: (controllers: Array<WebVRController>) => void;
+        rigParenting: boolean;
+        private _lightOnControllers;
+        constructor(name: string, position: Vector3, scene: Scene, webVROptions?: WebVROptions);
+        _checkInputs(): void;
+        updateFromDevice(poseData: DevicePose): void;
+        /**
+         * WebVR's attach control will start broadcasting frames to the device.
+         * Note that in certain browsers (chrome for example) this function must be called
+         * within a user-interaction callback. Example:
+         * <pre> scene.onPointerDown = function() { camera.attachControl(canvas); }</pre>
+         *
+         * @param {HTMLElement} element
+         * @param {boolean} [noPreventDefault]
+         *
+         * @memberOf WebVRFreeCamera
+         */
+        attachControl(element: HTMLElement, noPreventDefault?: boolean): void;
+        detachControl(element: HTMLElement): void;
+        getClassName(): string;
+        resetToCurrentRotation(): void;
+        _updateRigCameras(): void;
+        /**
+         * This function is called by the two RIG cameras.
+         * 'this' is the left or right camera (and NOT (!!!) the WebVRFreeCamera instance)
+         */
+        protected _getWebVRViewMatrix(): Matrix;
+        protected _getWebVRProjectionMatrix(): Matrix;
+        initControllers(): void;
+    }
+}
+
+declare module BABYLON {
     class ArcRotateCameraGamepadInput implements ICameraInput<ArcRotateCamera> {
         camera: ArcRotateCamera;
         gamepad: Gamepad;
@@ -14694,129 +14819,6 @@ declare module BABYLON {
 }
 
 declare module BABYLON {
-    class VRCameraMetrics {
-        hResolution: number;
-        vResolution: number;
-        hScreenSize: number;
-        vScreenSize: number;
-        vScreenCenter: number;
-        eyeToScreenDistance: number;
-        lensSeparationDistance: number;
-        interpupillaryDistance: number;
-        distortionK: number[];
-        chromaAbCorrection: number[];
-        postProcessScaleFactor: number;
-        lensCenterOffset: number;
-        compensateDistortion: boolean;
-        readonly aspectRatio: number;
-        readonly aspectRatioFov: number;
-        readonly leftHMatrix: Matrix;
-        readonly rightHMatrix: Matrix;
-        readonly leftPreViewMatrix: Matrix;
-        readonly rightPreViewMatrix: Matrix;
-        static GetDefault(): VRCameraMetrics;
-    }
-}
-
-declare module BABYLON {
-    class VRDeviceOrientationFreeCamera extends DeviceOrientationCamera {
-        constructor(name: string, position: Vector3, scene: Scene, compensateDistortion?: boolean, vrCameraMetrics?: VRCameraMetrics);
-        getClassName(): string;
-    }
-    class VRDeviceOrientationGamepadCamera extends VRDeviceOrientationFreeCamera {
-        constructor(name: string, position: Vector3, scene: Scene, compensateDistortion?: boolean, vrCameraMetrics?: VRCameraMetrics);
-        getClassName(): string;
-    }
-    class VRDeviceOrientationArcRotateCamera extends ArcRotateCamera {
-        constructor(name: string, alpha: number, beta: number, radius: number, target: Vector3, scene: Scene, compensateDistortion?: boolean, vrCameraMetrics?: VRCameraMetrics);
-        getClassName(): string;
-    }
-}
-
-declare var HMDVRDevice: any;
-declare var VRDisplay: any;
-declare var VRFrameData: any;
-declare module BABYLON {
-    /**
-     * This is a copy of VRPose.
-     * IMPORTANT!! The data is right-hand data.
-     * @export
-     * @interface DevicePose
-     */
-    interface DevicePose {
-        readonly position?: Float32Array;
-        readonly linearVelocity?: Float32Array;
-        readonly linearAcceleration?: Float32Array;
-        readonly orientation?: Float32Array;
-        readonly angularVelocity?: Float32Array;
-        readonly angularAcceleration?: Float32Array;
-    }
-    interface PoseControlled {
-        position: Vector3;
-        rotationQuaternion: Quaternion;
-        devicePosition?: Vector3;
-        deviceRotationQuaternion: Quaternion;
-        rawPose: DevicePose;
-        deviceScaleFactor: number;
-        updateFromDevice(poseData: DevicePose): any;
-    }
-    interface WebVROptions {
-        trackPosition?: boolean;
-        positionScale?: number;
-        displayName?: string;
-        controllerMeshes?: boolean;
-        defaultLightningOnControllers?: boolean;
-    }
-    class WebVRFreeCamera extends FreeCamera implements PoseControlled {
-        private webVROptions;
-        _vrDevice: any;
-        rawPose: DevicePose;
-        private _vrEnabled;
-        private _specsVersion;
-        private _attached;
-        private _oldSize;
-        private _oldHardwareScaleFactor;
-        private _frameData;
-        private _quaternionCache;
-        private _positionOffset;
-        protected _descendants: Array<Node>;
-        devicePosition: Vector3;
-        deviceRotationQuaternion: any;
-        deviceScaleFactor: number;
-        controllers: Array<WebVRController>;
-        onControllersAttached: (controllers: Array<WebVRController>) => void;
-        rigParenting: boolean;
-        private _lightOnControllers;
-        constructor(name: string, position: Vector3, scene: Scene, webVROptions?: WebVROptions);
-        _checkInputs(): void;
-        updateFromDevice(poseData: DevicePose): void;
-        /**
-         * WebVR's attach control will start broadcasting frames to the device.
-         * Note that in certain browsers (chrome for example) this function must be called
-         * within a user-interaction callback. Example:
-         * <pre> scene.onPointerDown = function() { camera.attachControl(canvas); }</pre>
-         *
-         * @param {HTMLElement} element
-         * @param {boolean} [noPreventDefault]
-         *
-         * @memberOf WebVRFreeCamera
-         */
-        attachControl(element: HTMLElement, noPreventDefault?: boolean): void;
-        detachControl(element: HTMLElement): void;
-        getClassName(): string;
-        resetToCurrentRotation(): void;
-        _updateRigCameras(): void;
-        /**
-         * This function is called by the two RIG cameras.
-         * 'this' is the left or right camera (and NOT (!!!) the WebVRFreeCamera instance)
-         */
-        protected _getWebVRViewMatrix(): Matrix;
-        protected _getWebVRProjectionMatrix(): Matrix;
-        initControllers(): void;
-    }
-}
-
-declare module BABYLON {
     interface IOctreeContainer<T> {
         blocks: Array<OctreeBlock<T>>;
     }
@@ -14863,9 +14865,6 @@ declare module BABYLON {
     }
 }
 
-declare module BABYLON.Internals {
-}
-
 declare module BABYLON {
     interface IShadowGenerator {
         getShadowMap(): RenderTargetTexture;
@@ -14979,6 +14978,9 @@ declare module BABYLON {
     }
 }
 
+declare module BABYLON.Internals {
+}
+
 declare module BABYLON {
     class BaseTexture {
         name: string;

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 32 - 32
dist/preview release/babylon.noworker.js


+ 5 - 5
dist/preview release/loaders/babylon.glTF1FileLoader.d.ts

@@ -5,8 +5,8 @@ declare module BABYLON {
         bin: ArrayBufferView;
     }
     interface IGLTFLoader {
-        importMeshAsync: (meshesNames: any, scene: Scene, data: IGLTFLoaderData, rootUrl: string, onsuccess?: (meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]) => void, onerror?: () => void) => boolean;
-        loadAsync: (scene: Scene, data: IGLTFLoaderData, rootUrl: string, onsuccess: () => void, onerror: () => void) => boolean;
+        importMeshAsync: (meshesNames: any, scene: Scene, data: IGLTFLoaderData, rootUrl: string, onsuccess: (meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]) => void, onerror: () => void) => void;
+        loadAsync: (scene: Scene, data: IGLTFLoaderData, rootUrl: string, onsuccess: () => void, onerror: () => void) => void;
     }
     class GLTFFileLoader implements ISceneLoaderPluginAsync {
         static GLTFLoaderV1: IGLTFLoader;
@@ -14,8 +14,8 @@ declare module BABYLON {
         static HomogeneousCoordinates: boolean;
         static IncrementalLoading: boolean;
         extensions: ISceneLoaderPluginExtensions;
-        importMeshAsync(meshesNames: any, scene: Scene, data: any, rootUrl: string, onSuccess?: (meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]) => void, onError?: () => void): boolean;
-        loadAsync(scene: Scene, data: string | ArrayBuffer, rootUrl: string, onSuccess: () => void, onError: () => void): boolean;
+        importMeshAsync(meshesNames: any, scene: Scene, data: any, rootUrl: string, onSuccess: (meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]) => void, onError: () => void): void;
+        loadAsync(scene: Scene, data: string | ArrayBuffer, rootUrl: string, onSuccess: () => void, onError: () => void): void;
         private static _parse(data);
         private _getLoader(loaderData);
         private static _parseBinary(data);
@@ -370,7 +370,7 @@ declare module BABYLON.GLTF1 {
         };
         static RegisterExtension(extension: GLTFLoaderExtension): void;
         importMeshAsync(meshesNames: any, scene: Scene, data: IGLTFLoaderData, rootUrl: string, onSuccess?: (meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]) => void, onError?: () => void, onProgress?: () => void): boolean;
-        loadAsync(scene: Scene, data: IGLTFLoaderData, rootUrl: string, onSuccess: () => void, onError: () => void): boolean;
+        loadAsync(scene: Scene, data: IGLTFLoaderData, rootUrl: string, onSuccess: () => void, onError: () => void): void;
         private _loadShadersAsync(gltfRuntime, onload);
         private _loadBuffersAsync(gltfRuntime, onload, onProgress?);
         private _createNodes(gltfRuntime);

+ 5 - 4
dist/preview release/loaders/babylon.glTF1FileLoader.js

@@ -12,15 +12,17 @@ var BABYLON;
             var loaderData = GLTFFileLoader._parse(data);
             var loader = this._getLoader(loaderData);
             if (!loader) {
-                return false;
+                onError();
+                return;
             }
-            return loader.importMeshAsync(meshesNames, scene, loaderData, rootUrl, onSuccess, onError);
+            loader.importMeshAsync(meshesNames, scene, loaderData, rootUrl, onSuccess, onError);
         };
         GLTFFileLoader.prototype.loadAsync = function (scene, data, rootUrl, onSuccess, onError) {
             var loaderData = GLTFFileLoader._parse(data);
             var loader = this._getLoader(loaderData);
             if (!loader) {
-                return false;
+                onError();
+                return;
             }
             return loader.loadAsync(scene, loaderData, rootUrl, onSuccess, onError);
         };
@@ -1662,7 +1664,6 @@ var BABYLON;
                         }
                     }, onError);
                 }, onError);
-                return true;
             };
             GLTFLoader.prototype._loadShadersAsync = function (gltfRuntime, onload) {
                 var hasShaders = false;

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 1 - 1
dist/preview release/loaders/babylon.glTF1FileLoader.min.js


+ 20 - 18
dist/preview release/loaders/babylon.glTF2FileLoader.d.ts

@@ -5,8 +5,8 @@ declare module BABYLON {
         bin: ArrayBufferView;
     }
     interface IGLTFLoader {
-        importMeshAsync: (meshesNames: any, scene: Scene, data: IGLTFLoaderData, rootUrl: string, onsuccess?: (meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]) => void, onerror?: () => void) => boolean;
-        loadAsync: (scene: Scene, data: IGLTFLoaderData, rootUrl: string, onsuccess: () => void, onerror: () => void) => boolean;
+        importMeshAsync: (meshesNames: any, scene: Scene, data: IGLTFLoaderData, rootUrl: string, onsuccess: (meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]) => void, onerror: () => void) => void;
+        loadAsync: (scene: Scene, data: IGLTFLoaderData, rootUrl: string, onsuccess: () => void, onerror: () => void) => void;
     }
     class GLTFFileLoader implements ISceneLoaderPluginAsync {
         static GLTFLoaderV1: IGLTFLoader;
@@ -14,8 +14,8 @@ declare module BABYLON {
         static HomogeneousCoordinates: boolean;
         static IncrementalLoading: boolean;
         extensions: ISceneLoaderPluginExtensions;
-        importMeshAsync(meshesNames: any, scene: Scene, data: any, rootUrl: string, onSuccess?: (meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]) => void, onError?: () => void): boolean;
-        loadAsync(scene: Scene, data: string | ArrayBuffer, rootUrl: string, onSuccess: () => void, onError: () => void): boolean;
+        importMeshAsync(meshesNames: any, scene: Scene, data: any, rootUrl: string, onSuccess: (meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]) => void, onError: () => void): void;
+        loadAsync(scene: Scene, data: string | ArrayBuffer, rootUrl: string, onSuccess: () => void, onError: () => void): void;
         private static _parse(data);
         private _getLoader(loaderData);
         private static _parseBinary(data);
@@ -78,11 +78,11 @@ declare module BABYLON.GLTF2 {
     }
     enum ETextureMagFilter {
         NEAREST = 9728,
-        LINEAR = 9728,
+        LINEAR = 9729,
     }
     enum ETextureMinFilter {
         NEAREST = 9728,
-        LINEAR = 9728,
+        LINEAR = 9729,
         NEAREST_MIPMAP_NEAREST = 9984,
         LINEAR_MIPMAP_NEAREST = 9985,
         NEAREST_MIPMAP_LINEAR = 9986,
@@ -276,7 +276,8 @@ declare module BABYLON.GLTF2 {
         source: number;
         target?: ETextureTarget;
         type?: ETextureType;
-        babylonTexture?: Texture;
+        babylonTextures: Texture[];
+        blobURL: string;
     }
     interface IGLTFTextureInfo {
         index: number;
@@ -335,22 +336,23 @@ declare module BABYLON.GLTF2 {
         };
         static RegisterExtension(extension: GLTFLoaderExtension): void;
         static LoadMaterial(runtime: IGLTFRuntime, index: number): IGLTFMaterial;
-        static LoadMetallicRoughnessMaterialProperties: (runtime: IGLTFRuntime, material: IGLTFMaterial) => void;
-        static LoadCommonMaterialProperties(runtime: IGLTFRuntime, material: IGLTFMaterial): void;
+        static LoadMetallicRoughnessMaterialPropertiesAsync(runtime: IGLTFRuntime, material: IGLTFMaterial, onSuccess: () => void, onError: () => void): void;
+        static LoadCommonMaterialPropertiesAsync(runtime: IGLTFRuntime, material: IGLTFMaterial, onSuccess: () => void, onError: () => void): void;
         static LoadAlphaProperties(runtime: IGLTFRuntime, material: IGLTFMaterial): void;
         static LoadTextureAsync(runtime: IGLTFRuntime, textureInfo: IGLTFTextureInfo, onSuccess: (babylonTexture: Texture) => void, onError: () => void): void;
-        static CreateTextureAsync(runtime: IGLTFRuntime, textureInfo: IGLTFTextureInfo, buffer: ArrayBufferView, mimeType: string, onSuccess: (babylonTexture: Texture) => void, onError: () => void): void;
+        private static _createTextureAsync(runtime, texture, texCoord, url, onSuccess, onError);
         /**
         * Import meshes
         */
-        importMeshAsync(meshesNames: any, scene: Scene, data: IGLTFLoaderData, rootUrl: string, onSuccess?: (meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]) => void, onError?: () => void): boolean;
+        importMeshAsync(meshesNames: any, scene: Scene, data: IGLTFLoaderData, rootUrl: string, onSuccess?: (meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]) => void, onError?: () => void): void;
         /**
         * Load scene
         */
-        loadAsync(scene: Scene, data: IGLTFLoaderData, rootUrl: string, onSuccess: () => void, onError: () => void): boolean;
-        private _loadBuffersAsync(runtime, onSuccess, onError);
-        private _loadBufferAsync(runtime, index, onSuccess, onError);
-        private _createRuntime(scene, data, rootUrl, importOnlyMeshes);
+        loadAsync(scene: Scene, data: IGLTFLoaderData, rootUrl: string, onSuccess: () => void, onError: () => void): void;
+        private static _loadBuffersAsync(runtime, onSuccess, onError);
+        private static _loadBufferAsync(runtime, index, onSuccess, onError);
+        private static _loadMaterialsAsync(runtime, onSuccess, onError);
+        private static _createRuntime(scene, data, rootUrl, importOnlyMeshes);
     }
 }
 
@@ -412,9 +414,9 @@ declare module BABYLON.GLTF2 {
         constructor(name: string);
         readonly name: string;
         protected postCreateRuntime(runtime: IGLTFRuntime): void;
-        protected loadMaterial(runtime: IGLTFRuntime, index: number): boolean;
+        protected loadMaterialAsync(runtime: IGLTFRuntime, index: number, onSuccess: () => void, onError: () => void): boolean;
         static PostCreateRuntime(runtime: IGLTFRuntime): void;
-        static LoadMaterial(runtime: IGLTFRuntime, index: number): void;
+        static LoadMaterialAsync(runtime: IGLTFRuntime, index: number, onSuccess: () => void, onError: () => void): void;
     }
 }
 
@@ -422,6 +424,6 @@ declare module BABYLON.GLTF2 {
 declare module BABYLON.GLTF2 {
     class GLTFMaterialsPbrSpecularGlossinessExtension extends GLTFLoaderExtension {
         constructor();
-        protected loadMaterial(runtime: IGLTFRuntime, index: number): boolean;
+        protected loadMaterialAsync(runtime: IGLTFRuntime, index: number, onSuccess: () => void, onError: () => void): boolean;
     }
 }

+ 220 - 116
dist/preview release/loaders/babylon.glTF2FileLoader.js

@@ -12,15 +12,17 @@ var BABYLON;
             var loaderData = GLTFFileLoader._parse(data);
             var loader = this._getLoader(loaderData);
             if (!loader) {
-                return false;
+                onError();
+                return;
             }
-            return loader.importMeshAsync(meshesNames, scene, loaderData, rootUrl, onSuccess, onError);
+            loader.importMeshAsync(meshesNames, scene, loaderData, rootUrl, onSuccess, onError);
         };
         GLTFFileLoader.prototype.loadAsync = function (scene, data, rootUrl, onSuccess, onError) {
             var loaderData = GLTFFileLoader._parse(data);
             var loader = this._getLoader(loaderData);
             if (!loader) {
-                return false;
+                onError();
+                return;
             }
             return loader.loadAsync(scene, loaderData, rootUrl, onSuccess, onError);
         };
@@ -284,12 +286,12 @@ var BABYLON;
         var ETextureMagFilter;
         (function (ETextureMagFilter) {
             ETextureMagFilter[ETextureMagFilter["NEAREST"] = 9728] = "NEAREST";
-            ETextureMagFilter[ETextureMagFilter["LINEAR"] = 9728] = "LINEAR";
+            ETextureMagFilter[ETextureMagFilter["LINEAR"] = 9729] = "LINEAR";
         })(ETextureMagFilter = GLTF2.ETextureMagFilter || (GLTF2.ETextureMagFilter = {}));
         var ETextureMinFilter;
         (function (ETextureMinFilter) {
             ETextureMinFilter[ETextureMinFilter["NEAREST"] = 9728] = "NEAREST";
-            ETextureMinFilter[ETextureMinFilter["LINEAR"] = 9728] = "LINEAR";
+            ETextureMinFilter[ETextureMinFilter["LINEAR"] = 9729] = "LINEAR";
             ETextureMinFilter[ETextureMinFilter["NEAREST_MIPMAP_NEAREST"] = 9984] = "NEAREST_MIPMAP_NEAREST";
             ETextureMinFilter[ETextureMinFilter["LINEAR_MIPMAP_NEAREST"] = 9985] = "LINEAR_MIPMAP_NEAREST";
             ETextureMinFilter[ETextureMinFilter["NEAREST_MIPMAP_LINEAR"] = 9986] = "NEAREST_MIPMAP_LINEAR";
@@ -983,11 +985,11 @@ var BABYLON;
                 var skeleton = runtime.babylonScene.skeletons[i];
                 runtime.babylonScene.beginAnimation(skeleton, 0, Number.MAX_VALUE, true, 1.0);
             }
-        };
-        var importMaterials = function (runtime) {
-            if (runtime.gltf.materials) {
-                for (var i = 0; i < runtime.gltf.materials.length; i++) {
-                    GLTF2.GLTFLoaderExtension.LoadMaterial(runtime, i);
+            // Revoke object urls created during load
+            for (var i = 0; i < runtime.gltf.textures.length; i++) {
+                var texture = runtime.gltf.textures[i];
+                if (texture.blobURL) {
+                    URL.revokeObjectURL(texture.blobURL);
                 }
             }
         };
@@ -1040,14 +1042,92 @@ var BABYLON;
                 material.babylonMaterial.useScalarInLinearSpace = true;
                 return material;
             };
-            GLTFLoader.LoadCommonMaterialProperties = function (runtime, material) {
+            GLTFLoader.LoadMetallicRoughnessMaterialPropertiesAsync = function (runtime, material, onSuccess, onError) {
+                // Ensure metallic workflow
+                material.babylonMaterial.metallic = 1;
+                material.babylonMaterial.roughness = 1;
+                var properties = material.pbrMetallicRoughness;
+                if (!properties) {
+                    onSuccess();
+                    return;
+                }
+                //
+                // Load Factors
+                //
+                material.babylonMaterial.albedoColor = properties.baseColorFactor ? BABYLON.Color3.FromArray(properties.baseColorFactor) : new BABYLON.Color3(1, 1, 1);
+                material.babylonMaterial.metallic = properties.metallicFactor || 1;
+                material.babylonMaterial.roughness = properties.roughnessFactor || 1;
+                //
+                // Load Textures
+                //
+                if (!properties.baseColorTexture && !properties.metallicRoughnessTexture) {
+                    onSuccess();
+                    return;
+                }
+                var checkSuccess = function () {
+                    if ((!properties.baseColorTexture || material.babylonMaterial.albedoTexture) &&
+                        (!properties.metallicRoughnessTexture || material.babylonMaterial.metallicTexture)) {
+                        onSuccess();
+                    }
+                };
+                if (properties.baseColorTexture) {
+                    GLTFLoader.LoadTextureAsync(runtime, properties.baseColorTexture, function (texture) {
+                        material.babylonMaterial.albedoTexture = texture;
+                        GLTFLoader.LoadAlphaProperties(runtime, material);
+                        checkSuccess();
+                    }, function () {
+                        BABYLON.Tools.Error("Failed to load base color texture");
+                        onError();
+                    });
+                }
+                if (properties.metallicRoughnessTexture) {
+                    GLTFLoader.LoadTextureAsync(runtime, properties.metallicRoughnessTexture, function (texture) {
+                        material.babylonMaterial.metallicTexture = texture;
+                        material.babylonMaterial.useMetallnessFromMetallicTextureBlue = true;
+                        material.babylonMaterial.useRoughnessFromMetallicTextureGreen = true;
+                        material.babylonMaterial.useRoughnessFromMetallicTextureAlpha = false;
+                        checkSuccess();
+                    }, function () {
+                        BABYLON.Tools.Error("Failed to load metallic roughness texture");
+                        onError();
+                    });
+                }
+            };
+            GLTFLoader.LoadCommonMaterialPropertiesAsync = function (runtime, material, onSuccess, onError) {
+                //
+                // Load Factors
+                //
+                material.babylonMaterial.useEmissiveAsIllumination = (material.emissiveFactor || material.emissiveTexture) ? true : false;
+                material.babylonMaterial.emissiveColor = material.emissiveFactor ? BABYLON.Color3.FromArray(material.emissiveFactor) : new BABYLON.Color3(0, 0, 0);
+                if (material.doubleSided) {
+                    material.babylonMaterial.backFaceCulling = false;
+                    material.babylonMaterial.twoSidedLighting = true;
+                }
+                //
+                // Load Textures
+                //
+                if (!material.normalTexture && !material.occlusionTexture && !material.emissiveTexture) {
+                    onSuccess();
+                    return;
+                }
+                var checkSuccess = function () {
+                    if ((!material.normalTexture || material.babylonMaterial.bumpTexture) &&
+                        (!material.occlusionTexture || material.babylonMaterial.ambientTexture) &&
+                        (!material.emissiveTexture || material.babylonMaterial.emissiveTexture)) {
+                        onSuccess();
+                    }
+                };
                 if (material.normalTexture) {
                     GLTFLoader.LoadTextureAsync(runtime, material.normalTexture, function (babylonTexture) {
                         material.babylonMaterial.bumpTexture = babylonTexture;
                         if (material.normalTexture.scale !== undefined) {
                             material.babylonMaterial.bumpTexture.level = material.normalTexture.scale;
                         }
-                    }, function () { return BABYLON.Tools.Warn("Failed to load normal texture"); });
+                        checkSuccess();
+                    }, function () {
+                        BABYLON.Tools.Error("Failed to load normal texture");
+                        onError();
+                    });
                 }
                 if (material.occlusionTexture) {
                     GLTFLoader.LoadTextureAsync(runtime, material.occlusionTexture, function (babylonTexture) {
@@ -1056,18 +1136,20 @@ var BABYLON;
                         if (material.occlusionTexture.strength !== undefined) {
                             material.babylonMaterial.ambientTextureStrength = material.occlusionTexture.strength;
                         }
-                    }, function () { return BABYLON.Tools.Warn("Failed to load occlusion texture"); });
+                        checkSuccess();
+                    }, function () {
+                        BABYLON.Tools.Error("Failed to load occlusion texture");
+                        onError();
+                    });
                 }
-                material.babylonMaterial.useEmissiveAsIllumination = (material.emissiveFactor || material.emissiveTexture) ? true : false;
-                material.babylonMaterial.emissiveColor = material.emissiveFactor ? BABYLON.Color3.FromArray(material.emissiveFactor) : new BABYLON.Color3(0, 0, 0);
                 if (material.emissiveTexture) {
                     GLTFLoader.LoadTextureAsync(runtime, material.emissiveTexture, function (babylonTexture) {
                         material.babylonMaterial.emissiveTexture = babylonTexture;
-                    }, function () { return BABYLON.Tools.Warn("Failed to load emissive texture"); });
-                }
-                if (material.doubleSided) {
-                    material.babylonMaterial.backFaceCulling = false;
-                    material.babylonMaterial.twoSidedLighting = true;
+                        checkSuccess();
+                    }, function () {
+                        BABYLON.Tools.Error("Failed to load emissive texture");
+                        onError();
+                    });
                 }
             };
             GLTFLoader.LoadAlphaProperties = function (runtime, material) {
@@ -1092,64 +1174,69 @@ var BABYLON;
             };
             GLTFLoader.LoadTextureAsync = function (runtime, textureInfo, onSuccess, onError) {
                 var texture = runtime.gltf.textures[textureInfo.index];
+                var texCoord = textureInfo.texCoord || 0;
                 if (!texture || texture.source === undefined) {
                     onError();
                     return;
                 }
-                if (texture.babylonTexture) {
-                    onSuccess(texture.babylonTexture);
+                if (texture.babylonTextures) {
+                    var babylonTexture = texture.babylonTextures[texCoord];
+                    if (!babylonTexture) {
+                        for (var i = 0; i < texture.babylonTextures.length; i++) {
+                            babylonTexture = texture.babylonTextures[i];
+                            if (babylonTexture) {
+                                babylonTexture = babylonTexture.clone();
+                                babylonTexture.coordinatesIndex = texCoord;
+                                break;
+                            }
+                        }
+                    }
+                    onSuccess(babylonTexture);
                     return;
                 }
                 var source = runtime.gltf.images[texture.source];
-                if (source.uri === undefined) {
-                    var bufferView = runtime.gltf.bufferViews[source.bufferView];
-                    var buffer = GLTF2.GLTFUtils.GetBufferFromBufferView(runtime, bufferView, 0, bufferView.byteLength, GLTF2.EComponentType.UNSIGNED_BYTE);
-                    GLTFLoader.CreateTextureAsync(runtime, textureInfo, buffer, source.mimeType, onSuccess, onError);
-                }
-                else if (GLTF2.GLTFUtils.IsBase64(source.uri)) {
-                    GLTFLoader.CreateTextureAsync(runtime, textureInfo, new Uint8Array(GLTF2.GLTFUtils.DecodeBase64(source.uri)), source.mimeType, onSuccess, onError);
+                var sourceURL = runtime.rootUrl + source.uri;
+                if (texture.blobURL) {
+                    sourceURL = texture.blobURL;
                 }
                 else {
-                    BABYLON.Tools.LoadFile(runtime.rootUrl + source.uri, function (data) {
-                        GLTFLoader.CreateTextureAsync(runtime, textureInfo, new Uint8Array(data), source.mimeType, onSuccess, onError);
-                    }, null, null, true, onError);
+                    if (source.uri === undefined) {
+                        var bufferView = runtime.gltf.bufferViews[source.bufferView];
+                        var buffer = GLTF2.GLTFUtils.GetBufferFromBufferView(runtime, bufferView, 0, bufferView.byteLength, GLTF2.EComponentType.UNSIGNED_BYTE);
+                        texture.blobURL = URL.createObjectURL(new Blob([buffer], { type: source.mimeType }));
+                        sourceURL = texture.blobURL;
+                    }
+                    else if (GLTF2.GLTFUtils.IsBase64(source.uri)) {
+                        var decodedBuffer = new Uint8Array(GLTF2.GLTFUtils.DecodeBase64(source.uri));
+                        texture.blobURL = URL.createObjectURL(new Blob([decodedBuffer], { type: source.mimeType }));
+                        sourceURL = texture.blobURL;
+                    }
                 }
+                GLTFLoader._createTextureAsync(runtime, texture, texCoord, sourceURL, onSuccess, onError);
             };
-            GLTFLoader.CreateTextureAsync = function (runtime, textureInfo, buffer, mimeType, onSuccess, onError) {
-                var texture = runtime.gltf.textures[textureInfo.index];
-                if (!texture || texture.source === undefined) {
-                    onError();
-                    return;
-                }
-                if (texture.babylonTexture) {
-                    onSuccess(texture.babylonTexture);
-                    return;
-                }
+            GLTFLoader._createTextureAsync = function (runtime, texture, texCoord, url, onSuccess, onError) {
                 var sampler = texture.sampler ? runtime.gltf.samplers[texture.sampler] : {};
-                var createMipMaps = (sampler.minFilter === GLTF2.ETextureMinFilter.NEAREST_MIPMAP_NEAREST) ||
-                    (sampler.minFilter === GLTF2.ETextureMinFilter.NEAREST_MIPMAP_LINEAR) ||
-                    (sampler.minFilter === GLTF2.ETextureMinFilter.LINEAR_MIPMAP_NEAREST) ||
-                    (sampler.minFilter === GLTF2.ETextureMinFilter.LINEAR_MIPMAP_LINEAR);
+                var noMipMaps = (sampler.minFilter === GLTF2.ETextureMinFilter.NEAREST || sampler.minFilter === GLTF2.ETextureMinFilter.LINEAR);
                 var samplingMode = BABYLON.Texture.BILINEAR_SAMPLINGMODE;
-                var blob = new Blob([buffer], { type: mimeType });
-                var blobURL = URL.createObjectURL(blob);
-                var revokeBlobURL = function () { return URL.revokeObjectURL(blobURL); };
-                texture.babylonTexture = new BABYLON.Texture(blobURL, runtime.babylonScene, !createMipMaps, true, samplingMode, revokeBlobURL, revokeBlobURL);
-                texture.babylonTexture.coordinatesIndex = textureInfo.texCoord === undefined ? 0 : textureInfo.texCoord;
-                texture.babylonTexture.wrapU = GLTF2.GLTFUtils.GetWrapMode(sampler.wrapS);
-                texture.babylonTexture.wrapV = GLTF2.GLTFUtils.GetWrapMode(sampler.wrapT);
-                texture.babylonTexture.name = texture.name;
-                onSuccess(texture.babylonTexture);
+                var babylonTexture = new BABYLON.Texture(url, runtime.babylonScene, noMipMaps, true, samplingMode, function () {
+                    onSuccess(babylonTexture);
+                }, onError);
+                babylonTexture.coordinatesIndex = texCoord;
+                babylonTexture.wrapU = GLTF2.GLTFUtils.GetWrapMode(sampler.wrapS);
+                babylonTexture.wrapV = GLTF2.GLTFUtils.GetWrapMode(sampler.wrapT);
+                babylonTexture.name = texture.name;
+                // Cache the texture
+                texture.babylonTextures = texture.babylonTextures || [];
+                texture.babylonTextures[texCoord] = babylonTexture;
             };
             /**
             * Import meshes
             */
             GLTFLoader.prototype.importMeshAsync = function (meshesNames, scene, data, rootUrl, onSuccess, onError) {
                 scene.useRightHandedSystem = true;
-                var runtime = this._createRuntime(scene, data, rootUrl, true);
+                var runtime = GLTFLoader._createRuntime(scene, data, rootUrl, true);
                 if (!runtime) {
-                    if (onError)
-                        onError();
+                    onError();
                     return;
                 }
                 if (meshesNames === "") {
@@ -1183,58 +1270,50 @@ var BABYLON;
                     }
                 }
                 // Load buffers, materials, etc.
-                this._loadBuffersAsync(runtime, function () {
-                    importMaterials(runtime);
-                    postLoad(runtime);
-                    if (!BABYLON.GLTFFileLoader.IncrementalLoading && onSuccess) {
+                GLTFLoader._loadBuffersAsync(runtime, function () {
+                    GLTFLoader._loadMaterialsAsync(runtime, function () {
+                        postLoad(runtime);
                         onSuccess(meshes, null, skeletons);
-                    }
+                    }, onError);
                 }, onError);
                 if (BABYLON.GLTFFileLoader.IncrementalLoading && onSuccess) {
                     onSuccess(meshes, null, skeletons);
                 }
-                return true;
             };
             /**
             * Load scene
             */
             GLTFLoader.prototype.loadAsync = function (scene, data, rootUrl, onSuccess, onError) {
                 scene.useRightHandedSystem = true;
-                var runtime = this._createRuntime(scene, data, rootUrl, false);
+                var runtime = GLTFLoader._createRuntime(scene, data, rootUrl, false);
                 if (!runtime) {
-                    if (onError)
-                        onError();
-                    return false;
+                    onError();
+                    return;
                 }
                 importScene(runtime);
-                this._loadBuffersAsync(runtime, function () {
-                    importMaterials(runtime);
-                    postLoad(runtime);
-                    if (!BABYLON.GLTFFileLoader.IncrementalLoading) {
+                GLTFLoader._loadBuffersAsync(runtime, function () {
+                    GLTFLoader._loadMaterialsAsync(runtime, function () {
+                        postLoad(runtime);
                         onSuccess();
-                    }
+                    }, onError);
                 }, onError);
-                if (BABYLON.GLTFFileLoader.IncrementalLoading) {
-                    onSuccess();
-                }
-                return true;
             };
-            GLTFLoader.prototype._loadBuffersAsync = function (runtime, onSuccess, onError) {
+            GLTFLoader._loadBuffersAsync = function (runtime, onSuccess, onError) {
                 var _this = this;
                 if (runtime.gltf.buffers.length == 0) {
                     onSuccess();
                     return;
                 }
-                var loadedCount = 0;
+                var successCount = 0;
                 runtime.gltf.buffers.forEach(function (buffer, index) {
                     _this._loadBufferAsync(runtime, index, function () {
-                        if (++loadedCount >= runtime.gltf.buffers.length) {
+                        if (++successCount === runtime.gltf.buffers.length) {
                             onSuccess();
                         }
                     }, onError);
                 });
             };
-            GLTFLoader.prototype._loadBufferAsync = function (runtime, index, onSuccess, onError) {
+            GLTFLoader._loadBufferAsync = function (runtime, index, onSuccess, onError) {
                 var buffer = runtime.gltf.buffers[index];
                 if (buffer.uri === undefined) {
                     // buffer.loadedBufferView should already be set
@@ -1254,7 +1333,22 @@ var BABYLON;
                     }, null, null, true, onError);
                 }
             };
-            GLTFLoader.prototype._createRuntime = function (scene, data, rootUrl, importOnlyMeshes) {
+            GLTFLoader._loadMaterialsAsync = function (runtime, onSuccess, onError) {
+                var materials = runtime.gltf.materials;
+                if (!materials) {
+                    onSuccess();
+                    return;
+                }
+                var successCount = 0;
+                for (var i = 0; i < materials.length; i++) {
+                    GLTF2.GLTFLoaderExtension.LoadMaterialAsync(runtime, i, function () {
+                        if (++successCount === materials.length) {
+                            onSuccess();
+                        }
+                    }, onError);
+                }
+            };
+            GLTFLoader._createRuntime = function (scene, data, rootUrl, importOnlyMeshes) {
                 var runtime = {
                     gltf: data.json,
                     babylonScene: scene,
@@ -1283,32 +1377,6 @@ var BABYLON;
             return GLTFLoader;
         }());
         GLTFLoader.Extensions = {};
-        GLTFLoader.LoadMetallicRoughnessMaterialProperties = function (runtime, material) {
-            var properties = material.pbrMetallicRoughness;
-            if (!properties)
-                return;
-            material.babylonMaterial.albedoColor = properties.baseColorFactor ? BABYLON.Color3.FromArray(properties.baseColorFactor) : new BABYLON.Color3(1, 1, 1);
-            material.babylonMaterial.metallic = properties.metallicFactor === undefined ? 1 : properties.metallicFactor;
-            material.babylonMaterial.roughness = properties.roughnessFactor === undefined ? 1 : properties.roughnessFactor;
-            if (properties.baseColorTexture) {
-                GLTFLoader.LoadTextureAsync(runtime, properties.baseColorTexture, function (texture) {
-                    material.babylonMaterial.albedoTexture = texture;
-                    GLTFLoader.LoadAlphaProperties(runtime, material);
-                }, function () {
-                    BABYLON.Tools.Warn("Failed to load base color texture");
-                });
-            }
-            if (properties.metallicRoughnessTexture) {
-                GLTFLoader.LoadTextureAsync(runtime, properties.metallicRoughnessTexture, function (texture) {
-                    material.babylonMaterial.metallicTexture = texture;
-                    material.babylonMaterial.useMetallnessFromMetallicTextureBlue = true;
-                    material.babylonMaterial.useRoughnessFromMetallicTextureGreen = true;
-                    material.babylonMaterial.useRoughnessFromMetallicTextureAlpha = false;
-                }, function () {
-                    BABYLON.Tools.Warn("Failed to load metallic roughness texture");
-                });
-            }
-        };
         GLTF2.GLTFLoader = GLTFLoader;
         BABYLON.GLTFFileLoader.GLTFLoaderV2 = new GLTFLoader();
     })(GLTF2 = BABYLON.GLTF2 || (BABYLON.GLTF2 = {}));
@@ -1469,7 +1537,7 @@ var BABYLON;
             });
             GLTFLoaderExtension.prototype.postCreateRuntime = function (runtime) { };
             // Return true to stop other extensions from loading materials.
-            GLTFLoaderExtension.prototype.loadMaterial = function (runtime, index) { return false; };
+            GLTFLoaderExtension.prototype.loadMaterialAsync = function (runtime, index, onSuccess, onError) { return false; };
             // ---------
             // Utilities
             // ---------
@@ -1479,18 +1547,33 @@ var BABYLON;
                     extension.postCreateRuntime(runtime);
                 }
             };
-            GLTFLoaderExtension.LoadMaterial = function (runtime, index) {
+            GLTFLoaderExtension.LoadMaterialAsync = function (runtime, index, onSuccess, onError) {
                 for (var extensionName in GLTF2.GLTFLoader.Extensions) {
                     var extension = GLTF2.GLTFLoader.Extensions[extensionName];
-                    if (extension.loadMaterial(runtime, index)) {
+                    if (extension.loadMaterialAsync(runtime, index, onSuccess, onError)) {
                         return;
                     }
                 }
                 var material = GLTF2.GLTFLoader.LoadMaterial(runtime, index);
-                if (material) {
-                    GLTF2.GLTFLoader.LoadMetallicRoughnessMaterialProperties(runtime, material);
-                    GLTF2.GLTFLoader.LoadCommonMaterialProperties(runtime, material);
+                if (!material) {
+                    onSuccess();
+                    return;
                 }
+                var metallicRoughnessPropertiesSuccess = false;
+                var commonPropertiesSuccess = false;
+                var checkSuccess = function () {
+                    if (metallicRoughnessPropertiesSuccess && commonPropertiesSuccess) {
+                        onSuccess();
+                    }
+                };
+                GLTF2.GLTFLoader.LoadMetallicRoughnessMaterialPropertiesAsync(runtime, material, function () {
+                    metallicRoughnessPropertiesSuccess = true;
+                    checkSuccess();
+                }, onError);
+                GLTF2.GLTFLoader.LoadCommonMaterialPropertiesAsync(runtime, material, function () {
+                    commonPropertiesSuccess = true;
+                    checkSuccess();
+                }, onError);
             };
             return GLTFLoaderExtension;
         }());
@@ -1520,33 +1603,54 @@ var BABYLON;
             function GLTFMaterialsPbrSpecularGlossinessExtension() {
                 return _super.call(this, "KHR_materials_pbrSpecularGlossiness") || this;
             }
-            GLTFMaterialsPbrSpecularGlossinessExtension.prototype.loadMaterial = function (runtime, index) {
+            GLTFMaterialsPbrSpecularGlossinessExtension.prototype.loadMaterialAsync = function (runtime, index, onSuccess, onError) {
                 var material = GLTF2.GLTFLoader.LoadMaterial(runtime, index);
                 if (!material || !material.extensions)
                     return false;
                 var properties = material.extensions[this.name];
                 if (!properties)
                     return false;
+                //
+                // Load Factors
+                //
                 material.babylonMaterial.albedoColor = properties.diffuseFactor ? BABYLON.Color3.FromArray(properties.diffuseFactor) : new BABYLON.Color3(1, 1, 1);
                 material.babylonMaterial.reflectivityColor = properties.specularFactor ? BABYLON.Color3.FromArray(properties.specularFactor) : new BABYLON.Color3(1, 1, 1);
                 material.babylonMaterial.microSurface = properties.glossinessFactor === undefined ? 1 : properties.glossinessFactor;
+                //
+                // Load Textures
+                //
+                var commonMaterialPropertiesSuccess = false;
+                var checkSuccess = function () {
+                    if ((!properties.diffuseTexture || material.babylonMaterial.albedoTexture) &&
+                        (!properties.specularGlossinessTexture || material.babylonMaterial.reflectivityTexture) &&
+                        commonMaterialPropertiesSuccess) {
+                        onSuccess();
+                    }
+                };
                 if (properties.diffuseTexture) {
                     GLTF2.GLTFLoader.LoadTextureAsync(runtime, properties.diffuseTexture, function (texture) {
                         material.babylonMaterial.albedoTexture = texture;
                         GLTF2.GLTFLoader.LoadAlphaProperties(runtime, material);
+                        checkSuccess();
                     }, function () {
                         BABYLON.Tools.Warn("Failed to load diffuse texture");
+                        onError();
                     });
                 }
                 if (properties.specularGlossinessTexture) {
                     GLTF2.GLTFLoader.LoadTextureAsync(runtime, properties.specularGlossinessTexture, function (texture) {
                         material.babylonMaterial.reflectivityTexture = texture;
                         material.babylonMaterial.useMicroSurfaceFromReflectivityMapAlpha = true;
+                        checkSuccess();
                     }, function () {
                         BABYLON.Tools.Warn("Failed to load metallic roughness texture");
+                        onError();
                     });
                 }
-                GLTF2.GLTFLoader.LoadCommonMaterialProperties(runtime, material);
+                GLTF2.GLTFLoader.LoadCommonMaterialPropertiesAsync(runtime, material, function () {
+                    commonMaterialPropertiesSuccess = true;
+                    checkSuccess();
+                }, onError);
                 return true;
             };
             return GLTFMaterialsPbrSpecularGlossinessExtension;

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 1 - 1
dist/preview release/loaders/babylon.glTF2FileLoader.min.js


+ 21 - 19
dist/preview release/loaders/babylon.glTFFileLoader.d.ts

@@ -5,8 +5,8 @@ declare module BABYLON {
         bin: ArrayBufferView;
     }
     interface IGLTFLoader {
-        importMeshAsync: (meshesNames: any, scene: Scene, data: IGLTFLoaderData, rootUrl: string, onsuccess?: (meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]) => void, onerror?: () => void) => boolean;
-        loadAsync: (scene: Scene, data: IGLTFLoaderData, rootUrl: string, onsuccess: () => void, onerror: () => void) => boolean;
+        importMeshAsync: (meshesNames: any, scene: Scene, data: IGLTFLoaderData, rootUrl: string, onsuccess: (meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]) => void, onerror: () => void) => void;
+        loadAsync: (scene: Scene, data: IGLTFLoaderData, rootUrl: string, onsuccess: () => void, onerror: () => void) => void;
     }
     class GLTFFileLoader implements ISceneLoaderPluginAsync {
         static GLTFLoaderV1: IGLTFLoader;
@@ -14,8 +14,8 @@ declare module BABYLON {
         static HomogeneousCoordinates: boolean;
         static IncrementalLoading: boolean;
         extensions: ISceneLoaderPluginExtensions;
-        importMeshAsync(meshesNames: any, scene: Scene, data: any, rootUrl: string, onSuccess?: (meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]) => void, onError?: () => void): boolean;
-        loadAsync(scene: Scene, data: string | ArrayBuffer, rootUrl: string, onSuccess: () => void, onError: () => void): boolean;
+        importMeshAsync(meshesNames: any, scene: Scene, data: any, rootUrl: string, onSuccess: (meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]) => void, onError: () => void): void;
+        loadAsync(scene: Scene, data: string | ArrayBuffer, rootUrl: string, onSuccess: () => void, onError: () => void): void;
         private static _parse(data);
         private _getLoader(loaderData);
         private static _parseBinary(data);
@@ -370,7 +370,7 @@ declare module BABYLON.GLTF1 {
         };
         static RegisterExtension(extension: GLTFLoaderExtension): void;
         importMeshAsync(meshesNames: any, scene: Scene, data: IGLTFLoaderData, rootUrl: string, onSuccess?: (meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]) => void, onError?: () => void, onProgress?: () => void): boolean;
-        loadAsync(scene: Scene, data: IGLTFLoaderData, rootUrl: string, onSuccess: () => void, onError: () => void): boolean;
+        loadAsync(scene: Scene, data: IGLTFLoaderData, rootUrl: string, onSuccess: () => void, onError: () => void): void;
         private _loadShadersAsync(gltfRuntime, onload);
         private _loadBuffersAsync(gltfRuntime, onload, onProgress?);
         private _createNodes(gltfRuntime);
@@ -573,11 +573,11 @@ declare module BABYLON.GLTF2 {
     }
     enum ETextureMagFilter {
         NEAREST = 9728,
-        LINEAR = 9728,
+        LINEAR = 9729,
     }
     enum ETextureMinFilter {
         NEAREST = 9728,
-        LINEAR = 9728,
+        LINEAR = 9729,
         NEAREST_MIPMAP_NEAREST = 9984,
         LINEAR_MIPMAP_NEAREST = 9985,
         NEAREST_MIPMAP_LINEAR = 9986,
@@ -771,7 +771,8 @@ declare module BABYLON.GLTF2 {
         source: number;
         target?: ETextureTarget;
         type?: ETextureType;
-        babylonTexture?: Texture;
+        babylonTextures: Texture[];
+        blobURL: string;
     }
     interface IGLTFTextureInfo {
         index: number;
@@ -830,22 +831,23 @@ declare module BABYLON.GLTF2 {
         };
         static RegisterExtension(extension: GLTFLoaderExtension): void;
         static LoadMaterial(runtime: IGLTFRuntime, index: number): IGLTFMaterial;
-        static LoadMetallicRoughnessMaterialProperties: (runtime: IGLTFRuntime, material: IGLTFMaterial) => void;
-        static LoadCommonMaterialProperties(runtime: IGLTFRuntime, material: IGLTFMaterial): void;
+        static LoadMetallicRoughnessMaterialPropertiesAsync(runtime: IGLTFRuntime, material: IGLTFMaterial, onSuccess: () => void, onError: () => void): void;
+        static LoadCommonMaterialPropertiesAsync(runtime: IGLTFRuntime, material: IGLTFMaterial, onSuccess: () => void, onError: () => void): void;
         static LoadAlphaProperties(runtime: IGLTFRuntime, material: IGLTFMaterial): void;
         static LoadTextureAsync(runtime: IGLTFRuntime, textureInfo: IGLTFTextureInfo, onSuccess: (babylonTexture: Texture) => void, onError: () => void): void;
-        static CreateTextureAsync(runtime: IGLTFRuntime, textureInfo: IGLTFTextureInfo, buffer: ArrayBufferView, mimeType: string, onSuccess: (babylonTexture: Texture) => void, onError: () => void): void;
+        private static _createTextureAsync(runtime, texture, texCoord, url, onSuccess, onError);
         /**
         * Import meshes
         */
-        importMeshAsync(meshesNames: any, scene: Scene, data: IGLTFLoaderData, rootUrl: string, onSuccess?: (meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]) => void, onError?: () => void): boolean;
+        importMeshAsync(meshesNames: any, scene: Scene, data: IGLTFLoaderData, rootUrl: string, onSuccess?: (meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]) => void, onError?: () => void): void;
         /**
         * Load scene
         */
-        loadAsync(scene: Scene, data: IGLTFLoaderData, rootUrl: string, onSuccess: () => void, onError: () => void): boolean;
-        private _loadBuffersAsync(runtime, onSuccess, onError);
-        private _loadBufferAsync(runtime, index, onSuccess, onError);
-        private _createRuntime(scene, data, rootUrl, importOnlyMeshes);
+        loadAsync(scene: Scene, data: IGLTFLoaderData, rootUrl: string, onSuccess: () => void, onError: () => void): void;
+        private static _loadBuffersAsync(runtime, onSuccess, onError);
+        private static _loadBufferAsync(runtime, index, onSuccess, onError);
+        private static _loadMaterialsAsync(runtime, onSuccess, onError);
+        private static _createRuntime(scene, data, rootUrl, importOnlyMeshes);
     }
 }
 
@@ -907,9 +909,9 @@ declare module BABYLON.GLTF2 {
         constructor(name: string);
         readonly name: string;
         protected postCreateRuntime(runtime: IGLTFRuntime): void;
-        protected loadMaterial(runtime: IGLTFRuntime, index: number): boolean;
+        protected loadMaterialAsync(runtime: IGLTFRuntime, index: number, onSuccess: () => void, onError: () => void): boolean;
         static PostCreateRuntime(runtime: IGLTFRuntime): void;
-        static LoadMaterial(runtime: IGLTFRuntime, index: number): void;
+        static LoadMaterialAsync(runtime: IGLTFRuntime, index: number, onSuccess: () => void, onError: () => void): void;
     }
 }
 
@@ -917,6 +919,6 @@ declare module BABYLON.GLTF2 {
 declare module BABYLON.GLTF2 {
     class GLTFMaterialsPbrSpecularGlossinessExtension extends GLTFLoaderExtension {
         constructor();
-        protected loadMaterial(runtime: IGLTFRuntime, index: number): boolean;
+        protected loadMaterialAsync(runtime: IGLTFRuntime, index: number, onSuccess: () => void, onError: () => void): boolean;
     }
 }

+ 220 - 117
dist/preview release/loaders/babylon.glTFFileLoader.js

@@ -12,15 +12,17 @@ var BABYLON;
             var loaderData = GLTFFileLoader._parse(data);
             var loader = this._getLoader(loaderData);
             if (!loader) {
-                return false;
+                onError();
+                return;
             }
-            return loader.importMeshAsync(meshesNames, scene, loaderData, rootUrl, onSuccess, onError);
+            loader.importMeshAsync(meshesNames, scene, loaderData, rootUrl, onSuccess, onError);
         };
         GLTFFileLoader.prototype.loadAsync = function (scene, data, rootUrl, onSuccess, onError) {
             var loaderData = GLTFFileLoader._parse(data);
             var loader = this._getLoader(loaderData);
             if (!loader) {
-                return false;
+                onError();
+                return;
             }
             return loader.loadAsync(scene, loaderData, rootUrl, onSuccess, onError);
         };
@@ -1662,7 +1664,6 @@ var BABYLON;
                         }
                     }, onError);
                 }, onError);
-                return true;
             };
             GLTFLoader.prototype._loadShadersAsync = function (gltfRuntime, onload) {
                 var hasShaders = false;
@@ -2435,12 +2436,12 @@ var BABYLON;
         var ETextureMagFilter;
         (function (ETextureMagFilter) {
             ETextureMagFilter[ETextureMagFilter["NEAREST"] = 9728] = "NEAREST";
-            ETextureMagFilter[ETextureMagFilter["LINEAR"] = 9728] = "LINEAR";
+            ETextureMagFilter[ETextureMagFilter["LINEAR"] = 9729] = "LINEAR";
         })(ETextureMagFilter = GLTF2.ETextureMagFilter || (GLTF2.ETextureMagFilter = {}));
         var ETextureMinFilter;
         (function (ETextureMinFilter) {
             ETextureMinFilter[ETextureMinFilter["NEAREST"] = 9728] = "NEAREST";
-            ETextureMinFilter[ETextureMinFilter["LINEAR"] = 9728] = "LINEAR";
+            ETextureMinFilter[ETextureMinFilter["LINEAR"] = 9729] = "LINEAR";
             ETextureMinFilter[ETextureMinFilter["NEAREST_MIPMAP_NEAREST"] = 9984] = "NEAREST_MIPMAP_NEAREST";
             ETextureMinFilter[ETextureMinFilter["LINEAR_MIPMAP_NEAREST"] = 9985] = "LINEAR_MIPMAP_NEAREST";
             ETextureMinFilter[ETextureMinFilter["NEAREST_MIPMAP_LINEAR"] = 9986] = "NEAREST_MIPMAP_LINEAR";
@@ -3134,11 +3135,11 @@ var BABYLON;
                 var skeleton = runtime.babylonScene.skeletons[i];
                 runtime.babylonScene.beginAnimation(skeleton, 0, Number.MAX_VALUE, true, 1.0);
             }
-        };
-        var importMaterials = function (runtime) {
-            if (runtime.gltf.materials) {
-                for (var i = 0; i < runtime.gltf.materials.length; i++) {
-                    GLTF2.GLTFLoaderExtension.LoadMaterial(runtime, i);
+            // Revoke object urls created during load
+            for (var i = 0; i < runtime.gltf.textures.length; i++) {
+                var texture = runtime.gltf.textures[i];
+                if (texture.blobURL) {
+                    URL.revokeObjectURL(texture.blobURL);
                 }
             }
         };
@@ -3191,14 +3192,92 @@ var BABYLON;
                 material.babylonMaterial.useScalarInLinearSpace = true;
                 return material;
             };
-            GLTFLoader.LoadCommonMaterialProperties = function (runtime, material) {
+            GLTFLoader.LoadMetallicRoughnessMaterialPropertiesAsync = function (runtime, material, onSuccess, onError) {
+                // Ensure metallic workflow
+                material.babylonMaterial.metallic = 1;
+                material.babylonMaterial.roughness = 1;
+                var properties = material.pbrMetallicRoughness;
+                if (!properties) {
+                    onSuccess();
+                    return;
+                }
+                //
+                // Load Factors
+                //
+                material.babylonMaterial.albedoColor = properties.baseColorFactor ? BABYLON.Color3.FromArray(properties.baseColorFactor) : new BABYLON.Color3(1, 1, 1);
+                material.babylonMaterial.metallic = properties.metallicFactor || 1;
+                material.babylonMaterial.roughness = properties.roughnessFactor || 1;
+                //
+                // Load Textures
+                //
+                if (!properties.baseColorTexture && !properties.metallicRoughnessTexture) {
+                    onSuccess();
+                    return;
+                }
+                var checkSuccess = function () {
+                    if ((!properties.baseColorTexture || material.babylonMaterial.albedoTexture) &&
+                        (!properties.metallicRoughnessTexture || material.babylonMaterial.metallicTexture)) {
+                        onSuccess();
+                    }
+                };
+                if (properties.baseColorTexture) {
+                    GLTFLoader.LoadTextureAsync(runtime, properties.baseColorTexture, function (texture) {
+                        material.babylonMaterial.albedoTexture = texture;
+                        GLTFLoader.LoadAlphaProperties(runtime, material);
+                        checkSuccess();
+                    }, function () {
+                        BABYLON.Tools.Error("Failed to load base color texture");
+                        onError();
+                    });
+                }
+                if (properties.metallicRoughnessTexture) {
+                    GLTFLoader.LoadTextureAsync(runtime, properties.metallicRoughnessTexture, function (texture) {
+                        material.babylonMaterial.metallicTexture = texture;
+                        material.babylonMaterial.useMetallnessFromMetallicTextureBlue = true;
+                        material.babylonMaterial.useRoughnessFromMetallicTextureGreen = true;
+                        material.babylonMaterial.useRoughnessFromMetallicTextureAlpha = false;
+                        checkSuccess();
+                    }, function () {
+                        BABYLON.Tools.Error("Failed to load metallic roughness texture");
+                        onError();
+                    });
+                }
+            };
+            GLTFLoader.LoadCommonMaterialPropertiesAsync = function (runtime, material, onSuccess, onError) {
+                //
+                // Load Factors
+                //
+                material.babylonMaterial.useEmissiveAsIllumination = (material.emissiveFactor || material.emissiveTexture) ? true : false;
+                material.babylonMaterial.emissiveColor = material.emissiveFactor ? BABYLON.Color3.FromArray(material.emissiveFactor) : new BABYLON.Color3(0, 0, 0);
+                if (material.doubleSided) {
+                    material.babylonMaterial.backFaceCulling = false;
+                    material.babylonMaterial.twoSidedLighting = true;
+                }
+                //
+                // Load Textures
+                //
+                if (!material.normalTexture && !material.occlusionTexture && !material.emissiveTexture) {
+                    onSuccess();
+                    return;
+                }
+                var checkSuccess = function () {
+                    if ((!material.normalTexture || material.babylonMaterial.bumpTexture) &&
+                        (!material.occlusionTexture || material.babylonMaterial.ambientTexture) &&
+                        (!material.emissiveTexture || material.babylonMaterial.emissiveTexture)) {
+                        onSuccess();
+                    }
+                };
                 if (material.normalTexture) {
                     GLTFLoader.LoadTextureAsync(runtime, material.normalTexture, function (babylonTexture) {
                         material.babylonMaterial.bumpTexture = babylonTexture;
                         if (material.normalTexture.scale !== undefined) {
                             material.babylonMaterial.bumpTexture.level = material.normalTexture.scale;
                         }
-                    }, function () { return BABYLON.Tools.Warn("Failed to load normal texture"); });
+                        checkSuccess();
+                    }, function () {
+                        BABYLON.Tools.Error("Failed to load normal texture");
+                        onError();
+                    });
                 }
                 if (material.occlusionTexture) {
                     GLTFLoader.LoadTextureAsync(runtime, material.occlusionTexture, function (babylonTexture) {
@@ -3207,18 +3286,20 @@ var BABYLON;
                         if (material.occlusionTexture.strength !== undefined) {
                             material.babylonMaterial.ambientTextureStrength = material.occlusionTexture.strength;
                         }
-                    }, function () { return BABYLON.Tools.Warn("Failed to load occlusion texture"); });
+                        checkSuccess();
+                    }, function () {
+                        BABYLON.Tools.Error("Failed to load occlusion texture");
+                        onError();
+                    });
                 }
-                material.babylonMaterial.useEmissiveAsIllumination = (material.emissiveFactor || material.emissiveTexture) ? true : false;
-                material.babylonMaterial.emissiveColor = material.emissiveFactor ? BABYLON.Color3.FromArray(material.emissiveFactor) : new BABYLON.Color3(0, 0, 0);
                 if (material.emissiveTexture) {
                     GLTFLoader.LoadTextureAsync(runtime, material.emissiveTexture, function (babylonTexture) {
                         material.babylonMaterial.emissiveTexture = babylonTexture;
-                    }, function () { return BABYLON.Tools.Warn("Failed to load emissive texture"); });
-                }
-                if (material.doubleSided) {
-                    material.babylonMaterial.backFaceCulling = false;
-                    material.babylonMaterial.twoSidedLighting = true;
+                        checkSuccess();
+                    }, function () {
+                        BABYLON.Tools.Error("Failed to load emissive texture");
+                        onError();
+                    });
                 }
             };
             GLTFLoader.LoadAlphaProperties = function (runtime, material) {
@@ -3243,64 +3324,69 @@ var BABYLON;
             };
             GLTFLoader.LoadTextureAsync = function (runtime, textureInfo, onSuccess, onError) {
                 var texture = runtime.gltf.textures[textureInfo.index];
+                var texCoord = textureInfo.texCoord || 0;
                 if (!texture || texture.source === undefined) {
                     onError();
                     return;
                 }
-                if (texture.babylonTexture) {
-                    onSuccess(texture.babylonTexture);
+                if (texture.babylonTextures) {
+                    var babylonTexture = texture.babylonTextures[texCoord];
+                    if (!babylonTexture) {
+                        for (var i = 0; i < texture.babylonTextures.length; i++) {
+                            babylonTexture = texture.babylonTextures[i];
+                            if (babylonTexture) {
+                                babylonTexture = babylonTexture.clone();
+                                babylonTexture.coordinatesIndex = texCoord;
+                                break;
+                            }
+                        }
+                    }
+                    onSuccess(babylonTexture);
                     return;
                 }
                 var source = runtime.gltf.images[texture.source];
-                if (source.uri === undefined) {
-                    var bufferView = runtime.gltf.bufferViews[source.bufferView];
-                    var buffer = GLTF2.GLTFUtils.GetBufferFromBufferView(runtime, bufferView, 0, bufferView.byteLength, GLTF2.EComponentType.UNSIGNED_BYTE);
-                    GLTFLoader.CreateTextureAsync(runtime, textureInfo, buffer, source.mimeType, onSuccess, onError);
-                }
-                else if (GLTF2.GLTFUtils.IsBase64(source.uri)) {
-                    GLTFLoader.CreateTextureAsync(runtime, textureInfo, new Uint8Array(GLTF2.GLTFUtils.DecodeBase64(source.uri)), source.mimeType, onSuccess, onError);
+                var sourceURL = runtime.rootUrl + source.uri;
+                if (texture.blobURL) {
+                    sourceURL = texture.blobURL;
                 }
                 else {
-                    BABYLON.Tools.LoadFile(runtime.rootUrl + source.uri, function (data) {
-                        GLTFLoader.CreateTextureAsync(runtime, textureInfo, new Uint8Array(data), source.mimeType, onSuccess, onError);
-                    }, null, null, true, onError);
+                    if (source.uri === undefined) {
+                        var bufferView = runtime.gltf.bufferViews[source.bufferView];
+                        var buffer = GLTF2.GLTFUtils.GetBufferFromBufferView(runtime, bufferView, 0, bufferView.byteLength, GLTF2.EComponentType.UNSIGNED_BYTE);
+                        texture.blobURL = URL.createObjectURL(new Blob([buffer], { type: source.mimeType }));
+                        sourceURL = texture.blobURL;
+                    }
+                    else if (GLTF2.GLTFUtils.IsBase64(source.uri)) {
+                        var decodedBuffer = new Uint8Array(GLTF2.GLTFUtils.DecodeBase64(source.uri));
+                        texture.blobURL = URL.createObjectURL(new Blob([decodedBuffer], { type: source.mimeType }));
+                        sourceURL = texture.blobURL;
+                    }
                 }
+                GLTFLoader._createTextureAsync(runtime, texture, texCoord, sourceURL, onSuccess, onError);
             };
-            GLTFLoader.CreateTextureAsync = function (runtime, textureInfo, buffer, mimeType, onSuccess, onError) {
-                var texture = runtime.gltf.textures[textureInfo.index];
-                if (!texture || texture.source === undefined) {
-                    onError();
-                    return;
-                }
-                if (texture.babylonTexture) {
-                    onSuccess(texture.babylonTexture);
-                    return;
-                }
+            GLTFLoader._createTextureAsync = function (runtime, texture, texCoord, url, onSuccess, onError) {
                 var sampler = texture.sampler ? runtime.gltf.samplers[texture.sampler] : {};
-                var createMipMaps = (sampler.minFilter === GLTF2.ETextureMinFilter.NEAREST_MIPMAP_NEAREST) ||
-                    (sampler.minFilter === GLTF2.ETextureMinFilter.NEAREST_MIPMAP_LINEAR) ||
-                    (sampler.minFilter === GLTF2.ETextureMinFilter.LINEAR_MIPMAP_NEAREST) ||
-                    (sampler.minFilter === GLTF2.ETextureMinFilter.LINEAR_MIPMAP_LINEAR);
+                var noMipMaps = (sampler.minFilter === GLTF2.ETextureMinFilter.NEAREST || sampler.minFilter === GLTF2.ETextureMinFilter.LINEAR);
                 var samplingMode = BABYLON.Texture.BILINEAR_SAMPLINGMODE;
-                var blob = new Blob([buffer], { type: mimeType });
-                var blobURL = URL.createObjectURL(blob);
-                var revokeBlobURL = function () { return URL.revokeObjectURL(blobURL); };
-                texture.babylonTexture = new BABYLON.Texture(blobURL, runtime.babylonScene, !createMipMaps, true, samplingMode, revokeBlobURL, revokeBlobURL);
-                texture.babylonTexture.coordinatesIndex = textureInfo.texCoord === undefined ? 0 : textureInfo.texCoord;
-                texture.babylonTexture.wrapU = GLTF2.GLTFUtils.GetWrapMode(sampler.wrapS);
-                texture.babylonTexture.wrapV = GLTF2.GLTFUtils.GetWrapMode(sampler.wrapT);
-                texture.babylonTexture.name = texture.name;
-                onSuccess(texture.babylonTexture);
+                var babylonTexture = new BABYLON.Texture(url, runtime.babylonScene, noMipMaps, true, samplingMode, function () {
+                    onSuccess(babylonTexture);
+                }, onError);
+                babylonTexture.coordinatesIndex = texCoord;
+                babylonTexture.wrapU = GLTF2.GLTFUtils.GetWrapMode(sampler.wrapS);
+                babylonTexture.wrapV = GLTF2.GLTFUtils.GetWrapMode(sampler.wrapT);
+                babylonTexture.name = texture.name;
+                // Cache the texture
+                texture.babylonTextures = texture.babylonTextures || [];
+                texture.babylonTextures[texCoord] = babylonTexture;
             };
             /**
             * Import meshes
             */
             GLTFLoader.prototype.importMeshAsync = function (meshesNames, scene, data, rootUrl, onSuccess, onError) {
                 scene.useRightHandedSystem = true;
-                var runtime = this._createRuntime(scene, data, rootUrl, true);
+                var runtime = GLTFLoader._createRuntime(scene, data, rootUrl, true);
                 if (!runtime) {
-                    if (onError)
-                        onError();
+                    onError();
                     return;
                 }
                 if (meshesNames === "") {
@@ -3334,58 +3420,50 @@ var BABYLON;
                     }
                 }
                 // Load buffers, materials, etc.
-                this._loadBuffersAsync(runtime, function () {
-                    importMaterials(runtime);
-                    postLoad(runtime);
-                    if (!BABYLON.GLTFFileLoader.IncrementalLoading && onSuccess) {
+                GLTFLoader._loadBuffersAsync(runtime, function () {
+                    GLTFLoader._loadMaterialsAsync(runtime, function () {
+                        postLoad(runtime);
                         onSuccess(meshes, null, skeletons);
-                    }
+                    }, onError);
                 }, onError);
                 if (BABYLON.GLTFFileLoader.IncrementalLoading && onSuccess) {
                     onSuccess(meshes, null, skeletons);
                 }
-                return true;
             };
             /**
             * Load scene
             */
             GLTFLoader.prototype.loadAsync = function (scene, data, rootUrl, onSuccess, onError) {
                 scene.useRightHandedSystem = true;
-                var runtime = this._createRuntime(scene, data, rootUrl, false);
+                var runtime = GLTFLoader._createRuntime(scene, data, rootUrl, false);
                 if (!runtime) {
-                    if (onError)
-                        onError();
-                    return false;
+                    onError();
+                    return;
                 }
                 importScene(runtime);
-                this._loadBuffersAsync(runtime, function () {
-                    importMaterials(runtime);
-                    postLoad(runtime);
-                    if (!BABYLON.GLTFFileLoader.IncrementalLoading) {
+                GLTFLoader._loadBuffersAsync(runtime, function () {
+                    GLTFLoader._loadMaterialsAsync(runtime, function () {
+                        postLoad(runtime);
                         onSuccess();
-                    }
+                    }, onError);
                 }, onError);
-                if (BABYLON.GLTFFileLoader.IncrementalLoading) {
-                    onSuccess();
-                }
-                return true;
             };
-            GLTFLoader.prototype._loadBuffersAsync = function (runtime, onSuccess, onError) {
+            GLTFLoader._loadBuffersAsync = function (runtime, onSuccess, onError) {
                 var _this = this;
                 if (runtime.gltf.buffers.length == 0) {
                     onSuccess();
                     return;
                 }
-                var loadedCount = 0;
+                var successCount = 0;
                 runtime.gltf.buffers.forEach(function (buffer, index) {
                     _this._loadBufferAsync(runtime, index, function () {
-                        if (++loadedCount >= runtime.gltf.buffers.length) {
+                        if (++successCount === runtime.gltf.buffers.length) {
                             onSuccess();
                         }
                     }, onError);
                 });
             };
-            GLTFLoader.prototype._loadBufferAsync = function (runtime, index, onSuccess, onError) {
+            GLTFLoader._loadBufferAsync = function (runtime, index, onSuccess, onError) {
                 var buffer = runtime.gltf.buffers[index];
                 if (buffer.uri === undefined) {
                     // buffer.loadedBufferView should already be set
@@ -3405,7 +3483,22 @@ var BABYLON;
                     }, null, null, true, onError);
                 }
             };
-            GLTFLoader.prototype._createRuntime = function (scene, data, rootUrl, importOnlyMeshes) {
+            GLTFLoader._loadMaterialsAsync = function (runtime, onSuccess, onError) {
+                var materials = runtime.gltf.materials;
+                if (!materials) {
+                    onSuccess();
+                    return;
+                }
+                var successCount = 0;
+                for (var i = 0; i < materials.length; i++) {
+                    GLTF2.GLTFLoaderExtension.LoadMaterialAsync(runtime, i, function () {
+                        if (++successCount === materials.length) {
+                            onSuccess();
+                        }
+                    }, onError);
+                }
+            };
+            GLTFLoader._createRuntime = function (scene, data, rootUrl, importOnlyMeshes) {
                 var runtime = {
                     gltf: data.json,
                     babylonScene: scene,
@@ -3434,32 +3527,6 @@ var BABYLON;
             return GLTFLoader;
         }());
         GLTFLoader.Extensions = {};
-        GLTFLoader.LoadMetallicRoughnessMaterialProperties = function (runtime, material) {
-            var properties = material.pbrMetallicRoughness;
-            if (!properties)
-                return;
-            material.babylonMaterial.albedoColor = properties.baseColorFactor ? BABYLON.Color3.FromArray(properties.baseColorFactor) : new BABYLON.Color3(1, 1, 1);
-            material.babylonMaterial.metallic = properties.metallicFactor === undefined ? 1 : properties.metallicFactor;
-            material.babylonMaterial.roughness = properties.roughnessFactor === undefined ? 1 : properties.roughnessFactor;
-            if (properties.baseColorTexture) {
-                GLTFLoader.LoadTextureAsync(runtime, properties.baseColorTexture, function (texture) {
-                    material.babylonMaterial.albedoTexture = texture;
-                    GLTFLoader.LoadAlphaProperties(runtime, material);
-                }, function () {
-                    BABYLON.Tools.Warn("Failed to load base color texture");
-                });
-            }
-            if (properties.metallicRoughnessTexture) {
-                GLTFLoader.LoadTextureAsync(runtime, properties.metallicRoughnessTexture, function (texture) {
-                    material.babylonMaterial.metallicTexture = texture;
-                    material.babylonMaterial.useMetallnessFromMetallicTextureBlue = true;
-                    material.babylonMaterial.useRoughnessFromMetallicTextureGreen = true;
-                    material.babylonMaterial.useRoughnessFromMetallicTextureAlpha = false;
-                }, function () {
-                    BABYLON.Tools.Warn("Failed to load metallic roughness texture");
-                });
-            }
-        };
         GLTF2.GLTFLoader = GLTFLoader;
         BABYLON.GLTFFileLoader.GLTFLoaderV2 = new GLTFLoader();
     })(GLTF2 = BABYLON.GLTF2 || (BABYLON.GLTF2 = {}));
@@ -3620,7 +3687,7 @@ var BABYLON;
             });
             GLTFLoaderExtension.prototype.postCreateRuntime = function (runtime) { };
             // Return true to stop other extensions from loading materials.
-            GLTFLoaderExtension.prototype.loadMaterial = function (runtime, index) { return false; };
+            GLTFLoaderExtension.prototype.loadMaterialAsync = function (runtime, index, onSuccess, onError) { return false; };
             // ---------
             // Utilities
             // ---------
@@ -3630,18 +3697,33 @@ var BABYLON;
                     extension.postCreateRuntime(runtime);
                 }
             };
-            GLTFLoaderExtension.LoadMaterial = function (runtime, index) {
+            GLTFLoaderExtension.LoadMaterialAsync = function (runtime, index, onSuccess, onError) {
                 for (var extensionName in GLTF2.GLTFLoader.Extensions) {
                     var extension = GLTF2.GLTFLoader.Extensions[extensionName];
-                    if (extension.loadMaterial(runtime, index)) {
+                    if (extension.loadMaterialAsync(runtime, index, onSuccess, onError)) {
                         return;
                     }
                 }
                 var material = GLTF2.GLTFLoader.LoadMaterial(runtime, index);
-                if (material) {
-                    GLTF2.GLTFLoader.LoadMetallicRoughnessMaterialProperties(runtime, material);
-                    GLTF2.GLTFLoader.LoadCommonMaterialProperties(runtime, material);
+                if (!material) {
+                    onSuccess();
+                    return;
                 }
+                var metallicRoughnessPropertiesSuccess = false;
+                var commonPropertiesSuccess = false;
+                var checkSuccess = function () {
+                    if (metallicRoughnessPropertiesSuccess && commonPropertiesSuccess) {
+                        onSuccess();
+                    }
+                };
+                GLTF2.GLTFLoader.LoadMetallicRoughnessMaterialPropertiesAsync(runtime, material, function () {
+                    metallicRoughnessPropertiesSuccess = true;
+                    checkSuccess();
+                }, onError);
+                GLTF2.GLTFLoader.LoadCommonMaterialPropertiesAsync(runtime, material, function () {
+                    commonPropertiesSuccess = true;
+                    checkSuccess();
+                }, onError);
             };
             return GLTFLoaderExtension;
         }());
@@ -3671,33 +3753,54 @@ var BABYLON;
             function GLTFMaterialsPbrSpecularGlossinessExtension() {
                 return _super.call(this, "KHR_materials_pbrSpecularGlossiness") || this;
             }
-            GLTFMaterialsPbrSpecularGlossinessExtension.prototype.loadMaterial = function (runtime, index) {
+            GLTFMaterialsPbrSpecularGlossinessExtension.prototype.loadMaterialAsync = function (runtime, index, onSuccess, onError) {
                 var material = GLTF2.GLTFLoader.LoadMaterial(runtime, index);
                 if (!material || !material.extensions)
                     return false;
                 var properties = material.extensions[this.name];
                 if (!properties)
                     return false;
+                //
+                // Load Factors
+                //
                 material.babylonMaterial.albedoColor = properties.diffuseFactor ? BABYLON.Color3.FromArray(properties.diffuseFactor) : new BABYLON.Color3(1, 1, 1);
                 material.babylonMaterial.reflectivityColor = properties.specularFactor ? BABYLON.Color3.FromArray(properties.specularFactor) : new BABYLON.Color3(1, 1, 1);
                 material.babylonMaterial.microSurface = properties.glossinessFactor === undefined ? 1 : properties.glossinessFactor;
+                //
+                // Load Textures
+                //
+                var commonMaterialPropertiesSuccess = false;
+                var checkSuccess = function () {
+                    if ((!properties.diffuseTexture || material.babylonMaterial.albedoTexture) &&
+                        (!properties.specularGlossinessTexture || material.babylonMaterial.reflectivityTexture) &&
+                        commonMaterialPropertiesSuccess) {
+                        onSuccess();
+                    }
+                };
                 if (properties.diffuseTexture) {
                     GLTF2.GLTFLoader.LoadTextureAsync(runtime, properties.diffuseTexture, function (texture) {
                         material.babylonMaterial.albedoTexture = texture;
                         GLTF2.GLTFLoader.LoadAlphaProperties(runtime, material);
+                        checkSuccess();
                     }, function () {
                         BABYLON.Tools.Warn("Failed to load diffuse texture");
+                        onError();
                     });
                 }
                 if (properties.specularGlossinessTexture) {
                     GLTF2.GLTFLoader.LoadTextureAsync(runtime, properties.specularGlossinessTexture, function (texture) {
                         material.babylonMaterial.reflectivityTexture = texture;
                         material.babylonMaterial.useMicroSurfaceFromReflectivityMapAlpha = true;
+                        checkSuccess();
                     }, function () {
                         BABYLON.Tools.Warn("Failed to load metallic roughness texture");
+                        onError();
                     });
                 }
-                GLTF2.GLTFLoader.LoadCommonMaterialProperties(runtime, material);
+                GLTF2.GLTFLoader.LoadCommonMaterialPropertiesAsync(runtime, material, function () {
+                    commonMaterialPropertiesSuccess = true;
+                    checkSuccess();
+                }, onError);
                 return true;
             };
             return GLTFMaterialsPbrSpecularGlossinessExtension;

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 2 - 2
dist/preview release/loaders/babylon.glTFFileLoader.min.js


+ 25 - 6
src/Materials/babylon.material.ts

@@ -488,12 +488,6 @@
                 this._scene.materials.splice(index, 1);
             }
 
-            // Shader are kept in cache for further use but we can get rid of this by using forceDisposeEffect
-            if (forceDisposeEffect && this._effect) {
-                this._scene.getEngine()._releaseEffect(this._effect);
-                this._effect = null;
-            }
-
             // Remove from meshes
             for (index = 0; index < this._scene.meshes.length; index++) {
                 var mesh = this._scene.meshes[index];
@@ -501,8 +495,33 @@
                 if (mesh.material === this) {
                     mesh.material = null;
                 }
+
+                if ((<Mesh>mesh).geometry) {
+                    var geometry = (<Mesh>mesh).geometry;
+
+                    if (this.storeEffectOnSubMeshes) {
+                        for (var subMesh of mesh.subMeshes) {
+                            geometry._releaseVertexArrayObject(subMesh._materialEffect);
+                        }
+                    } else {
+                        geometry._releaseVertexArrayObject(this._effect)
+                    }
+                }
             }
 
+            // Shader are kept in cache for further use but we can get rid of this by using forceDisposeEffect
+            if (forceDisposeEffect && this._effect) {
+                    if (this.storeEffectOnSubMeshes) {
+                        for (var subMesh of mesh.subMeshes) {
+                            this._scene.getEngine()._releaseEffect(subMesh._materialEffect); 
+                        }
+                    } else {
+                        this._scene.getEngine()._releaseEffect(this._effect);                    
+                    }
+
+                this._effect = null;
+            }
+            
             // Callback
             this.onDisposeObservable.notifyObservers(this);
 

+ 7 - 0
src/Mesh/babylon.geometry.ts

@@ -348,6 +348,13 @@
             return this._indexBuffer;
         }
 
+        public _releaseVertexArrayObject(effect: Effect) {
+            if (this._vertexArrayObjects[effect.key]) {
+                this._engine.releaseVertexArrayObject(this._vertexArrayObjects[effect.key]);
+                delete this._vertexArrayObjects[effect.key];
+            }
+        }
+
         public releaseForMesh(mesh: Mesh, shouldDispose?: boolean): void {
             var meshes = this._meshes;
             var index = meshes.indexOf(mesh);

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

@@ -16,7 +16,7 @@
         public _id: number;
 
         public _materialDefines: MaterialDefines;
-        private _materialEffect: Effect;
+        public _materialEffect: Effect;
         private _currentMaterial: Material;
 
         public get effect(): Effect {

+ 9 - 3
src/babylon.engine.ts

@@ -3311,6 +3311,14 @@
             }
         }
 
+        public releaseEffects() {
+            for (var name in this._compiledEffects) {
+                this._gl.deleteProgram(this._compiledEffects[name]._program);
+            }
+
+            this._compiledEffects = {};
+        }
+
         // Dispose
         public dispose(): void {
             this.hideLoadingUI();
@@ -3326,9 +3334,7 @@
             Engine.audioEngine.dispose();
 
             // Release effects
-            for (var name in this._compiledEffects) {
-                this._gl.deleteProgram(this._compiledEffects[name]._program);
-            }
+            this.releaseEffects();
 
             // Unbind
             this.unbindAllAttributes();