浏览代码

Merge branch 'master' of https://github.com/BabylonJS/Babylon.js into dev

Rémi Louvat 7 年之前
父节点
当前提交
90d1fbd0e8
共有 69 个文件被更改,包括 19514 次插入16314 次删除
  1. 7336 7035
      Playground/babylon.d.txt
  2. 2 2
      Playground/indexStable.html
  3. 2 1
      Tools/Gulp/config.json
  4. 6383 6132
      dist/preview release/babylon.d.ts
  5. 1 1
      dist/preview release/babylon.js
  6. 877 193
      dist/preview release/babylon.max.js
  7. 877 193
      dist/preview release/babylon.no-module.max.js
  8. 1 1
      dist/preview release/babylon.worker.js
  9. 879 195
      dist/preview release/es6.js
  10. 15 11
      dist/preview release/gui/babylon.gui.d.ts
  11. 1 1
      dist/preview release/gui/babylon.gui.js
  12. 1 1
      dist/preview release/gui/babylon.gui.min.js
  13. 1 1
      dist/preview release/gui/babylon.gui.min.js.map
  14. 30 22
      dist/preview release/gui/babylon.gui.module.d.ts
  15. 1 1
      dist/preview release/inspector/babylon.inspector.d.ts
  16. 2 2
      dist/preview release/inspector/babylon.inspector.module.d.ts
  17. 9 2
      dist/preview release/loaders/babylon.glTF2FileLoader.js
  18. 1 1
      dist/preview release/loaders/babylon.glTF2FileLoader.min.js
  19. 9 2
      dist/preview release/loaders/babylon.glTFFileLoader.js
  20. 1 1
      dist/preview release/loaders/babylon.glTFFileLoader.min.js
  21. 9 2
      dist/preview release/loaders/babylonjs.loaders.js
  22. 1 1
      dist/preview release/loaders/babylonjs.loaders.min.js
  23. 1 0
      dist/preview release/materialsLibrary/babylon.waterMaterial.js
  24. 1 1
      dist/preview release/materialsLibrary/babylon.waterMaterial.min.js
  25. 1 0
      dist/preview release/materialsLibrary/babylonjs.materials.js
  26. 1 1
      dist/preview release/materialsLibrary/babylonjs.materials.min.js
  27. 2 7
      dist/preview release/typedocValidationBaseline.json
  28. 4 161
      dist/preview release/viewer/babylon.viewer.d.ts
  29. 3 3
      dist/preview release/viewer/babylon.viewer.js
  30. 14 14
      dist/preview release/viewer/babylon.viewer.max.js
  31. 3 165
      dist/preview release/viewer/babylon.viewer.module.d.ts
  32. 6 1
      dist/preview release/what's new.md
  33. 25 5
      gui/src/2D/advancedDynamicTexture.ts
  34. 1 1
      gui/src/2D/controls/control.ts
  35. 5 19
      gui/src/2D/controls/inputText.ts
  36. 60 8
      gui/src/2D/controls/selector.ts
  37. 9 2
      loaders/src/glTF/2.0/babylon.glTFLoader.ts
  38. 2 0
      materialsLibrary/src/water/babylon.waterMaterial.ts
  39. 2 2
      sandbox/index.js
  40. 3 3
      src/Behaviors/Mesh/babylon.pointerDragBehavior.ts
  41. 1 0
      src/Behaviors/Mesh/babylon.sixDofDragBehavior.ts
  42. 1 1
      src/Cameras/VR/babylon.webVRCamera.ts
  43. 0 1
      src/Cameras/babylon.camera.ts
  44. 7 2
      src/Engine/Extensions/babylon.engine.occlusionQuery.ts
  45. 6 5
      src/Lights/babylon.hemisphericLight.ts
  46. 0 32
      src/Lights/babylon.light.ts
  47. 36 4
      src/Lights/babylon.shadowLight.ts
  48. 15 0
      src/Materials/Background/babylon.backgroundMaterial.ts
  49. 16 0
      src/Materials/PBR/babylon.pbrBaseMaterial.ts
  50. 5 0
      src/Materials/babylon.material.ts
  51. 15 0
      src/Materials/babylon.standardMaterial.ts
  52. 1 1
      src/Mesh/babylon.geometry.ts
  53. 4 3
      src/Mesh/babylon.mesh.ts
  54. 1 1
      src/Mesh/babylon.subMesh.ts
  55. 34 55
      src/Mesh/babylon.transformNode.ts
  56. 50 0
      src/Particles/babylon.IParticleSystem.ts
  57. 44 1
      src/Particles/babylon.baseParticleSystem.ts
  58. 90 26
      src/Particles/babylon.gpuParticleSystem.ts
  59. 20 0
      src/Particles/babylon.particle.ts
  60. 2371 1935
      src/Particles/babylon.particleSystem.ts
  61. 68 0
      src/Particles/babylon.subEmitter.ts
  62. 27 4
      src/PostProcess/RenderPipeline/Pipelines/babylon.defaultRenderingPipeline.ts
  63. 7 0
      src/Rendering/babylon.depthRenderer.ts
  64. 16 1
      src/Rendering/babylon.depthRendererSceneComponent.ts
  65. 17 2
      src/Shaders/particles.fragment.fx
  66. 11 0
      src/Shaders/particles.vertex.fx
  67. 41 30
      src/babylon.node.ts
  68. 26 16
      src/babylon.scene.ts
  69. 2 0
      src/babylon.sceneComponent.ts

文件差异内容过多而无法显示
+ 7336 - 7035
Playground/babylon.d.txt


+ 2 - 2
Playground/indexStable.html

@@ -40,7 +40,7 @@
         <!-- Monaco -->
         <script src="node_modules/monaco-editor/min/vs/loader.js"></script>
         <!-- Babylon.js -->
-        <script src="https://cdn.babylonjs.com/babylon.js"></script>
+        <script src="https://cdn.babylonjs.com/babylon.max.js"></script>
         <script src="https://cdn.babylonjs.com/inspector/babylon.inspector.bundle.js"></script>
 
         <script src="https://cdn.babylonjs.com/loaders/babylon.glTFFileLoader.js"></script>
@@ -471,4 +471,4 @@
         </script>        
     </body>
 
-</html>
+</html>

+ 2 - 1
Tools/Gulp/config.json

@@ -300,7 +300,8 @@
                 "../../src/Particles/EmitterTypes/babylon.sphereParticleEmitter.js",
                 "../../src/Particles/EmitterTypes/babylon.hemisphericParticleEmitter.js",
                 "../../src/Particles/EmitterTypes/babylon.pointParticleEmitter.js",
-                "../../src/Particles/babylon.particleSystemComponent.js"
+                "../../src/Particles/babylon.particleSystemComponent.js",
+                "../../src/Particles/babylon.subEmitter.js"
             ],
             "dependUpon": [
                 "core"

文件差异内容过多而无法显示
+ 6383 - 6132
dist/preview release/babylon.d.ts


文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/babylon.js


文件差异内容过多而无法显示
+ 877 - 193
dist/preview release/babylon.max.js


文件差异内容过多而无法显示
+ 877 - 193
dist/preview release/babylon.no-module.max.js


文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/babylon.worker.js


文件差异内容过多而无法显示
+ 879 - 195
dist/preview release/es6.js


+ 15 - 11
dist/preview release/gui/babylon.gui.d.ts

@@ -1,6 +1,6 @@
 /*BabylonJS GUI*/
 // Dependencies for this module:
-//   ../../../../tools/Gulp/babylonjs
+//   ../../../../Tools/gulp/babylonjs
 declare module BABYLON.GUI {
 }
 declare module BABYLON.GUI {
@@ -28,11 +28,10 @@ declare module BABYLON.GUI {
                 */
             processKeyboard(evt: KeyboardEvent): void;
             /**
-                * Function called to let the current focused control keeps the focus
-                * @param pointerId defines the unique id of the current pointer
-                * @returns a boolean indicating if the control wants to keep the focus
+                * Function called to get the list of controls that should not steal the focus from this control
+                * @returns an array of controls
                 */
-            keepFocus(pointerId: number): boolean;
+            keepsFocusWith(): BABYLON.Nullable<Control[]>;
     }
     /**
         * Class used to create texture to support 2D GUI elements
@@ -1086,7 +1085,7 @@ declare module BABYLON.GUI {
                 * @param container defines the container to look for
                 * @returns true if the container is one of the ascendant of the control
                 */
-            IsAscendant(container: Container): boolean;
+            isAscendant(container: Control): boolean;
             /**
                 * Gets coordinates in local control space
                 * @param globalCoordinates defines the coordinates to transform
@@ -1431,11 +1430,10 @@ declare module BABYLON.GUI {
             onFocus(): void;
             protected _getTypeName(): string;
             /**
-                * Function called to let the current focused control keeps the focus
-                * @param pointerId defines the unique id of the current pointer
-                * @returns a boolean indicating if the control wants to keep the focus
+                * Function called to get the list of controls that should not steal the focus from this control
+                * @returns an array of controls
                 */
-            keepFocus(pointerId: number): boolean;
+            keepsFocusWith(): BABYLON.Nullable<Control[]>;
             /** @hidden */
             processKey(keyCode: number, key?: string): void;
             /** @hidden */
@@ -1704,7 +1702,9 @@ declare module BABYLON.GUI {
             /** @hidden */
             _setSelectorButtonBackground(selectorNb: number, color: string): void;
     }
-    /** Class used to hold the controls for the checkboxes, radio buttons and sliders */
+    /** Class used to hold the controls for the checkboxes, radio buttons and sliders
+        * @see http://doc.babylonjs.com/how_to/selector
+     */
     export class SelectionPanel extends Rectangle {
             /** name of SelectionPanel */
             name: string;
@@ -1731,6 +1731,10 @@ declare module BABYLON.GUI {
             buttonBackground: string;
             /** Gets or sets the color of separator bar */
             barColor: string;
+            /** Gets or sets the height of separator bar */
+            barHeight: string;
+            /** Gets or sets the height of spacers*/
+            spacerHeight: string;
             /** Add a group to the selection panel
                 * @param group is the selector group to add
                 */

文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/gui/babylon.gui.js


文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/gui/babylon.gui.min.js


文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/gui/babylon.gui.min.js.map


+ 30 - 22
dist/preview release/gui/babylon.gui.module.d.ts

@@ -1,6 +1,6 @@
 /*BabylonJS GUI*/
 // Dependencies for this module:
-//   ../../../../tools/Gulp/babylonjs
+//   ../../../../Tools/gulp/babylonjs
 
 declare module 'babylonjs-gui' {
     export * from "babylonjs-gui/2D";
@@ -71,11 +71,10 @@ declare module 'babylonjs-gui/2D/advancedDynamicTexture' {
                 */
             processKeyboard(evt: KeyboardEvent): void;
             /**
-                * Function called to let the current focused control keeps the focus
-                * @param pointerId defines the unique id of the current pointer
-                * @returns a boolean indicating if the control wants to keep the focus
+                * Function called to get the list of controls that should not steal the focus from this control
+                * @returns an array of controls
                 */
-            keepFocus(pointerId: number): boolean;
+            keepsFocusWith(): Nullable<Control[]>;
     }
     /**
         * Class used to create texture to support 2D GUI elements
@@ -1189,7 +1188,7 @@ declare module 'babylonjs-gui/2D/controls/control' {
                 * @param container defines the container to look for
                 * @returns true if the container is one of the ascendant of the control
                 */
-            IsAscendant(container: Container): boolean;
+            isAscendant(container: Control): boolean;
             /**
                 * Gets coordinates in local control space
                 * @param globalCoordinates defines the coordinates to transform
@@ -1551,11 +1550,10 @@ declare module 'babylonjs-gui/2D/controls/inputText' {
             onFocus(): void;
             protected _getTypeName(): string;
             /**
-                * Function called to let the current focused control keeps the focus
-                * @param pointerId defines the unique id of the current pointer
-                * @returns a boolean indicating if the control wants to keep the focus
+                * Function called to get the list of controls that should not steal the focus from this control
+                * @returns an array of controls
                 */
-            keepFocus(pointerId: number): boolean;
+            keepsFocusWith(): Nullable<Control[]>;
             /** @hidden */
             processKey(keyCode: number, key?: string): void;
             /** @hidden */
@@ -1846,7 +1844,9 @@ declare module 'babylonjs-gui/2D/controls/selector' {
             /** @hidden */
             _setSelectorButtonBackground(selectorNb: number, color: string): void;
     }
-    /** Class used to hold the controls for the checkboxes, radio buttons and sliders */
+    /** Class used to hold the controls for the checkboxes, radio buttons and sliders
+        * @see http://doc.babylonjs.com/how_to/selector
+     */
     export class SelectionPanel extends Rectangle {
             /** name of SelectionPanel */
             name: string;
@@ -1873,6 +1873,10 @@ declare module 'babylonjs-gui/2D/controls/selector' {
             buttonBackground: string;
             /** Gets or sets the color of separator bar */
             barColor: string;
+            /** Gets or sets the height of separator bar */
+            barHeight: string;
+            /** Gets or sets the height of spacers*/
+            spacerHeight: string;
             /** Add a group to the selection panel
                 * @param group is the selector group to add
                 */
@@ -2808,7 +2812,7 @@ declare module 'babylonjs-gui/3D/materials/fluentMaterial' {
 
 /*BabylonJS GUI*/
 // Dependencies for this module:
-//   ../../../../tools/Gulp/babylonjs
+//   ../../../../Tools/gulp/babylonjs
 declare module BABYLON.GUI {
 }
 declare module BABYLON.GUI {
@@ -2836,11 +2840,10 @@ declare module BABYLON.GUI {
                 */
             processKeyboard(evt: KeyboardEvent): void;
             /**
-                * Function called to let the current focused control keeps the focus
-                * @param pointerId defines the unique id of the current pointer
-                * @returns a boolean indicating if the control wants to keep the focus
+                * Function called to get the list of controls that should not steal the focus from this control
+                * @returns an array of controls
                 */
-            keepFocus(pointerId: number): boolean;
+            keepsFocusWith(): BABYLON.Nullable<Control[]>;
     }
     /**
         * Class used to create texture to support 2D GUI elements
@@ -3894,7 +3897,7 @@ declare module BABYLON.GUI {
                 * @param container defines the container to look for
                 * @returns true if the container is one of the ascendant of the control
                 */
-            IsAscendant(container: Container): boolean;
+            isAscendant(container: Control): boolean;
             /**
                 * Gets coordinates in local control space
                 * @param globalCoordinates defines the coordinates to transform
@@ -4239,11 +4242,10 @@ declare module BABYLON.GUI {
             onFocus(): void;
             protected _getTypeName(): string;
             /**
-                * Function called to let the current focused control keeps the focus
-                * @param pointerId defines the unique id of the current pointer
-                * @returns a boolean indicating if the control wants to keep the focus
+                * Function called to get the list of controls that should not steal the focus from this control
+                * @returns an array of controls
                 */
-            keepFocus(pointerId: number): boolean;
+            keepsFocusWith(): BABYLON.Nullable<Control[]>;
             /** @hidden */
             processKey(keyCode: number, key?: string): void;
             /** @hidden */
@@ -4512,7 +4514,9 @@ declare module BABYLON.GUI {
             /** @hidden */
             _setSelectorButtonBackground(selectorNb: number, color: string): void;
     }
-    /** Class used to hold the controls for the checkboxes, radio buttons and sliders */
+    /** Class used to hold the controls for the checkboxes, radio buttons and sliders
+        * @see http://doc.babylonjs.com/how_to/selector
+     */
     export class SelectionPanel extends Rectangle {
             /** name of SelectionPanel */
             name: string;
@@ -4539,6 +4543,10 @@ declare module BABYLON.GUI {
             buttonBackground: string;
             /** Gets or sets the color of separator bar */
             barColor: string;
+            /** Gets or sets the height of separator bar */
+            barHeight: string;
+            /** Gets or sets the height of spacers*/
+            spacerHeight: string;
             /** Add a group to the selection panel
                 * @param group is the selector group to add
                 */

+ 1 - 1
dist/preview release/inspector/babylon.inspector.d.ts

@@ -1,6 +1,6 @@
 /*BabylonJS Inspector*/
 // Dependencies for this module:
-//   ../../../../tools/Gulp/babylonjs
+//   ../../../../Tools/gulp/babylonjs
 declare module INSPECTOR {
 }
 declare module INSPECTOR {

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

@@ -1,6 +1,6 @@
 /*BabylonJS Inspector*/
 // Dependencies for this module:
-//   ../../../../tools/Gulp/babylonjs
+//   ../../../../Tools/gulp/babylonjs
 
 declare module 'babylonjs-inspector' {
     export * from 'babylonjs-inspector/adapters';
@@ -1340,7 +1340,7 @@ declare module 'babylonjs-inspector/treetools/SoundInteractions' {
 
 /*BabylonJS Inspector*/
 // Dependencies for this module:
-//   ../../../../tools/Gulp/babylonjs
+//   ../../../../Tools/gulp/babylonjs
 declare module INSPECTOR {
 }
 declare module INSPECTOR {

+ 9 - 2
dist/preview release/loaders/babylon.glTF2FileLoader.js

@@ -1865,11 +1865,18 @@ var BABYLON;
                         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) {
+                        return new BABYLON.VertexBuffer(_this.babylonScene.getEngine(), data, kind, false);
+                    });
+                }
                 else {
                     var bufferView_1 = ArrayItem.Get(context + "/bufferView", this.gltf.bufferViews, accessor.bufferView);
-                    accessor._babylonVertexBuffer = this._loadVertexBufferViewAsync(bufferView_1, kind).then(function (buffer) {
+                    accessor._babylonVertexBuffer = this._loadVertexBufferViewAsync(bufferView_1, kind).then(function (babylonBuffer) {
                         var size = GLTFLoader._GetNumComponents(context, accessor.type);
-                        return new BABYLON.VertexBuffer(_this.babylonScene.getEngine(), buffer, kind, false, false, bufferView_1.byteStride, false, accessor.byteOffset, size, accessor.componentType, accessor.normalized, true);
+                        return new BABYLON.VertexBuffer(_this.babylonScene.getEngine(), babylonBuffer, kind, false, false, bufferView_1.byteStride, false, accessor.byteOffset, size, accessor.componentType, accessor.normalized, true);
                     });
                 }
                 return accessor._babylonVertexBuffer;

文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/loaders/babylon.glTF2FileLoader.min.js


+ 9 - 2
dist/preview release/loaders/babylon.glTFFileLoader.js

@@ -4072,11 +4072,18 @@ var BABYLON;
                         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) {
+                        return new BABYLON.VertexBuffer(_this.babylonScene.getEngine(), data, kind, false);
+                    });
+                }
                 else {
                     var bufferView_1 = ArrayItem.Get(context + "/bufferView", this.gltf.bufferViews, accessor.bufferView);
-                    accessor._babylonVertexBuffer = this._loadVertexBufferViewAsync(bufferView_1, kind).then(function (buffer) {
+                    accessor._babylonVertexBuffer = this._loadVertexBufferViewAsync(bufferView_1, kind).then(function (babylonBuffer) {
                         var size = GLTFLoader._GetNumComponents(context, accessor.type);
-                        return new BABYLON.VertexBuffer(_this.babylonScene.getEngine(), buffer, kind, false, false, bufferView_1.byteStride, false, accessor.byteOffset, size, accessor.componentType, accessor.normalized, true);
+                        return new BABYLON.VertexBuffer(_this.babylonScene.getEngine(), babylonBuffer, kind, false, false, bufferView_1.byteStride, false, accessor.byteOffset, size, accessor.componentType, accessor.normalized, true);
                     });
                 }
                 return accessor._babylonVertexBuffer;

文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/loaders/babylon.glTFFileLoader.min.js


+ 9 - 2
dist/preview release/loaders/babylonjs.loaders.js

@@ -5131,11 +5131,18 @@ var BABYLON;
                         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) {
+                        return new BABYLON.VertexBuffer(_this.babylonScene.getEngine(), data, kind, false);
+                    });
+                }
                 else {
                     var bufferView_1 = ArrayItem.Get(context + "/bufferView", this.gltf.bufferViews, accessor.bufferView);
-                    accessor._babylonVertexBuffer = this._loadVertexBufferViewAsync(bufferView_1, kind).then(function (buffer) {
+                    accessor._babylonVertexBuffer = this._loadVertexBufferViewAsync(bufferView_1, kind).then(function (babylonBuffer) {
                         var size = GLTFLoader._GetNumComponents(context, accessor.type);
-                        return new BABYLON.VertexBuffer(_this.babylonScene.getEngine(), buffer, kind, false, false, bufferView_1.byteStride, false, accessor.byteOffset, size, accessor.componentType, accessor.normalized, true);
+                        return new BABYLON.VertexBuffer(_this.babylonScene.getEngine(), babylonBuffer, kind, false, false, bufferView_1.byteStride, false, accessor.byteOffset, size, accessor.componentType, accessor.normalized, true);
                     });
                 }
                 return accessor._babylonVertexBuffer;

文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/loaders/babylonjs.loaders.min.js


+ 1 - 0
dist/preview release/materialsLibrary/babylon.waterMaterial.js

@@ -127,6 +127,7 @@ var BABYLON;
             _this._lastTime = 0;
             _this._lastDeltaTime = 0;
             _this._createRenderTargets(scene, renderTargetSize);
+            _this.hasRenderTargetTextures = true;
             // Create render targets
             _this.getRenderTargetTextures = function () {
                 _this._renderTargets.reset();

文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/materialsLibrary/babylon.waterMaterial.min.js


+ 1 - 0
dist/preview release/materialsLibrary/babylonjs.materials.js

@@ -1601,6 +1601,7 @@ var BABYLON;
             _this._lastTime = 0;
             _this._lastDeltaTime = 0;
             _this._createRenderTargets(scene, renderTargetSize);
+            _this.hasRenderTargetTextures = true;
             // Create render targets
             _this.getRenderTargetTextures = function () {
                 _this._renderTargets.reset();

文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/materialsLibrary/babylonjs.materials.min.js


+ 2 - 7
dist/preview release/typedocValidationBaseline.json

@@ -1,7 +1,7 @@
 {
-  "errors": 3875,
+  "errors": 3874,
   "babylon.typedoc.json": {
-    "errors": 3875,
+    "errors": 3874,
     "AnimationGroup": {
       "Constructor": {
         "new AnimationGroup": {
@@ -18226,11 +18226,6 @@
             "MissingText": true
           }
         },
-        "position": {
-          "Comments": {
-            "MissingText": true
-          }
-        },
         "scalingDeterminant": {
           "Comments": {
             "MissingText": true

+ 4 - 161
dist/preview release/viewer/babylon.viewer.d.ts

@@ -4,8 +4,8 @@
 declare module "babylonjs-loaders"{ export=BABYLON;}
 // Generated by dts-bundle v0.7.3
 // Dependencies for this module:
-//   ../../../../../tools/Gulp/babylonjs
-//   ../../../../../tools/Gulp/babylonjs-loaders
+//   ../../../../../Tools/gulp/babylonjs
+//   ../../../../../Tools/gulp/babylonjs-loaders
 declare module BabylonViewer {
     /**
         * BabylonJS Viewer
@@ -515,167 +515,10 @@ declare module BabylonViewer {
     }
 }
 declare module BabylonViewer {
-    /**
-        * The current state of the model
-        */
-    export enum ModelState {
-            INIT = 0,
-            LOADING = 1,
-            LOADED = 2,
-            ENTRY = 3,
-            ENTRYDONE = 4,
-            COMPLETE = 5,
-            CANCELED = 6,
-            ERROR = 7
-    }
-    /**
-        * The viewer model is a container for all assets representing a sngle loaded model.
-        */
-    export class ViewerModel implements BABYLON.IDisposable {
-            /**
-                * The loader used to load this model.
-                */
-            loader: BABYLON.ISceneLoaderPlugin | BABYLON.ISceneLoaderPluginAsync;
-            /**
-                * This model's root mesh (the parent of all other meshes).
-                * This mesh does not(!) exist in the meshes array.
-                */
-            rootMesh: BABYLON.AbstractMesh;
-            /**
-                * ParticleSystems connected to this model
-                */
-            particleSystems: Array<BABYLON.IParticleSystem>;
-            /**
-                * Skeletons defined in this model
-                */
-            skeletons: Array<BABYLON.Skeleton>;
-            /**
-                * The current model animation.
-                * On init, this will be undefined.
-                */
-            currentAnimation: IModelAnimation;
-            /**
-                * Observers registered here will be executed when the model is done loading
-                */
-            onLoadedObservable: BABYLON.Observable<ViewerModel>;
-            /**
-                * Observers registered here will be executed when the loader notified of a progress event
-                */
-            onLoadProgressObservable: BABYLON.Observable<BABYLON.SceneLoaderProgressEvent>;
-            /**
-                * Observers registered here will be executed when the loader notified of an error.
-                */
-            onLoadErrorObservable: BABYLON.Observable<{
-                    message: string;
-                    exception: any;
-            }>;
-            /**
-                * Will be executed after the model finished loading and complete, including entry animation and lod
-                */
-            onCompleteObservable: BABYLON.Observable<ViewerModel>;
-            /**
-                * Observers registered here will be executed every time the model is being configured.
-                * This can be used to extend the model's configuration without extending the class itself
-                */
-            onAfterConfigure: BABYLON.Observable<ViewerModel>;
-            /**
-                * The current model state (loaded, error, etc)
-                */
-            state: ModelState;
-            /**
-                * A loadID provided by the modelLoader, unique to ths (Abstract)Viewer instance.
-                */
-            loadId: number;
-            loadInfo: BABYLON.GLTF2.IAsset;
-            constructor(_observablesManager: ObservablesManager, modelConfiguration: IModelConfiguration, _configurationContainer?: ConfigurationContainer | undefined);
-            shadowsRenderedAfterLoad: boolean;
-            getViewerId(): string | undefined;
-            /**
-             * Set whether this model is enabled or not.
-             */
-            enabled: boolean;
-            loaderDone: boolean;
-            /**
-                * Add a mesh to this model.
-                * Any mesh that has no parent will be provided with the root mesh as its new parent.
-                *
-                * @param mesh the new mesh to add
-                * @param triggerLoaded should this mesh trigger the onLoaded observable. Used when adding meshes manually.
-                */
-            addMesh(mesh: BABYLON.AbstractMesh, triggerLoaded?: boolean): Promise<ViewerModel> | undefined;
-            /**
-                * get the list of meshes (excluding the root mesh)
-                */
-            readonly meshes: BABYLON.AbstractMesh[];
-            /**
-             * (Re-)set the model's entire configuration
-             * @param newConfiguration the new configuration to replace the new one
-             */
-            configuration: IModelConfiguration;
-            /**
-                * Update the current configuration with new values.
-                * Configuration will not be overwritten, but merged with the new configuration.
-                * Priority is to the new configuration
-                * @param newConfiguration the configuration to be merged into the current configuration;
-                */
-            updateConfiguration(newConfiguration: Partial<IModelConfiguration>): void;
-            /**
-                * Add a new animation group to this model.
-                * @param animationGroup the new animation group to be added
-                */
-            addAnimationGroup(animationGroup: BABYLON.AnimationGroup): void;
-            /**
-                * Get the ModelAnimation array
-                */
-            getAnimations(): Array<IModelAnimation>;
-            /**
-                * Get the animations' names. Using the names you can play a specific animation.
-                */
-            getAnimationNames(): Array<string>;
-            /**
-                * Get an animation by the provided name. Used mainly when playing n animation.
-                * @param name the name of the animation to find
-                */
-            protected _getAnimationByName(name: string): BABYLON.Nullable<IModelAnimation>;
-            /**
-                * Choose an initialized animation using its name and start playing it
-                * @param name the name of the animation to play
-                * @returns The model aniamtion to be played.
-                */
-            playAnimation(name: string): IModelAnimation;
-            setCurrentAnimationByName(name: string): IModelAnimation;
-            /**
-                * Apply a material configuration to a material
-                * @param material BABYLON.Material to apply configuration to
-                * @hidden
-                */
-            _applyModelMaterialConfiguration(material: BABYLON.Material): void;
-            /**
-             * Begin @animations with the specified @easingFunction
-             * @param animations The BABYLON Animations to begin
-             * @param duration of transition, in seconds
-             * @param easingFunction An easing function to apply
-             * @param easingMode A easing mode to apply to the easingFunction
-             * @param onAnimationEnd Call back trigger at the end of the animation.
-             */
-            transitionTo(animations: BABYLON.Animation[], duration: number, easingFunction: any, easingMode: number | undefined, onAnimationEnd: () => void): void;
-            /**
-                * Stops and removes all animations that have been applied to the model
-                */
-            stopAllAnimations(): void;
-            /**
-                * Will remove this model from the viewer (but NOT dispose it).
-                */
-            remove(): void;
-            /**
-                * Dispose this model, including all of its associated assets.
-                */
-            dispose(): void;
-    }
 }
 declare module BabylonViewer {
     /**
-        * BABYLON.Animation play mode enum - is the animation looping or playing once
+        * Animation play mode enum - is the animation looping or playing once
         */
     export const enum AnimationPlayMode {
             ONCE = 0,
@@ -757,7 +600,7 @@ declare module BabylonViewer {
                 */
             readonly currentFrame: number;
             /**
-                * BABYLON.Animation's FPS value
+                * Animation's FPS value
                 */
             readonly fps: number;
             /**

文件差异内容过多而无法显示
+ 3 - 3
dist/preview release/viewer/babylon.viewer.js


文件差异内容过多而无法显示
+ 14 - 14
dist/preview release/viewer/babylon.viewer.max.js


+ 3 - 165
dist/preview release/viewer/babylon.viewer.module.d.ts

@@ -5,8 +5,8 @@ declare module "babylonjs-loaders"{ export=BABYLON;}
 
 // Generated by dts-bundle v0.7.3
 // Dependencies for this module:
-//   ../../../../../tools/Gulp/babylonjs
-//   ../../../../../tools/Gulp/babylonjs-loaders
+//   ../../../../../Tools/gulp/babylonjs
+//   ../../../../../Tools/gulp/babylonjs-loaders
 
 declare module 'babylonjs-viewer' {
     import { mapperManager } from 'babylonjs-viewer/configuration/mappers';
@@ -566,169 +566,7 @@ declare module 'babylonjs-viewer/loader/modelLoader' {
 }
 
 declare module 'babylonjs-viewer/model/viewerModel' {
-    import { ISceneLoaderPlugin, ISceneLoaderPluginAsync, AnimationGroup, AbstractMesh, Observable, SceneLoaderProgressEvent, IParticleSystem, Skeleton, IDisposable, Nullable, Animation, Material } from "babylonjs";
-    import { GLTF2 } from "babylonjs-loaders";
-    import { IModelConfiguration } from "babylonjs-viewer/configuration/interfaces/modelConfiguration";
-    import { IModelAnimation } from "babylonjs-viewer/model/modelAnimation";
-    import { ObservablesManager } from "babylonjs-viewer/managers/observablesManager";
-    import { ConfigurationContainer } from "babylonjs-viewer/configuration/configurationContainer";
-    /**
-        * The current state of the model
-        */
-    export enum ModelState {
-            INIT = 0,
-            LOADING = 1,
-            LOADED = 2,
-            ENTRY = 3,
-            ENTRYDONE = 4,
-            COMPLETE = 5,
-            CANCELED = 6,
-            ERROR = 7
-    }
-    /**
-        * The viewer model is a container for all assets representing a sngle loaded model.
-        */
-    export class ViewerModel implements IDisposable {
-            /**
-                * The loader used to load this model.
-                */
-            loader: ISceneLoaderPlugin | ISceneLoaderPluginAsync;
-            /**
-                * This model's root mesh (the parent of all other meshes).
-                * This mesh does not(!) exist in the meshes array.
-                */
-            rootMesh: AbstractMesh;
-            /**
-                * ParticleSystems connected to this model
-                */
-            particleSystems: Array<IParticleSystem>;
-            /**
-                * Skeletons defined in this model
-                */
-            skeletons: Array<Skeleton>;
-            /**
-                * The current model animation.
-                * On init, this will be undefined.
-                */
-            currentAnimation: IModelAnimation;
-            /**
-                * Observers registered here will be executed when the model is done loading
-                */
-            onLoadedObservable: Observable<ViewerModel>;
-            /**
-                * Observers registered here will be executed when the loader notified of a progress event
-                */
-            onLoadProgressObservable: Observable<SceneLoaderProgressEvent>;
-            /**
-                * Observers registered here will be executed when the loader notified of an error.
-                */
-            onLoadErrorObservable: Observable<{
-                    message: string;
-                    exception: any;
-            }>;
-            /**
-                * Will be executed after the model finished loading and complete, including entry animation and lod
-                */
-            onCompleteObservable: Observable<ViewerModel>;
-            /**
-                * Observers registered here will be executed every time the model is being configured.
-                * This can be used to extend the model's configuration without extending the class itself
-                */
-            onAfterConfigure: Observable<ViewerModel>;
-            /**
-                * The current model state (loaded, error, etc)
-                */
-            state: ModelState;
-            /**
-                * A loadID provided by the modelLoader, unique to ths (Abstract)Viewer instance.
-                */
-            loadId: number;
-            loadInfo: GLTF2.IAsset;
-            constructor(_observablesManager: ObservablesManager, modelConfiguration: IModelConfiguration, _configurationContainer?: ConfigurationContainer | undefined);
-            shadowsRenderedAfterLoad: boolean;
-            getViewerId(): string | undefined;
-            /**
-             * Set whether this model is enabled or not.
-             */
-            enabled: boolean;
-            loaderDone: boolean;
-            /**
-                * Add a mesh to this model.
-                * Any mesh that has no parent will be provided with the root mesh as its new parent.
-                *
-                * @param mesh the new mesh to add
-                * @param triggerLoaded should this mesh trigger the onLoaded observable. Used when adding meshes manually.
-                */
-            addMesh(mesh: AbstractMesh, triggerLoaded?: boolean): Promise<ViewerModel> | undefined;
-            /**
-                * get the list of meshes (excluding the root mesh)
-                */
-            readonly meshes: AbstractMesh[];
-            /**
-             * (Re-)set the model's entire configuration
-             * @param newConfiguration the new configuration to replace the new one
-             */
-            configuration: IModelConfiguration;
-            /**
-                * Update the current configuration with new values.
-                * Configuration will not be overwritten, but merged with the new configuration.
-                * Priority is to the new configuration
-                * @param newConfiguration the configuration to be merged into the current configuration;
-                */
-            updateConfiguration(newConfiguration: Partial<IModelConfiguration>): void;
-            /**
-                * Add a new animation group to this model.
-                * @param animationGroup the new animation group to be added
-                */
-            addAnimationGroup(animationGroup: AnimationGroup): void;
-            /**
-                * Get the ModelAnimation array
-                */
-            getAnimations(): Array<IModelAnimation>;
-            /**
-                * Get the animations' names. Using the names you can play a specific animation.
-                */
-            getAnimationNames(): Array<string>;
-            /**
-                * Get an animation by the provided name. Used mainly when playing n animation.
-                * @param name the name of the animation to find
-                */
-            protected _getAnimationByName(name: string): Nullable<IModelAnimation>;
-            /**
-                * Choose an initialized animation using its name and start playing it
-                * @param name the name of the animation to play
-                * @returns The model aniamtion to be played.
-                */
-            playAnimation(name: string): IModelAnimation;
-            setCurrentAnimationByName(name: string): IModelAnimation;
-            /**
-                * Apply a material configuration to a material
-                * @param material Material to apply configuration to
-                * @hidden
-                */
-            _applyModelMaterialConfiguration(material: Material): void;
-            /**
-             * Begin @animations with the specified @easingFunction
-             * @param animations The BABYLON Animations to begin
-             * @param duration of transition, in seconds
-             * @param easingFunction An easing function to apply
-             * @param easingMode A easing mode to apply to the easingFunction
-             * @param onAnimationEnd Call back trigger at the end of the animation.
-             */
-            transitionTo(animations: Animation[], duration: number, easingFunction: any, easingMode: number | undefined, onAnimationEnd: () => void): void;
-            /**
-                * Stops and removes all animations that have been applied to the model
-                */
-            stopAllAnimations(): void;
-            /**
-                * Will remove this model from the viewer (but NOT dispose it).
-                */
-            remove(): void;
-            /**
-                * Dispose this model, including all of its associated assets.
-                */
-            dispose(): void;
-    }
+    
 }
 
 declare module 'babylonjs-viewer/model/modelAnimation' {

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

@@ -6,7 +6,7 @@
   - New GUI 3D controls toolset. [Complete doc + demos](http://doc.babylonjs.com/how_to/gui3d) ([Deltakosh](https://github.com/deltakosh))
   - New GUI control: [Grid](http://doc.babylonjs.com/how_to/gui#grid) ([Deltakosh](https://github.com/deltakosh))
   - New GUI control: [InputPassword](https://doc.babylonjs.com/how_to/gui#inputpassword) ([theom](https://github.com/theom))
-  -New GUI container SelectionPanel ([JohnK](https://github.com/BabylonJSGuide))
+  -New GUI container [SelectionPanel](http://doc.babylonjs.com/how_to/selector) ([JohnK](https://github.com/BabylonJSGuide))
 - Gizmo Support ([TrevorDev](https://github.com/TrevorDev))
   - Gizmo and GizmoManager classes used to manipulate meshes in a scene. Gizmo types include: position, scale, rotation and bounding box. [Doc](http://doc.babylonjs.com/how_to/gizmo) ([TrevorDev](https://github.com/TrevorDev))
   - New behaviors: PointerDragBehavior, SixDofDragBehavior and MultiPointerScaleBehavior to enable smooth drag and drop/scaling with mouse or 6dof controller on a mesh. [Doc](http://doc.babylonjs.com/how_to/meshbehavior) ([TrevorDev](https://github.com/TrevorDev))
@@ -40,6 +40,8 @@
   - Added support for noise textures. [Doc](http://doc.babylonjs.com/babylon101/particles#noise-texture)
   - Added support for emit rate gradients. [Doc](http://doc.babylonjs.com/babylon101/particles#emit-rate-over-time)
   - Start size gradient support for particles. [Doc](http://doc.babylonjs.com/babylon101/particles#start-size-over-time) ([TrevorDev](https://github.com/TrevorDev))
+  - Attached sub emitters. [Doc](http://doc.babylonjs.com/how_to/sub_emitters) ([TrevorDev](https://github.com/TrevorDev))
+  - Cylinder particle emitter and constructor in baseParticle [Doc](https://doc.babylonjs.com/babylon101/particles#cylinder-emitter) ([TrevorDev](https://github.com/TrevorDev))
   - Added support for cylinder particle emitter. [Doc](https://doc.babylonjs.com/babylon101/particles#cylinder-emitter) ([TrevorDev](https://github.com/TrevorDev))
   - Added support for random start cell when using animated sprite sheets. [Doc](http://doc.babylonjs.com/how_to/animate)
 - Added SceneComponent to help decoupling Scene from its components. ([sebavan](http://www.github.com/sebavan))
@@ -66,6 +68,7 @@
 
 ### Core Engine
 
+- Improved the way world matrices were computed ([Deltakosh](https://github.com/deltakosh))
 - Added `scene.rootNodes` to track root nodes (ie. nodes with no parent) ([Deltakosh](https://github.com/deltakosh))
 - Added `scene.pickSpriteWithRay` function ([Deltakosh](https://github.com/deltakosh))
 - Added support for multiple clip planes. [Demo](https://www.babylonjs-playground.com/#Y6W087) ([Deltakosh](https://github.com/deltakosh))
@@ -190,6 +193,7 @@
 - GPUParticleSystem does not get stuck in burst loop when stopped and started ([TrevorDev](https://github.com/TrevorDev))
 - trackPosition:false not working in webVRCamera ([TrevorDev](https://github.com/TrevorDev))
 - Spring Joint could not be removed ([TrevorDev](https://github.com/TrevorDev))
+- Sometimes duplicate controller models are loaded in VR ([TrevorDev](https://github.com/TrevorDev))
 
 ### Core Engine
 
@@ -206,6 +210,7 @@
 - Oimo.js now receives quaternion and not euler when a body is being constructed ([RaananW](https://github.com/RaananW))
 - Improving visual quality on SSAO2 shader ([CraigFeldspar](https://github.com/CraigFeldspar))
 - Fixed a bug where changing the sample count on `PostProcess` would not update the WebGL Texture ([CraigFeldspar](https://github.com/CraigFeldspar))
+- Fixed multi camera support in defaultRenderingPipeline depth of field ([sebavan](http://www.github.com/sebavan))
 
 ### Viewer
 

+ 25 - 5
gui/src/2D/advancedDynamicTexture.ts

@@ -23,11 +23,10 @@ export interface IFocusableControl {
     processKeyboard(evt: KeyboardEvent): void;
 
     /**
-     * Function called to let the current focused control keeps the focus
-     * @param pointerId defines the unique id of the current pointer
-     * @returns a boolean indicating if the control wants to keep the focus
+     * Function called to get the list of controls that should not steal the focus from this control
+     * @returns an array of controls
      */
-    wantTokeepFocus(pointerId: number): boolean;
+    keepsFocusWith(): Nullable<Control[]>;
 }
 
 /**
@@ -666,7 +665,28 @@ export class AdvancedDynamicTexture extends DynamicTexture {
                 delete this._lastControlDown[pointerId];
 
                 if (this.focusedControl) {
-                    if (!this.focusedControl.wantTokeepFocus(pointerId)) {
+                    const friendlyControls = this.focusedControl.keepsFocusWith();
+                    
+                    let canMoveFocus = true;
+
+                    if (friendlyControls) {
+                        for (var control of friendlyControls) {
+                            // Same host, no need to keep the focus
+                            if (this === control._host) {
+                                continue;
+                            }
+
+                            // Different hosts
+                            const otherHost = control._host;
+
+                            if (otherHost._lastControlOver[pointerId] && otherHost._lastControlOver[pointerId].isAscendant(control)) {
+                                canMoveFocus = false;
+                                break;
+                            }
+                        }
+                    }
+
+                    if (canMoveFocus) {
                         this.focusedControl = null;
                     }
                 }

+ 1 - 1
gui/src/2D/controls/control.ts

@@ -750,7 +750,7 @@ export class Control {
      * @param container defines the container to look for
      * @returns true if the container is one of the ascendant of the control
      */
-    public isAscendant(container: Container): boolean {
+    public isAscendant(container: Control): boolean {
         if (!this.parent) {
             return false;
         }

+ 5 - 19
gui/src/2D/controls/inputText.ts

@@ -277,28 +277,14 @@ export class InputText extends Control implements IFocusableControl {
     }
 
     /**
-     * Function called to let the current focused control keeps the focus
-     * @param pointerId defines the unique id of the current pointer generating the focus change
-     * @returns a boolean indicating if the control wants to keep the focus
+     * Function called to get the list of controls that should not steal the focus from this control
+     * @returns an array of controls
      */
-    public wantTokeepFocus(pointerId: number): boolean {
+    public keepsFocusWith(): Nullable<Control[]> {
         if (!this._connectedVirtualKeyboard) {
-            return false;
+            return null;
         }
-
-        // Same host, no need to keep the focus
-        if (this._host === this._connectedVirtualKeyboard._host) {
-            return false;
-        }
-
-        // Different hosts
-        const otherHost = this._connectedVirtualKeyboard._host;
-
-        if (otherHost._lastControlOver[pointerId] && otherHost._lastControlOver[pointerId].isAscendant(this._connectedVirtualKeyboard)) {
-            return true;
-        }
-
-        return false;
+        return [this._connectedVirtualKeyboard];
     }
 
     /** @hidden */

+ 60 - 8
gui/src/2D/controls/selector.ts

@@ -5,6 +5,7 @@ import {TextBlock} from "./textBlock";
 import {Checkbox} from "./checkbox";
 import {RadioButton} from "./radioButton";
 import {Slider} from "./slider";
+import { Container } from "./container";
 
 /** Class used to create a RadioGroup 
  * which contains groups of radio buttons
@@ -278,18 +279,21 @@ export class SliderGroup extends SelectorGroup{
 }
 
 
-/** Class used to hold the controls for the checkboxes, radio buttons and sliders */
+/** Class used to hold the controls for the checkboxes, radio buttons and sliders 
+ * @see http://doc.babylonjs.com/how_to/selector
+*/
 export class SelectionPanel extends Rectangle {
     private _panel: StackPanel;
     private _buttonColor: string = "#364249";
     private _buttonBackground: string = "#CCCCCC"; 
     private _headerColor: string = "black";
     private _barColor: string = "white";
+    private _barHeight: string = "2px";
+    private _spacerHeight: string = "20px";
     private _labelColor: string;
     private _groups: SelectorGroup[];
     private _bars: any[] = new Array();
 
-
     /**
     * Creates a new SelectionPanel
     * @param name of SelectionPanel
@@ -302,7 +306,7 @@ export class SelectionPanel extends Rectangle {
         public groups: SelectorGroup[] = []) {
         super(name);
         this._groups = groups;
-        this.thickness = 4;
+        this.thickness = 2;
         this._panel = new StackPanel();
         this._panel.verticalAlignment = Control.VERTICAL_ALIGNMENT_TOP;
         this._panel.horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT;
@@ -426,18 +430,66 @@ export class SelectionPanel extends Rectangle {
 
     private _setBarColor() {
         for(var i = 0; i < this._bars.length; i++) {
-            this._bars[i].background = this._barColor;
+            this._bars[i].children[0].background = this._barColor;
+        }
+    }
+
+    /** Gets or sets the height of separator bar */
+    public get barHeight(): string {
+        return this._barHeight;
+    }
+
+    public set barHeight(value: string) {
+        if(this._barHeight === value) {
+            return;
+        }
+        
+        this._barHeight = value;
+        this._setBarHeight();
+    }
+
+    private _setBarHeight() {
+        for(var i = 0; i < this._bars.length; i++) {
+            this._bars[i].children[0].height = this._barHeight;
+        }
+    }
+
+    /** Gets or sets the height of spacers*/
+    public get spacerHeight(): string {
+        return this._spacerHeight;
+    }
+
+    public set spacerHeight(value: string) {
+        if(this._spacerHeight === value) {
+            return;
+        }
+        
+        this._spacerHeight = value;
+        this._setSpacerHeight();
+    }
+
+    private _setSpacerHeight() {
+        for(var i = 0; i < this._bars.length; i++) {
+            this._bars[i].height = this._spacerHeight;
         }
     }
 
     /** Adds a bar between groups */
     private _addSpacer(): void {
-        var separator = new Rectangle();
+        var separator = new Container();
         separator.width = 1;
-        separator.height = "5px";
+        separator.height = this._spacerHeight;
         separator.horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT;
-        separator.background = this._barColor;
-        separator.color = "transparent";
+
+        var bar = new Rectangle();
+        bar.width = 1;
+        bar.height = this._barHeight;
+        bar.horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT;
+        bar.verticalAlignment = Control.VERTICAL_ALIGNMENT_CENTER;
+        bar.background = this._barColor;
+        bar.color = "transparent";
+        separator.addControl(bar);
+
         this._panel.addControl(separator);
         this._bars.push(separator);
     }

+ 9 - 2
loaders/src/glTF/2.0/babylon.glTFLoader.ts

@@ -1357,11 +1357,18 @@ module BABYLON.GLTF2 {
                     return new 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 % VertexBuffer.GetTypeByteLength(accessor.componentType) !== 0) {
+                Tools.Warn("Accessor byte offset is not a multiple of component type byte length");
+                accessor._babylonVertexBuffer = this._loadFloatAccessorAsync(`#/accessors/${accessor.index}`, accessor).then(data => {
+                    return new VertexBuffer(this.babylonScene.getEngine(), data, kind, false);
+                });
+            }
             else {
                 const bufferView = ArrayItem.Get(`${context}/bufferView`, this.gltf.bufferViews, accessor.bufferView);
-                accessor._babylonVertexBuffer = this._loadVertexBufferViewAsync(bufferView, kind).then(buffer => {
+                accessor._babylonVertexBuffer = this._loadVertexBufferViewAsync(bufferView, kind).then(babylonBuffer => {
                     const size = GLTFLoader._GetNumComponents(context, accessor.type);
-                    return new VertexBuffer(this.babylonScene.getEngine(), buffer, kind, false, false, bufferView.byteStride,
+                    return new VertexBuffer(this.babylonScene.getEngine(), babylonBuffer, kind, false, false, bufferView.byteStride,
                         false, accessor.byteOffset, size, accessor.componentType, accessor.normalized, true);
                 });
             }

+ 2 - 0
materialsLibrary/src/water/babylon.waterMaterial.ts

@@ -164,6 +164,8 @@ module BABYLON {
 
             this._createRenderTargets(scene, renderTargetSize);
 
+            this.hasRenderTargetTextures = true;
+
             // Create render targets
             this.getRenderTargetTextures = (): SmartArray<RenderTargetTexture> => {
                 this._renderTargets.reset();

+ 2 - 2
sandbox/index.js

@@ -313,9 +313,9 @@ if (BABYLON.Engine.isSupported()) {
             else {
                 footer.style.display = "none";
                 errorZone.style.display = "none";
-                if (enableDebugLayer) {
+                if (debugLayerEnabled) {
                     currentScene.debugLayer.hide();
-                    enableDebugLayer = false;
+                    debugLayerEnabled = false;
                 }
             }
         }

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

@@ -149,7 +149,7 @@ module BABYLON {
                 }
                 
                 if (pointerInfo.type == BABYLON.PointerEventTypes.POINTERDOWN) {
-                    
+
                     if(!this.dragging && pointerInfo.pickInfo && pointerInfo.pickInfo.hit && pointerInfo.pickInfo.pickedMesh && pointerInfo.pickInfo.pickedPoint && pointerInfo.pickInfo.ray && pickPredicate(pointerInfo.pickInfo.pickedMesh)){
                         this._startDrag((<PointerEvent>pointerInfo.event).pointerId, pointerInfo.pickInfo.ray, pointerInfo.pickInfo.pickedPoint);
                     }
@@ -159,7 +159,7 @@ module BABYLON {
                     }
                 }else if(pointerInfo.type == BABYLON.PointerEventTypes.POINTERMOVE){
                     var pointerId = (<PointerEvent>pointerInfo.event).pointerId;
-
+                    
                     // Keep track of last pointer ray, this is used simulating the start of a drag in startDrag()
                     if(!this._lastPointerRay[pointerId]){
                         this._lastPointerRay[pointerId] = new BABYLON.Ray(new BABYLON.Vector3(), new BABYLON.Vector3());
@@ -237,7 +237,7 @@ module BABYLON {
             var pickedPoint = this._pickWithRayOnDragPlane(this._startDragRay);
             if(pickedPoint){
                 this.dragging = true;
-                this.currentDraggingPointerID = 1;
+                this.currentDraggingPointerID = pointerId;
                 this.lastDragPosition.copyFrom(pickedPoint);
                 this.onDragStartObservable.notifyObservers({dragPlanePoint: pickedPoint, pointerId: this.currentDraggingPointerID});
                 this._targetPosition.copyFrom((this._attachedNode).absolutePosition)

+ 1 - 0
src/Behaviors/Mesh/babylon.sixDofDragBehavior.ts

@@ -92,6 +92,7 @@ module BABYLON {
 
                         // Attach the virtual drag mesh to the virtual origin mesh so it can be dragged
                         this._virtualOriginMesh.removeChild(this._virtualDragMesh);
+                        pickedMesh.computeWorldMatrix();
                         this._virtualDragMesh.position.copyFrom(pickedMesh.absolutePosition);
                         if(!pickedMesh.rotationQuaternion){
                             pickedMesh.rotationQuaternion = Quaternion.RotationYawPitchRoll(pickedMesh.rotation.y,pickedMesh.rotation.x,pickedMesh.rotation.z);

+ 1 - 1
src/Cameras/VR/babylon.webVRCamera.ts

@@ -736,7 +736,7 @@ module BABYLON {
                                     }
                                     let activateLightOnSubMeshes = function (mesh: AbstractMesh, light: HemisphericLight) {
                                         let children = mesh.getChildren();
-                                        if (children.length !== 0) {
+                                        if (children && children.length !== 0) {
                                             children.forEach((mesh) => {
                                                 light.includedOnlyMeshes.push(<AbstractMesh>mesh);
                                                 activateLightOnSubMeshes(<AbstractMesh>mesh, light);

+ 0 - 1
src/Cameras/babylon.camera.ts

@@ -166,7 +166,6 @@
         private _computedViewMatrix = Matrix.Identity();
         public _projectionMatrix = new Matrix();
         private _doNotComputeProjectionMatrix = false;
-        private _worldMatrix = Matrix.Identity();
         public _postProcesses = new Array<Nullable<PostProcess>>();
         private _transformMatrix = Matrix.Zero();
 

+ 7 - 2
src/Engine/Extensions/babylon.engine.occlusionQuery.ts

@@ -250,14 +250,19 @@ module BABYLON {
 
     // We also need to update AbstractMesh as there is a portion of the code there
     AbstractMesh.prototype._checkOcclusionQuery = function() {
+        if (this.occlusionType === AbstractMesh.OCCLUSION_TYPE_NONE) {
+            this._isOccluded = false;
+            return;
+        }
+
         var engine = this.getEngine();
 
-        if (!engine.isQueryResultAvailable) { // Occlusion query where not referenced
+        if (engine.webGLVersion < 2) {
             this._isOccluded = false;
             return;
         }
 
-        if (engine.webGLVersion < 2 || this.occlusionType === AbstractMesh.OCCLUSION_TYPE_NONE) {
+        if (!engine.isQueryResultAvailable) { // Occlusion query where not referenced
             this._isOccluded = false;
             return;
         }

+ 6 - 5
src/Lights/babylon.hemisphericLight.ts

@@ -19,9 +19,7 @@
          * The light reflection direction, not the incoming direction.
          */
         @serializeAsVector3()
-        public direction: Vector3
-
-        private _worldMatrix: Matrix;
+        public direction: Vector3;
 
         /**
          * Creates a HemisphericLight object in the scene according to the passed direction (Vector3).  
@@ -93,9 +91,12 @@
         }
 
         /**
-         * @hidden internal use only.
+         * Computes the world matrix of the node
+         * @param force defines if the cache version should be invalidated forcing the world matrix to be created from scratch
+         * @param useWasUpdatedFlag defines a reserved property
+         * @returns the world matrix
          */
-        public _getWorldMatrix(): Matrix {
+        public computeWorldMatrix(force?: boolean, useWasUpdatedFlag?: boolean): Matrix {
             if (!this._worldMatrix) {
                 this._worldMatrix = Matrix.Identity();
             }

+ 0 - 32
src/Lights/babylon.light.ts

@@ -301,8 +301,6 @@ module BABYLON {
             this._markMeshesAsLightDirty();
         }
 
-        private _parentedWorldMatrix: Matrix;
-
         /**
          * Shadow generator associted to the light.
          * @hidden Internal use only.
@@ -354,11 +352,6 @@ module BABYLON {
         public abstract transferToEffect(effect: Effect, lightIndex: string): Light;
 
         /**
-         * @hidden internal use only.
-         */
-        public abstract _getWorldMatrix(): Matrix;
-
-        /**
          * Returns the string "Light".
          * @returns the class name
          */
@@ -440,31 +433,6 @@ module BABYLON {
         }
 
         /**
-         * Computes and Returns the light World matrix.
-         * @returns the world matrix 
-         */
-        public getWorldMatrix(): Matrix {
-            this._currentRenderId = this.getScene().getRenderId();
-            this._childRenderId = this._currentRenderId;
-
-            var worldMatrix = this._getWorldMatrix();
-
-            if (this.parent && this.parent.getWorldMatrix) {
-                if (!this._parentedWorldMatrix) {
-                    this._parentedWorldMatrix = Matrix.Identity();
-                }
-
-                worldMatrix.multiplyToRef(this.parent.getWorldMatrix(), this._parentedWorldMatrix);
-
-                this._markSyncedWithParent();
-
-                return this._parentedWorldMatrix;
-            }
-
-            return worldMatrix;
-        }
-
-        /**
 		 * Sort function to order lights for rendering.
 		 * @param a First Light object to compare to second.
 		 * @param b Second Light object to compare first.

+ 36 - 4
src/Lights/babylon.shadowLight.ts

@@ -206,7 +206,6 @@
          */
         public transformedDirection: Vector3;
 
-        private _worldMatrix: Matrix;
         private _needProjectionMatrixCompute: boolean = true;
 
         /**
@@ -301,17 +300,50 @@
             this._needProjectionMatrixCompute = true;
         }
 
+        /** @hidden */
+        public _initCache() {
+            super._initCache();
+
+            this._cache.position = Vector3.Zero();
+        }
+
+        /** @hidden */
+        public _isSynchronized(): boolean {
+            if (!this._cache.position.equals(this.position))
+                return false;
+
+            return true;
+        }        
+
         /**
-         * Get the world matrix of the sahdow lights.
-         * @hidden Internal Use Only
+         * Computes the world matrix of the node
+         * @param force defines if the cache version should be invalidated forcing the world matrix to be created from scratch
+         * @returns the world matrix
          */
-        public _getWorldMatrix(): Matrix {
+        public computeWorldMatrix(force?: boolean): Matrix {
+            if (!force && this.isSynchronized()) {
+                this._currentRenderId = this.getScene().getRenderId();
+                return this._worldMatrix;
+            }
+
+            this._updateCache();
+            this._cache.position.copyFrom(this.position);
+
             if (!this._worldMatrix) {
                 this._worldMatrix = Matrix.Identity();
             }
 
             Matrix.TranslationToRef(this.position.x, this.position.y, this.position.z, this._worldMatrix);
 
+            if (this.parent && this.parent.getWorldMatrix) {
+                this._worldMatrix.multiplyToRef(this.parent.getWorldMatrix(), this._worldMatrix);
+
+                this._markSyncedWithParent();
+            }            
+
+            // Cache the determinant
+            this._worldMatrixDeterminant = this._worldMatrix.determinant();
+
             return this._worldMatrix;
         }
 

+ 15 - 0
src/Materials/Background/babylon.backgroundMaterial.ts

@@ -584,6 +584,21 @@
         }
 
         /**
+         * Gets a boolean indicating that current material needs to register RTT
+         */        
+        public get hasRenderTargetTextures(): boolean {
+            if (this._diffuseTexture && this._diffuseTexture.isRenderTarget) {
+                return true;
+            }
+
+            if (this._reflectionTexture && this._reflectionTexture.isRenderTarget) {
+                return true;
+            }
+
+            return false;
+        }
+
+        /**
          * The entire material has been created in order to prevent overdraw.
          * @returns false
          */

+ 16 - 0
src/Materials/PBR/babylon.pbrBaseMaterial.ts

@@ -609,6 +609,22 @@
             this._environmentBRDFTexture = TextureTools.GetEnvironmentBRDFTexture(scene);
         }
 
+
+        /**
+         * Gets a boolean indicating that current material needs to register RTT
+         */               
+        public get hasRenderTargetTextures(): boolean {
+            if (StandardMaterial.ReflectionTextureEnabled && this._reflectionTexture && this._reflectionTexture.isRenderTarget) {
+                return true;
+            }
+
+            if (StandardMaterial.RefractionTextureEnabled && this._refractionTexture && this._refractionTexture.isRenderTarget) {
+                return true;
+            }
+
+            return false;
+        }        
+
         /**
          * Gets the name of the material class.
          */

+ 5 - 0
src/Materials/babylon.material.ts

@@ -494,6 +494,11 @@
         public getRenderTargetTextures: () => SmartArray<RenderTargetTexture>;
 
         /**
+         * Gets a boolean indicating that current material needs to register RTT
+         */
+        public hasRenderTargetTextures = false;
+
+        /**
          * Specifies if the material should be serialized
          */
         public doNotSerialize = false;

+ 15 - 0
src/Materials/babylon.standardMaterial.ts

@@ -513,6 +513,21 @@ module BABYLON {
             }
         }
 
+        /**
+         * Gets a boolean indicating that current material needs to register RTT
+         */               
+        public get hasRenderTargetTextures(): boolean {
+            if (StandardMaterial.ReflectionTextureEnabled && this._reflectionTexture && this._reflectionTexture.isRenderTarget) {
+                return true;
+            }
+
+            if (StandardMaterial.RefractionTextureEnabled && this._refractionTexture && this._refractionTexture.isRenderTarget) {
+                return true;
+            }
+
+            return false;
+        }
+
         public getClassName(): string {
             return "StandardMaterial";
         }

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

@@ -42,7 +42,7 @@
         /** @hidden */
         public _delayLoadingFunction: Nullable<(any: any, geometry: Geometry) => void>;
         /** @hidden */
-        public _softwareSkinningRenderId: number;
+        public _softwareSkinningFrameId: number;
         private _vertexArrayObjects: { [key: string]: WebGLVertexArrayObject; };
         private _updatable: boolean;
 

+ 4 - 3
src/Mesh/babylon.mesh.ts

@@ -831,7 +831,8 @@
 
             var data = this._getPositionData(applySkeleton);
             if (data) {
-                var extend = Tools.ExtractMinAndMax(data, 0, this.getTotalVertices());
+                const bias = this.geometry ? this.geometry.boundingBias : null;
+                var extend = Tools.ExtractMinAndMax(data, 0, this.getTotalVertices(), bias);
                 this._boundingInfo = new BoundingInfo(extend.minimum, extend.maximum);
             }
 
@@ -3295,11 +3296,11 @@
                 return this;
             }
 
-            if (this.geometry._softwareSkinningRenderId == this.getScene().getRenderId()) {
+            if (this.geometry._softwareSkinningFrameId == this.getScene().getFrameId()) {
                 return this;
             }
 
-            this.geometry._softwareSkinningRenderId = this.getScene().getRenderId();
+            this.geometry._softwareSkinningFrameId = this.getScene().getFrameId();
 
             if (!this.isVerticesDataPresent(VertexBuffer.PositionKind)) {
                 return this;

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

@@ -67,7 +67,7 @@
         }
 
         public get IsGlobal(): boolean {
-            return (this.verticesStart === 0 && this.verticesCount == this._mesh.getTotalVertices());
+            return (this.verticesStart === 0 && this.verticesCount === this._mesh.getTotalVertices());
         }
 
         /**

+ 34 - 55
src/Mesh/babylon.transformNode.ts

@@ -14,13 +14,16 @@ module BABYLON {
         private _rightInverted = new Vector3(-1, 0, 0);
 
         // Properties
-        @serializeAsVector3()
+        @serializeAsVector3("position")
+        private _position = Vector3.Zero();
+
+        @serializeAsVector3("rotation")
         private _rotation = Vector3.Zero();
 
-        @serializeAsQuaternion()
+        @serializeAsQuaternion("rotationQuaternion")
         private _rotationQuaternion: Nullable<Quaternion>;
 
-        @serializeAsVector3()
+        @serializeAsVector3("scaling")
         protected _scaling = Vector3.One();
         protected _isDirty = false;
         private _transformToBoneReferal: Nullable<TransformNode>;
@@ -53,17 +56,11 @@ module BABYLON {
         @serialize()
         public ignoreNonUniformScaling = false;
 
-        @serializeAsVector3()
-        public position = Vector3.Zero();
-
         // Cache      
         /** @hidden */
         public _poseMatrix: Matrix;
         private _localWorld = Matrix.Zero();
-        /** @hidden */
-        public _worldMatrix = Matrix.Zero();
-        /** @hidden */
-        public _worldMatrixDeterminant = 0;
+
         private _absolutePosition = Vector3.Zero();
         private _pivotMatrix = Matrix.Identity();
         private _pivotMatrixInverse: Matrix;
@@ -93,9 +90,20 @@ module BABYLON {
         }
 
         /**
-          * Rotation property : a Vector3 depicting the rotation value in radians around each local axis X, Y, Z. 
-          * If rotation quaternion is set, this Vector3 will (almost always) be the Zero vector!
-          * Default : (0.0, 0.0, 0.0)
+          * Gets or set the node position (default is (0.0, 0.0, 0.0))
+          */
+         public get position(): Vector3 {
+            return this._position;
+        }
+
+        public set position(newPosition: Vector3) {
+            this._position = newPosition;
+            this._isDirty = true;
+        }        
+
+        /**
+          * Gets or sets the rotation property : a Vector3 defining the rotation value in radians around each local axis X, Y, Z  (default is (0.0, 0.0, 0.0)).
+          * If rotation quaternion is set, this Vector3 will be ignored and copy from the quaternion
           */
         public get rotation(): Vector3 {
             return this._rotation;
@@ -103,28 +111,24 @@ module BABYLON {
 
         public set rotation(newRotation: Vector3) {
             this._rotation = newRotation;
+            this._isDirty = true;
         }
 
         /**
-         * Scaling property : a Vector3 depicting the mesh scaling along each local axis X, Y, Z.  
-         * Default : (1.0, 1.0, 1.0)
+         * Gets or sets the scaling property : a Vector3 defining the node scaling along each local axis X, Y, Z (default is (0.0, 0.0, 0.0)).
          */
         public get scaling(): Vector3 {
             return this._scaling;
         }
 
-        /**
-         * Scaling property : a Vector3 depicting the mesh scaling along each local axis X, Y, Z.  
-         * Default : (1.0, 1.0, 1.0)
-        */
         public set scaling(newScaling: Vector3) {
             this._scaling = newScaling;
+            this._isDirty = true;
         }
 
         /**
-         * Rotation Quaternion property : this a Quaternion object depicting the mesh rotation by using a unit quaternion. 
-         * It's null by default.  
-         * If set, only the rotationQuaternion is then used to compute the mesh rotation and its property `.rotation\ is then ignored and set to (0.0, 0.0, 0.0)
+         * Gets or sets the rotation Quaternion property : this a Quaternion object defining the node rotation by using a unit quaternion (null by default).
+         * If set, only the rotationQuaternion is then used to compute the node rotation (ie. node.rotation will be ignored)
          */
         public get rotationQuaternion(): Nullable<Quaternion> {
             return this._rotationQuaternion;
@@ -169,30 +173,6 @@ module BABYLON {
         }
 
         /**
-         * Returns the latest update of the World matrix
-         * Returns a Matrix.  
-         */
-        public getWorldMatrix(): Matrix {
-            if (this._currentRenderId !== this.getScene().getRenderId()) {
-                this.computeWorldMatrix();
-            }
-            return this._worldMatrix;
-        }
-
-        /** @hidden */
-        public _getWorldMatrixDeterminant(): number {
-            return this._worldMatrixDeterminant;
-        }
-
-        /**
-         * Returns directly the latest state of the mesh World matrix. 
-         * A Matrix is returned.    
-         */
-        public get worldMatrixFromCache(): Matrix {
-            return this._worldMatrix;
-        }
-
-        /**
          * Copies the parameter passed Matrix into the mesh Pose matrix.  
          * Returns the TransformNode.  
          */
@@ -226,7 +206,7 @@ module BABYLON {
                 return false;
             }
 
-            if (!this._cache.position.equals(this.position))
+            if (!this._cache.position.equals(this._position))
                 return false;
 
             if (this._rotationQuaternion) {
@@ -234,10 +214,10 @@ module BABYLON {
                     return false;
             }
 
-            if (!this._cache.rotation.equals(this.rotation))
+            if (!this._cache.rotation.equals(this._rotation))
                 return false;
 
-            if (!this._cache.scaling.equals(this.scaling))
+            if (!this._cache.scaling.equals(this._scaling))
                 return false;
 
             return true;
@@ -753,22 +733,21 @@ module BABYLON {
         }
 
         /**
-         * Computes the mesh World matrix and returns it.  
-         * If the mesh world matrix is frozen, this computation does nothing more than returning the last frozen values.  
-         * If the parameter `force` is let to `false` (default), the current cached World matrix is returned. 
-         * If the parameter `force`is set to `true`, the actual computation is done.  
-         * Returns the mesh World Matrix.
+         * Computes the world matrix of the node
+         * @param force defines if the cache version should be invalidated forcing the world matrix to be created from scratch
+         * @returns the world matrix
          */
         public computeWorldMatrix(force?: boolean): Matrix {
             if (this._isWorldMatrixFrozen) {
                 return this._worldMatrix;
             }
 
-            if (!force && this.isSynchronized(true)) {
+            if (!force && this.isSynchronized()) {
                 this._currentRenderId = this.getScene().getRenderId();
                 return this._worldMatrix;
             }
 
+            this._updateCache();
             this._cache.position.copyFrom(this.position);
             this._cache.scaling.copyFrom(this.scaling);
             this._cache.pivotMatrixUpdated = false;

+ 50 - 0
src/Particles/babylon.IParticleSystem.ts

@@ -422,7 +422,57 @@ module BABYLON {
          * @returns the list of start size gradients
          */
         getStartSizeGradients(): Nullable<Array<FactorGradient>>;  
+
+        /**
+         * Gets the current list of color gradients.
+         * You must use addColorGradient and removeColorGradient to udpate this list
+         * @returns the list of color gradients
+         */
+        getColorGradients(): Nullable<Array<ColorGradient>>;      
+        
+        /**
+         * Adds a new ramp gradient used to remap particle colors
+         * @param gradient defines the gradient to use (between 0 and 1)
+         * @param color defines the color to affect to the specified gradient
+         * @returns the current particle system
+         */
+        addRampGradient(gradient: number, color: Color4): IParticleSystem;     
+        /**
+         * Gets the current list of ramp gradients.
+         * You must use addRampGradient and removeRampGradient to udpate this list
+         * @returns the list of ramp gradients
+         */
+        getRampGradients(): Nullable<Array<ColorGradient>>;             
         
+        /**
+         * Adds a new color remap gradient
+         * @param gradient defines the gradient to use (between 0 and 1)
+         * @param min defines the color remap minimal range        
+         * @param max defines the color remap maximal range        
+         * @returns the current particle system
+         */
+        addColorRemapGradient(gradient: number, min: number, max: number): IParticleSystem;    
+        /**
+         * Gets the current list of color remap gradients.
+         * You must use addColorRemapGradient and removeColorRemapGradient to udpate this list
+         * @returns the list of color remap gradients
+         */
+        getColorRemapGradients(): Nullable<Array<FactorGradient>>;
+        
+        /**
+         * Adds a new alpha remap gradient
+         * @param gradient defines the gradient to use (between 0 and 1)
+         * @param min defines the alpha remap minimal range        
+         * @param max defines the alpha remap maximal range        
+         * @returns the current particle system
+         */
+        addAlphaRemapGradient(gradient: number, min: number, max: number): IParticleSystem; 
+        /**
+         * Gets the current list of alpha remap gradients.
+         * You must use addAlphaRemapGradient and removeAlphaRemapGradient to udpate this list
+         * @returns the list of alpha remap gradients
+         */
+        getAlphaRemapGradients(): Nullable<Array<FactorGradient>>;            
 
         /**
          * Creates a Point Emitter for the particle system (emits directly from the emitter position)

+ 44 - 1
src/Particles/babylon.baseParticleSystem.ts

@@ -218,7 +218,7 @@ module BABYLON {
 
         /** @hidden */
         protected _isAnimationSheetEnabled: boolean;
-        
+       
         /**
          * Gets or sets whether an animation sprite sheet is enabled or not on the particle system
          */
@@ -258,6 +258,9 @@ module BABYLON {
         protected _dragGradients: Nullable<Array<FactorGradient>> = null;
         protected _emitRateGradients: Nullable<Array<FactorGradient>> = null;
         protected _startSizeGradients: Nullable<Array<FactorGradient>> = null;
+        protected _rampGradients: Nullable<Array<ColorGradient>> = null;
+        protected _colorRemapGradients: Nullable<Array<FactorGradient>> = null;
+        protected _alphaRemapGradients: Nullable<Array<FactorGradient>> = null;        
 
         /**
          * Gets the current list of drag gradients.
@@ -299,6 +302,24 @@ module BABYLON {
         }        
 
         /**
+         * Gets the current list of color remap gradients.
+         * You must use addColorRemapGradient and removeColorRemapGradient to udpate this list
+         * @returns the list of color remap gradients
+         */
+        public getColorRemapGradients(): Nullable<Array<FactorGradient>> {
+            return this._colorRemapGradients;
+        }   
+
+        /**
+         * Gets the current list of alpha remap gradients.
+         * You must use addAlphaRemapGradient and removeAlphaRemapGradient to udpate this list
+         * @returns the list of alpha remap gradients
+         */
+        public getAlphaRemapGradients(): Nullable<Array<FactorGradient>> {
+            return this._alphaRemapGradients;
+        }   
+
+        /**
          * Gets the current list of life time gradients.
          * You must use addLifeTimeGradient and removeLifeTimeGradient to udpate this list
          * @returns the list of life time gradients
@@ -515,6 +536,28 @@ module BABYLON {
         protected _reset() {
         }
 
+        /** @hidden */
+        protected _removeGradientAndTexture(gradient: number, gradients: Nullable<IValueGradient[]>, texture: RawTexture): BaseParticleSystem {
+            if (!gradients) {
+                return this;
+            }
+
+            let index = 0;
+            for (var valueGradient of gradients) {
+                if (valueGradient.gradient === gradient) {
+                    gradients.splice(index, 1);
+                    break;
+                }
+                index++;
+            }
+
+            if (texture) {
+                texture.dispose();
+            }            
+
+            return this;
+        } 
+
         /**
          * Instantiates a particle system.
          * Particles are often small sprites used to simulate hard-to-reproduce phenomena like fire, smoke, water, or abstract visual effects like magic glitter and faery dust.

+ 90 - 26
src/Particles/babylon.gpuParticleSystem.ts

@@ -157,29 +157,13 @@
         }            
                
         private _colorGradientsTexture: RawTexture;
-
-        private _removeGradient(gradient: number, gradients: Nullable<IValueGradient[]>, texture: RawTexture): GPUParticleSystem {
-            if (!gradients) {
-                return this;
-            }
-
-            let index = 0;
-            for (var valueGradient of gradients) {
-                if (valueGradient.gradient === gradient) {
-                    gradients.splice(index, 1);
-                    break;
-                }
-                index++;
-            }
-
-            if (texture) {
-                texture.dispose();
-            }            
-
+        
+        protected _removeGradientAndTexture(gradient: number, gradients: Nullable<IValueGradient[]>, texture: RawTexture): BaseParticleSystem {
+            super._removeGradientAndTexture(gradient, gradients, texture);
             this._releaseBuffers();
 
             return this;
-        }    
+        }
         
         /**
          * Adds a new color gradient
@@ -224,7 +208,7 @@
          * @returns the current particle system
          */
         public removeColorGradient(gradient: number): GPUParticleSystem {
-            this._removeGradient(gradient, this._colorGradients, this._colorGradientsTexture);
+            this._removeGradientAndTexture(gradient, this._colorGradients, this._colorGradientsTexture);
             (<any>this._colorGradientsTexture) = null;
 
             return this;
@@ -284,7 +268,7 @@
          * @returns the current particle system
          */
         public removeSizeGradient(gradient: number): GPUParticleSystem {
-            this._removeGradient(gradient, this._sizeGradients, this._sizeGradientsTexture);
+            this._removeGradientAndTexture(gradient, this._sizeGradients, this._sizeGradientsTexture);
             (<any>this._sizeGradientsTexture) = null;
 
             return this;            
@@ -319,7 +303,7 @@
          * @returns the current particle system
          */
         public removeAngularSpeedGradient(gradient: number): GPUParticleSystem {
-            this._removeGradient(gradient, this._angularSpeedGradients, this._angularSpeedGradientsTexture);
+            this._removeGradientAndTexture(gradient, this._angularSpeedGradients, this._angularSpeedGradientsTexture);
             (<any>this._angularSpeedGradientsTexture) = null;
 
             return this;           
@@ -354,7 +338,7 @@
          * @returns the current particle system
          */
         public removeVelocityGradient(gradient: number): GPUParticleSystem {
-            this._removeGradient(gradient, this._velocityGradients, this._velocityGradientsTexture);
+            this._removeGradientAndTexture(gradient, this._velocityGradients, this._velocityGradientsTexture);
             (<any>this._velocityGradientsTexture) = null;
 
             return this;           
@@ -389,7 +373,7 @@
          * @returns the current particle system
          */
         public removeLimitVelocityGradient(gradient: number): GPUParticleSystem {
-            this._removeGradient(gradient, this._limitVelocityGradients, this._limitVelocityGradientsTexture);
+            this._removeGradientAndTexture(gradient, this._limitVelocityGradients, this._limitVelocityGradientsTexture);
             (<any>this._limitVelocityGradientsTexture) = null;
 
             return this;
@@ -424,7 +408,7 @@
          * @returns the current particle system
          */
         public removeDragGradient(gradient: number): GPUParticleSystem {
-            this._removeGradient(gradient, this._dragGradients, this._dragGradientsTexture);
+            this._removeGradientAndTexture(gradient, this._dragGradients, this._dragGradientsTexture);
             (<any>this._dragGradientsTexture) = null;
 
             return this;
@@ -475,6 +459,86 @@
         } 
 
         /**
+         * Not supported by GPUParticleSystem
+         * @param gradient defines the gradient to use (between 0 and 1)
+         * @param min defines the color remap minimal range        
+         * @param max defines the color remap maximal range        
+         * @returns the current particle system
+         */
+        public addColorRemapGradient(gradient: number, min: number, max: number): IParticleSystem {
+            // Do nothing as start size is not supported by GPUParticleSystem
+
+            return this;
+        }
+
+        /**
+         * Not supported by GPUParticleSystem
+         * @param gradient defines the gradient to remove
+         * @returns the current particle system
+         */
+        public removeColorRemapGradient(gradient: number): IParticleSystem {
+            // Do nothing as start size is not supported by GPUParticleSystem
+
+            return this;
+        }  
+
+        /**
+         * Not supported by GPUParticleSystem
+         * @param gradient defines the gradient to use (between 0 and 1)
+         * @param min defines the alpha remap minimal range        
+         * @param max defines the alpha remap maximal range        
+         * @returns the current particle system
+         */
+        public addAlphaRemapGradient(gradient: number, min: number, max: number): IParticleSystem {
+            // Do nothing as start size is not supported by GPUParticleSystem
+
+            return this;
+        }
+
+        /**
+         * Not supported by GPUParticleSystem
+         * @param gradient defines the gradient to remove
+         * @returns the current particle system
+         */
+        public removeAlphaRemapGradient(gradient: number): IParticleSystem {
+            // Do nothing as start size is not supported by GPUParticleSystem
+
+            return this;
+        }   
+        
+        /**
+         * Not supported by GPUParticleSystem
+         * @param gradient defines the gradient to use (between 0 and 1)
+         * @param color defines the color to affect to the specified gradient
+         * @returns the current particle system
+         */
+        public addRampGradient(gradient: number, color: Color4): IParticleSystem {
+            //Not supported by GPUParticleSystem          
+
+            return this;
+        }
+
+        /**
+         * Not supported by GPUParticleSystem
+         * @param gradient defines the gradient to remove
+         * @returns the current particle system
+         */
+        public removeRampGradient(gradient: number): IParticleSystem {
+            //Not supported by GPUParticleSystem
+
+            return this;
+        }  
+        
+        /**
+         * Not supported by GPUParticleSystem
+         * @returns the list of ramp gradients
+         */
+        public getRampGradients(): Nullable<Array<ColorGradient>> {
+            return null;
+        }             
+        
+
+        /**
          * Instantiates a GPU particle system.
          * Particles are often small sprites used to simulate hard-to-reproduce phenomena like fire, smoke, water, or abstract visual effects like magic glitter and faery dust.
          * @param name The name of the particle system

+ 20 - 0
src/Particles/babylon.particle.ts

@@ -5,6 +5,11 @@
      * This is mainly define by its coordinates, direction, velocity and age.
      */
     export class Particle {
+        private static _Count = 0;
+        /**
+         * Unique ID of the particle
+         */
+        public id:number;
         /**
          * The world position of the particle in the scene.
          */
@@ -60,6 +65,11 @@
          */
         public cellIndex: number = 0;  
 
+        /**
+         * The information required to support color remapping
+         */
+        public remapData: Vector4;
+
         /** @hidden */
         public _randomCellOffset?: number;
 
@@ -67,6 +77,9 @@
         public _initialDirection: Nullable<Vector3>;
 
         /** @hidden */
+        public _attachedSubEmitters: Nullable<Array<SubEmitter>> = null;
+
+        /** @hidden */
         public _initialStartSpriteCellID: number;
         public _initialEndSpriteCellID: number;
 
@@ -111,6 +124,7 @@
         public _currentDrag1 = 0;
         /** @hidden */
         public _currentDrag2 = 0;  
+     
 
         /**
          * Creates a new instance Particle
@@ -121,6 +135,7 @@
              * The particle system the particle belongs to.
              */
             public particleSystem: ParticleSystem) {
+            this.id = Particle._Count++;
             if (!this.particleSystem.isAnimationSheetEnabled) {
                 return;
             }
@@ -191,6 +206,8 @@
             other.angularSpeed = this.angularSpeed;
             other.particleSystem = this.particleSystem;
             other.cellIndex = this.cellIndex;
+            other.id = this.id;
+            other._attachedSubEmitters = this._attachedSubEmitters;
             if (this._currentColorGradient) {
                 other._currentColorGradient = this._currentColorGradient;
                 other._currentColor1.copyFrom(this._currentColor1);
@@ -225,6 +242,9 @@
                 other._initialStartSpriteCellID = this._initialStartSpriteCellID;
                 other._initialEndSpriteCellID = this._initialEndSpriteCellID;
             }
+            if (this.particleSystem.useRampGradients) {
+                other.remapData.copyFrom(this.remapData);
+            }
         }
     }
 } 

文件差异内容过多而无法显示
+ 2371 - 1935
src/Particles/babylon.particleSystem.ts


+ 68 - 0
src/Particles/babylon.subEmitter.ts

@@ -0,0 +1,68 @@
+module BABYLON {
+    /**
+     * Type of sub emitter
+     */
+    export enum SubEmitterType {
+        /**
+         * Attached to the particle over it's lifetime
+         */
+        ATTACHED,
+        /**
+         * Created when the particle dies
+         */
+        END
+    }
+
+    /**
+     * Sub emitter class used to emit particles from an existing particle
+     */
+    export class SubEmitter {
+        /**
+         * Type of the submitter (Default: END)
+         */
+        public type = SubEmitterType.END;
+        /**
+         * If the particle should inherit the direction from the particle it's attached to. (+Y will face the direction the particle is moving) (Default: false)
+         * Note: This only is supported when using an emitter of type Mesh
+         */
+        public inheritDirection = false;
+        /**
+         * How much of the attached particles speed should be added to the sub emitted particle (default: 0)
+         */
+        public inheritedVelocityAmount = 0;
+        /**
+         * Creates a sub emitter
+         * @param particleSystem the particle system to be used by the sub emitter
+         */
+        constructor(
+            /**
+             * the particle system to be used by the sub emitter
+             */
+            public particleSystem: ParticleSystem) {
+        }
+        /**
+         * Clones the sub emitter
+         * @returns the cloned sub emitter
+         */
+        clone(): SubEmitter {
+            // Clone particle system
+            var emitter = this.particleSystem.emitter;
+            if (!emitter) {
+                emitter = new Vector3();
+            } else if (emitter instanceof Vector3) {
+                emitter = emitter.clone();
+            } else if (emitter instanceof AbstractMesh) {
+                emitter = new Mesh("", emitter._scene);
+            }
+            var clone = new SubEmitter(this.particleSystem.clone("", emitter));
+
+            // Clone properties
+            clone.type = this.type;
+            clone.inheritDirection = this.inheritDirection;
+            clone.inheritedVelocityAmount = this.inheritedVelocityAmount;
+
+            clone.particleSystem._disposeEmitterOnDispose = true;
+            return clone;
+        }
+    }
+}

+ 27 - 4
src/PostProcess/RenderPipeline/Pipelines/babylon.defaultRenderingPipeline.ts

@@ -457,6 +457,8 @@
             }
         }
 
+        private _depthOfFieldSceneObserver: Nullable<Observer<Scene>> = null;
+
         private _buildPipeline() {
             if (!this._buildAllowed) {
                 return;
@@ -474,17 +476,37 @@
             this._reset();
             this._prevPostProcess = null;
             this._prevPrevPostProcess = null;
-            this._hasCleared = false;            
+            this._hasCleared = false;
 
             if (this.depthOfFieldEnabled) {
-                var depthTexture = this._scene.enableDepthRenderer(this._cameras[0]).getDepthMap();
-                this.depthOfField.depthTexture = depthTexture;
+                // Multi camera suport
+                if (this._cameras.length > 1) {
+                    for (let camera of this._cameras) {
+                        const depthRenderer = this._scene.enableDepthRenderer(camera);
+                        depthRenderer.useOnlyInActiveCamera = true;
+                    }
+
+                    this._depthOfFieldSceneObserver = this._scene.onAfterRenderTargetsRenderObservable.add((scene) => {
+                        if (this._cameras.indexOf(scene.activeCamera!) > -1) {
+                            this.depthOfField.depthTexture = scene.enableDepthRenderer(scene.activeCamera).getDepthMap();
+                        }
+                    });
+                }
+                else {
+                    this._scene.onAfterRenderTargetsRenderObservable.remove(this._depthOfFieldSceneObserver);
+                    const depthRenderer = this._scene.enableDepthRenderer(this._cameras[0]);
+                    this.depthOfField.depthTexture = depthRenderer.getDepthMap();
+                }
+
                 if(!this.depthOfField._isReady()){
                     this.depthOfField._updateEffects();
                 }
                 this.addEffect(this.depthOfField);
                 this._setAutoClearAndTextureSharing(this.depthOfField._effects[0], true);
             }
+            else {
+                this._scene.onAfterRenderTargetsRenderObservable.remove(this._depthOfFieldSceneObserver);
+            }
 
             if (this.bloomEnabled) {
                 if(!this.bloom._isReady()){
@@ -562,7 +584,8 @@
                         this.sharpen.dispose(camera);
                     }
     
-                    if(this.depthOfField){
+                    if(this.depthOfField) {
+                        this._scene.onAfterRenderTargetsRenderObservable.remove(this._depthOfFieldSceneObserver);
                         this.depthOfField.disposeEffects(camera);
                     }
 

+ 7 - 0
src/Rendering/babylon.depthRenderer.ts

@@ -12,6 +12,13 @@
         private _camera:Nullable<Camera>;
 
         /**
+         * Specifiess that the depth renderer will only be used within
+         * the camera it is created for.
+         * This can help forcing its rendering during the camera processing.
+         */
+        public useOnlyInActiveCamera: boolean = false;
+
+        /**
          * Instantiates a depth renderer
          * @param scene The scene the renderer belongs to
          * @param type The texture type of the depth map (default: Engine.TEXTURETYPE_FLOAT)

+ 16 - 1
src/Rendering/babylon.depthRendererSceneComponent.ts

@@ -79,6 +79,7 @@
          */
         public register(): void {
             this.scene._gatherRenderTargetsStage.registerStep(SceneComponentConstants.STEP_GATHERRENDERTARGETS_DEPTHRENDERER, this, this._gatherRenderTargets);
+            this.scene._gatherActiveCameraRenderTargetsStage.registerStep(SceneComponentConstants.STEP_GATHERACTIVECAMERARENDERTARGETS_DEPTHRENDERER, this, this._gatherActiveCameraRenderTargets);
         }
 
         /**
@@ -101,7 +102,21 @@
         private _gatherRenderTargets(renderTargets: SmartArrayNoDuplicate<RenderTargetTexture>): void {
             if (this.scene._depthRenderer) {
                 for (var key in this.scene._depthRenderer) {
-                    renderTargets.push(this.scene._depthRenderer[key].getDepthMap());
+                    let depthRenderer = this.scene._depthRenderer[key];
+                    if (!depthRenderer.useOnlyInActiveCamera) {
+                        renderTargets.push(depthRenderer.getDepthMap());
+                    }
+                }
+            }
+        }
+
+        private _gatherActiveCameraRenderTargets(renderTargets: SmartArrayNoDuplicate<RenderTargetTexture>): void {
+            if (this.scene._depthRenderer) {
+                for (var key in this.scene._depthRenderer) {
+                    let depthRenderer = this.scene._depthRenderer[key];
+                    if (depthRenderer.useOnlyInActiveCamera && this.scene.activeCamera!.id === key) {
+                        renderTargets.push(depthRenderer.getDepthMap());
+                    }
                 }
             }
         }

+ 17 - 2
src/Shaders/particles.fragment.fx

@@ -12,15 +12,30 @@ uniform sampler2D diffuseSampler;
 
 #include<imageProcessingFunctions>
 
+#ifdef RAMPGRADIENT
+varying vec4 remapRanges;
+uniform sampler2D rampSampler;
+#endif
+
 void main(void) {
 	#include<clipPlaneFragment>
 
 	vec4 textureColor = texture2D(diffuseSampler, vUV);
 	vec4 baseColor = (textureColor * textureMask + (vec4(1., 1., 1., 1.) - textureMask)) * vColor;
 
+	#ifdef RAMPGRADIENT
+		float alpha = textureColor.a;
+		float remappedColorIndex = clamp((alpha - remapRanges.x) / remapRanges.y, 0.0, 1.0);
+
+		baseColor.rgb *= texture2D(rampSampler, vec2(remappedColorIndex, 0.)).rgb;
+
+		// Remapped alpha
+		baseColor.a = clamp((alpha - remapRanges.z) / remapRanges.w, 0.0, 1.0);
+	#endif
+
 	#ifdef BLENDMULTIPLYMODE
-	float alpha = vColor.a * textureColor.a;
-	baseColor.rgb = baseColor.rgb * alpha + vec3(1.0) * (1.0 - alpha);
+		float sourceAlpha = vColor.a * textureColor.a;
+		baseColor.rgb = baseColor.rgb * sourceAlpha + vec3(1.0) * (1.0 - sourceAlpha);
 	#endif
 
 // Apply image processing if relevant. As this applies in linear space, 

+ 11 - 0
src/Shaders/particles.vertex.fx

@@ -9,6 +9,9 @@ attribute float cellIndex;
 #ifndef BILLBOARD	
 attribute vec3 direction;
 #endif
+#ifdef RAMPGRADIENT
+attribute vec4 remapData;
+#endif
 attribute vec2 offset;
 
 // Uniforms
@@ -24,6 +27,10 @@ uniform vec3 particlesInfos; // x (number of rows) y(number of columns) z(rowSiz
 varying vec2 vUV;
 varying vec4 vColor;
 
+#ifdef RAMPGRADIENT
+varying vec4 remapRanges;
+#endif
+
 #if defined(CLIPPLANE) || defined(CLIPPLANE2) || defined(CLIPPLANE3) || defined(CLIPPLANE4)
 uniform mat4 invView;
 #endif
@@ -75,6 +82,10 @@ void main(void) {
 	vec3 viewPos = (view * vec4(position, 1.0)).xyz + rotatedCorner; 
 #endif
 
+#ifdef RAMPGRADIENT
+	remapRanges = remapData;
+#endif
+
 	// Position
 	gl_Position = projection * vec4(viewPos, 1.0);   
 #else

+ 41 - 30
src/babylon.node.ts

@@ -104,6 +104,11 @@
         private _parentNode: Nullable<Node>;
         private _children: Node[];
 
+        /** @hidden */
+        public _worldMatrix = Matrix.Zero();
+        /** @hidden */
+        public _worldMatrixDeterminant = 0;        
+
         /**
          * Gets a boolean indicating if the node has been disposed
          * @returns true if the node was disposed
@@ -304,19 +309,32 @@
             return null;
         }
 
+
         /**
-         * Returns the world matrix of the node
-         * @returns a matrix containing the node's world matrix
+         * Returns the latest update of the World matrix
+         * @returns a Matrix
          */
         public getWorldMatrix(): Matrix {
-            return Matrix.Identity();
+            if (this._currentRenderId !== this._scene.getRenderId()) {
+                this.computeWorldMatrix();
+            }
+            return this._worldMatrix;
         }
 
+
         /** @hidden */
         public _getWorldMatrixDeterminant(): number {
-            return 1;
+            return this._worldMatrixDeterminant;
         }
 
+        /**
+         * Returns directly the latest state of the mesh World matrix. 
+         * A Matrix is returned.    
+         */
+        public get worldMatrixFromCache(): Matrix {
+            return this._worldMatrix;
+        }        
+
         // override it in derived class if you add new variables to the cache
         // and call the parent class method
         /** @hidden */
@@ -349,46 +367,36 @@
 
         /** @hidden */
         public _markSyncedWithParent() {
-            if (this.parent) {
-                this._parentRenderId = this.parent._childRenderId;
+            if (this._parentNode) {
+                this._parentRenderId = this._parentNode._childRenderId;
             }
         }
 
         /** @hidden */
         public isSynchronizedWithParent(): boolean {
-            if (!this.parent) {
+            if (!this._parentNode) {
                 return true;
             }
 
-            if (this._parentRenderId !== this.parent._childRenderId) {
+            if (this._parentRenderId !== this._parentNode._childRenderId) {
                 return false;
             }
 
-            return this.parent.isSynchronized();
+            return this._parentNode.isSynchronized();
         }
 
         /** @hidden */
-        public isSynchronized(updateCache?: boolean): boolean {
-            var check = this.hasNewParent();
-
-            check = check || !this.isSynchronizedWithParent();
-
-            check = check || !this._isSynchronized();
-
-            if (updateCache)
-                this.updateCache(true);
-
-            return !check;
-        }
-
-        /** @hidden */
-        public hasNewParent(): boolean {
-            if (this._cache.parent === this.parent)
+        public isSynchronized(): boolean {
+            if (this._cache.parent != this._parentNode) {
+                this._cache.parent = this._parentNode;
                 return false;
+            }
 
-            this._cache.parent = this.parent;
+            if (!this.isSynchronizedWithParent()) {
+                return false;
+            }
 
-            return true;
+            return this._isSynchronized();
         }
 
         /**
@@ -415,8 +423,8 @@
                 return false;
             }
 
-            if (this.parent !== undefined && this.parent !== null) {
-                return this.parent.isEnabled(checkAncestors);
+            if (this._parentNode !== undefined && this._parentNode !== null) {
+                return this._parentNode.isEnabled(checkAncestors);
             }
 
             return true;
@@ -640,7 +648,10 @@
          * @returns the world matrix
          */
         public computeWorldMatrix(force?: boolean): Matrix {
-            return Matrix.Identity();
+            if (!this._worldMatrix) {
+                this._worldMatrix = Matrix.Identity();
+            }
+            return this._worldMatrix;
         }
 
         /**

+ 26 - 16
src/babylon.scene.ts

@@ -904,13 +904,6 @@
             return this._mainSoundTrack;
         }
 
-        /**
-         * Gets or sets the VRExperienceHelper attached to the scene
-         * @see http://doc.babylonjs.com/how_to/webvr_helper
-         * @ignorenaming
-         */
-        public VRHelper: VRExperienceHelper;
-
         // Private
         private _engine: Engine;
 
@@ -941,6 +934,7 @@
         public _cachedVisibility: Nullable<number>;
 
         private _renderId = 0;
+        private _frameId = 0;
         private _executeWhenReadyTimeoutId = -1;
         private _intermediateRendering = false;
 
@@ -1090,11 +1084,16 @@
         public _beforeClearStage = Stage.Create<SimpleStageAction>();
         /**
          * @hidden
-         * Defines the actions happening before camera updates.
+         * Defines the actions when collecting render targets for the frame.
          */
         public _gatherRenderTargetsStage = Stage.Create<RenderTargetsStageAction>();
         /**
          * @hidden
+         * Defines the actions happening for one camera in the frame.
+         */
+        public _gatherActiveCameraRenderTargetsStage = Stage.Create<RenderTargetsStageAction>();
+        /**
+         * @hidden
          * Defines the actions happening during the per mesh ready checks.
          */
         public _isReadyForMeshStage = Stage.Create<MeshStageAction>();
@@ -1488,13 +1487,21 @@
         }
 
         /** 
-         * Gets an unique Id for the current frame
+         * Gets an unique Id for the current render phase
          * @returns a number
          */
         public getRenderId(): number {
             return this._renderId;
         }
 
+        /** 
+         * Gets an unique Id for the current frame
+         * @returns a number
+         */
+        public getFrameId(): number {
+            return this._frameId;
+        }
+
         /** Call this function if you want to manually increment the render Id*/
         public incrementRenderId(): void {
             this._renderId++;
@@ -3949,7 +3956,7 @@
                 const material = subMesh.getMaterial();
                 if (material !== null && material !== undefined) {
                     // Render targets
-                    if (material.getRenderTargetTextures !== undefined) {
+                    if (material.hasRenderTargetTextures && material.getRenderTargetTextures !== undefined) {
                         if (this._processedMaterials.indexOf(material) === -1) {
                             this._processedMaterials.push(material);
 
@@ -4151,7 +4158,7 @@
         }
 
         private _activeMesh(sourceMesh: AbstractMesh, mesh: AbstractMesh): void {
-            if (this.skeletonsEnabled && mesh.skeleton !== null && mesh.skeleton !== undefined) {
+            if (this._skeletonsEnabled && mesh.skeleton !== null && mesh.skeleton !== undefined) {
                 if (this._activeSkeletons.pushNoDuplicate(mesh.skeleton)) {
                     mesh.skeleton.prepare();
                 }
@@ -4246,6 +4253,11 @@
                 this._renderTargets.concatWithNoDuplicate(rigParent.customRenderTargets);
             }
 
+            // Collects render targets from external components.
+            for (let step of this._gatherActiveCameraRenderTargetsStage) {
+                step.action(this._renderTargets);
+            }
+
             if (this.renderTargetsEnabled) {
                 this._intermediateRendering = true;
 
@@ -4378,6 +4390,8 @@
                 return;
             }
 
+            this._frameId++;
+
             // Register components that have been associated lately to the scene.
             this._registerTransientComponents();
 
@@ -4763,6 +4777,7 @@
             this._beforeCameraUpdateStage.clear();
             this._beforeClearStage.clear();
             this._gatherRenderTargetsStage.clear();
+            this._gatherActiveCameraRenderTargetsStage.clear();
             this._pointerMoveStage.clear();
             this._pointerDownStage.clear();
             this._pointerUpStage.clear();
@@ -4830,11 +4845,6 @@
                 this.disposeSounds();
             }
 
-            // VR Helper
-            if (this.VRHelper) {
-                this.VRHelper.dispose();
-            }
-
             // Detach cameras
             var canvas = this._engine.getRenderingCanvas();
 

+ 2 - 0
src/babylon.sceneComponent.ts

@@ -55,6 +55,8 @@
         public static readonly STEP_GATHERRENDERTARGETS_DEPTHRENDERER = 2;
         public static readonly STEP_GATHERRENDERTARGETS_POSTPROCESSRENDERPIPELINEMANAGER = 3;
 
+        public static readonly STEP_GATHERACTIVECAMERARENDERTARGETS_DEPTHRENDERER = 0;
+
         public static readonly STEP_POINTERMOVE_SPRITE = 0;
         public static readonly STEP_POINTERDOWN_SPRITE = 0;
         public static readonly STEP_POINTERUP_SPRITE = 0;