Selaa lähdekoodia

Merge branch 'master' into ktxFallback

Trevor Baron 6 vuotta sitten
vanhempi
commit
1f3828d146
52 muutettua tiedostoa jossa 9299 lisäystä ja 8840 poistoa
  1. 1848 1789
      Playground/babylon.d.txt
  2. 6348 6299
      dist/preview release/babylon.d.ts
  3. 1 1
      dist/preview release/babylon.js
  4. 177 43
      dist/preview release/babylon.max.js
  5. 177 43
      dist/preview release/babylon.no-module.max.js
  6. 1 1
      dist/preview release/babylon.worker.js
  7. 177 43
      dist/preview release/es6.js
  8. 1 1
      dist/preview release/glTF2Interface/package.json
  9. 8 2
      dist/preview release/gui/babylon.gui.d.ts
  10. 1 1
      dist/preview release/gui/babylon.gui.js
  11. 1 1
      dist/preview release/gui/babylon.gui.min.js
  12. 1 1
      dist/preview release/gui/babylon.gui.min.js.map
  13. 16 4
      dist/preview release/gui/babylon.gui.module.d.ts
  14. 2 2
      dist/preview release/gui/package.json
  15. 49 121
      dist/preview release/inspector/babylon.inspector.d.ts
  16. 90 269
      dist/preview release/inspector/babylon.inspector.module.d.ts
  17. 5 5
      dist/preview release/inspector/package.json
  18. 8 0
      dist/preview release/loaders/babylon.glTF2FileLoader.d.ts
  19. 58 35
      dist/preview release/loaders/babylon.glTF2FileLoader.js
  20. 1 1
      dist/preview release/loaders/babylon.glTF2FileLoader.min.js
  21. 8 0
      dist/preview release/loaders/babylon.glTFFileLoader.d.ts
  22. 58 35
      dist/preview release/loaders/babylon.glTFFileLoader.js
  23. 1 1
      dist/preview release/loaders/babylon.glTFFileLoader.min.js
  24. 8 0
      dist/preview release/loaders/babylonjs.loaders.d.ts
  25. 58 35
      dist/preview release/loaders/babylonjs.loaders.js
  26. 1 1
      dist/preview release/loaders/babylonjs.loaders.min.js
  27. 8 0
      dist/preview release/loaders/babylonjs.loaders.module.d.ts
  28. 3 3
      dist/preview release/loaders/package.json
  29. 2 2
      dist/preview release/materialsLibrary/package.json
  30. 2 2
      dist/preview release/postProcessesLibrary/package.json
  31. 2 2
      dist/preview release/proceduralTexturesLibrary/package.json
  32. 3 3
      dist/preview release/serializers/package.json
  33. 5 19
      dist/preview release/viewer/babylon.viewer.d.ts
  34. 1 1
      dist/preview release/viewer/babylon.viewer.js
  35. 2 2
      dist/preview release/viewer/babylon.viewer.max.js
  36. 5 22
      dist/preview release/viewer/babylon.viewer.module.d.ts
  37. 4 1
      dist/preview release/what's new.md
  38. 5 0
      gui/src/2D/controls/control.ts
  39. 3 1
      gui/src/2D/valueAndUnit.ts
  40. 1 1
      package.json
  41. 3 3
      src/Behaviors/Mesh/babylon.pointerDragBehavior.ts
  42. 9 7
      src/Cameras/babylon.targetCamera.ts
  43. 1 1
      src/Engine/babylon.engine.ts
  44. 15 1
      src/Layer/babylon.layer.ts
  45. 40 9
      src/Layer/babylon.layerSceneComponent.ts
  46. 3 2
      src/Loading/babylon.sceneLoader.ts
  47. 3 3
      src/Materials/Textures/babylon.internalTexture.ts
  48. 10 0
      src/Materials/Textures/babylon.renderTargetTexture.ts
  49. 22 13
      src/Materials/Textures/babylon.videoTexture.ts
  50. 6 1
      src/Mesh/babylon.geometry.ts
  51. 28 7
      src/babylon.scene.ts
  52. 9 0
      src/babylon.sceneComponent.ts

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 1848 - 1789
Playground/babylon.d.txt


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 6348 - 6299
dist/preview release/babylon.d.ts


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


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


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 177 - 43
dist/preview release/babylon.no-module.max.js


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


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


+ 1 - 1
dist/preview release/glTF2Interface/package.json

@@ -1,7 +1,7 @@
 {
     "name": "babylonjs-gltf2interface",
     "description": "A typescript declaration of babylon's gltf2 inteface.",
-    "version": "4.0.0-alpha.6",
+    "version": "4.0.0-alpha.7",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"

+ 8 - 2
dist/preview release/gui/babylon.gui.d.ts

@@ -879,6 +879,10 @@ declare module BABYLON.GUI {
             protected _disabledColor: string;
             /** @hidden */
             _tag: any;
+            /**
+                * Gets or sets an object used to store user defined information for the node
+                */
+            metadata: any;
             /** Gets or sets a boolean indicating if the control can be hit with pointer events */
             isHitTestVisible: boolean;
             /** Gets or sets a boolean indicating if the control can block pointer events */
@@ -1473,9 +1477,11 @@ declare module BABYLON.GUI {
             maxWidth: string | number;
             /** Gets the maximum width allowed by the control in pixels */
             readonly maxWidthInPixels: number;
-            /** Gets and sets the text highlighter transparency; default: 0.4 */
+            /** Gets or sets the text highlighter transparency; default: 0.4 */
             highligherOpacity: number;
-            /** Gets and sets the text hightlight color */
+            /** Gets or sets a boolean indicating whether to select complete text by default on input focus */
+            onFocusSelectAll: boolean;
+            /** Gets or sets the text hightlight color */
             textHighlightColor: string;
             /** Gets or sets control margin */
             margin: string;

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


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


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


+ 16 - 4
dist/preview release/gui/babylon.gui.module.d.ts

@@ -986,6 +986,10 @@ declare module 'babylonjs-gui/2D/controls/control' {
             protected _disabledColor: string;
             /** @hidden */
             _tag: any;
+            /**
+                * Gets or sets an object used to store user defined information for the node
+                */
+            metadata: any;
             /** Gets or sets a boolean indicating if the control can be hit with pointer events */
             isHitTestVisible: boolean;
             /** Gets or sets a boolean indicating if the control can block pointer events */
@@ -1598,9 +1602,11 @@ declare module 'babylonjs-gui/2D/controls/inputText' {
             maxWidth: string | number;
             /** Gets the maximum width allowed by the control in pixels */
             readonly maxWidthInPixels: number;
-            /** Gets and sets the text highlighter transparency; default: 0.4 */
+            /** Gets or sets the text highlighter transparency; default: 0.4 */
             highligherOpacity: number;
-            /** Gets and sets the text hightlight color */
+            /** Gets or sets a boolean indicating whether to select complete text by default on input focus */
+            onFocusSelectAll: boolean;
+            /** Gets or sets the text hightlight color */
             textHighlightColor: string;
             /** Gets or sets control margin */
             margin: string;
@@ -3864,6 +3870,10 @@ declare module BABYLON.GUI {
             protected _disabledColor: string;
             /** @hidden */
             _tag: any;
+            /**
+                * Gets or sets an object used to store user defined information for the node
+                */
+            metadata: any;
             /** Gets or sets a boolean indicating if the control can be hit with pointer events */
             isHitTestVisible: boolean;
             /** Gets or sets a boolean indicating if the control can block pointer events */
@@ -4458,9 +4468,11 @@ declare module BABYLON.GUI {
             maxWidth: string | number;
             /** Gets the maximum width allowed by the control in pixels */
             readonly maxWidthInPixels: number;
-            /** Gets and sets the text highlighter transparency; default: 0.4 */
+            /** Gets or sets the text highlighter transparency; default: 0.4 */
             highligherOpacity: number;
-            /** Gets and sets the text hightlight color */
+            /** Gets or sets a boolean indicating whether to select complete text by default on input focus */
+            onFocusSelectAll: boolean;
+            /** Gets or sets the text hightlight color */
             textHighlightColor: string;
             /** Gets or sets control margin */
             margin: string;

+ 2 - 2
dist/preview release/gui/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-gui",
     "description": "The Babylon.js GUI library is an extension you can use to generate interactive user interface. It is build on top of the DynamicTexture.",
-    "version": "4.0.0-alpha.6",
+    "version": "4.0.0-alpha.7",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"
@@ -27,7 +27,7 @@
     ],
     "license": "Apache-2.0",
     "dependencies": {
-        "babylonjs": "4.0.0-alpha.6"
+        "babylonjs": "4.0.0-alpha.7"
     },
     "engines": {
         "node": "*"

+ 49 - 121
dist/preview release/inspector/babylon.inspector.d.ts

@@ -16,53 +16,55 @@ declare module INSPECTOR {
 declare module INSPECTOR {
 }
 declare module INSPECTOR {
-}
-declare module INSPECTOR {
-}
-declare module INSPECTOR {
-}
-declare module INSPECTOR {
-    export class Inspector {
-            /** The HTML document relative to this inspector (the window or the popup depending on its mode) */
-            static DOCUMENT: HTMLDocument;
-            /** The HTML window. In popup mode, it's the popup itself. Otherwise, it's the current tab */
-            static WINDOW: Window;
-            onGUILoaded: BABYLON.Observable<any>;
-            static GUIObject: any;
-            /** The inspector is created with the given engine.
-                * If the parameter 'popup' is false, the inspector is created as a right panel on the main window.
-                * If the parameter 'popup' is true, the inspector is created in another popup.
-                */
-            constructor(scene: BABYLON.Scene, popup?: boolean, initialTab?: number | string, parentElement?: BABYLON.Nullable<HTMLElement>, newColors?: {
-                    backgroundColor?: string;
-                    backgroundColorLighter?: string;
-                    backgroundColorLighter2?: string;
-                    backgroundColorLighter3?: string;
-                    color?: string;
-                    colorTop?: string;
-                    colorBot?: string;
-            });
-            readonly scene: BABYLON.Scene;
-            readonly popupMode: boolean;
-            /**
-                * Filter the list of item present in the tree.
-                * All item returned should have the given filter contained in the item id.
-             */
-            filterItem(filter: string): void;
-            /** Display the mesh tab on the given object */
-            displayObjectDetails(mesh: BABYLON.AbstractMesh): void;
-            /** Clean the whole tree of item and rebuilds it */
-            refresh(): void;
-            /** Remove the inspector panel when it's built as a right panel:
-                * remove the right panel and remove the wrapper
-                */
-            dispose(): void;
-            /** Open the inspector in a new popup
-                * Set 'firstTime' to true if there is no inspector created beforehands
-                */
-            openPopup(firstTime?: boolean): void;
-            getActiveTabIndex(): number;
-    }
+    export class Tools {
+        static LookForItem(item: any, selectedEntity: any): boolean;
+        static SortAndFilter(items: any[]): any[];
+    }
+}
+declare module INSPECTOR {
+}
+declare module INSPECTOR {
+}
+export declare class Inspector {
+        /** The HTML document relative to this inspector (the window or the popup depending on its mode) */
+        static DOCUMENT: HTMLDocument;
+        /** The HTML window. In popup mode, it's the popup itself. Otherwise, it's the current tab */
+        static WINDOW: Window;
+        onGUILoaded: BABYLON.Observable<any>;
+        static GUIObject: any;
+        /** The inspector is created with the given engine.
+            * If the parameter 'popup' is false, the inspector is created as a right panel on the main window.
+            * If the parameter 'popup' is true, the inspector is created in another popup.
+            */
+        constructor(scene: BABYLON.Scene, popup?: boolean, initialTab?: number | string, parentElement?: BABYLON.Nullable<HTMLElement>, newColors?: {
+                backgroundColor?: string;
+                backgroundColorLighter?: string;
+                backgroundColorLighter2?: string;
+                backgroundColorLighter3?: string;
+                color?: string;
+                colorTop?: string;
+                colorBot?: string;
+        });
+        readonly scene: BABYLON.Scene;
+        readonly popupMode: boolean;
+        /**
+            * Filter the list of item present in the tree.
+            * All item returned should have the given filter contained in the item id.
+         */
+        filterItem(filter: string): void;
+        /** Display the mesh tab on the given object */
+        displayObjectDetails(mesh: BABYLON.AbstractMesh): void;
+        /** Clean the whole tree of item and rebuilds it */
+        refresh(): void;
+        /** Remove the inspector panel when it's built as a right panel:
+            * remove the right panel and remove the wrapper
+            */
+        dispose(): void;
+        /** Open the inspector in a new popup
+            * Set 'firstTime' to true if there is no inspector created beforehands
+            */
+        openPopup(firstTime?: boolean): void;
+        getActiveTabIndex(): number;
 }
 declare module INSPECTOR {
     export const PROPERTIES: {
@@ -835,80 +837,6 @@ declare module INSPECTOR {
     }
 }
 declare module INSPECTOR {
-    export abstract class AbstractTool {
-            protected _inspector: Inspector;
-            constructor(iconSet: string, icon: string, parent: HTMLElement, inspector: Inspector, tooltip: string);
-            toHtml(): HTMLElement;
-            /**
-                * Returns the total width in pixel of this tool, 0 by default
-             */
-            getPixelWidth(): number;
-            /**
-                * Updates the icon of this tool with the given string
-                */
-            protected _updateIcon(icon: string): void;
-            abstract action(): void;
-    }
-}
-declare module INSPECTOR {
-    /**
-      * Removes the inspector panel
-      */
-    export class DisposeTool extends AbstractTool {
-        constructor(parent: HTMLElement, inspector: Inspector);
-        action(): void;
-    }
-}
-declare module INSPECTOR {
-    export class FullscreenTool extends AbstractTool {
-        constructor(parent: HTMLElement, inspector: Inspector);
-        action(): void;
-    }
-}
-declare module INSPECTOR {
-    export class LabelTool extends AbstractTool {
-        constructor(parent: HTMLElement, inspector: Inspector);
-        dispose(): void;
-        action(): void;
-    }
-}
-declare module INSPECTOR {
-    export class PauseScheduleTool extends AbstractTool {
-        constructor(parent: HTMLElement, inspector: Inspector);
-        action(): void;
-    }
-}
-declare module INSPECTOR {
-    export class PickTool extends AbstractTool {
-        constructor(parent: HTMLElement, inspector: Inspector);
-        action(): void;
-    }
-}
-declare module INSPECTOR {
-    export class PopupTool extends AbstractTool {
-        constructor(parent: HTMLElement, inspector: Inspector);
-        action(): void;
-    }
-}
-declare module INSPECTOR {
-    export class RefreshTool extends AbstractTool {
-        constructor(parent: HTMLElement, inspector: Inspector);
-        action(): void;
-    }
-}
-declare module INSPECTOR {
-    export class Toolbar extends BasicElement {
-        constructor(inspector: Inspector);
-        update(): void;
-        protected _build(): void;
-        /**
-          * Returns the total width in pixel of the tabbar,
-          * that corresponds to the sum of the width of each tab + toolbar width
-         */
-        getPixelWidth(): number;
-    }
-}
-declare module INSPECTOR {
     export class TreeItem extends BasicElement {
             children: Array<TreeItem>;
             constructor(tab: Tab, obj: Adapter);

+ 90 - 269
dist/preview release/inspector/babylon.inspector.module.d.ts

@@ -74,15 +74,10 @@ declare module 'babylonjs-inspector/tabs' {
 }
 
 declare module 'babylonjs-inspector/tools' {
-    export * from 'babylonjs-inspector/tools/AbstractTool';
-    export * from 'babylonjs-inspector/tools/DisposeTool';
-    export * from 'babylonjs-inspector/tools/FullscreenTool';
-    export * from 'babylonjs-inspector/tools/LabelTool';
-    export * from 'babylonjs-inspector/tools/PauseScheduleTool';
-    export * from 'babylonjs-inspector/tools/PickTool';
-    export * from 'babylonjs-inspector/tools/PopupTool';
-    export * from 'babylonjs-inspector/tools/RefreshTool';
-    export * from 'babylonjs-inspector/tools/Toolbar';
+    export class Tools {
+        static LookForItem(item: any, selectedEntity: any): boolean;
+        static SortAndFilter(items: any[]): any[];
+    }
 }
 
 declare module 'babylonjs-inspector/tree' {
@@ -99,50 +94,48 @@ declare module 'babylonjs-inspector/treetools' {
     export * from 'babylonjs-inspector/treetools/SoundInteractions';
 }
 
-declare module 'babylonjs-inspector/Inspector' {
-    import { AbstractMesh, Nullable, Scene, Observable } from "babylonjs";
-    
-    export class Inspector {
-            /** The HTML document relative to this inspector (the window or the popup depending on its mode) */
-            static DOCUMENT: HTMLDocument;
-            /** The HTML window. In popup mode, it's the popup itself. Otherwise, it's the current tab */
-            static WINDOW: Window;
-            onGUILoaded: Observable<any>;
-            static GUIObject: any;
-            /** The inspector is created with the given engine.
-                * If the parameter 'popup' is false, the inspector is created as a right panel on the main window.
-                * If the parameter 'popup' is true, the inspector is created in another popup.
-                */
-            constructor(scene: Scene, popup?: boolean, initialTab?: number | string, parentElement?: Nullable<HTMLElement>, newColors?: {
-                    backgroundColor?: string;
-                    backgroundColorLighter?: string;
-                    backgroundColorLighter2?: string;
-                    backgroundColorLighter3?: string;
-                    color?: string;
-                    colorTop?: string;
-                    colorBot?: string;
-            });
-            readonly scene: Scene;
-            readonly popupMode: boolean;
-            /**
-                * Filter the list of item present in the tree.
-                * All item returned should have the given filter contained in the item id.
-             */
-            filterItem(filter: string): void;
-            /** Display the mesh tab on the given object */
-            displayObjectDetails(mesh: AbstractMesh): void;
-            /** Clean the whole tree of item and rebuilds it */
-            refresh(): void;
-            /** Remove the inspector panel when it's built as a right panel:
-                * remove the right panel and remove the wrapper
-                */
-            dispose(): void;
-            /** Open the inspector in a new popup
-                * Set 'firstTime' to true if there is no inspector created beforehands
-                */
-            openPopup(firstTime?: boolean): void;
-            getActiveTabIndex(): number;
-    }
+import { AbstractMesh, Nullable, Scene, Observable } from "babylonjs";
+
+export declare class Inspector {
+        /** The HTML document relative to this inspector (the window or the popup depending on its mode) */
+        static DOCUMENT: HTMLDocument;
+        /** The HTML window. In popup mode, it's the popup itself. Otherwise, it's the current tab */
+        static WINDOW: Window;
+        onGUILoaded: Observable<any>;
+        static GUIObject: any;
+        /** The inspector is created with the given engine.
+            * If the parameter 'popup' is false, the inspector is created as a right panel on the main window.
+            * If the parameter 'popup' is true, the inspector is created in another popup.
+            */
+        constructor(scene: Scene, popup?: boolean, initialTab?: number | string, parentElement?: Nullable<HTMLElement>, newColors?: {
+                backgroundColor?: string;
+                backgroundColorLighter?: string;
+                backgroundColorLighter2?: string;
+                backgroundColorLighter3?: string;
+                color?: string;
+                colorTop?: string;
+                colorBot?: string;
+        });
+        readonly scene: Scene;
+        readonly popupMode: boolean;
+        /**
+            * Filter the list of item present in the tree.
+            * All item returned should have the given filter contained in the item id.
+         */
+        filterItem(filter: string): void;
+        /** Display the mesh tab on the given object */
+        displayObjectDetails(mesh: AbstractMesh): void;
+        /** Clean the whole tree of item and rebuilds it */
+        refresh(): void;
+        /** Remove the inspector panel when it's built as a right panel:
+            * remove the right panel and remove the wrapper
+            */
+        dispose(): void;
+        /** Open the inspector in a new popup
+            * Set 'firstTime' to true if there is no inspector created beforehands
+            */
+        openPopup(firstTime?: boolean): void;
+        getActiveTabIndex(): number;
 }
 
 declare module 'babylonjs-inspector/properties' {
@@ -1082,106 +1075,6 @@ declare module 'babylonjs-inspector/tabs/ToolsTab' {
     }
 }
 
-declare module 'babylonjs-inspector/tools/AbstractTool' {
-    import { Inspector } from "babylonjs-inspector/Inspector";
-    export abstract class AbstractTool {
-            protected _inspector: Inspector;
-            constructor(iconSet: string, icon: string, parent: HTMLElement, inspector: Inspector, tooltip: string);
-            toHtml(): HTMLElement;
-            /**
-                * Returns the total width in pixel of this tool, 0 by default
-             */
-            getPixelWidth(): number;
-            /**
-                * Updates the icon of this tool with the given string
-                */
-            protected _updateIcon(icon: string): void;
-            abstract action(): void;
-    }
-}
-
-declare module 'babylonjs-inspector/tools/DisposeTool' {
-    import { AbstractTool } from "babylonjs-inspector/tools/AbstractTool";
-    import { Inspector } from "babylonjs-inspector/Inspector";
-    /**
-      * Removes the inspector panel
-      */
-    export class DisposeTool extends AbstractTool {
-        constructor(parent: HTMLElement, inspector: Inspector);
-        action(): void;
-    }
-}
-
-declare module 'babylonjs-inspector/tools/FullscreenTool' {
-    import { AbstractTool } from "babylonjs-inspector/tools/AbstractTool";
-    import { Inspector } from "babylonjs-inspector/Inspector";
-    export class FullscreenTool extends AbstractTool {
-        constructor(parent: HTMLElement, inspector: Inspector);
-        action(): void;
-    }
-}
-
-declare module 'babylonjs-inspector/tools/LabelTool' {
-    import { Inspector } from "babylonjs-inspector/Inspector";
-    import { AbstractTool } from "babylonjs-inspector/tools/AbstractTool";
-    export class LabelTool extends AbstractTool {
-        constructor(parent: HTMLElement, inspector: Inspector);
-        dispose(): void;
-        action(): void;
-    }
-}
-
-declare module 'babylonjs-inspector/tools/PauseScheduleTool' {
-    import { Inspector } from "babylonjs-inspector/Inspector";
-    import { AbstractTool } from "babylonjs-inspector/tools/AbstractTool";
-    export class PauseScheduleTool extends AbstractTool {
-        constructor(parent: HTMLElement, inspector: Inspector);
-        action(): void;
-    }
-}
-
-declare module 'babylonjs-inspector/tools/PickTool' {
-    import { Inspector } from "babylonjs-inspector/Inspector";
-    import { AbstractTool } from "babylonjs-inspector/tools/AbstractTool";
-    export class PickTool extends AbstractTool {
-        constructor(parent: HTMLElement, inspector: Inspector);
-        action(): void;
-    }
-}
-
-declare module 'babylonjs-inspector/tools/PopupTool' {
-    import { Inspector } from "babylonjs-inspector/Inspector";
-    import { AbstractTool } from "babylonjs-inspector/tools/AbstractTool";
-    export class PopupTool extends AbstractTool {
-        constructor(parent: HTMLElement, inspector: Inspector);
-        action(): void;
-    }
-}
-
-declare module 'babylonjs-inspector/tools/RefreshTool' {
-    import { Inspector } from "babylonjs-inspector/Inspector";
-    import { AbstractTool } from "babylonjs-inspector/tools/AbstractTool";
-    export class RefreshTool extends AbstractTool {
-        constructor(parent: HTMLElement, inspector: Inspector);
-        action(): void;
-    }
-}
-
-declare module 'babylonjs-inspector/tools/Toolbar' {
-    import { BasicElement } from "babylonjs-inspector/gui/BasicElement";
-    import { Inspector } from "babylonjs-inspector/Inspector";
-    export class Toolbar extends BasicElement {
-        constructor(inspector: Inspector);
-        update(): void;
-        protected _build(): void;
-        /**
-          * Returns the total width in pixel of the tabbar,
-          * that corresponds to the sum of the width of each tab + toolbar width
-         */
-        getPixelWidth(): number;
-    }
-}
-
 declare module 'babylonjs-inspector/tree/TreeItem' {
     import { BasicElement } from "babylonjs-inspector/gui/BasicElement";
     import { Tab } from "babylonjs-inspector/tabs/Tab";
@@ -1359,53 +1252,55 @@ declare module INSPECTOR {
 declare module INSPECTOR {
 }
 declare module INSPECTOR {
+    export class Tools {
+        static LookForItem(item: any, selectedEntity: any): boolean;
+        static SortAndFilter(items: any[]): any[];
+    }
 }
 declare module INSPECTOR {
 }
 declare module INSPECTOR {
 }
-declare module INSPECTOR {
-    export class Inspector {
-            /** The HTML document relative to this inspector (the window or the popup depending on its mode) */
-            static DOCUMENT: HTMLDocument;
-            /** The HTML window. In popup mode, it's the popup itself. Otherwise, it's the current tab */
-            static WINDOW: Window;
-            onGUILoaded: BABYLON.Observable<any>;
-            static GUIObject: any;
-            /** The inspector is created with the given engine.
-                * If the parameter 'popup' is false, the inspector is created as a right panel on the main window.
-                * If the parameter 'popup' is true, the inspector is created in another popup.
-                */
-            constructor(scene: BABYLON.Scene, popup?: boolean, initialTab?: number | string, parentElement?: BABYLON.Nullable<HTMLElement>, newColors?: {
-                    backgroundColor?: string;
-                    backgroundColorLighter?: string;
-                    backgroundColorLighter2?: string;
-                    backgroundColorLighter3?: string;
-                    color?: string;
-                    colorTop?: string;
-                    colorBot?: string;
-            });
-            readonly scene: BABYLON.Scene;
-            readonly popupMode: boolean;
-            /**
-                * Filter the list of item present in the tree.
-                * All item returned should have the given filter contained in the item id.
-             */
-            filterItem(filter: string): void;
-            /** Display the mesh tab on the given object */
-            displayObjectDetails(mesh: BABYLON.AbstractMesh): void;
-            /** Clean the whole tree of item and rebuilds it */
-            refresh(): void;
-            /** Remove the inspector panel when it's built as a right panel:
-                * remove the right panel and remove the wrapper
-                */
-            dispose(): void;
-            /** Open the inspector in a new popup
-                * Set 'firstTime' to true if there is no inspector created beforehands
-                */
-            openPopup(firstTime?: boolean): void;
-            getActiveTabIndex(): number;
-    }
+export declare class Inspector {
+        /** The HTML document relative to this inspector (the window or the popup depending on its mode) */
+        static DOCUMENT: HTMLDocument;
+        /** The HTML window. In popup mode, it's the popup itself. Otherwise, it's the current tab */
+        static WINDOW: Window;
+        onGUILoaded: BABYLON.Observable<any>;
+        static GUIObject: any;
+        /** The inspector is created with the given engine.
+            * If the parameter 'popup' is false, the inspector is created as a right panel on the main window.
+            * If the parameter 'popup' is true, the inspector is created in another popup.
+            */
+        constructor(scene: BABYLON.Scene, popup?: boolean, initialTab?: number | string, parentElement?: BABYLON.Nullable<HTMLElement>, newColors?: {
+                backgroundColor?: string;
+                backgroundColorLighter?: string;
+                backgroundColorLighter2?: string;
+                backgroundColorLighter3?: string;
+                color?: string;
+                colorTop?: string;
+                colorBot?: string;
+        });
+        readonly scene: BABYLON.Scene;
+        readonly popupMode: boolean;
+        /**
+            * Filter the list of item present in the tree.
+            * All item returned should have the given filter contained in the item id.
+         */
+        filterItem(filter: string): void;
+        /** Display the mesh tab on the given object */
+        displayObjectDetails(mesh: BABYLON.AbstractMesh): void;
+        /** Clean the whole tree of item and rebuilds it */
+        refresh(): void;
+        /** Remove the inspector panel when it's built as a right panel:
+            * remove the right panel and remove the wrapper
+            */
+        dispose(): void;
+        /** Open the inspector in a new popup
+            * Set 'firstTime' to true if there is no inspector created beforehands
+            */
+        openPopup(firstTime?: boolean): void;
+        getActiveTabIndex(): number;
 }
 declare module INSPECTOR {
     export const PROPERTIES: {
@@ -2178,80 +2073,6 @@ declare module INSPECTOR {
     }
 }
 declare module INSPECTOR {
-    export abstract class AbstractTool {
-            protected _inspector: Inspector;
-            constructor(iconSet: string, icon: string, parent: HTMLElement, inspector: Inspector, tooltip: string);
-            toHtml(): HTMLElement;
-            /**
-                * Returns the total width in pixel of this tool, 0 by default
-             */
-            getPixelWidth(): number;
-            /**
-                * Updates the icon of this tool with the given string
-                */
-            protected _updateIcon(icon: string): void;
-            abstract action(): void;
-    }
-}
-declare module INSPECTOR {
-    /**
-      * Removes the inspector panel
-      */
-    export class DisposeTool extends AbstractTool {
-        constructor(parent: HTMLElement, inspector: Inspector);
-        action(): void;
-    }
-}
-declare module INSPECTOR {
-    export class FullscreenTool extends AbstractTool {
-        constructor(parent: HTMLElement, inspector: Inspector);
-        action(): void;
-    }
-}
-declare module INSPECTOR {
-    export class LabelTool extends AbstractTool {
-        constructor(parent: HTMLElement, inspector: Inspector);
-        dispose(): void;
-        action(): void;
-    }
-}
-declare module INSPECTOR {
-    export class PauseScheduleTool extends AbstractTool {
-        constructor(parent: HTMLElement, inspector: Inspector);
-        action(): void;
-    }
-}
-declare module INSPECTOR {
-    export class PickTool extends AbstractTool {
-        constructor(parent: HTMLElement, inspector: Inspector);
-        action(): void;
-    }
-}
-declare module INSPECTOR {
-    export class PopupTool extends AbstractTool {
-        constructor(parent: HTMLElement, inspector: Inspector);
-        action(): void;
-    }
-}
-declare module INSPECTOR {
-    export class RefreshTool extends AbstractTool {
-        constructor(parent: HTMLElement, inspector: Inspector);
-        action(): void;
-    }
-}
-declare module INSPECTOR {
-    export class Toolbar extends BasicElement {
-        constructor(inspector: Inspector);
-        update(): void;
-        protected _build(): void;
-        /**
-          * Returns the total width in pixel of the tabbar,
-          * that corresponds to the sum of the width of each tab + toolbar width
-         */
-        getPixelWidth(): number;
-    }
-}
-declare module INSPECTOR {
     export class TreeItem extends BasicElement {
             children: Array<TreeItem>;
             constructor(tab: Tab, obj: Adapter);

+ 5 - 5
dist/preview release/inspector/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-inspector",
     "description": "The Babylon.js inspector.",
-    "version": "4.0.0-alpha.6",
+    "version": "4.0.0-alpha.7",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"
@@ -28,10 +28,10 @@
     ],
     "license": "Apache-2.0",
     "dependencies": {
-        "babylonjs": "4.0.0-alpha.6",
-        "babylonjs-gui": "4.0.0-alpha.6",
-        "babylonjs-loaders": "4.0.0-alpha.6",
-        "babylonjs-serializers": "4.0.0-alpha.6"
+        "babylonjs": "4.0.0-alpha.7",
+        "babylonjs-gui": "4.0.0-alpha.7",
+        "babylonjs-loaders": "4.0.0-alpha.7",
+        "babylonjs-serializers": "4.0.0-alpha.7"
     },
     "engines": {
         "node": "*"

+ 8 - 0
dist/preview release/loaders/babylon.glTF2FileLoader.d.ts

@@ -758,6 +758,14 @@ declare module BABYLON.GLTF2 {
          */
         loadUriAsync(context: string, uri: string): Promise<ArrayBufferView>;
         private _onProgress;
+        /**
+         * Adds a JSON pointer to the metadata of the Babylon object at `<object>.metadata.gltf.pointers`.
+         * @param babylonObject the Babylon object with metadata
+         * @param pointer the JSON pointer
+         */
+        static AddPointerMetadata(babylonObject: {
+            metadata: any;
+        }, pointer: string): void;
         private static _GetTextureWrapMode;
         private static _GetTextureSamplingMode;
         private static _GetTypedArray;

+ 58 - 35
dist/preview release/loaders/babylon.glTF2FileLoader.js

@@ -941,11 +941,11 @@ var BABYLON;
                     _this._extensionsOnLoading();
                     var promises = new Array();
                     if (nodes) {
-                        promises.push(_this.loadSceneAsync("#/nodes", { nodes: nodes, index: -1 }));
+                        promises.push(_this.loadSceneAsync("/nodes", { nodes: nodes, index: -1 }));
                     }
                     else {
-                        var scene = ArrayItem.Get("#/scene", _this.gltf.scenes, _this.gltf.scene || 0);
-                        promises.push(_this.loadSceneAsync("#/scenes/" + scene.index, scene));
+                        var scene = ArrayItem.Get("/scene", _this.gltf.scenes, _this.gltf.scene || 0);
+                        promises.push(_this.loadSceneAsync("/scenes/" + scene.index, scene));
                     }
                     if (_this._parent.compileMaterials) {
                         promises.push(_this._compileMaterialsAsync());
@@ -1109,7 +1109,7 @@ var BABYLON;
                     for (var _i = 0, _a = scene.nodes; _i < _a.length; _i++) {
                         var index = _a[_i];
                         var node = ArrayItem.Get(context + "/nodes/" + index, this.gltf.nodes, index);
-                        promises.push(this.loadNodeAsync("#/nodes/" + node.index, node, function (babylonMesh) {
+                        promises.push(this.loadNodeAsync("/nodes/" + node.index, node, function (babylonMesh) {
                             babylonMesh.parent = _this._rootBabylonMesh;
                         }));
                     }
@@ -1217,17 +1217,18 @@ var BABYLON;
                 var promises = new Array();
                 this.logOpen(context + " " + (node.name || ""));
                 var loadNode = function (babylonTransformNode) {
+                    GLTFLoader.AddPointerMetadata(babylonTransformNode, context);
                     GLTFLoader._LoadTransform(node, babylonTransformNode);
                     if (node.camera != undefined) {
                         var camera = ArrayItem.Get(context + "/camera", _this.gltf.cameras, node.camera);
-                        promises.push(_this.loadCameraAsync("#/cameras/" + camera.index, camera, function (babylonCamera) {
+                        promises.push(_this.loadCameraAsync("/cameras/" + camera.index, camera, function (babylonCamera) {
                             babylonCamera.parent = babylonTransformNode;
                         }));
                     }
                     if (node.children) {
                         var _loop_1 = function (index) {
                             var childNode = ArrayItem.Get(context + "/children/" + index, _this.gltf.nodes, index);
-                            promises.push(_this.loadNodeAsync("#/nodes/" + node.index, childNode, function (childBabylonMesh) {
+                            promises.push(_this.loadNodeAsync("/nodes/" + childNode.index, childNode, function (childBabylonMesh) {
                                 // See https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#skins (second implementation note)
                                 if (childNode.skin != undefined) {
                                     childBabylonMesh.parent = _this._rootBabylonMesh;
@@ -1250,7 +1251,7 @@ var BABYLON;
                 }
                 else {
                     var mesh = ArrayItem.Get(context + "/mesh", this.gltf.meshes, node.mesh);
-                    promises.push(this._loadMeshAsync("#/meshes/" + mesh.index, node, mesh, loadNode));
+                    promises.push(this._loadMeshAsync("/meshes/" + mesh.index, node, mesh, loadNode));
                 }
                 this.logClose();
                 return Promise.all(promises).then(function () {
@@ -1291,7 +1292,7 @@ var BABYLON;
                 }
                 if (node.skin != undefined) {
                     var skin = ArrayItem.Get(context + "/skin", this.gltf.skins, node.skin);
-                    promises.push(this._loadSkinAsync("#/skins/" + skin.index, node, skin));
+                    promises.push(this._loadSkinAsync("/skins/" + skin.index, node, skin));
                 }
                 assign(node._babylonTransformNode);
                 this.logClose();
@@ -1331,7 +1332,7 @@ var BABYLON;
                     }
                     else {
                         var material = ArrayItem.Get(context + "/material", this.gltf.materials, primitive.material);
-                        promises.push(this._loadMaterialAsync("#/materials/" + material.index, material, babylonMesh_1, babylonDrawMode, function (babylonMaterial) {
+                        promises.push(this._loadMaterialAsync("/materials/" + material.index, material, babylonMesh_1, babylonDrawMode, function (babylonMaterial) {
                             babylonMesh_1.material = babylonMaterial;
                         }));
                     }
@@ -1344,6 +1345,7 @@ var BABYLON;
                     }
                     babylonAbstractMesh = babylonMesh_1;
                 }
+                GLTFLoader.AddPointerMetadata(babylonAbstractMesh, context);
                 this._parent.onMeshLoadedObservable.notifyObservers(babylonAbstractMesh);
                 assign(babylonAbstractMesh);
                 this.logClose();
@@ -1368,7 +1370,7 @@ var BABYLON;
                 }
                 else {
                     var accessor = ArrayItem.Get(context + "/indices", this.gltf.accessors, primitive.indices);
-                    promises.push(this._loadIndicesAccessorAsync("#/accessors/" + accessor.index, accessor).then(function (data) {
+                    promises.push(this._loadIndicesAccessorAsync("/accessors/" + accessor.index, accessor).then(function (data) {
                         babylonGeometry.setIndices(data);
                     }));
                 }
@@ -1381,7 +1383,7 @@ var BABYLON;
                         babylonMesh._delayInfo.push(kind);
                     }
                     var accessor = ArrayItem.Get(context + "/attributes/" + attribute, _this.gltf.accessors, attributes[attribute]);
-                    promises.push(_this._loadVertexAccessorAsync("#/accessors/" + accessor.index, accessor, kind).then(function (babylonVertexBuffer) {
+                    promises.push(_this._loadVertexAccessorAsync("/accessors/" + accessor.index, accessor, kind).then(function (babylonVertexBuffer) {
                         babylonGeometry.setVerticesBuffer(babylonVertexBuffer, accessor.count);
                     }));
                     if (callback) {
@@ -1445,7 +1447,7 @@ var BABYLON;
                         return;
                     }
                     var accessor = ArrayItem.Get(context + "/" + attribute, _this.gltf.accessors, attributes[attribute]);
-                    promises.push(_this._loadFloatAccessorAsync("#/accessors/" + accessor.index, accessor).then(function (data) {
+                    promises.push(_this._loadFloatAccessorAsync("/accessors/" + accessor.index, accessor).then(function (data) {
                         setData(babylonVertexBuffer, data);
                     }));
                 };
@@ -1558,7 +1560,7 @@ var BABYLON;
                     return Promise.resolve(null);
                 }
                 var accessor = ArrayItem.Get(context + "/inverseBindMatrices", this.gltf.accessors, skin.inverseBindMatrices);
-                return this._loadFloatAccessorAsync("#/accessors/" + accessor.index, accessor);
+                return this._loadFloatAccessorAsync("/accessors/" + accessor.index, accessor);
             };
             GLTFLoader.prototype._updateBoneMatrices = function (babylonSkeleton, inverseBindMatricesData) {
                 for (var _i = 0, _a = babylonSkeleton.bones; _i < _a.length; _i++) {
@@ -1627,8 +1629,9 @@ var BABYLON;
                         throw new Error(context + ": Invalid camera type (" + camera.type + ")");
                     }
                 }
-                assign(babylonCamera);
+                GLTFLoader.AddPointerMetadata(babylonCamera, context);
                 this._parent.onCameraLoadedObservable.notifyObservers(babylonCamera);
+                assign(babylonCamera);
                 return Promise.all(promises).then(function () {
                     return babylonCamera;
                 });
@@ -1641,7 +1644,7 @@ var BABYLON;
                 var promises = new Array();
                 for (var index = 0; index < animations.length; index++) {
                     var animation = animations[index];
-                    promises.push(this.loadAnimationAsync("#/animations/" + animation.index, animation));
+                    promises.push(this.loadAnimationAsync("/animations/" + animation.index, animation));
                 }
                 return Promise.all(promises).then(function () { });
             };
@@ -1844,8 +1847,8 @@ var BABYLON;
                 var inputAccessor = ArrayItem.Get(context + "/input", this.gltf.accessors, sampler.input);
                 var outputAccessor = ArrayItem.Get(context + "/output", this.gltf.accessors, sampler.output);
                 sampler._data = Promise.all([
-                    this._loadFloatAccessorAsync("#/accessors/" + inputAccessor.index, inputAccessor),
-                    this._loadFloatAccessorAsync("#/accessors/" + outputAccessor.index, outputAccessor)
+                    this._loadFloatAccessorAsync("/accessors/" + inputAccessor.index, inputAccessor),
+                    this._loadFloatAccessorAsync("/accessors/" + outputAccessor.index, outputAccessor)
                 ]).then(function (_a) {
                     var inputData = _a[0], outputData = _a[1];
                     return {
@@ -1877,7 +1880,7 @@ var BABYLON;
                     return bufferView._data;
                 }
                 var buffer = ArrayItem.Get(context + "/buffer", this.gltf.buffers, bufferView.buffer);
-                bufferView._data = this._loadBufferAsync("#/buffers/" + buffer.index, buffer).then(function (data) {
+                bufferView._data = this._loadBufferAsync("/buffers/" + buffer.index, buffer).then(function (data) {
                     try {
                         return new Uint8Array(data.buffer, data.byteOffset + (bufferView.byteOffset || 0), bufferView.byteLength);
                     }
@@ -1900,7 +1903,7 @@ var BABYLON;
                     return accessor._data;
                 }
                 var bufferView = ArrayItem.Get(context + "/bufferView", this.gltf.bufferViews, accessor.bufferView);
-                accessor._data = this.loadBufferViewAsync("#/bufferViews/" + bufferView.index, bufferView).then(function (data) {
+                accessor._data = this.loadBufferViewAsync("/bufferViews/" + bufferView.index, bufferView).then(function (data) {
                     return GLTFLoader._GetTypedArray(context, accessor.componentType, data, accessor.byteOffset, accessor.count);
                 });
                 return accessor._data;
@@ -1921,7 +1924,7 @@ var BABYLON;
                 }
                 else {
                     var bufferView = ArrayItem.Get(context + "/bufferView", this.gltf.bufferViews, accessor.bufferView);
-                    accessor._data = this.loadBufferViewAsync("#/bufferViews/" + bufferView.index, bufferView).then(function (data) {
+                    accessor._data = this.loadBufferViewAsync("/bufferViews/" + bufferView.index, bufferView).then(function (data) {
                         return GLTFLoader._GetTypedArray(context, accessor.componentType, data, accessor.byteOffset, length);
                     });
                 }
@@ -1931,8 +1934,8 @@ var BABYLON;
                         var indicesBufferView = ArrayItem.Get(context + "/sparse/indices/bufferView", _this.gltf.bufferViews, sparse_1.indices.bufferView);
                         var valuesBufferView = ArrayItem.Get(context + "/sparse/values/bufferView", _this.gltf.bufferViews, sparse_1.values.bufferView);
                         return Promise.all([
-                            _this.loadBufferViewAsync("#/bufferViews/" + indicesBufferView.index, indicesBufferView),
-                            _this.loadBufferViewAsync("#/bufferViews/" + valuesBufferView.index, valuesBufferView)
+                            _this.loadBufferViewAsync("/bufferViews/" + indicesBufferView.index, indicesBufferView),
+                            _this.loadBufferViewAsync("/bufferViews/" + valuesBufferView.index, valuesBufferView)
                         ]).then(function (_a) {
                             var indicesData = _a[0], valuesData = _a[1];
                             var indices = GLTFLoader._GetTypedArray(context + "/sparse/indices", sparse_1.indices.componentType, indicesData, sparse_1.indices.byteOffset, sparse_1.count);
@@ -1955,7 +1958,7 @@ var BABYLON;
                 if (bufferView._babylonBuffer) {
                     return bufferView._babylonBuffer;
                 }
-                bufferView._babylonBuffer = this.loadBufferViewAsync("#/bufferViews/" + bufferView.index, bufferView).then(function (data) {
+                bufferView._babylonBuffer = this.loadBufferViewAsync("/bufferViews/" + bufferView.index, bufferView).then(function (data) {
                     return new BABYLON.Buffer(_this.babylonScene.getEngine(), data, false);
                 });
                 return bufferView._babylonBuffer;
@@ -1966,14 +1969,14 @@ var BABYLON;
                     return accessor._babylonVertexBuffer;
                 }
                 if (accessor.sparse) {
-                    accessor._babylonVertexBuffer = this._loadFloatAccessorAsync("#/accessors/" + accessor.index, accessor).then(function (data) {
+                    accessor._babylonVertexBuffer = this._loadFloatAccessorAsync("/accessors/" + accessor.index, accessor).then(function (data) {
                         return new BABYLON.VertexBuffer(_this.babylonScene.getEngine(), data, kind, false);
                     });
                 }
                 // HACK: If byte offset is not a multiple of component type byte length then load as a float array instead of using Babylon buffers.
                 else if (accessor.byteOffset && accessor.byteOffset % BABYLON.VertexBuffer.GetTypeByteLength(accessor.componentType) !== 0) {
                     BABYLON.Tools.Warn("Accessor byte offset is not a multiple of component type byte length");
-                    accessor._babylonVertexBuffer = this._loadFloatAccessorAsync("#/accessors/" + accessor.index, accessor).then(function (data) {
+                    accessor._babylonVertexBuffer = this._loadFloatAccessorAsync("/accessors/" + accessor.index, accessor).then(function (data) {
                         return new BABYLON.VertexBuffer(_this.babylonScene.getEngine(), data, kind, false);
                     });
                 }
@@ -2003,11 +2006,13 @@ var BABYLON;
                     babylonMaterial.roughness = properties.roughnessFactor == undefined ? 1 : properties.roughnessFactor;
                     if (properties.baseColorTexture) {
                         promises.push(this.loadTextureInfoAsync(context + "/baseColorTexture", properties.baseColorTexture, function (texture) {
+                            texture.name = babylonMaterial.name + " (Base Color)";
                             babylonMaterial.albedoTexture = texture;
                         }));
                     }
                     if (properties.metallicRoughnessTexture) {
                         promises.push(this.loadTextureInfoAsync(context + "/metallicRoughnessTexture", properties.metallicRoughnessTexture, function (texture) {
+                            texture.name = babylonMaterial.name + " (Metallic Roughness)";
                             babylonMaterial.metallicTexture = texture;
                         }));
                         babylonMaterial.useMetallnessFromMetallicTextureBlue = true;
@@ -2035,6 +2040,7 @@ var BABYLON;
                         promise: this.loadMaterialPropertiesAsync(context, material, babylonMaterial)
                     };
                     material._data[babylonDrawMode] = babylonData;
+                    GLTFLoader.AddPointerMetadata(babylonMaterial, context);
                     this._parent.onMaterialLoadedObservable.notifyObservers(babylonMaterial);
                     this.logClose();
                 }
@@ -2075,7 +2081,8 @@ var BABYLON;
                     return extensionPromise;
                 }
                 var name = material.name || "material" + material.index;
-                return this._createDefaultMaterial(name, babylonDrawMode);
+                var babylonMaterial = this._createDefaultMaterial(name, babylonDrawMode);
+                return babylonMaterial;
             };
             /**
              * Loads properties from a glTF material into a Babylon material.
@@ -2116,6 +2123,7 @@ var BABYLON;
                 }
                 if (material.normalTexture) {
                     promises.push(this.loadTextureInfoAsync(context + "/normalTexture", material.normalTexture, function (texture) {
+                        texture.name = babylonMaterial.name + " (Normal)";
                         babylonMaterial.bumpTexture = texture;
                     }));
                     babylonMaterial.invertNormalMapX = !this.babylonScene.useRightHandedSystem;
@@ -2126,6 +2134,7 @@ var BABYLON;
                 }
                 if (material.occlusionTexture) {
                     promises.push(this.loadTextureInfoAsync(context + "/occlusionTexture", material.occlusionTexture, function (texture) {
+                        texture.name = babylonMaterial.name + " (Occlusion)";
                         babylonMaterial.ambientTexture = texture;
                     }));
                     babylonMaterial.useAmbientInGrayScale = true;
@@ -2135,6 +2144,7 @@ var BABYLON;
                 }
                 if (material.emissiveTexture) {
                     promises.push(this.loadTextureInfoAsync(context + "/emissiveTexture", material.emissiveTexture, function (texture) {
+                        texture.name = babylonMaterial.name + " (Emissive)";
                         babylonMaterial.emissiveTexture = texture;
                     }));
                 }
@@ -2186,6 +2196,7 @@ var BABYLON;
              * @returns A promise that resolves with the loaded Babylon texture when the load is complete
              */
             GLTFLoader.prototype.loadTextureInfoAsync = function (context, textureInfo, assign) {
+                var _this = this;
                 if (assign === void 0) { assign = function () { }; }
                 var extensionPromise = this._extensionsLoadTextureInfoAsync(context, textureInfo, assign);
                 if (extensionPromise) {
@@ -2193,8 +2204,10 @@ var BABYLON;
                 }
                 this.logOpen("" + context);
                 var texture = ArrayItem.Get(context + "/index", this.gltf.textures, textureInfo.index);
-                var promise = this._loadTextureAsync("#/textures/" + textureInfo.index, texture, function (babylonTexture) {
+                var promise = this._loadTextureAsync("/textures/" + textureInfo.index, texture, function (babylonTexture) {
                     babylonTexture.coordinatesIndex = textureInfo.texCoord || 0;
+                    GLTFLoader.AddPointerMetadata(babylonTexture, context);
+                    _this._parent.onTextureLoadedObservable.notifyObservers(babylonTexture);
                     assign(babylonTexture);
                 });
                 this.logClose();
@@ -2206,7 +2219,7 @@ var BABYLON;
                 var promises = new Array();
                 this.logOpen(context + " " + (texture.name || ""));
                 var sampler = (texture.sampler == undefined ? GLTFLoader._DefaultSampler : ArrayItem.Get(context + "/sampler", this.gltf.samplers, texture.sampler));
-                var samplerData = this._loadSampler("#/samplers/" + sampler.index, sampler);
+                var samplerData = this._loadSampler("/samplers/" + sampler.index, sampler);
                 var deferred = new BABYLON.Deferred();
                 var babylonTexture = new BABYLON.Texture(null, this.babylonScene, samplerData.noMipMaps, false, samplerData.samplingMode, function () {
                     if (!_this._disposed) {
@@ -2218,17 +2231,15 @@ var BABYLON;
                     }
                 });
                 promises.push(deferred.promise);
-                babylonTexture.name = texture.name || "texture" + texture.index;
                 babylonTexture.wrapU = samplerData.wrapU;
                 babylonTexture.wrapV = samplerData.wrapV;
                 var image = ArrayItem.Get(context + "/source", this.gltf.images, texture.source);
-                promises.push(this.loadImageAsync("#/images/" + image.index, image).then(function (data) {
+                promises.push(this.loadImageAsync("/images/" + image.index, image).then(function (data) {
                     var name = image.uri || _this._fileName + "#image" + image.index;
                     var dataUrl = "data:" + _this._uniqueRootUrl + name;
                     babylonTexture.updateURL(dataUrl, new Blob([data], { type: image.mimeType }));
                 }));
                 assign(babylonTexture);
-                this._parent.onTextureLoadedObservable.notifyObservers(babylonTexture);
                 this.logClose();
                 return Promise.all(promises).then(function () {
                     return babylonTexture;
@@ -2259,7 +2270,7 @@ var BABYLON;
                     }
                     else {
                         var bufferView = ArrayItem.Get(context + "/bufferView", this.gltf.bufferViews, image.bufferView);
-                        image._data = this.loadBufferViewAsync("#/bufferViews/" + bufferView.index, bufferView);
+                        image._data = this.loadBufferViewAsync("/bufferViews/" + bufferView.index, bufferView);
                     }
                     this.logClose();
                 }
@@ -2339,6 +2350,17 @@ var BABYLON;
                 }
                 this._progressCallback(new BABYLON.SceneLoaderProgressEvent(lengthComputable, loaded, lengthComputable ? total : 0));
             };
+            /**
+             * Adds a JSON pointer to the metadata of the Babylon object at `<object>.metadata.gltf.pointers`.
+             * @param babylonObject the Babylon object with metadata
+             * @param pointer the JSON pointer
+             */
+            GLTFLoader.AddPointerMetadata = function (babylonObject, pointer) {
+                var metadata = (babylonObject.metadata = babylonObject.metadata || {});
+                var gltf = (metadata.gltf = metadata.gltf || {});
+                var pointers = (gltf.pointers = gltf.pointers || []);
+                pointers.push(pointer);
+            };
             GLTFLoader._GetTextureWrapMode = function (context, mode) {
                 // Set defaults if undefined
                 mode = mode == undefined ? 10497 /* REPEAT */ : mode;
@@ -3367,14 +3389,14 @@ var BABYLON;
                         babylonMaterial.microSurface = properties.glossinessFactor == undefined ? 1 : properties.glossinessFactor;
                         if (properties.diffuseTexture) {
                             promises.push(this._loader.loadTextureInfoAsync(context + "/diffuseTexture", properties.diffuseTexture, function (texture) {
+                                texture.name = babylonMaterial.name + " (Diffuse)";
                                 babylonMaterial.albedoTexture = texture;
-                                return Promise.resolve();
                             }));
                         }
                         if (properties.specularGlossinessTexture) {
                             promises.push(this._loader.loadTextureInfoAsync(context + "/specularGlossinessTexture", properties.specularGlossinessTexture, function (texture) {
+                                texture.name = babylonMaterial.name + " (Specular Glossiness)";
                                 babylonMaterial.reflectivityTexture = texture;
-                                return Promise.resolve();
                             }));
                             babylonMaterial.reflectivityTexture.hasAlpha = true;
                             babylonMaterial.useMicroSurfaceFromReflectivityMapAlpha = true;
@@ -3442,8 +3464,8 @@ var BABYLON;
                             }
                             if (properties.baseColorTexture) {
                                 promises.push(this._loader.loadTextureInfoAsync(context + "/baseColorTexture", properties.baseColorTexture, function (texture) {
+                                    texture.name = babylonMaterial.name + " (Base Color)";
                                     babylonMaterial.albedoTexture = texture;
-                                    return Promise.resolve();
                                 }));
                             }
                         }
@@ -3539,6 +3561,7 @@ var BABYLON;
                                 babylonLight.intensity = light.intensity == undefined ? 1 : light.intensity;
                                 babylonLight.range = light.range == undefined ? Number.MAX_VALUE : light.range;
                                 babylonLight.parent = babylonMesh;
+                                GLTF2.GLTFLoader.AddPointerMetadata(babylonLight, extensionContext);
                                 assign(babylonMesh);
                             });
                         });

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


+ 8 - 0
dist/preview release/loaders/babylon.glTFFileLoader.d.ts

@@ -1320,6 +1320,14 @@ declare module BABYLON.GLTF2 {
          */
         loadUriAsync(context: string, uri: string): Promise<ArrayBufferView>;
         private _onProgress;
+        /**
+         * Adds a JSON pointer to the metadata of the Babylon object at `<object>.metadata.gltf.pointers`.
+         * @param babylonObject the Babylon object with metadata
+         * @param pointer the JSON pointer
+         */
+        static AddPointerMetadata(babylonObject: {
+            metadata: any;
+        }, pointer: string): void;
         private static _GetTextureWrapMode;
         private static _GetTextureSamplingMode;
         private static _GetTypedArray;

+ 58 - 35
dist/preview release/loaders/babylon.glTFFileLoader.js

@@ -3149,11 +3149,11 @@ var BABYLON;
                     _this._extensionsOnLoading();
                     var promises = new Array();
                     if (nodes) {
-                        promises.push(_this.loadSceneAsync("#/nodes", { nodes: nodes, index: -1 }));
+                        promises.push(_this.loadSceneAsync("/nodes", { nodes: nodes, index: -1 }));
                     }
                     else {
-                        var scene = ArrayItem.Get("#/scene", _this.gltf.scenes, _this.gltf.scene || 0);
-                        promises.push(_this.loadSceneAsync("#/scenes/" + scene.index, scene));
+                        var scene = ArrayItem.Get("/scene", _this.gltf.scenes, _this.gltf.scene || 0);
+                        promises.push(_this.loadSceneAsync("/scenes/" + scene.index, scene));
                     }
                     if (_this._parent.compileMaterials) {
                         promises.push(_this._compileMaterialsAsync());
@@ -3317,7 +3317,7 @@ var BABYLON;
                     for (var _i = 0, _a = scene.nodes; _i < _a.length; _i++) {
                         var index = _a[_i];
                         var node = ArrayItem.Get(context + "/nodes/" + index, this.gltf.nodes, index);
-                        promises.push(this.loadNodeAsync("#/nodes/" + node.index, node, function (babylonMesh) {
+                        promises.push(this.loadNodeAsync("/nodes/" + node.index, node, function (babylonMesh) {
                             babylonMesh.parent = _this._rootBabylonMesh;
                         }));
                     }
@@ -3425,17 +3425,18 @@ var BABYLON;
                 var promises = new Array();
                 this.logOpen(context + " " + (node.name || ""));
                 var loadNode = function (babylonTransformNode) {
+                    GLTFLoader.AddPointerMetadata(babylonTransformNode, context);
                     GLTFLoader._LoadTransform(node, babylonTransformNode);
                     if (node.camera != undefined) {
                         var camera = ArrayItem.Get(context + "/camera", _this.gltf.cameras, node.camera);
-                        promises.push(_this.loadCameraAsync("#/cameras/" + camera.index, camera, function (babylonCamera) {
+                        promises.push(_this.loadCameraAsync("/cameras/" + camera.index, camera, function (babylonCamera) {
                             babylonCamera.parent = babylonTransformNode;
                         }));
                     }
                     if (node.children) {
                         var _loop_1 = function (index) {
                             var childNode = ArrayItem.Get(context + "/children/" + index, _this.gltf.nodes, index);
-                            promises.push(_this.loadNodeAsync("#/nodes/" + node.index, childNode, function (childBabylonMesh) {
+                            promises.push(_this.loadNodeAsync("/nodes/" + childNode.index, childNode, function (childBabylonMesh) {
                                 // See https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#skins (second implementation note)
                                 if (childNode.skin != undefined) {
                                     childBabylonMesh.parent = _this._rootBabylonMesh;
@@ -3458,7 +3459,7 @@ var BABYLON;
                 }
                 else {
                     var mesh = ArrayItem.Get(context + "/mesh", this.gltf.meshes, node.mesh);
-                    promises.push(this._loadMeshAsync("#/meshes/" + mesh.index, node, mesh, loadNode));
+                    promises.push(this._loadMeshAsync("/meshes/" + mesh.index, node, mesh, loadNode));
                 }
                 this.logClose();
                 return Promise.all(promises).then(function () {
@@ -3499,7 +3500,7 @@ var BABYLON;
                 }
                 if (node.skin != undefined) {
                     var skin = ArrayItem.Get(context + "/skin", this.gltf.skins, node.skin);
-                    promises.push(this._loadSkinAsync("#/skins/" + skin.index, node, skin));
+                    promises.push(this._loadSkinAsync("/skins/" + skin.index, node, skin));
                 }
                 assign(node._babylonTransformNode);
                 this.logClose();
@@ -3539,7 +3540,7 @@ var BABYLON;
                     }
                     else {
                         var material = ArrayItem.Get(context + "/material", this.gltf.materials, primitive.material);
-                        promises.push(this._loadMaterialAsync("#/materials/" + material.index, material, babylonMesh_1, babylonDrawMode, function (babylonMaterial) {
+                        promises.push(this._loadMaterialAsync("/materials/" + material.index, material, babylonMesh_1, babylonDrawMode, function (babylonMaterial) {
                             babylonMesh_1.material = babylonMaterial;
                         }));
                     }
@@ -3552,6 +3553,7 @@ var BABYLON;
                     }
                     babylonAbstractMesh = babylonMesh_1;
                 }
+                GLTFLoader.AddPointerMetadata(babylonAbstractMesh, context);
                 this._parent.onMeshLoadedObservable.notifyObservers(babylonAbstractMesh);
                 assign(babylonAbstractMesh);
                 this.logClose();
@@ -3576,7 +3578,7 @@ var BABYLON;
                 }
                 else {
                     var accessor = ArrayItem.Get(context + "/indices", this.gltf.accessors, primitive.indices);
-                    promises.push(this._loadIndicesAccessorAsync("#/accessors/" + accessor.index, accessor).then(function (data) {
+                    promises.push(this._loadIndicesAccessorAsync("/accessors/" + accessor.index, accessor).then(function (data) {
                         babylonGeometry.setIndices(data);
                     }));
                 }
@@ -3589,7 +3591,7 @@ var BABYLON;
                         babylonMesh._delayInfo.push(kind);
                     }
                     var accessor = ArrayItem.Get(context + "/attributes/" + attribute, _this.gltf.accessors, attributes[attribute]);
-                    promises.push(_this._loadVertexAccessorAsync("#/accessors/" + accessor.index, accessor, kind).then(function (babylonVertexBuffer) {
+                    promises.push(_this._loadVertexAccessorAsync("/accessors/" + accessor.index, accessor, kind).then(function (babylonVertexBuffer) {
                         babylonGeometry.setVerticesBuffer(babylonVertexBuffer, accessor.count);
                     }));
                     if (callback) {
@@ -3653,7 +3655,7 @@ var BABYLON;
                         return;
                     }
                     var accessor = ArrayItem.Get(context + "/" + attribute, _this.gltf.accessors, attributes[attribute]);
-                    promises.push(_this._loadFloatAccessorAsync("#/accessors/" + accessor.index, accessor).then(function (data) {
+                    promises.push(_this._loadFloatAccessorAsync("/accessors/" + accessor.index, accessor).then(function (data) {
                         setData(babylonVertexBuffer, data);
                     }));
                 };
@@ -3766,7 +3768,7 @@ var BABYLON;
                     return Promise.resolve(null);
                 }
                 var accessor = ArrayItem.Get(context + "/inverseBindMatrices", this.gltf.accessors, skin.inverseBindMatrices);
-                return this._loadFloatAccessorAsync("#/accessors/" + accessor.index, accessor);
+                return this._loadFloatAccessorAsync("/accessors/" + accessor.index, accessor);
             };
             GLTFLoader.prototype._updateBoneMatrices = function (babylonSkeleton, inverseBindMatricesData) {
                 for (var _i = 0, _a = babylonSkeleton.bones; _i < _a.length; _i++) {
@@ -3835,8 +3837,9 @@ var BABYLON;
                         throw new Error(context + ": Invalid camera type (" + camera.type + ")");
                     }
                 }
-                assign(babylonCamera);
+                GLTFLoader.AddPointerMetadata(babylonCamera, context);
                 this._parent.onCameraLoadedObservable.notifyObservers(babylonCamera);
+                assign(babylonCamera);
                 return Promise.all(promises).then(function () {
                     return babylonCamera;
                 });
@@ -3849,7 +3852,7 @@ var BABYLON;
                 var promises = new Array();
                 for (var index = 0; index < animations.length; index++) {
                     var animation = animations[index];
-                    promises.push(this.loadAnimationAsync("#/animations/" + animation.index, animation));
+                    promises.push(this.loadAnimationAsync("/animations/" + animation.index, animation));
                 }
                 return Promise.all(promises).then(function () { });
             };
@@ -4052,8 +4055,8 @@ var BABYLON;
                 var inputAccessor = ArrayItem.Get(context + "/input", this.gltf.accessors, sampler.input);
                 var outputAccessor = ArrayItem.Get(context + "/output", this.gltf.accessors, sampler.output);
                 sampler._data = Promise.all([
-                    this._loadFloatAccessorAsync("#/accessors/" + inputAccessor.index, inputAccessor),
-                    this._loadFloatAccessorAsync("#/accessors/" + outputAccessor.index, outputAccessor)
+                    this._loadFloatAccessorAsync("/accessors/" + inputAccessor.index, inputAccessor),
+                    this._loadFloatAccessorAsync("/accessors/" + outputAccessor.index, outputAccessor)
                 ]).then(function (_a) {
                     var inputData = _a[0], outputData = _a[1];
                     return {
@@ -4085,7 +4088,7 @@ var BABYLON;
                     return bufferView._data;
                 }
                 var buffer = ArrayItem.Get(context + "/buffer", this.gltf.buffers, bufferView.buffer);
-                bufferView._data = this._loadBufferAsync("#/buffers/" + buffer.index, buffer).then(function (data) {
+                bufferView._data = this._loadBufferAsync("/buffers/" + buffer.index, buffer).then(function (data) {
                     try {
                         return new Uint8Array(data.buffer, data.byteOffset + (bufferView.byteOffset || 0), bufferView.byteLength);
                     }
@@ -4108,7 +4111,7 @@ var BABYLON;
                     return accessor._data;
                 }
                 var bufferView = ArrayItem.Get(context + "/bufferView", this.gltf.bufferViews, accessor.bufferView);
-                accessor._data = this.loadBufferViewAsync("#/bufferViews/" + bufferView.index, bufferView).then(function (data) {
+                accessor._data = this.loadBufferViewAsync("/bufferViews/" + bufferView.index, bufferView).then(function (data) {
                     return GLTFLoader._GetTypedArray(context, accessor.componentType, data, accessor.byteOffset, accessor.count);
                 });
                 return accessor._data;
@@ -4129,7 +4132,7 @@ var BABYLON;
                 }
                 else {
                     var bufferView = ArrayItem.Get(context + "/bufferView", this.gltf.bufferViews, accessor.bufferView);
-                    accessor._data = this.loadBufferViewAsync("#/bufferViews/" + bufferView.index, bufferView).then(function (data) {
+                    accessor._data = this.loadBufferViewAsync("/bufferViews/" + bufferView.index, bufferView).then(function (data) {
                         return GLTFLoader._GetTypedArray(context, accessor.componentType, data, accessor.byteOffset, length);
                     });
                 }
@@ -4139,8 +4142,8 @@ var BABYLON;
                         var indicesBufferView = ArrayItem.Get(context + "/sparse/indices/bufferView", _this.gltf.bufferViews, sparse_1.indices.bufferView);
                         var valuesBufferView = ArrayItem.Get(context + "/sparse/values/bufferView", _this.gltf.bufferViews, sparse_1.values.bufferView);
                         return Promise.all([
-                            _this.loadBufferViewAsync("#/bufferViews/" + indicesBufferView.index, indicesBufferView),
-                            _this.loadBufferViewAsync("#/bufferViews/" + valuesBufferView.index, valuesBufferView)
+                            _this.loadBufferViewAsync("/bufferViews/" + indicesBufferView.index, indicesBufferView),
+                            _this.loadBufferViewAsync("/bufferViews/" + valuesBufferView.index, valuesBufferView)
                         ]).then(function (_a) {
                             var indicesData = _a[0], valuesData = _a[1];
                             var indices = GLTFLoader._GetTypedArray(context + "/sparse/indices", sparse_1.indices.componentType, indicesData, sparse_1.indices.byteOffset, sparse_1.count);
@@ -4163,7 +4166,7 @@ var BABYLON;
                 if (bufferView._babylonBuffer) {
                     return bufferView._babylonBuffer;
                 }
-                bufferView._babylonBuffer = this.loadBufferViewAsync("#/bufferViews/" + bufferView.index, bufferView).then(function (data) {
+                bufferView._babylonBuffer = this.loadBufferViewAsync("/bufferViews/" + bufferView.index, bufferView).then(function (data) {
                     return new BABYLON.Buffer(_this.babylonScene.getEngine(), data, false);
                 });
                 return bufferView._babylonBuffer;
@@ -4174,14 +4177,14 @@ var BABYLON;
                     return accessor._babylonVertexBuffer;
                 }
                 if (accessor.sparse) {
-                    accessor._babylonVertexBuffer = this._loadFloatAccessorAsync("#/accessors/" + accessor.index, accessor).then(function (data) {
+                    accessor._babylonVertexBuffer = this._loadFloatAccessorAsync("/accessors/" + accessor.index, accessor).then(function (data) {
                         return new BABYLON.VertexBuffer(_this.babylonScene.getEngine(), data, kind, false);
                     });
                 }
                 // HACK: If byte offset is not a multiple of component type byte length then load as a float array instead of using Babylon buffers.
                 else if (accessor.byteOffset && accessor.byteOffset % BABYLON.VertexBuffer.GetTypeByteLength(accessor.componentType) !== 0) {
                     BABYLON.Tools.Warn("Accessor byte offset is not a multiple of component type byte length");
-                    accessor._babylonVertexBuffer = this._loadFloatAccessorAsync("#/accessors/" + accessor.index, accessor).then(function (data) {
+                    accessor._babylonVertexBuffer = this._loadFloatAccessorAsync("/accessors/" + accessor.index, accessor).then(function (data) {
                         return new BABYLON.VertexBuffer(_this.babylonScene.getEngine(), data, kind, false);
                     });
                 }
@@ -4211,11 +4214,13 @@ var BABYLON;
                     babylonMaterial.roughness = properties.roughnessFactor == undefined ? 1 : properties.roughnessFactor;
                     if (properties.baseColorTexture) {
                         promises.push(this.loadTextureInfoAsync(context + "/baseColorTexture", properties.baseColorTexture, function (texture) {
+                            texture.name = babylonMaterial.name + " (Base Color)";
                             babylonMaterial.albedoTexture = texture;
                         }));
                     }
                     if (properties.metallicRoughnessTexture) {
                         promises.push(this.loadTextureInfoAsync(context + "/metallicRoughnessTexture", properties.metallicRoughnessTexture, function (texture) {
+                            texture.name = babylonMaterial.name + " (Metallic Roughness)";
                             babylonMaterial.metallicTexture = texture;
                         }));
                         babylonMaterial.useMetallnessFromMetallicTextureBlue = true;
@@ -4243,6 +4248,7 @@ var BABYLON;
                         promise: this.loadMaterialPropertiesAsync(context, material, babylonMaterial)
                     };
                     material._data[babylonDrawMode] = babylonData;
+                    GLTFLoader.AddPointerMetadata(babylonMaterial, context);
                     this._parent.onMaterialLoadedObservable.notifyObservers(babylonMaterial);
                     this.logClose();
                 }
@@ -4283,7 +4289,8 @@ var BABYLON;
                     return extensionPromise;
                 }
                 var name = material.name || "material" + material.index;
-                return this._createDefaultMaterial(name, babylonDrawMode);
+                var babylonMaterial = this._createDefaultMaterial(name, babylonDrawMode);
+                return babylonMaterial;
             };
             /**
              * Loads properties from a glTF material into a Babylon material.
@@ -4324,6 +4331,7 @@ var BABYLON;
                 }
                 if (material.normalTexture) {
                     promises.push(this.loadTextureInfoAsync(context + "/normalTexture", material.normalTexture, function (texture) {
+                        texture.name = babylonMaterial.name + " (Normal)";
                         babylonMaterial.bumpTexture = texture;
                     }));
                     babylonMaterial.invertNormalMapX = !this.babylonScene.useRightHandedSystem;
@@ -4334,6 +4342,7 @@ var BABYLON;
                 }
                 if (material.occlusionTexture) {
                     promises.push(this.loadTextureInfoAsync(context + "/occlusionTexture", material.occlusionTexture, function (texture) {
+                        texture.name = babylonMaterial.name + " (Occlusion)";
                         babylonMaterial.ambientTexture = texture;
                     }));
                     babylonMaterial.useAmbientInGrayScale = true;
@@ -4343,6 +4352,7 @@ var BABYLON;
                 }
                 if (material.emissiveTexture) {
                     promises.push(this.loadTextureInfoAsync(context + "/emissiveTexture", material.emissiveTexture, function (texture) {
+                        texture.name = babylonMaterial.name + " (Emissive)";
                         babylonMaterial.emissiveTexture = texture;
                     }));
                 }
@@ -4394,6 +4404,7 @@ var BABYLON;
              * @returns A promise that resolves with the loaded Babylon texture when the load is complete
              */
             GLTFLoader.prototype.loadTextureInfoAsync = function (context, textureInfo, assign) {
+                var _this = this;
                 if (assign === void 0) { assign = function () { }; }
                 var extensionPromise = this._extensionsLoadTextureInfoAsync(context, textureInfo, assign);
                 if (extensionPromise) {
@@ -4401,8 +4412,10 @@ var BABYLON;
                 }
                 this.logOpen("" + context);
                 var texture = ArrayItem.Get(context + "/index", this.gltf.textures, textureInfo.index);
-                var promise = this._loadTextureAsync("#/textures/" + textureInfo.index, texture, function (babylonTexture) {
+                var promise = this._loadTextureAsync("/textures/" + textureInfo.index, texture, function (babylonTexture) {
                     babylonTexture.coordinatesIndex = textureInfo.texCoord || 0;
+                    GLTFLoader.AddPointerMetadata(babylonTexture, context);
+                    _this._parent.onTextureLoadedObservable.notifyObservers(babylonTexture);
                     assign(babylonTexture);
                 });
                 this.logClose();
@@ -4414,7 +4427,7 @@ var BABYLON;
                 var promises = new Array();
                 this.logOpen(context + " " + (texture.name || ""));
                 var sampler = (texture.sampler == undefined ? GLTFLoader._DefaultSampler : ArrayItem.Get(context + "/sampler", this.gltf.samplers, texture.sampler));
-                var samplerData = this._loadSampler("#/samplers/" + sampler.index, sampler);
+                var samplerData = this._loadSampler("/samplers/" + sampler.index, sampler);
                 var deferred = new BABYLON.Deferred();
                 var babylonTexture = new BABYLON.Texture(null, this.babylonScene, samplerData.noMipMaps, false, samplerData.samplingMode, function () {
                     if (!_this._disposed) {
@@ -4426,17 +4439,15 @@ var BABYLON;
                     }
                 });
                 promises.push(deferred.promise);
-                babylonTexture.name = texture.name || "texture" + texture.index;
                 babylonTexture.wrapU = samplerData.wrapU;
                 babylonTexture.wrapV = samplerData.wrapV;
                 var image = ArrayItem.Get(context + "/source", this.gltf.images, texture.source);
-                promises.push(this.loadImageAsync("#/images/" + image.index, image).then(function (data) {
+                promises.push(this.loadImageAsync("/images/" + image.index, image).then(function (data) {
                     var name = image.uri || _this._fileName + "#image" + image.index;
                     var dataUrl = "data:" + _this._uniqueRootUrl + name;
                     babylonTexture.updateURL(dataUrl, new Blob([data], { type: image.mimeType }));
                 }));
                 assign(babylonTexture);
-                this._parent.onTextureLoadedObservable.notifyObservers(babylonTexture);
                 this.logClose();
                 return Promise.all(promises).then(function () {
                     return babylonTexture;
@@ -4467,7 +4478,7 @@ var BABYLON;
                     }
                     else {
                         var bufferView = ArrayItem.Get(context + "/bufferView", this.gltf.bufferViews, image.bufferView);
-                        image._data = this.loadBufferViewAsync("#/bufferViews/" + bufferView.index, bufferView);
+                        image._data = this.loadBufferViewAsync("/bufferViews/" + bufferView.index, bufferView);
                     }
                     this.logClose();
                 }
@@ -4547,6 +4558,17 @@ var BABYLON;
                 }
                 this._progressCallback(new BABYLON.SceneLoaderProgressEvent(lengthComputable, loaded, lengthComputable ? total : 0));
             };
+            /**
+             * Adds a JSON pointer to the metadata of the Babylon object at `<object>.metadata.gltf.pointers`.
+             * @param babylonObject the Babylon object with metadata
+             * @param pointer the JSON pointer
+             */
+            GLTFLoader.AddPointerMetadata = function (babylonObject, pointer) {
+                var metadata = (babylonObject.metadata = babylonObject.metadata || {});
+                var gltf = (metadata.gltf = metadata.gltf || {});
+                var pointers = (gltf.pointers = gltf.pointers || []);
+                pointers.push(pointer);
+            };
             GLTFLoader._GetTextureWrapMode = function (context, mode) {
                 // Set defaults if undefined
                 mode = mode == undefined ? 10497 /* REPEAT */ : mode;
@@ -5575,14 +5597,14 @@ var BABYLON;
                         babylonMaterial.microSurface = properties.glossinessFactor == undefined ? 1 : properties.glossinessFactor;
                         if (properties.diffuseTexture) {
                             promises.push(this._loader.loadTextureInfoAsync(context + "/diffuseTexture", properties.diffuseTexture, function (texture) {
+                                texture.name = babylonMaterial.name + " (Diffuse)";
                                 babylonMaterial.albedoTexture = texture;
-                                return Promise.resolve();
                             }));
                         }
                         if (properties.specularGlossinessTexture) {
                             promises.push(this._loader.loadTextureInfoAsync(context + "/specularGlossinessTexture", properties.specularGlossinessTexture, function (texture) {
+                                texture.name = babylonMaterial.name + " (Specular Glossiness)";
                                 babylonMaterial.reflectivityTexture = texture;
-                                return Promise.resolve();
                             }));
                             babylonMaterial.reflectivityTexture.hasAlpha = true;
                             babylonMaterial.useMicroSurfaceFromReflectivityMapAlpha = true;
@@ -5650,8 +5672,8 @@ var BABYLON;
                             }
                             if (properties.baseColorTexture) {
                                 promises.push(this._loader.loadTextureInfoAsync(context + "/baseColorTexture", properties.baseColorTexture, function (texture) {
+                                    texture.name = babylonMaterial.name + " (Base Color)";
                                     babylonMaterial.albedoTexture = texture;
-                                    return Promise.resolve();
                                 }));
                             }
                         }
@@ -5747,6 +5769,7 @@ var BABYLON;
                                 babylonLight.intensity = light.intensity == undefined ? 1 : light.intensity;
                                 babylonLight.range = light.range == undefined ? Number.MAX_VALUE : light.range;
                                 babylonLight.parent = babylonMesh;
+                                GLTF2.GLTFLoader.AddPointerMetadata(babylonLight, extensionContext);
                                 assign(babylonMesh);
                             });
                         });

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


+ 8 - 0
dist/preview release/loaders/babylonjs.loaders.d.ts

@@ -1450,6 +1450,14 @@ declare module BABYLON.GLTF2 {
          */
         loadUriAsync(context: string, uri: string): Promise<ArrayBufferView>;
         private _onProgress;
+        /**
+         * Adds a JSON pointer to the metadata of the Babylon object at `<object>.metadata.gltf.pointers`.
+         * @param babylonObject the Babylon object with metadata
+         * @param pointer the JSON pointer
+         */
+        static AddPointerMetadata(babylonObject: {
+            metadata: any;
+        }, pointer: string): void;
         private static _GetTextureWrapMode;
         private static _GetTextureSamplingMode;
         private static _GetTypedArray;

+ 58 - 35
dist/preview release/loaders/babylonjs.loaders.js

@@ -4211,11 +4211,11 @@ var BABYLON;
                     _this._extensionsOnLoading();
                     var promises = new Array();
                     if (nodes) {
-                        promises.push(_this.loadSceneAsync("#/nodes", { nodes: nodes, index: -1 }));
+                        promises.push(_this.loadSceneAsync("/nodes", { nodes: nodes, index: -1 }));
                     }
                     else {
-                        var scene = ArrayItem.Get("#/scene", _this.gltf.scenes, _this.gltf.scene || 0);
-                        promises.push(_this.loadSceneAsync("#/scenes/" + scene.index, scene));
+                        var scene = ArrayItem.Get("/scene", _this.gltf.scenes, _this.gltf.scene || 0);
+                        promises.push(_this.loadSceneAsync("/scenes/" + scene.index, scene));
                     }
                     if (_this._parent.compileMaterials) {
                         promises.push(_this._compileMaterialsAsync());
@@ -4379,7 +4379,7 @@ var BABYLON;
                     for (var _i = 0, _a = scene.nodes; _i < _a.length; _i++) {
                         var index = _a[_i];
                         var node = ArrayItem.Get(context + "/nodes/" + index, this.gltf.nodes, index);
-                        promises.push(this.loadNodeAsync("#/nodes/" + node.index, node, function (babylonMesh) {
+                        promises.push(this.loadNodeAsync("/nodes/" + node.index, node, function (babylonMesh) {
                             babylonMesh.parent = _this._rootBabylonMesh;
                         }));
                     }
@@ -4487,17 +4487,18 @@ var BABYLON;
                 var promises = new Array();
                 this.logOpen(context + " " + (node.name || ""));
                 var loadNode = function (babylonTransformNode) {
+                    GLTFLoader.AddPointerMetadata(babylonTransformNode, context);
                     GLTFLoader._LoadTransform(node, babylonTransformNode);
                     if (node.camera != undefined) {
                         var camera = ArrayItem.Get(context + "/camera", _this.gltf.cameras, node.camera);
-                        promises.push(_this.loadCameraAsync("#/cameras/" + camera.index, camera, function (babylonCamera) {
+                        promises.push(_this.loadCameraAsync("/cameras/" + camera.index, camera, function (babylonCamera) {
                             babylonCamera.parent = babylonTransformNode;
                         }));
                     }
                     if (node.children) {
                         var _loop_1 = function (index) {
                             var childNode = ArrayItem.Get(context + "/children/" + index, _this.gltf.nodes, index);
-                            promises.push(_this.loadNodeAsync("#/nodes/" + node.index, childNode, function (childBabylonMesh) {
+                            promises.push(_this.loadNodeAsync("/nodes/" + childNode.index, childNode, function (childBabylonMesh) {
                                 // See https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#skins (second implementation note)
                                 if (childNode.skin != undefined) {
                                     childBabylonMesh.parent = _this._rootBabylonMesh;
@@ -4520,7 +4521,7 @@ var BABYLON;
                 }
                 else {
                     var mesh = ArrayItem.Get(context + "/mesh", this.gltf.meshes, node.mesh);
-                    promises.push(this._loadMeshAsync("#/meshes/" + mesh.index, node, mesh, loadNode));
+                    promises.push(this._loadMeshAsync("/meshes/" + mesh.index, node, mesh, loadNode));
                 }
                 this.logClose();
                 return Promise.all(promises).then(function () {
@@ -4561,7 +4562,7 @@ var BABYLON;
                 }
                 if (node.skin != undefined) {
                     var skin = ArrayItem.Get(context + "/skin", this.gltf.skins, node.skin);
-                    promises.push(this._loadSkinAsync("#/skins/" + skin.index, node, skin));
+                    promises.push(this._loadSkinAsync("/skins/" + skin.index, node, skin));
                 }
                 assign(node._babylonTransformNode);
                 this.logClose();
@@ -4601,7 +4602,7 @@ var BABYLON;
                     }
                     else {
                         var material = ArrayItem.Get(context + "/material", this.gltf.materials, primitive.material);
-                        promises.push(this._loadMaterialAsync("#/materials/" + material.index, material, babylonMesh_1, babylonDrawMode, function (babylonMaterial) {
+                        promises.push(this._loadMaterialAsync("/materials/" + material.index, material, babylonMesh_1, babylonDrawMode, function (babylonMaterial) {
                             babylonMesh_1.material = babylonMaterial;
                         }));
                     }
@@ -4614,6 +4615,7 @@ var BABYLON;
                     }
                     babylonAbstractMesh = babylonMesh_1;
                 }
+                GLTFLoader.AddPointerMetadata(babylonAbstractMesh, context);
                 this._parent.onMeshLoadedObservable.notifyObservers(babylonAbstractMesh);
                 assign(babylonAbstractMesh);
                 this.logClose();
@@ -4638,7 +4640,7 @@ var BABYLON;
                 }
                 else {
                     var accessor = ArrayItem.Get(context + "/indices", this.gltf.accessors, primitive.indices);
-                    promises.push(this._loadIndicesAccessorAsync("#/accessors/" + accessor.index, accessor).then(function (data) {
+                    promises.push(this._loadIndicesAccessorAsync("/accessors/" + accessor.index, accessor).then(function (data) {
                         babylonGeometry.setIndices(data);
                     }));
                 }
@@ -4651,7 +4653,7 @@ var BABYLON;
                         babylonMesh._delayInfo.push(kind);
                     }
                     var accessor = ArrayItem.Get(context + "/attributes/" + attribute, _this.gltf.accessors, attributes[attribute]);
-                    promises.push(_this._loadVertexAccessorAsync("#/accessors/" + accessor.index, accessor, kind).then(function (babylonVertexBuffer) {
+                    promises.push(_this._loadVertexAccessorAsync("/accessors/" + accessor.index, accessor, kind).then(function (babylonVertexBuffer) {
                         babylonGeometry.setVerticesBuffer(babylonVertexBuffer, accessor.count);
                     }));
                     if (callback) {
@@ -4715,7 +4717,7 @@ var BABYLON;
                         return;
                     }
                     var accessor = ArrayItem.Get(context + "/" + attribute, _this.gltf.accessors, attributes[attribute]);
-                    promises.push(_this._loadFloatAccessorAsync("#/accessors/" + accessor.index, accessor).then(function (data) {
+                    promises.push(_this._loadFloatAccessorAsync("/accessors/" + accessor.index, accessor).then(function (data) {
                         setData(babylonVertexBuffer, data);
                     }));
                 };
@@ -4828,7 +4830,7 @@ var BABYLON;
                     return Promise.resolve(null);
                 }
                 var accessor = ArrayItem.Get(context + "/inverseBindMatrices", this.gltf.accessors, skin.inverseBindMatrices);
-                return this._loadFloatAccessorAsync("#/accessors/" + accessor.index, accessor);
+                return this._loadFloatAccessorAsync("/accessors/" + accessor.index, accessor);
             };
             GLTFLoader.prototype._updateBoneMatrices = function (babylonSkeleton, inverseBindMatricesData) {
                 for (var _i = 0, _a = babylonSkeleton.bones; _i < _a.length; _i++) {
@@ -4897,8 +4899,9 @@ var BABYLON;
                         throw new Error(context + ": Invalid camera type (" + camera.type + ")");
                     }
                 }
-                assign(babylonCamera);
+                GLTFLoader.AddPointerMetadata(babylonCamera, context);
                 this._parent.onCameraLoadedObservable.notifyObservers(babylonCamera);
+                assign(babylonCamera);
                 return Promise.all(promises).then(function () {
                     return babylonCamera;
                 });
@@ -4911,7 +4914,7 @@ var BABYLON;
                 var promises = new Array();
                 for (var index = 0; index < animations.length; index++) {
                     var animation = animations[index];
-                    promises.push(this.loadAnimationAsync("#/animations/" + animation.index, animation));
+                    promises.push(this.loadAnimationAsync("/animations/" + animation.index, animation));
                 }
                 return Promise.all(promises).then(function () { });
             };
@@ -5114,8 +5117,8 @@ var BABYLON;
                 var inputAccessor = ArrayItem.Get(context + "/input", this.gltf.accessors, sampler.input);
                 var outputAccessor = ArrayItem.Get(context + "/output", this.gltf.accessors, sampler.output);
                 sampler._data = Promise.all([
-                    this._loadFloatAccessorAsync("#/accessors/" + inputAccessor.index, inputAccessor),
-                    this._loadFloatAccessorAsync("#/accessors/" + outputAccessor.index, outputAccessor)
+                    this._loadFloatAccessorAsync("/accessors/" + inputAccessor.index, inputAccessor),
+                    this._loadFloatAccessorAsync("/accessors/" + outputAccessor.index, outputAccessor)
                 ]).then(function (_a) {
                     var inputData = _a[0], outputData = _a[1];
                     return {
@@ -5147,7 +5150,7 @@ var BABYLON;
                     return bufferView._data;
                 }
                 var buffer = ArrayItem.Get(context + "/buffer", this.gltf.buffers, bufferView.buffer);
-                bufferView._data = this._loadBufferAsync("#/buffers/" + buffer.index, buffer).then(function (data) {
+                bufferView._data = this._loadBufferAsync("/buffers/" + buffer.index, buffer).then(function (data) {
                     try {
                         return new Uint8Array(data.buffer, data.byteOffset + (bufferView.byteOffset || 0), bufferView.byteLength);
                     }
@@ -5170,7 +5173,7 @@ var BABYLON;
                     return accessor._data;
                 }
                 var bufferView = ArrayItem.Get(context + "/bufferView", this.gltf.bufferViews, accessor.bufferView);
-                accessor._data = this.loadBufferViewAsync("#/bufferViews/" + bufferView.index, bufferView).then(function (data) {
+                accessor._data = this.loadBufferViewAsync("/bufferViews/" + bufferView.index, bufferView).then(function (data) {
                     return GLTFLoader._GetTypedArray(context, accessor.componentType, data, accessor.byteOffset, accessor.count);
                 });
                 return accessor._data;
@@ -5191,7 +5194,7 @@ var BABYLON;
                 }
                 else {
                     var bufferView = ArrayItem.Get(context + "/bufferView", this.gltf.bufferViews, accessor.bufferView);
-                    accessor._data = this.loadBufferViewAsync("#/bufferViews/" + bufferView.index, bufferView).then(function (data) {
+                    accessor._data = this.loadBufferViewAsync("/bufferViews/" + bufferView.index, bufferView).then(function (data) {
                         return GLTFLoader._GetTypedArray(context, accessor.componentType, data, accessor.byteOffset, length);
                     });
                 }
@@ -5201,8 +5204,8 @@ var BABYLON;
                         var indicesBufferView = ArrayItem.Get(context + "/sparse/indices/bufferView", _this.gltf.bufferViews, sparse_1.indices.bufferView);
                         var valuesBufferView = ArrayItem.Get(context + "/sparse/values/bufferView", _this.gltf.bufferViews, sparse_1.values.bufferView);
                         return Promise.all([
-                            _this.loadBufferViewAsync("#/bufferViews/" + indicesBufferView.index, indicesBufferView),
-                            _this.loadBufferViewAsync("#/bufferViews/" + valuesBufferView.index, valuesBufferView)
+                            _this.loadBufferViewAsync("/bufferViews/" + indicesBufferView.index, indicesBufferView),
+                            _this.loadBufferViewAsync("/bufferViews/" + valuesBufferView.index, valuesBufferView)
                         ]).then(function (_a) {
                             var indicesData = _a[0], valuesData = _a[1];
                             var indices = GLTFLoader._GetTypedArray(context + "/sparse/indices", sparse_1.indices.componentType, indicesData, sparse_1.indices.byteOffset, sparse_1.count);
@@ -5225,7 +5228,7 @@ var BABYLON;
                 if (bufferView._babylonBuffer) {
                     return bufferView._babylonBuffer;
                 }
-                bufferView._babylonBuffer = this.loadBufferViewAsync("#/bufferViews/" + bufferView.index, bufferView).then(function (data) {
+                bufferView._babylonBuffer = this.loadBufferViewAsync("/bufferViews/" + bufferView.index, bufferView).then(function (data) {
                     return new BABYLON.Buffer(_this.babylonScene.getEngine(), data, false);
                 });
                 return bufferView._babylonBuffer;
@@ -5236,14 +5239,14 @@ var BABYLON;
                     return accessor._babylonVertexBuffer;
                 }
                 if (accessor.sparse) {
-                    accessor._babylonVertexBuffer = this._loadFloatAccessorAsync("#/accessors/" + accessor.index, accessor).then(function (data) {
+                    accessor._babylonVertexBuffer = this._loadFloatAccessorAsync("/accessors/" + accessor.index, accessor).then(function (data) {
                         return new BABYLON.VertexBuffer(_this.babylonScene.getEngine(), data, kind, false);
                     });
                 }
                 // HACK: If byte offset is not a multiple of component type byte length then load as a float array instead of using Babylon buffers.
                 else if (accessor.byteOffset && accessor.byteOffset % BABYLON.VertexBuffer.GetTypeByteLength(accessor.componentType) !== 0) {
                     BABYLON.Tools.Warn("Accessor byte offset is not a multiple of component type byte length");
-                    accessor._babylonVertexBuffer = this._loadFloatAccessorAsync("#/accessors/" + accessor.index, accessor).then(function (data) {
+                    accessor._babylonVertexBuffer = this._loadFloatAccessorAsync("/accessors/" + accessor.index, accessor).then(function (data) {
                         return new BABYLON.VertexBuffer(_this.babylonScene.getEngine(), data, kind, false);
                     });
                 }
@@ -5273,11 +5276,13 @@ var BABYLON;
                     babylonMaterial.roughness = properties.roughnessFactor == undefined ? 1 : properties.roughnessFactor;
                     if (properties.baseColorTexture) {
                         promises.push(this.loadTextureInfoAsync(context + "/baseColorTexture", properties.baseColorTexture, function (texture) {
+                            texture.name = babylonMaterial.name + " (Base Color)";
                             babylonMaterial.albedoTexture = texture;
                         }));
                     }
                     if (properties.metallicRoughnessTexture) {
                         promises.push(this.loadTextureInfoAsync(context + "/metallicRoughnessTexture", properties.metallicRoughnessTexture, function (texture) {
+                            texture.name = babylonMaterial.name + " (Metallic Roughness)";
                             babylonMaterial.metallicTexture = texture;
                         }));
                         babylonMaterial.useMetallnessFromMetallicTextureBlue = true;
@@ -5305,6 +5310,7 @@ var BABYLON;
                         promise: this.loadMaterialPropertiesAsync(context, material, babylonMaterial)
                     };
                     material._data[babylonDrawMode] = babylonData;
+                    GLTFLoader.AddPointerMetadata(babylonMaterial, context);
                     this._parent.onMaterialLoadedObservable.notifyObservers(babylonMaterial);
                     this.logClose();
                 }
@@ -5345,7 +5351,8 @@ var BABYLON;
                     return extensionPromise;
                 }
                 var name = material.name || "material" + material.index;
-                return this._createDefaultMaterial(name, babylonDrawMode);
+                var babylonMaterial = this._createDefaultMaterial(name, babylonDrawMode);
+                return babylonMaterial;
             };
             /**
              * Loads properties from a glTF material into a Babylon material.
@@ -5386,6 +5393,7 @@ var BABYLON;
                 }
                 if (material.normalTexture) {
                     promises.push(this.loadTextureInfoAsync(context + "/normalTexture", material.normalTexture, function (texture) {
+                        texture.name = babylonMaterial.name + " (Normal)";
                         babylonMaterial.bumpTexture = texture;
                     }));
                     babylonMaterial.invertNormalMapX = !this.babylonScene.useRightHandedSystem;
@@ -5396,6 +5404,7 @@ var BABYLON;
                 }
                 if (material.occlusionTexture) {
                     promises.push(this.loadTextureInfoAsync(context + "/occlusionTexture", material.occlusionTexture, function (texture) {
+                        texture.name = babylonMaterial.name + " (Occlusion)";
                         babylonMaterial.ambientTexture = texture;
                     }));
                     babylonMaterial.useAmbientInGrayScale = true;
@@ -5405,6 +5414,7 @@ var BABYLON;
                 }
                 if (material.emissiveTexture) {
                     promises.push(this.loadTextureInfoAsync(context + "/emissiveTexture", material.emissiveTexture, function (texture) {
+                        texture.name = babylonMaterial.name + " (Emissive)";
                         babylonMaterial.emissiveTexture = texture;
                     }));
                 }
@@ -5456,6 +5466,7 @@ var BABYLON;
              * @returns A promise that resolves with the loaded Babylon texture when the load is complete
              */
             GLTFLoader.prototype.loadTextureInfoAsync = function (context, textureInfo, assign) {
+                var _this = this;
                 if (assign === void 0) { assign = function () { }; }
                 var extensionPromise = this._extensionsLoadTextureInfoAsync(context, textureInfo, assign);
                 if (extensionPromise) {
@@ -5463,8 +5474,10 @@ var BABYLON;
                 }
                 this.logOpen("" + context);
                 var texture = ArrayItem.Get(context + "/index", this.gltf.textures, textureInfo.index);
-                var promise = this._loadTextureAsync("#/textures/" + textureInfo.index, texture, function (babylonTexture) {
+                var promise = this._loadTextureAsync("/textures/" + textureInfo.index, texture, function (babylonTexture) {
                     babylonTexture.coordinatesIndex = textureInfo.texCoord || 0;
+                    GLTFLoader.AddPointerMetadata(babylonTexture, context);
+                    _this._parent.onTextureLoadedObservable.notifyObservers(babylonTexture);
                     assign(babylonTexture);
                 });
                 this.logClose();
@@ -5476,7 +5489,7 @@ var BABYLON;
                 var promises = new Array();
                 this.logOpen(context + " " + (texture.name || ""));
                 var sampler = (texture.sampler == undefined ? GLTFLoader._DefaultSampler : ArrayItem.Get(context + "/sampler", this.gltf.samplers, texture.sampler));
-                var samplerData = this._loadSampler("#/samplers/" + sampler.index, sampler);
+                var samplerData = this._loadSampler("/samplers/" + sampler.index, sampler);
                 var deferred = new BABYLON.Deferred();
                 var babylonTexture = new BABYLON.Texture(null, this.babylonScene, samplerData.noMipMaps, false, samplerData.samplingMode, function () {
                     if (!_this._disposed) {
@@ -5488,17 +5501,15 @@ var BABYLON;
                     }
                 });
                 promises.push(deferred.promise);
-                babylonTexture.name = texture.name || "texture" + texture.index;
                 babylonTexture.wrapU = samplerData.wrapU;
                 babylonTexture.wrapV = samplerData.wrapV;
                 var image = ArrayItem.Get(context + "/source", this.gltf.images, texture.source);
-                promises.push(this.loadImageAsync("#/images/" + image.index, image).then(function (data) {
+                promises.push(this.loadImageAsync("/images/" + image.index, image).then(function (data) {
                     var name = image.uri || _this._fileName + "#image" + image.index;
                     var dataUrl = "data:" + _this._uniqueRootUrl + name;
                     babylonTexture.updateURL(dataUrl, new Blob([data], { type: image.mimeType }));
                 }));
                 assign(babylonTexture);
-                this._parent.onTextureLoadedObservable.notifyObservers(babylonTexture);
                 this.logClose();
                 return Promise.all(promises).then(function () {
                     return babylonTexture;
@@ -5529,7 +5540,7 @@ var BABYLON;
                     }
                     else {
                         var bufferView = ArrayItem.Get(context + "/bufferView", this.gltf.bufferViews, image.bufferView);
-                        image._data = this.loadBufferViewAsync("#/bufferViews/" + bufferView.index, bufferView);
+                        image._data = this.loadBufferViewAsync("/bufferViews/" + bufferView.index, bufferView);
                     }
                     this.logClose();
                 }
@@ -5609,6 +5620,17 @@ var BABYLON;
                 }
                 this._progressCallback(new BABYLON.SceneLoaderProgressEvent(lengthComputable, loaded, lengthComputable ? total : 0));
             };
+            /**
+             * Adds a JSON pointer to the metadata of the Babylon object at `<object>.metadata.gltf.pointers`.
+             * @param babylonObject the Babylon object with metadata
+             * @param pointer the JSON pointer
+             */
+            GLTFLoader.AddPointerMetadata = function (babylonObject, pointer) {
+                var metadata = (babylonObject.metadata = babylonObject.metadata || {});
+                var gltf = (metadata.gltf = metadata.gltf || {});
+                var pointers = (gltf.pointers = gltf.pointers || []);
+                pointers.push(pointer);
+            };
             GLTFLoader._GetTextureWrapMode = function (context, mode) {
                 // Set defaults if undefined
                 mode = mode == undefined ? 10497 /* REPEAT */ : mode;
@@ -6637,14 +6659,14 @@ var BABYLON;
                         babylonMaterial.microSurface = properties.glossinessFactor == undefined ? 1 : properties.glossinessFactor;
                         if (properties.diffuseTexture) {
                             promises.push(this._loader.loadTextureInfoAsync(context + "/diffuseTexture", properties.diffuseTexture, function (texture) {
+                                texture.name = babylonMaterial.name + " (Diffuse)";
                                 babylonMaterial.albedoTexture = texture;
-                                return Promise.resolve();
                             }));
                         }
                         if (properties.specularGlossinessTexture) {
                             promises.push(this._loader.loadTextureInfoAsync(context + "/specularGlossinessTexture", properties.specularGlossinessTexture, function (texture) {
+                                texture.name = babylonMaterial.name + " (Specular Glossiness)";
                                 babylonMaterial.reflectivityTexture = texture;
-                                return Promise.resolve();
                             }));
                             babylonMaterial.reflectivityTexture.hasAlpha = true;
                             babylonMaterial.useMicroSurfaceFromReflectivityMapAlpha = true;
@@ -6712,8 +6734,8 @@ var BABYLON;
                             }
                             if (properties.baseColorTexture) {
                                 promises.push(this._loader.loadTextureInfoAsync(context + "/baseColorTexture", properties.baseColorTexture, function (texture) {
+                                    texture.name = babylonMaterial.name + " (Base Color)";
                                     babylonMaterial.albedoTexture = texture;
-                                    return Promise.resolve();
                                 }));
                             }
                         }
@@ -6809,6 +6831,7 @@ var BABYLON;
                                 babylonLight.intensity = light.intensity == undefined ? 1 : light.intensity;
                                 babylonLight.range = light.range == undefined ? Number.MAX_VALUE : light.range;
                                 babylonLight.parent = babylonMesh;
+                                GLTF2.GLTFLoader.AddPointerMetadata(babylonLight, extensionContext);
                                 assign(babylonMesh);
                             });
                         });

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


+ 8 - 0
dist/preview release/loaders/babylonjs.loaders.module.d.ts

@@ -1457,6 +1457,14 @@ declare module BABYLON.GLTF2 {
          */
         loadUriAsync(context: string, uri: string): Promise<ArrayBufferView>;
         private _onProgress;
+        /**
+         * Adds a JSON pointer to the metadata of the Babylon object at `<object>.metadata.gltf.pointers`.
+         * @param babylonObject the Babylon object with metadata
+         * @param pointer the JSON pointer
+         */
+        static AddPointerMetadata(babylonObject: {
+            metadata: any;
+        }, pointer: string): void;
         private static _GetTextureWrapMode;
         private static _GetTextureSamplingMode;
         private static _GetTypedArray;

+ 3 - 3
dist/preview release/loaders/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-loaders",
     "description": "The Babylon.js file loaders library is an extension you can use to load different 3D file types into a Babylon scene.",
-    "version": "4.0.0-alpha.6",
+    "version": "4.0.0-alpha.7",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"
@@ -27,8 +27,8 @@
     ],
     "license": "Apache-2.0",
     "dependencies": {
-        "babylonjs-gltf2interface": "4.0.0-alpha.6",
-        "babylonjs": "4.0.0-alpha.6"
+        "babylonjs-gltf2interface": "4.0.0-alpha.7",
+        "babylonjs": "4.0.0-alpha.7"
     },
     "engines": {
         "node": "*"

+ 2 - 2
dist/preview release/materialsLibrary/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-materials",
     "description": "The Babylon.js materials library is a collection of advanced materials to be used in a Babylon.js scene.",
-    "version": "4.0.0-alpha.6",
+    "version": "4.0.0-alpha.7",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"
@@ -27,7 +27,7 @@
     ],
     "license": "Apache-2.0",
     "dependencies": {
-        "babylonjs": "4.0.0-alpha.6"
+        "babylonjs": "4.0.0-alpha.7"
     },
     "engines": {
         "node": "*"

+ 2 - 2
dist/preview release/postProcessesLibrary/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-post-process",
     "description": "The Babylon.js materials library is a collection of advanced materials to be used in a Babylon.js scene.",
-    "version": "4.0.0-alpha.6",
+    "version": "4.0.0-alpha.7",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"
@@ -27,7 +27,7 @@
     ],
     "license": "Apache-2.0",
     "dependencies": {
-        "babylonjs": "4.0.0-alpha.6"
+        "babylonjs": "4.0.0-alpha.7"
     },
     "engines": {
         "node": "*"

+ 2 - 2
dist/preview release/proceduralTexturesLibrary/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-procedural-textures",
     "description": "The Babylon.js materials library is a collection of advanced materials to be used in a Babylon.js scene.",
-    "version": "4.0.0-alpha.6",
+    "version": "4.0.0-alpha.7",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"
@@ -27,7 +27,7 @@
     ],
     "license": "Apache-2.0",
     "dependencies": {
-        "babylonjs": "4.0.0-alpha.6"
+        "babylonjs": "4.0.0-alpha.7"
     },
     "engines": {
         "node": "*"

+ 3 - 3
dist/preview release/serializers/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-serializers",
     "description": "The Babylon.js serializers library is an extension you can use to serialize Babylon scenes.",
-    "version": "4.0.0-alpha.6",
+    "version": "4.0.0-alpha.7",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"
@@ -27,8 +27,8 @@
     ],
     "license": "Apache-2.0",
     "dependencies": {
-        "babylonjs": "4.0.0-alpha.6",
-        "babylonjs-gltf2interface": "4.0.0-alpha.6"
+        "babylonjs": "4.0.0-alpha.7",
+        "babylonjs-gltf2interface": "4.0.0-alpha.7"
     },
     "engines": {
         "node": "*"

+ 5 - 19
dist/preview release/viewer/babylon.viewer.d.ts

@@ -168,11 +168,11 @@ declare module BabylonViewer {
                 * Mainly used for help and errors
                 * @param subScreen the name of the subScreen. Those can be defined in the configuration object
                 */
-            showOverlayScreen(subScreen: string): Promise<Template> | Promise<string>;
+            showOverlayScreen(subScreen: string): Promise<string> | Promise<Template>;
             /**
                 * Hide the overlay screen.
                 */
-            hideOverlayScreen(): Promise<Template> | Promise<string>;
+            hideOverlayScreen(): Promise<string> | Promise<Template>;
             /**
                 * show the viewer (in case it was hidden)
                 *
@@ -189,11 +189,11 @@ declare module BabylonViewer {
                 * Show the loading screen.
                 * The loading screen can be configured using the configuration object
                 */
-            showLoadingScreen(): Promise<Template> | Promise<string>;
+            showLoadingScreen(): Promise<string> | Promise<Template>;
             /**
                 * Hide the loading screen
                 */
-            hideLoadingScreen(): Promise<Template> | Promise<string>;
+            hideLoadingScreen(): Promise<string> | Promise<Template>;
             dispose(): void;
             protected _onConfigurationLoaded(configuration: ViewerConfiguration): void;
     }
@@ -924,7 +924,7 @@ declare module BabylonViewer {
       * @param name the name of the custom optimizer configuration
       * @param upgrade set to true if you want to upgrade optimizer and false if you want to degrade
       */
-    export function getCustomOptimizerByName(name: string, upgrade?: boolean): typeof extendedUpgrade;
+    export function getCustomOptimizerByName(name: string, upgrade?: boolean): (sceneManager: SceneManager) => boolean;
     export function registerCustomOptimizer(name: string, optimizer: (sceneManager: SceneManager) => boolean): void;
 }
 declare module BabylonViewer {
@@ -1558,20 +1558,6 @@ declare module BabylonViewer {
     export function addLoaderPlugin(name: string, plugin: ILoaderPlugin): void;
 }
 declare module BabylonViewer {
-    /**
-        * A custom upgrade-oriented function configuration for the scene optimizer.
-        *
-        * @param viewer the viewer to optimize
-        */
-    export function extendedUpgrade(sceneManager: SceneManager): boolean;
-    /**
-        * A custom degrade-oriented function configuration for the scene optimizer.
-        *
-        * @param viewer the viewer to optimize
-        */
-    export function extendedDegrade(sceneManager: SceneManager): boolean;
-}
-declare module BabylonViewer {
 }
 declare module BabylonViewer {
     export interface IEnvironmentMapConfiguration {

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


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


+ 5 - 22
dist/preview release/viewer/babylon.viewer.module.d.ts

@@ -200,11 +200,11 @@ declare module 'babylonjs-viewer/viewer/defaultViewer' {
                 * Mainly used for help and errors
                 * @param subScreen the name of the subScreen. Those can be defined in the configuration object
                 */
-            showOverlayScreen(subScreen: string): Promise<Template> | Promise<string>;
+            showOverlayScreen(subScreen: string): Promise<string> | Promise<Template>;
             /**
                 * Hide the overlay screen.
                 */
-            hideOverlayScreen(): Promise<Template> | Promise<string>;
+            hideOverlayScreen(): Promise<string> | Promise<Template>;
             /**
                 * show the viewer (in case it was hidden)
                 *
@@ -221,11 +221,11 @@ declare module 'babylonjs-viewer/viewer/defaultViewer' {
                 * Show the loading screen.
                 * The loading screen can be configured using the configuration object
                 */
-            showLoadingScreen(): Promise<Template> | Promise<string>;
+            showLoadingScreen(): Promise<string> | Promise<Template>;
             /**
                 * Hide the loading screen
                 */
-            hideLoadingScreen(): Promise<Template> | Promise<string>;
+            hideLoadingScreen(): Promise<string> | Promise<Template>;
             dispose(): void;
             protected _onConfigurationLoaded(configuration: ViewerConfiguration): void;
     }
@@ -985,14 +985,13 @@ declare module 'babylonjs-viewer/templating/viewerTemplatePlugin' {
 }
 
 declare module 'babylonjs-viewer/optimizer/custom' {
-    import { extendedUpgrade } from "babylonjs-viewer/optimizer/custom/extended";
     import { SceneManager } from "babylonjs-viewer/managers/sceneManager";
     /**
       *
       * @param name the name of the custom optimizer configuration
       * @param upgrade set to true if you want to upgrade optimizer and false if you want to degrade
       */
-    export function getCustomOptimizerByName(name: string, upgrade?: boolean): typeof extendedUpgrade;
+    export function getCustomOptimizerByName(name: string, upgrade?: boolean): (sceneManager: SceneManager) => boolean;
     export function registerCustomOptimizer(name: string, optimizer: (sceneManager: SceneManager) => boolean): void;
 }
 
@@ -1663,22 +1662,6 @@ declare module 'babylonjs-viewer/loader/plugins' {
     export function addLoaderPlugin(name: string, plugin: ILoaderPlugin): void;
 }
 
-declare module 'babylonjs-viewer/optimizer/custom/extended' {
-    import { SceneManager } from 'babylonjs-viewer/managers/sceneManager';
-    /**
-        * A custom upgrade-oriented function configuration for the scene optimizer.
-        *
-        * @param viewer the viewer to optimize
-        */
-    export function extendedUpgrade(sceneManager: SceneManager): boolean;
-    /**
-        * A custom degrade-oriented function configuration for the scene optimizer.
-        *
-        * @param viewer the viewer to optimize
-        */
-    export function extendedDegrade(sceneManager: SceneManager): boolean;
-}
-
 declare module 'babylonjs-viewer/configuration/interfaces' {
     export * from 'babylonjs-viewer/configuration/interfaces/cameraConfiguration';
     export * from 'babylonjs-viewer/configuration/interfaces/colorGradingConfiguration';

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

@@ -61,6 +61,7 @@
 - Added support for deserializing morph target animations in animation groups
 - AssetContainer dispose method ([TrevorDev](https://github.com/TrevorDev))
 - Loading texture with KTX will fallback to non-KTX loader if KTX loader fails ([TrevorDev](https://github.com/TrevorDev))
+- `Layer` are now supported in `RenderTargetTexture` ([Sebavan](https://github.com/Sebavan))
 
 ### glTF Loader
 
@@ -78,12 +79,13 @@
 - Removed bones from rootNodes where they should never have been ([Deltakosh](https://github.com/deltakosh))
 - Refocusing on input gui with pointer events ([TrevorDev](https://github.com/TrevorDev))
 - Gizmo scaling not consistent when camera is parented ([TrevorDev](https://github.com/TrevorDev))
-- Context loss causing unexpected results with dynamic textures ([TrevorDev](https://github.com/TrevorDev))
+- Context loss causing unexpected results with dynamic textures, geometries with the same name and reflectionTextures ([TrevorDev](https://github.com/TrevorDev))
 - CreateScreenshotUsingRenderTarget stretches mirror textures when setting both width and height ([TrevorDev](https://github.com/TrevorDev))
 - VR helper only updating vr cameras position when entering vr, rotation was missing ([TrevorDev](https://github.com/TrevorDev))
 - Fix VR controllers after gltfLoader transformNode change ([TrevorDev](https://github.com/TrevorDev))
 - Bounding Box fixedDragMeshScreenSize stopped working and allow rotating through bounding box ([TrevorDev](https://github.com/TrevorDev))
 - VR helper would rotate non vr camera while in VR ([TrevorDev](https://github.com/TrevorDev))
+- PointerDragBahavior using Mesh as base type, causing type-checking problems with AbstractMesh ([Poolminer](https://github.com/Poolminer/))
 
 ### Core Engine
 - Fixed a bug with `mesh.alwaysSelectAsActiveMesh` preventing layerMask to be taken in account ([Deltakosh](https://github.com/deltakosh))
@@ -95,6 +97,7 @@
 - Add missing effect layer to asset container ([TrevorDev](https://github.com/TrevorDev))
 - Fixed effect layer compatibility with multi materials ([Sebavan](https://github.com/Sebavan))
 - Added a `DeepImmutable<T>` type to specifiy that a referenced object should be considered recursively immutable, meaning that all its properties are `readonly` and that if a property is a reference to an object, this object is also recursively immutable. ([barroij](https://github.com/barroij))
+- Fixed `VideoTexture` poster property when autoplay is turned off.
 
 ### Viewer
 

+ 5 - 0
gui/src/2D/controls/control.ts

@@ -86,6 +86,11 @@ export class Control {
     /** @hidden */
     public _tag: any;
 
+    /**
+     * Gets or sets an object used to store user defined information for the node
+     */
+    public metadata: any = null;
+
     /** Gets or sets a boolean indicating if the control can be hit with pointer events */
     public isHitTestVisible = true;
     /** Gets or sets a boolean indicating if the control can block pointer events */

+ 3 - 1
gui/src/2D/valueAndUnit.ts

@@ -5,6 +5,7 @@ import { AdvancedDynamicTexture } from "./advancedDynamicTexture";
  */
 export class ValueAndUnit {
     private _value = 1;
+    private _originalUnit: number;
     /**
      * Gets or sets a value indicating that this value will not scale accordingly with adaptive scaling property
      * @see http://doc.babylonjs.com/how_to/gui#adaptive-scaling
@@ -23,6 +24,7 @@ export class ValueAndUnit {
         /** defines a boolean indicating if the value can be negative */
         public negativeValueAllowed = true) {
         this._value = value;
+        this._originalUnit = unit;
     }
 
     /** Gets a boolean indicating if the value is a percentage */
@@ -116,7 +118,7 @@ export class ValueAndUnit {
         }
 
         var sourceValue = parseFloat(match[1]);
-        var sourceUnit = this.unit;
+        var sourceUnit = this._originalUnit;
 
         if (!this.negativeValueAllowed) {
             if (sourceValue < 0) {

+ 1 - 1
package.json

@@ -9,7 +9,7 @@
     ],
     "name": "babylonjs",
     "description": "Babylon.js is a JavaScript 3D engine based on webgl.",
-    "version": "4.0.0-alpha.6",
+    "version": "4.0.0-alpha.7",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"

+ 3 - 3
src/Behaviors/Mesh/babylon.pointerDragBehavior.ts

@@ -2,9 +2,9 @@ module BABYLON {
     /**
      * A behavior that when attached to a mesh will allow the mesh to be dragged around the screen based on pointer events
      */
-    export class PointerDragBehavior implements Behavior<Mesh> {
+    export class PointerDragBehavior implements Behavior<AbstractMesh> {
         private static _AnyMouseID = -2;
-        private _attachedNode: Mesh;
+        private _attachedNode: AbstractMesh;
         private _dragPlane: Mesh;
         private _scene: Scene;
         private _pointerObserver: Nullable<Observer<PointerInfo>>;
@@ -117,7 +117,7 @@ module BABYLON {
          * Attaches the drag behavior the passed in mesh
          * @param ownerNode The mesh that will be dragged around once attached
          */
-        public attach(ownerNode: Mesh): void {
+        public attach(ownerNode: AbstractMesh): void {
             this._scene = ownerNode.getScene();
             this._attachedNode = ownerNode;
 

+ 9 - 7
src/Cameras/babylon.targetCamera.ts

@@ -5,6 +5,8 @@ module BABYLON {
      * @see http://doc.babylonjs.com/features/cameras
      */
     export class TargetCamera extends Camera {
+        private static _RigCamTransformMatrix = new Matrix();
+        private static _TargetTransformMatrix = new Matrix();
 
         /**
          * Define the current direction the camera is moving to
@@ -59,7 +61,6 @@ module BABYLON {
         public _cameraTransformMatrix = Matrix.Zero();
         /** @hidden */
         public _cameraRotationMatrix = Matrix.Zero();
-        private _rigCamTransformMatrix: Matrix;
 
         /** @hidden */
         public _referencePoint = new Vector3(0, 0, 1);
@@ -435,6 +436,8 @@ module BABYLON {
             var camLeft = <TargetCamera>this._rigCameras[0];
             var camRight = <TargetCamera>this._rigCameras[1];
 
+            this.computeWorldMatrix();
+
             switch (this.cameraRigMode) {
                 case Camera.RIG_MODE_STEREOSCOPIC_ANAGLYPH:
                 case Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_PARALLEL:
@@ -467,15 +470,14 @@ module BABYLON {
         }
 
         private _getRigCamPosition(halfSpace: number, result: Vector3) {
-            if (!this._rigCamTransformMatrix) {
-                this._rigCamTransformMatrix = new Matrix();
-            }
             var target = this.getTarget();
-            Matrix.Translation(-target.x, -target.y, -target.z).multiplyToRef(Matrix.RotationY(halfSpace), this._rigCamTransformMatrix);
+            Matrix.TranslationToRef(-target.x, -target.y, -target.z, TargetCamera._TargetTransformMatrix);
+            TargetCamera._TargetTransformMatrix.multiplyToRef(Matrix.RotationY(halfSpace), TargetCamera._RigCamTransformMatrix);
+            Matrix.TranslationToRef(target.x, target.y, target.z, TargetCamera._TargetTransformMatrix);
 
-            this._rigCamTransformMatrix = this._rigCamTransformMatrix.multiply(Matrix.Translation(target.x, target.y, target.z));
+            TargetCamera._RigCamTransformMatrix.multiplyToRef(TargetCamera._TargetTransformMatrix, TargetCamera._RigCamTransformMatrix);
 
-            Vector3.TransformCoordinatesToRef(this.position, this._rigCamTransformMatrix, result);
+            Vector3.TransformCoordinatesToRef(this.position, TargetCamera._RigCamTransformMatrix, result);
         }
 
         /**

+ 1 - 1
src/Engine/babylon.engine.ts

@@ -481,7 +481,7 @@ module BABYLON {
          * Returns the current version of the framework
          */
         public static get Version(): string {
-            return "4.0.0-alpha.6";
+            return "4.0.0-alpha.7";
         }
 
         /**

+ 15 - 1
src/Layer/babylon.layer.ts

@@ -48,6 +48,17 @@ module BABYLON {
          */
         public layerMask: number = 0x0FFFFFFF;
 
+        /**
+         * Define the list of render target the layer is visible into.
+         */
+        public renderTargetTextures: RenderTargetTexture[] = [];
+
+        /**
+         * Define if the layer is only used in renderTarget or if it also
+         * renders in the main frame buffer of the canvas.
+         */
+        public renderOnlyInRenderTargetTextures = false;
+
         private _scene: Scene;
         private _vertexBuffers: { [key: string]: Nullable<VertexBuffer> } = {};
         private _indexBuffer: Nullable<WebGLBuffer>;
@@ -198,7 +209,7 @@ module BABYLON {
 
             // Check
             if (!currentEffect.isReady() || !this.texture || !this.texture.isReady()) {
-                return;
+                return;
             }
 
             var engine = this._scene.getEngine();
@@ -256,6 +267,9 @@ module BABYLON {
                 this.texture = null;
             }
 
+            // Clean RTT list
+            this.renderTargetTextures = [];
+
             // Remove from scene
             var index = this._scene.layers.indexOf(this);
             this._scene.layers.splice(index, 1);

+ 40 - 9
src/Layer/babylon.layerSceneComponent.ts

@@ -37,8 +37,11 @@ module BABYLON {
          * Registers the component in a given scene
          */
         public register(): void {
-            this.scene._beforeCameraDrawStage.registerStep(SceneComponentConstants.STEP_BEFORECAMERADRAW_LAYER, this, this._drawBackground);
-            this.scene._afterCameraDrawStage.registerStep(SceneComponentConstants.STEP_AFTERCAMERADRAW_LAYER, this, this._drawForeground);
+            this.scene._beforeCameraDrawStage.registerStep(SceneComponentConstants.STEP_BEFORECAMERADRAW_LAYER, this, this._drawCameraBackground);
+            this.scene._afterCameraDrawStage.registerStep(SceneComponentConstants.STEP_AFTERCAMERADRAW_LAYER, this, this._drawCameraForeground);
+
+            this.scene._beforeRenderTargetDrawStage.registerStep(SceneComponentConstants.STEP_BEFORERENDERTARGETDRAW_LAYER, this, this._drawRenderTargetBackground);
+            this.scene._afterRenderTargetDrawStage.registerStep(SceneComponentConstants.STEP_AFTERRENDERTARGETDRAW_LAYER, this, this._drawRenderTargetForeground);
         }
 
         /**
@@ -64,14 +67,13 @@ module BABYLON {
             }
         }
 
-        private _draw(camera: Camera, isBackground: boolean): void {
+        private _draw(predicate: (layer: Layer) => boolean): void {
             let layers = this.scene.layers;
 
             if (layers.length) {
                 this._engine.setDepthBuffer(false);
-                const cameraLayerMask = camera.layerMask;
                 for (let layer of layers) {
-                    if (layer.isBackground === isBackground && ((layer.layerMask & cameraLayerMask) !== 0)) {
+                    if (predicate(layer)) {
                         layer.render();
                     }
                 }
@@ -79,12 +81,41 @@ module BABYLON {
             }
         }
 
-        private _drawBackground(camera: Camera): void {
-            this._draw(camera, true);
+        private _drawCameraPredicate(layer: Layer, isBackground: boolean, cameraLayerMask: number): boolean {
+            return !layer.renderOnlyInRenderTargetTextures &&
+                layer.isBackground === isBackground &&
+                ((layer.layerMask & cameraLayerMask) !== 0);
+        }
+
+        private _drawCameraBackground(camera: Camera): void {
+            this._draw((layer: Layer) => {
+                return this._drawCameraPredicate(layer, true, camera.layerMask);
+            });
+        }
+
+        private _drawCameraForeground(camera: Camera): void {
+            this._draw((layer: Layer) => {
+                return this._drawCameraPredicate(layer, false, camera.layerMask);
+            });
+        }
+
+        private _drawRenderTargetPredicate(layer: Layer, isBackground: boolean, cameraLayerMask: number, renderTargetTexture: RenderTargetTexture): boolean {
+            return (layer.renderTargetTextures.length > 0) &&
+                layer.isBackground === isBackground &&
+                (layer.renderTargetTextures.indexOf(renderTargetTexture) > -1) &&
+                ((layer.layerMask & cameraLayerMask) !== 0);
+        }
+
+        private _drawRenderTargetBackground(renderTarget: RenderTargetTexture): void {
+            this._draw((layer: Layer) => {
+                return this._drawRenderTargetPredicate(layer, true, this.scene.activeCamera!.layerMask, renderTarget);
+            });
         }
 
-        private _drawForeground(camera: Camera): void {
-            this._draw(camera, false);
+        private _drawRenderTargetForeground(renderTarget: RenderTargetTexture): void {
+            this._draw((layer: Layer) => {
+                return this._drawRenderTargetPredicate(layer, false, this.scene.activeCamera!.layerMask, renderTarget);
+            });
         }
     }
 }

+ 3 - 2
src/Loading/babylon.sceneLoader.ts

@@ -403,7 +403,9 @@ module BABYLON {
                 return plugin;
             }
 
-            if (fileInfo.rootUrl.indexOf("file:") === -1) {
+            const file = FilesInput.FilesToLoad[fileInfo.name.toLowerCase()];
+
+            if (fileInfo.rootUrl.indexOf("file:") === -1 || (fileInfo.rootUrl.indexOf("file:") !== -1 && !file)) {
                 let engine = scene.getEngine();
                 let canUseOfflineSupport = engine.enableOfflineSupport;
                 if (canUseOfflineSupport) {
@@ -429,7 +431,6 @@ module BABYLON {
             }
             // Loading file from disk via input file or drag'n'drop
             else {
-                const file = FilesInput.FilesToLoad[fileInfo.name.toLowerCase()];
                 if (file) {
                     request = Tools.ReadFile(file, dataCallback, onProgress, useArrayBuffer);
                 } else {

+ 3 - 3
src/Materials/Textures/babylon.internalTexture.ts

@@ -287,9 +287,9 @@ module BABYLON {
 
                 case InternalTexture.DATASOURCE_URL:
                     proxy = this._engine.createTexture(this.url, !this.generateMipMaps, this.invertY, null, this.samplingMode, () => {
+                        proxy._swapAndDie(this);
                         this.isReady = true;
                     }, null, this._buffer, undefined, this.format);
-                    proxy._swapAndDie(this);
                     return;
 
                 case InternalTexture.DATASOURCE_RAW:
@@ -354,9 +354,9 @@ module BABYLON {
 
                 case InternalTexture.DATASOURCE_CUBE:
                     proxy = this._engine.createCubeTexture(this.url, null, this._files, !this.generateMipMaps, () => {
+                        proxy._swapAndDie(this);
                         this.isReady = true;
                     }, null, this.format, this._extension);
-                    proxy._swapAndDie(this);
                     return;
 
                 case InternalTexture.DATASOURCE_CUBERAW:
@@ -368,9 +368,9 @@ module BABYLON {
                 case InternalTexture.DATASOURCE_CUBERAW_RGBD:
                     proxy = this._engine.createRawCubeTexture(null, this.width, this.format, this.type, this.generateMipMaps, this.invertY, this.samplingMode, this._compression);
                     RawCubeTexture._UpdateRGBDAsync(proxy, this._bufferViewArrayArray!, this._sphericalPolynomial, this._lodGenerationScale, this._lodGenerationOffset).then(() => {
+                        proxy._swapAndDie(this);
                         this.isReady = true;
                     });
-                    proxy._swapAndDie(this);
                     return;
 
                 case InternalTexture.DATASOURCE_CUBEPREFILTERED:

+ 10 - 0
src/Materials/Textures/babylon.renderTargetTexture.ts

@@ -754,9 +754,19 @@ module BABYLON {
                 scene.updateTransformMatrix(true);
             }
 
+            // Before Camera Draw
+            for (let step of scene._beforeRenderTargetDrawStage) {
+                step.action(this);
+            }
+
             // Render
             this._renderingManager.render(this.customRenderFunction, currentRenderList, this.renderParticles, this.renderSprites);
 
+            // After Camera Draw
+            for (let step of scene._afterRenderTargetDrawStage) {
+                step.action(this);
+            }
+
             if (this._postProcessManager) {
                 this._postProcessManager._finalizeFrame(false, this._texture, faceIndex, this._postProcesses, this.ignoreCameraViewport);
             }

+ 22 - 13
src/Materials/Textures/babylon.videoTexture.ts

@@ -56,7 +56,9 @@ module BABYLON {
         private _generateMipMaps: boolean;
         private _engine: Engine;
         private _stillImageCaptured = false;
-        private _poster = false;
+        private _displayingPosterTexture = false;
+        private _settings: VideoTextureSettings;
+        private _createInternalTextureOnEvent: string;
 
         /**
          * Creates a video texture.
@@ -93,6 +95,8 @@ module BABYLON {
 
             this.name = name || this._getName(src);
             this.video = this._getVideo(src);
+            this._settings = settings;
+
             if (settings.poster) {
                 this.video.poster = settings.poster;
             }
@@ -106,18 +110,20 @@ module BABYLON {
 
             this.video.setAttribute("playsinline", "");
 
-            this.video.addEventListener("canplay", this._createInternalTexture);
             this.video.addEventListener("paused", this._updateInternalTexture);
             this.video.addEventListener("seeked", this._updateInternalTexture);
             this.video.addEventListener("emptied", this.reset);
+            this._createInternalTextureOnEvent = (settings.poster && !settings.autoPlay) ? "play" : "canplay";
+            this.video.addEventListener(this._createInternalTextureOnEvent, this._createInternalTexture);
 
-            if (this.video.readyState >= this.video.HAVE_CURRENT_DATA) {
-                this._createInternalTexture();
-            }
-
-            if (settings.poster) {
+            const videoHasEnoughData = (this.video.readyState >= this.video.HAVE_CURRENT_DATA);
+            if (settings.poster &&
+                (!settings.autoPlay || !videoHasEnoughData)) {
                 this._texture = this._engine.createTexture(settings.poster!, false, true, scene);
-                this._poster = true;
+                this._displayingPosterTexture = true;
+            }
+            else if (videoHasEnoughData) {
+                this._createInternalTexture();
             }
         }
 
@@ -155,9 +161,9 @@ module BABYLON {
 
         private _createInternalTexture = (): void => {
             if (this._texture != null) {
-                if (this._poster) {
+                if (this._displayingPosterTexture) {
                     this._texture.dispose();
-                    this._poster = false;
+                    this._displayingPosterTexture = false;
                 }
                 else {
                     return;
@@ -181,7 +187,7 @@ module BABYLON {
                 this._samplingMode
             );
 
-            if (!this.video.autoplay) {
+            if (!this.video.autoplay && !this._settings.poster) {
                 let oldHandler = this.video.onplaying;
                 let error = false;
                 this.video.onplaying = () => {
@@ -231,7 +237,7 @@ module BABYLON {
                 return;
             }
 
-            if (!this._poster) {
+            if (!this._displayingPosterTexture) {
                 this._texture.dispose();
                 this._texture = null;
             }
@@ -278,6 +284,9 @@ module BABYLON {
             if (this.video.readyState < this.video.HAVE_CURRENT_DATA) {
                 return;
             }
+            if (this._displayingPosterTexture) {
+                return;
+            }
 
             this._engine.updateVideoTexture(this._texture, this.video, this._invertY);
         }
@@ -301,7 +310,7 @@ module BABYLON {
                 this._onUserActionRequestedObservable = null;
             }
 
-            this.video.removeEventListener("canplay", this._createInternalTexture);
+            this.video.removeEventListener(this._createInternalTextureOnEvent, this._createInternalTexture);
             this.video.removeEventListener("paused", this._updateInternalTexture);
             this.video.removeEventListener("seeked", this._updateInternalTexture);
             this.video.removeEventListener("emptied", this.reset);

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

@@ -5,10 +5,14 @@ module BABYLON {
     export class Geometry implements IGetSetVerticesData {
         // Members
         /**
-         * Gets or sets the unique ID of the geometry
+         * Gets or sets the ID of the geometry
          */
         public id: string;
         /**
+         * Gets or sets the unique ID of the geometry
+         */
+        public uniqueId: number;
+        /**
          * Gets the delay loading state of the geometry (none by default which means not delayed)
          */
         public delayLoadState = Engine.DELAYLOADSTATE_NONE;
@@ -94,6 +98,7 @@ module BABYLON {
          */
         constructor(id: string, scene: Scene, vertexData?: VertexData, updatable: boolean = false, mesh: Nullable<Mesh> = null) {
             this.id = id;
+            this.uniqueId = scene.getUniqueId();
             this._engine = scene.getEngine();
             this._meshes = [];
             this._scene = scene;

+ 28 - 7
src/babylon.scene.ts

@@ -1172,6 +1172,11 @@ module BABYLON {
         public _beforeCameraDrawStage = Stage.Create<CameraStageAction>();
         /**
          * @hidden
+         * Defines the actions happening just before a render target is drawing.
+         */
+        public _beforeRenderTargetDrawStage = Stage.Create<RenderTargetStageAction>();
+        /**
+         * @hidden
          * Defines the actions happening just before a rendering group is drawing.
          */
         public _beforeRenderingGroupDrawStage = Stage.Create<RenderingGroupStageAction>();
@@ -1197,6 +1202,11 @@ module BABYLON {
         public _afterCameraDrawStage = Stage.Create<CameraStageAction>();
         /**
          * @hidden
+         * Defines the actions happening just after a render target has been drawn.
+         */
+        public _afterRenderTargetDrawStage = Stage.Create<RenderTargetStageAction>();
+        /**
+         * @hidden
          * Defines the actions happening just after rendering all cameras and computing intersections.
          */
         public _afterRenderStage = Stage.Create<SimpleStageAction>();
@@ -1724,14 +1734,13 @@ module BABYLON {
                         this.onPointerObservable.notifyObservers(pi, type);
                     }
                 }
-                if (pickResult.pickedMesh.actionManager) {
-                    if (clickInfo.ignore) {
-                        pickResult.pickedMesh.actionManager.processTrigger(ActionManager.OnPickUpTrigger, ActionEvent.CreateNew(pickResult.pickedMesh, evt));
-                    }
-                    if (!clickInfo.hasSwiped && !clickInfo.ignore && clickInfo.singleClick) {
+                if (pickResult.pickedMesh.actionManager && !clickInfo.ignore) {
+                    pickResult.pickedMesh.actionManager.processTrigger(ActionManager.OnPickUpTrigger, ActionEvent.CreateNew(pickResult.pickedMesh, evt));
+
+                    if (!clickInfo.hasSwiped && clickInfo.singleClick) {
                         pickResult.pickedMesh.actionManager.processTrigger(ActionManager.OnPickTrigger, ActionEvent.CreateNew(pickResult.pickedMesh, evt));
                     }
-                    if (clickInfo.doubleClick && !clickInfo.ignore && pickResult.pickedMesh.actionManager.hasSpecificTrigger(ActionManager.OnDoublePickTrigger)) {
+                    if (clickInfo.doubleClick && pickResult.pickedMesh.actionManager.hasSpecificTrigger(ActionManager.OnDoublePickTrigger)) {
                         pickResult.pickedMesh.actionManager.processTrigger(ActionManager.OnDoublePickTrigger, ActionEvent.CreateNew(pickResult.pickedMesh, evt));
                     }
                 }
@@ -3613,6 +3622,16 @@ module BABYLON {
             return null;
         }
 
+        private _getGeometryByUniqueID(id: number): Nullable<Geometry> {
+            for (var index = 0; index < this.geometries.length; index++) {
+                if (this.geometries[index].uniqueId === id) {
+                    return this.geometries[index];
+                }
+            }
+
+            return null;
+        }
+
         /**
          * Add a new geometry to this scene
          * @param geometry defines the geometry to be added to the scene.
@@ -3620,7 +3639,7 @@ module BABYLON {
          * @return a boolean defining if the geometry was added or not
          */
         public pushGeometry(geometry: Geometry, force?: boolean): boolean {
-            if (!force && this.getGeometryByID(geometry.id)) {
+            if (!force && this._getGeometryByUniqueID(geometry.uniqueId)) {
                 return false;
             }
 
@@ -4782,11 +4801,13 @@ module BABYLON {
             this._activeMeshStage.clear();
             this._cameraDrawRenderTargetStage.clear();
             this._beforeCameraDrawStage.clear();
+            this._beforeRenderTargetDrawStage.clear();
             this._beforeRenderingGroupDrawStage.clear();
             this._beforeRenderingMeshStage.clear();
             this._afterRenderingMeshStage.clear();
             this._afterRenderingGroupDrawStage.clear();
             this._afterCameraDrawStage.clear();
+            this._afterRenderTargetDrawStage.clear();
             this._afterRenderStage.clear();
             this._beforeCameraUpdateStage.clear();
             this._beforeClearStage.clear();

+ 9 - 0
src/babylon.sceneComponent.ts

@@ -35,6 +35,8 @@ module BABYLON {
         public static readonly STEP_BEFORECAMERADRAW_EFFECTLAYER = 0;
         public static readonly STEP_BEFORECAMERADRAW_LAYER = 1;
 
+        public static readonly STEP_BEFORERENDERTARGETDRAW_LAYER = 0;
+
         public static readonly STEP_BEFORERENDERINGMESH_OUTLINE = 0;
 
         public static readonly STEP_AFTERRENDERINGMESH_OUTLINE = 0;
@@ -47,6 +49,8 @@ module BABYLON {
 
         public static readonly STEP_BEFORECLEAR_PROCEDURALTEXTURE = 0;
 
+        public static readonly STEP_AFTERRENDERTARGETDRAW_LAYER = 0;
+
         public static readonly STEP_AFTERCAMERADRAW_EFFECTLAYER = 0;
         public static readonly STEP_AFTERCAMERADRAW_LENSFLARESYSTEM = 1;
         public static readonly STEP_AFTERCAMERADRAW_EFFECTLAYER_DRAW = 2;
@@ -146,6 +150,11 @@ module BABYLON {
     export type CameraStageAction = (camera: Camera) => void;
 
     /**
+     * Strong typing of a Render Target related stage step action
+     */
+    export type RenderTargetStageAction = (renderTarget: RenderTargetTexture) => void;
+
+    /**
      * Strong typing of a RenderingGroup related stage step action
      */
     export type RenderingGroupStageAction = (renderingGroupId: number) => void;