Pārlūkot izejas kodu

Merge branch 'master' into physicsDocs

Kacey Coley 7 gadi atpakaļ
vecāks
revīzija
c3210360cb
68 mainītis faili ar 44561 papildinājumiem un 38820 dzēšanām
  1. 19334 18381
      Playground/babylon.d.txt
  2. 19951 19002
      dist/preview release/babylon.d.ts
  3. 1 1
      dist/preview release/babylon.js
  4. 1164 274
      dist/preview release/babylon.max.js
  5. 1164 274
      dist/preview release/babylon.no-module.max.js
  6. 1 1
      dist/preview release/babylon.worker.js
  7. 1164 274
      dist/preview release/es6.js
  8. 1 1
      dist/preview release/glTF2Interface/package.json
  9. 5 1
      dist/preview release/gui/babylon.gui.d.ts
  10. 1 1
      dist/preview release/gui/babylon.gui.js
  11. 1 1
      dist/preview release/gui/babylon.gui.min.js
  12. 1 1
      dist/preview release/gui/babylon.gui.min.js.map
  13. 10 2
      dist/preview release/gui/babylon.gui.module.d.ts
  14. 1 1
      dist/preview release/gui/package.json
  15. 6 4
      dist/preview release/inspector/package.json
  16. 2 2
      dist/preview release/loaders/package.json
  17. 1 1
      dist/preview release/materialsLibrary/package.json
  18. 1 1
      dist/preview release/postProcessesLibrary/package.json
  19. 1 1
      dist/preview release/proceduralTexturesLibrary/package.json
  20. 2 2
      dist/preview release/serializers/package.json
  21. 397 138
      dist/preview release/viewer/babylon.viewer.d.ts
  22. 1 1
      dist/preview release/viewer/babylon.viewer.js
  23. 1 1
      dist/preview release/viewer/babylon.viewer.max.js
  24. 422 153
      dist/preview release/viewer/babylon.viewer.module.d.ts
  25. 1 0
      dist/preview release/what's new.md
  26. 10 3
      gui/src/2D/controls/control.ts
  27. 1 1
      package.json
  28. 10 4
      src/Cameras/Inputs/babylon.arcRotateCameraKeyboardMoveInput.ts
  29. 67 1
      src/Culling/Octrees/babylon.octree.ts
  30. 40 52
      src/Culling/babylon.boundingBox.ts
  31. 20 14
      src/Culling/babylon.boundingInfo.ts
  32. 12 15
      src/Culling/babylon.boundingSphere.ts
  33. 1 1
      src/Engine/babylon.engine.ts
  34. 2 2
      src/Materials/Textures/babylon.internalTexture.ts
  35. 70 11
      src/Materials/Textures/babylon.mirrorTexture.ts
  36. 81 2
      src/Materials/Textures/babylon.multiRenderTarget.ts
  37. 92 2
      src/Materials/Textures/babylon.rawTexture.ts
  38. 30 5
      src/Materials/Textures/babylon.refractionTexture.ts
  39. 21 1
      src/Materials/Textures/babylon.videoTexture.ts
  40. 29 7
      src/Math/babylon.math.ts
  41. 8 8
      src/Mesh/babylon.abstractMesh.ts
  42. 28 0
      src/Mesh/babylon.buffer.ts
  43. 8 4
      src/Mesh/babylon.geometry.ts
  44. 1 0
      src/Mesh/babylon.mesh.ts
  45. 17 19
      src/Mesh/babylon.meshBuilder.ts
  46. 1 1
      src/Mesh/babylon.subMesh.ts
  47. 83 83
      src/Mesh/babylon.vertexBuffer.ts
  48. 1 0
      src/Particles/babylon.particle.ts
  49. 2 1
      src/Particles/babylon.particleHelper.ts
  50. 27 22
      src/Particles/babylon.particleSystem.ts
  51. 2 0
      src/PostProcess/RenderPipeline/Pipelines/babylon.defaultRenderingPipeline.ts
  52. 6 0
      src/PostProcess/RenderPipeline/Pipelines/babylon.standardRenderingPipeline.ts
  53. 29 0
      src/PostProcess/RenderPipeline/babylon.postProcessRenderPipeline.ts
  54. 45 12
      src/PostProcess/RenderPipeline/babylon.postProcessRenderPipelineManager.ts
  55. 16 0
      src/PostProcess/babylon.blackAndWhitePostProcess.ts
  56. 13 0
      src/PostProcess/babylon.displayPassPostProcess.ts
  57. 22 1
      src/PostProcess/babylon.filterPostProcess.ts
  58. 15 0
      src/PostProcess/babylon.highlightsPostProcess.ts
  59. 8 1
      src/PostProcess/babylon.imageProcessingPostProcess.ts
  60. 3 0
      src/PostProcess/babylon.postProcess.ts
  61. 38 2
      src/PostProcess/babylon.refractionPostProcess.ts
  62. 12 0
      src/PostProcess/babylon.stereoscopicInterlacePostProcess.ts
  63. 10 0
      src/PostProcess/babylon.vrDistortionCorrectionPostProcess.ts
  64. 1 1
      src/Shaders/gpuUpdateParticles.vertex.fx
  65. 13 10
      src/Tools/babylon.tools.ts
  66. 26 15
      src/babylon.node.ts
  67. BIN
      tests/validation/ReferenceImages/ribbon morphing.png
  68. 6 0
      tests/validation/config.json

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 19334 - 18381
Playground/babylon.d.txt


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 19951 - 19002
dist/preview release/babylon.d.ts


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 1 - 1
dist/preview release/babylon.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 1164 - 274
dist/preview release/babylon.max.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 1164 - 274
dist/preview release/babylon.no-module.max.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 1 - 1
dist/preview release/babylon.worker.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 1164 - 274
dist/preview release/es6.js


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

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

+ 5 - 1
dist/preview release/gui/babylon.gui.d.ts

@@ -984,6 +984,10 @@ declare module BABYLON.GUI {
             /** Gets a boolean indicating that the control needs to update its rendering */
             readonly isDirty: boolean;
             /**
+                * Gets the current linked mesh (or null if none)
+                */
+            readonly linkedMesh: BABYLON.Nullable<BABYLON.AbstractMesh>;
+            /**
                 * Gets or sets a value indicating the padding to use on the left of the control
                 * @see http://doc.babylonjs.com/how_to/gui#position-and-size
                 */
@@ -1124,7 +1128,7 @@ declare module BABYLON.GUI {
             /** @hidden */
             _markMatrixAsDirty(): void;
             /** @hidden */
-            _markAsDirty(): void;
+            _markAsDirty(force?: boolean): void;
             /** @hidden */
             _markAllAsDirty(): void;
             /** @hidden */

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 1 - 1
dist/preview release/gui/babylon.gui.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 1 - 1
dist/preview release/gui/babylon.gui.min.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 1 - 1
dist/preview release/gui/babylon.gui.min.js.map


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

@@ -1087,6 +1087,10 @@ declare module 'babylonjs-gui/2D/controls/control' {
             /** Gets a boolean indicating that the control needs to update its rendering */
             readonly isDirty: boolean;
             /**
+                * Gets the current linked mesh (or null if none)
+                */
+            readonly linkedMesh: Nullable<AbstractMesh>;
+            /**
                 * Gets or sets a value indicating the padding to use on the left of the control
                 * @see http://doc.babylonjs.com/how_to/gui#position-and-size
                 */
@@ -1227,7 +1231,7 @@ declare module 'babylonjs-gui/2D/controls/control' {
             /** @hidden */
             _markMatrixAsDirty(): void;
             /** @hidden */
-            _markAsDirty(): void;
+            _markAsDirty(force?: boolean): void;
             /** @hidden */
             _markAllAsDirty(): void;
             /** @hidden */
@@ -3806,6 +3810,10 @@ declare module BABYLON.GUI {
             /** Gets a boolean indicating that the control needs to update its rendering */
             readonly isDirty: boolean;
             /**
+                * Gets the current linked mesh (or null if none)
+                */
+            readonly linkedMesh: BABYLON.Nullable<BABYLON.AbstractMesh>;
+            /**
                 * Gets or sets a value indicating the padding to use on the left of the control
                 * @see http://doc.babylonjs.com/how_to/gui#position-and-size
                 */
@@ -3946,7 +3954,7 @@ declare module BABYLON.GUI {
             /** @hidden */
             _markMatrixAsDirty(): void;
             /** @hidden */
-            _markAsDirty(): void;
+            _markAsDirty(force?: boolean): void;
             /** @hidden */
             _markAllAsDirty(): void;
             /** @hidden */

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

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-gui",
     "description": "The Babylon.js GUI library is an extension you can use to generate interactive user interface. It is build on top of the DynamicTexture.",
-    "version": "3.3.0-rc.1",
+    "version": "3.3.0-rc.3",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"

+ 6 - 4
dist/preview release/inspector/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-inspector",
     "description": "The Babylon.js inspector.",
-    "version": "3.3.0-rc.1",
+    "version": "3.3.0-rc.3",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"
@@ -27,10 +27,12 @@
         "inspector"
     ],
     "license": "Apache-2.0",
-    "peerDependencies": {
-        "babylonjs": ">=3.2.0-alpha"
+    "dependencies": {
+        "babylonjs": ">3.2.0",
+        "babylonjs-gui": ">3.2.0",
+        "babylonjs-loaders": ">3.2.0"
     },
     "engines": {
         "node": "*"
     }
-}
+}

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

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

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

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-materials",
     "description": "The Babylon.js materials library is a collection of advanced materials to be used in a Babylon.js scene.",
-    "version": "3.3.0-rc.1",
+    "version": "3.3.0-rc.3",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"

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

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-post-process",
     "description": "The Babylon.js materials library is a collection of advanced materials to be used in a Babylon.js scene.",
-    "version": "3.3.0-rc.1",
+    "version": "3.3.0-rc.3",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"

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

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-procedural-textures",
     "description": "The Babylon.js materials library is a collection of advanced materials to be used in a Babylon.js scene.",
-    "version": "3.3.0-rc.1",
+    "version": "3.3.0-rc.3",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"

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

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-serializers",
     "description": "The Babylon.js serializers library is an extension you can use to serialize Babylon scenes.",
-    "version": "3.3.0-rc.1",
+    "version": "3.3.0-rc.3",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"
@@ -27,7 +27,7 @@
     ],
     "license": "Apache-2.0",
     "dependencies": {
-        "babylonjs-gltf2interface": "3.3.0-rc.1"
+        "babylonjs-gltf2interface": "3.3.0-rc.3"
     },
     "peerDependencies": {
         "babylonjs": ">=3.2.0-alpha"

+ 397 - 138
dist/preview release/viewer/babylon.viewer.d.ts

@@ -168,11 +168,11 @@ declare module BabylonViewer {
                 * Mainly used for help and errors
                 * @param subScreen the name of the subScreen. Those can be defined in the configuration object
                 */
-            showOverlayScreen(subScreen: string): Promise<Template> | Promise<string>;
+            showOverlayScreen(subScreen: string): Promise<string> | Promise<Template>;
             /**
                 * Hide the overlay screen.
                 */
-            hideOverlayScreen(): Promise<Template> | Promise<string>;
+            hideOverlayScreen(): Promise<string> | Promise<Template>;
             /**
                 * show the viewer (in case it was hidden)
                 *
@@ -189,16 +189,252 @@ declare module BabylonViewer {
                 * Show the loading screen.
                 * The loading screen can be configured using the configuration object
                 */
-            showLoadingScreen(): Promise<Template> | Promise<string>;
+            showLoadingScreen(): Promise<string> | Promise<Template>;
             /**
                 * Hide the loading screen
                 */
-            hideLoadingScreen(): Promise<Template> | Promise<string>;
+            hideLoadingScreen(): Promise<string> | Promise<Template>;
             dispose(): void;
             protected _onConfigurationLoaded(configuration: ViewerConfiguration): void;
     }
 }
 declare module BabylonViewer {
+    /**
+        * The AbstractViewr is the center of Babylon's viewer.
+        * It is the basic implementation of the default viewer and is responsible of loading and showing the model and the templates
+        */
+    export abstract class AbstractViewer {
+            containerElement: HTMLElement;
+            /**
+                * The corresponsing template manager of this viewer.
+                */
+            templateManager: TemplateManager;
+            /**
+                * Babylon BABYLON.Engine corresponding with this viewer
+                */
+            engine: BABYLON.Engine;
+            /**
+                * The ID of this viewer. it will be generated randomly or use the HTML Element's ID.
+                */
+            readonly baseId: string;
+            /**
+                * The last loader used to load a model.
+                * @deprecated
+                */
+            lastUsedLoader: BABYLON.ISceneLoaderPlugin | BABYLON.ISceneLoaderPluginAsync;
+            /**
+                * The ModelLoader instance connected with this viewer.
+                */
+            modelLoader: ModelLoader;
+            /**
+                * A flag that controls whether or not the render loop should be executed
+                */
+            runRenderLoop: boolean;
+            /**
+                * The scene manager connected with this viewer instance
+                */
+            sceneManager: SceneManager;
+            /**
+                * Will notify when the scene was initialized
+                */
+            readonly onSceneInitObservable: BABYLON.Observable<BABYLON.Scene>;
+            /**
+                * will notify when the engine was initialized
+                */
+            readonly onEngineInitObservable: BABYLON.Observable<BABYLON.Engine>;
+            /**
+                * Will notify when a new model was added to the scene.
+                * Note that added does not neccessarily mean loaded!
+                */
+            readonly onModelAddedObservable: BABYLON.Observable<ViewerModel>;
+            /**
+                * will notify after every model load
+                */
+            readonly onModelLoadedObservable: BABYLON.Observable<ViewerModel>;
+            /**
+                * will notify when any model notify of progress
+                */
+            readonly onModelLoadProgressObservable: BABYLON.Observable<BABYLON.SceneLoaderProgressEvent>;
+            /**
+                * will notify when any model load failed.
+                */
+            readonly onModelLoadErrorObservable: BABYLON.Observable<{
+                    message: string;
+                    exception: any;
+            }>;
+            /**
+                * Will notify when a model was removed from the scene;
+                */
+            readonly onModelRemovedObservable: BABYLON.Observable<ViewerModel>;
+            /**
+                * will notify when a new loader was initialized.
+                * Used mainly to know when a model starts loading.
+                */
+            readonly onLoaderInitObservable: BABYLON.Observable<BABYLON.ISceneLoaderPlugin | BABYLON.ISceneLoaderPluginAsync>;
+            /**
+                * Observers registered here will be executed when the entire load process has finished.
+                */
+            readonly onInitDoneObservable: BABYLON.Observable<AbstractViewer>;
+            /**
+                * Functions added to this observable will be executed on each frame rendered.
+                */
+            readonly onFrameRenderedObservable: BABYLON.Observable<AbstractViewer>;
+            /**
+                * Observers registered here will be executed when VR more is entered.
+                */
+            readonly onEnteringVRObservable: BABYLON.Observable<AbstractViewer>;
+            /**
+                * Observers registered here will be executed when VR mode is exited.
+                */
+            readonly onExitingVRObservable: BABYLON.Observable<AbstractViewer>;
+            observablesManager: ObservablesManager;
+            /**
+                * The canvas associated with this viewer
+                */
+            protected _canvas: HTMLCanvasElement;
+            /**
+                * The (single) canvas of this viewer
+                */
+            readonly canvas: HTMLCanvasElement;
+            /**
+                * is this viewer disposed?
+                */
+            protected _isDisposed: boolean;
+            /**
+                * registered onBeforeRender functions.
+                * This functions are also registered at the native scene. The reference can be used to unregister them.
+                */
+            protected _registeredOnBeforeRenderFunctions: Array<() => void>;
+            /**
+                * The configuration loader of this viewer
+                */
+            protected _configurationLoader: ConfigurationLoader;
+            /**
+                * Is the viewer already initialized. for internal use.
+                */
+            protected _isInit: boolean;
+            protected _configurationContainer: ConfigurationContainer;
+            readonly configurationContainer: ConfigurationContainer;
+            constructor(containerElement: HTMLElement, initialConfiguration?: ViewerConfiguration);
+            /**
+                * get the baseId of this viewer
+                */
+            getBaseId(): string;
+            /**
+                * Do we have a canvas to render on, and is it a part of the scene
+                */
+            isCanvasInDOM(): boolean;
+            /**
+             * Set the viewer's background rendering flag.
+             */
+            renderInBackground: boolean;
+            /**
+                * Get the configuration object. This is a reference only.
+                * The configuration can ONLY be updated using the updateConfiguration function.
+                * changing this object will have no direct effect on the scene.
+                */
+            readonly configuration: ViewerConfiguration;
+            /**
+                * force resizing the engine.
+                */
+            forceResize(): void;
+            protected _hdToggled: boolean;
+            toggleHD(): void;
+            protected _vrToggled: boolean;
+            protected _vrScale: number;
+            protected _vrInit: boolean;
+            toggleVR(): void;
+            protected _initVR(): void;
+            /**
+                * The resize function that will be registered with the window object
+                */
+            protected _resize: () => void;
+            protected _onConfigurationLoaded(configuration: ViewerConfiguration): void;
+            /**
+                * Force a single render loop execution.
+                */
+            forceRender(): void;
+            /**
+                * render loop that will be executed by the engine
+                */
+            protected _render: (force?: boolean) => void;
+            /**
+                * Takes a screenshot of the scene and returns it as a base64 encoded png.
+                * @param callback optional callback that will be triggered when screenshot is done.
+                * @param width Optional screenshot width (default to 512).
+                * @param height Optional screenshot height (default to 512).
+                * @returns a promise with the screenshot data
+                */
+            takeScreenshot(callback?: (data: string) => void, width?: number, height?: number): Promise<string>;
+            /**
+                * Update the current viewer configuration with new values.
+                * Only provided information will be updated, old configuration values will be kept.
+                * If this.configuration was manually changed, you can trigger this function with no parameters,
+                * and the entire configuration will be updated.
+                * @param newConfiguration the partial configuration to update or a URL to a JSON holding the updated configuration
+                *
+                */
+            updateConfiguration(newConfiguration?: Partial<ViewerConfiguration> | string): void;
+            /**
+                * this is used to register native functions using the configuration object.
+                * This will configure the observers.
+                * @param observersConfiguration observers configuration
+                */
+            protected _configureObservers(observersConfiguration: IObserversConfiguration): void;
+            /**
+                * Dispose the entire viewer including the scene and the engine
+                */
+            dispose(): void;
+            /**
+                * This will prepare the container element for the viewer
+                */
+            protected abstract _prepareContainerElement(): any;
+            /**
+                * This function will execute when the HTML templates finished initializing.
+                * It should initialize the engine and continue execution.
+                *
+                * @returns {Promise<AbstractViewer>} The viewer object will be returned after the object was loaded.
+                */
+            protected _onTemplatesLoaded(): Promise<AbstractViewer>;
+            /**
+                * This will force the creation of an engine and a scene.
+                * It will also load a model if preconfigured.
+                * But first - it will load the extendible onTemplateLoaded()!
+                */
+            protected _onTemplateLoaded(): Promise<AbstractViewer>;
+            /**
+                * Initialize the engine. Retruns a promise in case async calls are needed.
+                *
+                * @protected
+                * @returns {Promise<BABYLON.Engine>}
+                * @memberof Viewer
+                */
+            protected _initEngine(): Promise<BABYLON.Engine>;
+            /**
+                * Initialize a model loading. The returned object (a ViewerModel object) will be loaded in the background.
+                * The difference between this and loadModel is that loadModel will fulfill the promise when the model finished loading.
+                *
+                * @param modelConfig model configuration to use when loading the model.
+                * @param clearScene should the scene be cleared before loading this model
+                * @returns a ViewerModel object that is not yet fully loaded.
+                */
+            initModel(modelConfig: string | File | IModelConfiguration, clearScene?: boolean): ViewerModel;
+            /**
+                * load a model using the provided configuration.
+                * This function, as opposed to initModel, will return a promise that resolves when the model is loaded, and rejects with error.
+                * If you want to attach to the observables of the model, use initModle instead.
+                *
+                * @param modelConfig the model configuration or URL to load.
+                * @param clearScene Should the scene be cleared before loading the model
+                * @returns a Promise the fulfills when the model finished loading successfully.
+                */
+            loadModel(modelConfig: string | File | IModelConfiguration, clearScene?: boolean): Promise<ViewerModel>;
+            protected _initTelemetryEvents(): void;
+            /**
+                * Injects all the spectre shader in the babylon shader store
+                */
+            protected _injectCustomShaders(): void;
+    }
 }
 declare module BabylonViewer {
     /**
@@ -976,69 +1212,26 @@ declare module BabylonViewer {
     }
 }
 declare module BabylonViewer {
-    export interface IModelConfiguration {
-            id?: string;
-            url?: string;
-            root?: string;
-            file?: string | File;
-            loader?: string;
-            position?: {
-                    x: number;
-                    y: number;
-                    z: number;
-            };
-            rotation?: {
-                    x: number;
-                    y: number;
-                    z: number;
-                    w?: number;
-            };
-            scaling?: {
-                    x: number;
-                    y: number;
-                    z: number;
-            };
-            parentObjectIndex?: number;
-            castShadow?: boolean;
-            receiveShadows?: boolean;
-            normalize?: boolean | {
-                    center?: boolean;
-                    unitSize?: boolean;
-                    parentIndex?: number;
-            };
-            title?: string;
-            subtitle?: string;
-            thumbnail?: string;
-            animation?: {
-                    autoStart?: boolean | string;
-                    playOnce?: boolean;
-                    autoStartIndex?: number;
-            };
-            entryAnimation?: IModelAnimationConfiguration;
-            exitAnimation?: IModelAnimationConfiguration;
-            material?: {
-                    directEnabled?: boolean;
-                    directIntensity?: number;
-                    emissiveIntensity?: number;
-                    environmentIntensity?: number;
-                    [propName: string]: any;
-            };
+    /**
+        * The configuration loader will load the configuration object from any source and will use the defined mapper to
+        * parse the object and return a conform ViewerConfiguration.
+        * It is a private member of the scene.
+        */
+    export class ConfigurationLoader {
+            constructor(_enableCache?: boolean);
             /**
-                * Rotation offset axis definition
+                * load a configuration object that is defined in the initial configuration provided.
+                * The viewer configuration can extend different types of configuration objects and have an extra configuration defined.
+                *
+                * @param initConfig the initial configuration that has the definitions of further configuration to load.
+                * @param callback an optional callback that will be called sync, if noconfiguration needs to be loaded or configuration is payload-only
+                * @returns A promise that delivers the extended viewer configuration, when done.
                 */
-            rotationOffsetAxis?: {
-                    x: number;
-                    y: number;
-                    z: number;
-            };
+            loadConfiguration(initConfig?: ViewerConfiguration, callback?: (config: ViewerConfiguration) => void): Promise<ViewerConfiguration>;
             /**
-                * the offset angle
+                * Dispose the configuration loader. This will cancel file requests, if active.
                 */
-            rotationOffsetAngle?: number;
-            loaderConfiguration?: {
-                    maxLODsToLoad?: number;
-                    progressiveLoading?: boolean;
-            };
+            dispose(): void;
     }
 }
 declare module BabylonViewer {
@@ -1106,33 +1299,6 @@ declare module BabylonViewer {
 }
 declare module BabylonViewer {
     /**
-        * Get a loader plugin according to its name.
-        * The plugin will be cached and will be reused if called for again.
-        *
-        * @param name the name of the plugin
-        */
-    export function getLoaderPluginByName(name: string): ILoaderPlugin;
-    /**
-        *
-        */
-    export function addLoaderPlugin(name: string, plugin: ILoaderPlugin): void;
-}
-declare module BabylonViewer {
-    /**
-        * A custom upgrade-oriented function configuration for the scene optimizer.
-        *
-        * @param viewer the viewer to optimize
-        */
-    export function extendedUpgrade(sceneManager: SceneManager): boolean;
-    /**
-        * A custom degrade-oriented function configuration for the scene optimizer.
-        *
-        * @param viewer the viewer to optimize
-        */
-    export function extendedDegrade(sceneManager: SceneManager): boolean;
-}
-declare module BabylonViewer {
-    /**
         * This interface describes the structure of the variable sent with the configuration observables of the scene manager.
         * O - the type of object we are dealing with (Light, BABYLON.ArcRotateCamera, BABYLON.Scene, etc')
         * T - the configuration type
@@ -1313,6 +1479,99 @@ declare module BabylonViewer {
     }
 }
 declare module BabylonViewer {
+    export interface IModelConfiguration {
+            id?: string;
+            url?: string;
+            root?: string;
+            file?: string | File;
+            loader?: string;
+            position?: {
+                    x: number;
+                    y: number;
+                    z: number;
+            };
+            rotation?: {
+                    x: number;
+                    y: number;
+                    z: number;
+                    w?: number;
+            };
+            scaling?: {
+                    x: number;
+                    y: number;
+                    z: number;
+            };
+            parentObjectIndex?: number;
+            castShadow?: boolean;
+            receiveShadows?: boolean;
+            normalize?: boolean | {
+                    center?: boolean;
+                    unitSize?: boolean;
+                    parentIndex?: number;
+            };
+            title?: string;
+            subtitle?: string;
+            thumbnail?: string;
+            animation?: {
+                    autoStart?: boolean | string;
+                    playOnce?: boolean;
+                    autoStartIndex?: number;
+            };
+            entryAnimation?: IModelAnimationConfiguration;
+            exitAnimation?: IModelAnimationConfiguration;
+            material?: {
+                    directEnabled?: boolean;
+                    directIntensity?: number;
+                    emissiveIntensity?: number;
+                    environmentIntensity?: number;
+                    [propName: string]: any;
+            };
+            /**
+                * Rotation offset axis definition
+                */
+            rotationOffsetAxis?: {
+                    x: number;
+                    y: number;
+                    z: number;
+            };
+            /**
+                * the offset angle
+                */
+            rotationOffsetAngle?: number;
+            loaderConfiguration?: {
+                    maxLODsToLoad?: number;
+                    progressiveLoading?: boolean;
+            };
+    }
+}
+declare module BabylonViewer {
+    /**
+        * Get a loader plugin according to its name.
+        * The plugin will be cached and will be reused if called for again.
+        *
+        * @param name the name of the plugin
+        */
+    export function getLoaderPluginByName(name: string): ILoaderPlugin;
+    /**
+        *
+        */
+    export function addLoaderPlugin(name: string, plugin: ILoaderPlugin): void;
+}
+declare module BabylonViewer {
+    /**
+        * A custom upgrade-oriented function configuration for the scene optimizer.
+        *
+        * @param viewer the viewer to optimize
+        */
+    export function extendedUpgrade(sceneManager: SceneManager): boolean;
+    /**
+        * A custom degrade-oriented function configuration for the scene optimizer.
+        *
+        * @param viewer the viewer to optimize
+        */
+    export function extendedDegrade(sceneManager: SceneManager): boolean;
+}
+declare module BabylonViewer {
 }
 declare module BabylonViewer {
     export interface IEnvironmentMapConfiguration {
@@ -1373,6 +1632,54 @@ declare module BabylonViewer {
 }
 declare module BabylonViewer {
     /**
+        * The ViewerLabs class will hold functions that are not (!) backwards compatible.
+        * The APIs in all labs-related classes and configuration  might change.
+        * Once stable, lab features will be moved to the publis API and configuration object.
+        */
+    export class ViewerLabs {
+            constructor(_scene: BABYLON.Scene);
+            assetsRootURL: string;
+            environment: PBREnvironment;
+            /**
+                        * Loads an environment map from a given URL
+                        * @param url URL of environment map
+                        * @param onSuccess Callback fired after environment successfully applied to the scene
+                        * @param onProgress Callback fired at progress events while loading the environment map
+                        * @param onError Callback fired when the load fails
+                        */
+            loadEnvironment(url: string, onSuccess?: (env: PBREnvironment) => void, onProgress?: (bytesLoaded: number, bytesTotal: number) => void, onError?: (e: any) => void): void;
+            /**
+                * Loads an environment map from a given URL
+                * @param buffer ArrayBuffer containing environment map
+                * @param onSuccess Callback fired after environment successfully applied to the scene
+                * @param onProgress Callback fired at progress events while loading the environment map
+                * @param onError Callback fired when the load fails
+                */
+            loadEnvironment(buffer: ArrayBuffer, onSuccess?: (env: PBREnvironment) => void, onProgress?: (bytesLoaded: number, bytesTotal: number) => void, onError?: (e: any) => void): void;
+            /**
+                * Sets the environment to an already loaded environment
+                * @param env PBREnvironment instance
+                * @param onSuccess Callback fired after environment successfully applied to the scene
+                * @param onProgress Callback fired at progress events while loading the environment map
+                * @param onError Callback fired when the load fails
+                */
+            loadEnvironment(env: PBREnvironment, onSuccess?: (env: PBREnvironment) => void, onProgress?: (bytesLoaded: number, bytesTotal: number) => void, onError?: (e: any) => void): void;
+            /**
+                * Applies an `EnvironmentMapConfiguration` to the scene
+                * @param environmentMapConfiguration Environment map configuration to apply
+                */
+            applyEnvironmentMapConfiguration(rotationY?: number): void;
+            /**
+                * Get an environment asset url by using the configuration if the path is not absolute.
+                * @param url Asset url
+                * @returns The Asset url using the `environmentAssetsRootURL` if the url is not an absolute path.
+                */
+            getAssetUrl(url: string): string;
+            rotateShadowLight(shadowLight: BABYLON.ShadowLight, amount: number, point?: BABYLON.Vector3, axis?: BABYLON.Vector3, target?: BABYLON.Vector3): void;
+    }
+}
+declare module BabylonViewer {
+    /**
         * Defines an animation to be applied to a model (translation, scale or rotation).
         */
     export interface IModelAnimationConfiguration {
@@ -1435,54 +1742,6 @@ declare module BabylonViewer {
     }
 }
 declare module BabylonViewer {
-    /**
-        * The ViewerLabs class will hold functions that are not (!) backwards compatible.
-        * The APIs in all labs-related classes and configuration  might change.
-        * Once stable, lab features will be moved to the publis API and configuration object.
-        */
-    export class ViewerLabs {
-            constructor(_scene: BABYLON.Scene);
-            assetsRootURL: string;
-            environment: PBREnvironment;
-            /**
-                        * Loads an environment map from a given URL
-                        * @param url URL of environment map
-                        * @param onSuccess Callback fired after environment successfully applied to the scene
-                        * @param onProgress Callback fired at progress events while loading the environment map
-                        * @param onError Callback fired when the load fails
-                        */
-            loadEnvironment(url: string, onSuccess?: (env: PBREnvironment) => void, onProgress?: (bytesLoaded: number, bytesTotal: number) => void, onError?: (e: any) => void): void;
-            /**
-                * Loads an environment map from a given URL
-                * @param buffer ArrayBuffer containing environment map
-                * @param onSuccess Callback fired after environment successfully applied to the scene
-                * @param onProgress Callback fired at progress events while loading the environment map
-                * @param onError Callback fired when the load fails
-                */
-            loadEnvironment(buffer: ArrayBuffer, onSuccess?: (env: PBREnvironment) => void, onProgress?: (bytesLoaded: number, bytesTotal: number) => void, onError?: (e: any) => void): void;
-            /**
-                * Sets the environment to an already loaded environment
-                * @param env PBREnvironment instance
-                * @param onSuccess Callback fired after environment successfully applied to the scene
-                * @param onProgress Callback fired at progress events while loading the environment map
-                * @param onError Callback fired when the load fails
-                */
-            loadEnvironment(env: PBREnvironment, onSuccess?: (env: PBREnvironment) => void, onProgress?: (bytesLoaded: number, bytesTotal: number) => void, onError?: (e: any) => void): void;
-            /**
-                * Applies an `EnvironmentMapConfiguration` to the scene
-                * @param environmentMapConfiguration Environment map configuration to apply
-                */
-            applyEnvironmentMapConfiguration(rotationY?: number): void;
-            /**
-                * Get an environment asset url by using the configuration if the path is not absolute.
-                * @param url Asset url
-                * @returns The Asset url using the `environmentAssetsRootURL` if the url is not an absolute path.
-                */
-            getAssetUrl(url: string): string;
-            rotateShadowLight(shadowLight: BABYLON.ShadowLight, amount: number, point?: BABYLON.Vector3, axis?: BABYLON.Vector3, target?: BABYLON.Vector3): void;
-    }
-}
-declare module BabylonViewer {
     export interface ICameraConfiguration {
         position?: {
             x: number;

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 1 - 1
dist/preview release/viewer/babylon.viewer.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 1 - 1
dist/preview release/viewer/babylon.viewer.max.js


+ 422 - 153
dist/preview release/viewer/babylon.viewer.module.d.ts

@@ -200,11 +200,11 @@ declare module 'babylonjs-viewer/viewer/defaultViewer' {
                 * Mainly used for help and errors
                 * @param subScreen the name of the subScreen. Those can be defined in the configuration object
                 */
-            showOverlayScreen(subScreen: string): Promise<Template> | Promise<string>;
+            showOverlayScreen(subScreen: string): Promise<string> | Promise<Template>;
             /**
                 * Hide the overlay screen.
                 */
-            hideOverlayScreen(): Promise<Template> | Promise<string>;
+            hideOverlayScreen(): Promise<string> | Promise<Template>;
             /**
                 * show the viewer (in case it was hidden)
                 *
@@ -221,18 +221,262 @@ declare module 'babylonjs-viewer/viewer/defaultViewer' {
                 * Show the loading screen.
                 * The loading screen can be configured using the configuration object
                 */
-            showLoadingScreen(): Promise<Template> | Promise<string>;
+            showLoadingScreen(): Promise<string> | Promise<Template>;
             /**
                 * Hide the loading screen
                 */
-            hideLoadingScreen(): Promise<Template> | Promise<string>;
+            hideLoadingScreen(): Promise<string> | Promise<Template>;
             dispose(): void;
             protected _onConfigurationLoaded(configuration: ViewerConfiguration): void;
     }
 }
 
 declare module 'babylonjs-viewer/viewer/viewer' {
-    
+    import { Engine, ISceneLoaderPlugin, ISceneLoaderPluginAsync, Observable, Scene, SceneLoaderProgressEvent } from 'babylonjs';
+    import { IModelConfiguration, IObserversConfiguration, ViewerConfiguration } from 'babylonjs-viewer/configuration';
+    import { ConfigurationContainer } from 'babylonjs-viewer/configuration/configurationContainer';
+    import { ConfigurationLoader } from 'babylonjs-viewer/configuration/loader';
+    import { ModelLoader } from 'babylonjs-viewer/loader/modelLoader';
+    import { ObservablesManager } from 'babylonjs-viewer/managers/observablesManager';
+    import { SceneManager } from 'babylonjs-viewer/managers/sceneManager';
+    import { ViewerModel } from 'babylonjs-viewer/model/viewerModel';
+    import { TemplateManager } from 'babylonjs-viewer/templating/templateManager';
+    /**
+        * The AbstractViewr is the center of Babylon's viewer.
+        * It is the basic implementation of the default viewer and is responsible of loading and showing the model and the templates
+        */
+    export abstract class AbstractViewer {
+            containerElement: HTMLElement;
+            /**
+                * The corresponsing template manager of this viewer.
+                */
+            templateManager: TemplateManager;
+            /**
+                * Babylon Engine corresponding with this viewer
+                */
+            engine: Engine;
+            /**
+                * The ID of this viewer. it will be generated randomly or use the HTML Element's ID.
+                */
+            readonly baseId: string;
+            /**
+                * The last loader used to load a model.
+                * @deprecated
+                */
+            lastUsedLoader: ISceneLoaderPlugin | ISceneLoaderPluginAsync;
+            /**
+                * The ModelLoader instance connected with this viewer.
+                */
+            modelLoader: ModelLoader;
+            /**
+                * A flag that controls whether or not the render loop should be executed
+                */
+            runRenderLoop: boolean;
+            /**
+                * The scene manager connected with this viewer instance
+                */
+            sceneManager: SceneManager;
+            /**
+                * Will notify when the scene was initialized
+                */
+            readonly onSceneInitObservable: Observable<Scene>;
+            /**
+                * will notify when the engine was initialized
+                */
+            readonly onEngineInitObservable: Observable<Engine>;
+            /**
+                * Will notify when a new model was added to the scene.
+                * Note that added does not neccessarily mean loaded!
+                */
+            readonly onModelAddedObservable: Observable<ViewerModel>;
+            /**
+                * will notify after every model load
+                */
+            readonly onModelLoadedObservable: Observable<ViewerModel>;
+            /**
+                * will notify when any model notify of progress
+                */
+            readonly onModelLoadProgressObservable: Observable<SceneLoaderProgressEvent>;
+            /**
+                * will notify when any model load failed.
+                */
+            readonly onModelLoadErrorObservable: Observable<{
+                    message: string;
+                    exception: any;
+            }>;
+            /**
+                * Will notify when a model was removed from the scene;
+                */
+            readonly onModelRemovedObservable: Observable<ViewerModel>;
+            /**
+                * will notify when a new loader was initialized.
+                * Used mainly to know when a model starts loading.
+                */
+            readonly onLoaderInitObservable: Observable<ISceneLoaderPlugin | ISceneLoaderPluginAsync>;
+            /**
+                * Observers registered here will be executed when the entire load process has finished.
+                */
+            readonly onInitDoneObservable: Observable<AbstractViewer>;
+            /**
+                * Functions added to this observable will be executed on each frame rendered.
+                */
+            readonly onFrameRenderedObservable: Observable<AbstractViewer>;
+            /**
+                * Observers registered here will be executed when VR more is entered.
+                */
+            readonly onEnteringVRObservable: Observable<AbstractViewer>;
+            /**
+                * Observers registered here will be executed when VR mode is exited.
+                */
+            readonly onExitingVRObservable: Observable<AbstractViewer>;
+            observablesManager: ObservablesManager;
+            /**
+                * The canvas associated with this viewer
+                */
+            protected _canvas: HTMLCanvasElement;
+            /**
+                * The (single) canvas of this viewer
+                */
+            readonly canvas: HTMLCanvasElement;
+            /**
+                * is this viewer disposed?
+                */
+            protected _isDisposed: boolean;
+            /**
+                * registered onBeforeRender functions.
+                * This functions are also registered at the native scene. The reference can be used to unregister them.
+                */
+            protected _registeredOnBeforeRenderFunctions: Array<() => void>;
+            /**
+                * The configuration loader of this viewer
+                */
+            protected _configurationLoader: ConfigurationLoader;
+            /**
+                * Is the viewer already initialized. for internal use.
+                */
+            protected _isInit: boolean;
+            protected _configurationContainer: ConfigurationContainer;
+            readonly configurationContainer: ConfigurationContainer;
+            constructor(containerElement: HTMLElement, initialConfiguration?: ViewerConfiguration);
+            /**
+                * get the baseId of this viewer
+                */
+            getBaseId(): string;
+            /**
+                * Do we have a canvas to render on, and is it a part of the scene
+                */
+            isCanvasInDOM(): boolean;
+            /**
+             * Set the viewer's background rendering flag.
+             */
+            renderInBackground: boolean;
+            /**
+                * Get the configuration object. This is a reference only.
+                * The configuration can ONLY be updated using the updateConfiguration function.
+                * changing this object will have no direct effect on the scene.
+                */
+            readonly configuration: ViewerConfiguration;
+            /**
+                * force resizing the engine.
+                */
+            forceResize(): void;
+            protected _hdToggled: boolean;
+            toggleHD(): void;
+            protected _vrToggled: boolean;
+            protected _vrScale: number;
+            protected _vrInit: boolean;
+            toggleVR(): void;
+            protected _initVR(): void;
+            /**
+                * The resize function that will be registered with the window object
+                */
+            protected _resize: () => void;
+            protected _onConfigurationLoaded(configuration: ViewerConfiguration): void;
+            /**
+                * Force a single render loop execution.
+                */
+            forceRender(): void;
+            /**
+                * render loop that will be executed by the engine
+                */
+            protected _render: (force?: boolean) => void;
+            /**
+                * Takes a screenshot of the scene and returns it as a base64 encoded png.
+                * @param callback optional callback that will be triggered when screenshot is done.
+                * @param width Optional screenshot width (default to 512).
+                * @param height Optional screenshot height (default to 512).
+                * @returns a promise with the screenshot data
+                */
+            takeScreenshot(callback?: (data: string) => void, width?: number, height?: number): Promise<string>;
+            /**
+                * Update the current viewer configuration with new values.
+                * Only provided information will be updated, old configuration values will be kept.
+                * If this.configuration was manually changed, you can trigger this function with no parameters,
+                * and the entire configuration will be updated.
+                * @param newConfiguration the partial configuration to update or a URL to a JSON holding the updated configuration
+                *
+                */
+            updateConfiguration(newConfiguration?: Partial<ViewerConfiguration> | string): void;
+            /**
+                * this is used to register native functions using the configuration object.
+                * This will configure the observers.
+                * @param observersConfiguration observers configuration
+                */
+            protected _configureObservers(observersConfiguration: IObserversConfiguration): void;
+            /**
+                * Dispose the entire viewer including the scene and the engine
+                */
+            dispose(): void;
+            /**
+                * This will prepare the container element for the viewer
+                */
+            protected abstract _prepareContainerElement(): any;
+            /**
+                * This function will execute when the HTML templates finished initializing.
+                * It should initialize the engine and continue execution.
+                *
+                * @returns {Promise<AbstractViewer>} The viewer object will be returned after the object was loaded.
+                */
+            protected _onTemplatesLoaded(): Promise<AbstractViewer>;
+            /**
+                * This will force the creation of an engine and a scene.
+                * It will also load a model if preconfigured.
+                * But first - it will load the extendible onTemplateLoaded()!
+                */
+            protected _onTemplateLoaded(): Promise<AbstractViewer>;
+            /**
+                * Initialize the engine. Retruns a promise in case async calls are needed.
+                *
+                * @protected
+                * @returns {Promise<Engine>}
+                * @memberof Viewer
+                */
+            protected _initEngine(): Promise<Engine>;
+            /**
+                * Initialize a model loading. The returned object (a ViewerModel object) will be loaded in the background.
+                * The difference between this and loadModel is that loadModel will fulfill the promise when the model finished loading.
+                *
+                * @param modelConfig model configuration to use when loading the model.
+                * @param clearScene should the scene be cleared before loading this model
+                * @returns a ViewerModel object that is not yet fully loaded.
+                */
+            initModel(modelConfig: string | File | IModelConfiguration, clearScene?: boolean): ViewerModel;
+            /**
+                * load a model using the provided configuration.
+                * This function, as opposed to initModel, will return a promise that resolves when the model is loaded, and rejects with error.
+                * If you want to attach to the observables of the model, use initModle instead.
+                *
+                * @param modelConfig the model configuration or URL to load.
+                * @param clearScene Should the scene be cleared before loading the model
+                * @returns a Promise the fulfills when the model finished loading successfully.
+                */
+            loadModel(modelConfig: string | File | IModelConfiguration, clearScene?: boolean): Promise<ViewerModel>;
+            protected _initTelemetryEvents(): void;
+            /**
+                * Injects all the spectre shader in the babylon shader store
+                */
+            protected _injectCustomShaders(): void;
+    }
 }
 
 declare module 'babylonjs-viewer/managers/telemetryManager' {
@@ -1051,71 +1295,28 @@ declare module 'babylonjs-viewer/configuration/configurationContainer' {
     }
 }
 
-declare module 'babylonjs-viewer/configuration/interfaces/modelConfiguration' {
-    import { IModelAnimationConfiguration } from "babylonjs-viewer/configuration/interfaces/modelAnimationConfiguration";
-    export interface IModelConfiguration {
-            id?: string;
-            url?: string;
-            root?: string;
-            file?: string | File;
-            loader?: string;
-            position?: {
-                    x: number;
-                    y: number;
-                    z: number;
-            };
-            rotation?: {
-                    x: number;
-                    y: number;
-                    z: number;
-                    w?: number;
-            };
-            scaling?: {
-                    x: number;
-                    y: number;
-                    z: number;
-            };
-            parentObjectIndex?: number;
-            castShadow?: boolean;
-            receiveShadows?: boolean;
-            normalize?: boolean | {
-                    center?: boolean;
-                    unitSize?: boolean;
-                    parentIndex?: number;
-            };
-            title?: string;
-            subtitle?: string;
-            thumbnail?: string;
-            animation?: {
-                    autoStart?: boolean | string;
-                    playOnce?: boolean;
-                    autoStartIndex?: number;
-            };
-            entryAnimation?: IModelAnimationConfiguration;
-            exitAnimation?: IModelAnimationConfiguration;
-            material?: {
-                    directEnabled?: boolean;
-                    directIntensity?: number;
-                    emissiveIntensity?: number;
-                    environmentIntensity?: number;
-                    [propName: string]: any;
-            };
+declare module 'babylonjs-viewer/configuration/loader' {
+    import { ViewerConfiguration } from 'babylonjs-viewer/configuration/configuration';
+    /**
+        * The configuration loader will load the configuration object from any source and will use the defined mapper to
+        * parse the object and return a conform ViewerConfiguration.
+        * It is a private member of the scene.
+        */
+    export class ConfigurationLoader {
+            constructor(_enableCache?: boolean);
             /**
-                * Rotation offset axis definition
+                * load a configuration object that is defined in the initial configuration provided.
+                * The viewer configuration can extend different types of configuration objects and have an extra configuration defined.
+                *
+                * @param initConfig the initial configuration that has the definitions of further configuration to load.
+                * @param callback an optional callback that will be called sync, if noconfiguration needs to be loaded or configuration is payload-only
+                * @returns A promise that delivers the extended viewer configuration, when done.
                 */
-            rotationOffsetAxis?: {
-                    x: number;
-                    y: number;
-                    z: number;
-            };
+            loadConfiguration(initConfig?: ViewerConfiguration, callback?: (config: ViewerConfiguration) => void): Promise<ViewerConfiguration>;
             /**
-                * the offset angle
+                * Dispose the configuration loader. This will cancel file requests, if active.
                 */
-            rotationOffsetAngle?: number;
-            loaderConfiguration?: {
-                    maxLODsToLoad?: number;
-                    progressiveLoading?: boolean;
-            };
+            dispose(): void;
     }
 }
 
@@ -1185,42 +1386,6 @@ declare module 'babylonjs-viewer/managers/observablesManager' {
     }
 }
 
-declare module 'babylonjs-viewer/loader/plugins' {
-    import { TelemetryLoaderPlugin } from "babylonjs-viewer/loader/plugins/telemetryLoaderPlugin";
-    import { ILoaderPlugin } from "babylonjs-viewer/loader/plugins/loaderPlugin";
-    import { MSFTLodLoaderPlugin } from 'babylonjs-viewer/loader/plugins/msftLodLoaderPlugin';
-    import { ApplyMaterialConfigPlugin } from 'babylonjs-viewer/loader/plugins/applyMaterialConfig';
-    import { ExtendedMaterialLoaderPlugin } from 'babylonjs-viewer/loader/plugins/extendedMaterialLoaderPlugin';
-    export { TelemetryLoaderPlugin, ILoaderPlugin, MSFTLodLoaderPlugin, ApplyMaterialConfigPlugin, ExtendedMaterialLoaderPlugin };
-    /**
-        * Get a loader plugin according to its name.
-        * The plugin will be cached and will be reused if called for again.
-        *
-        * @param name the name of the plugin
-        */
-    export function getLoaderPluginByName(name: string): ILoaderPlugin;
-    /**
-        *
-        */
-    export function addLoaderPlugin(name: string, plugin: ILoaderPlugin): void;
-}
-
-declare module 'babylonjs-viewer/optimizer/custom/extended' {
-    import { SceneManager } from 'babylonjs-viewer/managers/sceneManager';
-    /**
-        * A custom upgrade-oriented function configuration for the scene optimizer.
-        *
-        * @param viewer the viewer to optimize
-        */
-    export function extendedUpgrade(sceneManager: SceneManager): boolean;
-    /**
-        * A custom degrade-oriented function configuration for the scene optimizer.
-        *
-        * @param viewer the viewer to optimize
-        */
-    export function extendedDegrade(sceneManager: SceneManager): boolean;
-}
-
 declare module 'babylonjs-viewer/managers/sceneManager' {
     import { Scene, ArcRotateCamera, Engine, Light, SceneOptimizer, EnvironmentHelper, Color3, Observable, DefaultRenderingPipeline, Nullable, VRExperienceHelper } from 'babylonjs';
     import { ILightConfiguration, ISceneConfiguration, ISceneOptimizerConfiguration, ICameraConfiguration, ISkyboxConfiguration, ViewerConfiguration, IGroundConfiguration, IModelConfiguration, IVRConfiguration } from 'babylonjs-viewer/configuration';
@@ -1410,6 +1575,110 @@ declare module 'babylonjs-viewer/managers/sceneManager' {
     }
 }
 
+declare module 'babylonjs-viewer/configuration/interfaces/modelConfiguration' {
+    import { IModelAnimationConfiguration } from "babylonjs-viewer/configuration/interfaces/modelAnimationConfiguration";
+    export interface IModelConfiguration {
+            id?: string;
+            url?: string;
+            root?: string;
+            file?: string | File;
+            loader?: string;
+            position?: {
+                    x: number;
+                    y: number;
+                    z: number;
+            };
+            rotation?: {
+                    x: number;
+                    y: number;
+                    z: number;
+                    w?: number;
+            };
+            scaling?: {
+                    x: number;
+                    y: number;
+                    z: number;
+            };
+            parentObjectIndex?: number;
+            castShadow?: boolean;
+            receiveShadows?: boolean;
+            normalize?: boolean | {
+                    center?: boolean;
+                    unitSize?: boolean;
+                    parentIndex?: number;
+            };
+            title?: string;
+            subtitle?: string;
+            thumbnail?: string;
+            animation?: {
+                    autoStart?: boolean | string;
+                    playOnce?: boolean;
+                    autoStartIndex?: number;
+            };
+            entryAnimation?: IModelAnimationConfiguration;
+            exitAnimation?: IModelAnimationConfiguration;
+            material?: {
+                    directEnabled?: boolean;
+                    directIntensity?: number;
+                    emissiveIntensity?: number;
+                    environmentIntensity?: number;
+                    [propName: string]: any;
+            };
+            /**
+                * Rotation offset axis definition
+                */
+            rotationOffsetAxis?: {
+                    x: number;
+                    y: number;
+                    z: number;
+            };
+            /**
+                * the offset angle
+                */
+            rotationOffsetAngle?: number;
+            loaderConfiguration?: {
+                    maxLODsToLoad?: number;
+                    progressiveLoading?: boolean;
+            };
+    }
+}
+
+declare module 'babylonjs-viewer/loader/plugins' {
+    import { TelemetryLoaderPlugin } from "babylonjs-viewer/loader/plugins/telemetryLoaderPlugin";
+    import { ILoaderPlugin } from "babylonjs-viewer/loader/plugins/loaderPlugin";
+    import { MSFTLodLoaderPlugin } from 'babylonjs-viewer/loader/plugins/msftLodLoaderPlugin';
+    import { ApplyMaterialConfigPlugin } from 'babylonjs-viewer/loader/plugins/applyMaterialConfig';
+    import { ExtendedMaterialLoaderPlugin } from 'babylonjs-viewer/loader/plugins/extendedMaterialLoaderPlugin';
+    export { TelemetryLoaderPlugin, ILoaderPlugin, MSFTLodLoaderPlugin, ApplyMaterialConfigPlugin, ExtendedMaterialLoaderPlugin };
+    /**
+        * Get a loader plugin according to its name.
+        * The plugin will be cached and will be reused if called for again.
+        *
+        * @param name the name of the plugin
+        */
+    export function getLoaderPluginByName(name: string): ILoaderPlugin;
+    /**
+        *
+        */
+    export function addLoaderPlugin(name: string, plugin: ILoaderPlugin): void;
+}
+
+declare module 'babylonjs-viewer/optimizer/custom/extended' {
+    import { SceneManager } from 'babylonjs-viewer/managers/sceneManager';
+    /**
+        * A custom upgrade-oriented function configuration for the scene optimizer.
+        *
+        * @param viewer the viewer to optimize
+        */
+    export function extendedUpgrade(sceneManager: SceneManager): boolean;
+    /**
+        * A custom degrade-oriented function configuration for the scene optimizer.
+        *
+        * @param viewer the viewer to optimize
+        */
+    export function extendedDegrade(sceneManager: SceneManager): boolean;
+}
+
 declare module 'babylonjs-viewer/configuration/interfaces' {
     export * from 'babylonjs-viewer/configuration/interfaces/cameraConfiguration';
     export * from 'babylonjs-viewer/configuration/interfaces/colorGradingConfiguration';
@@ -1488,6 +1757,57 @@ declare module 'babylonjs-viewer/templating/eventManager' {
     }
 }
 
+declare module 'babylonjs-viewer/labs/viewerLabs' {
+    import { PBREnvironment } from "babylonjs-viewer/labs/environmentSerializer";
+    import { ShadowLight, Vector3, Scene } from 'babylonjs';
+    /**
+        * The ViewerLabs class will hold functions that are not (!) backwards compatible.
+        * The APIs in all labs-related classes and configuration  might change.
+        * Once stable, lab features will be moved to the publis API and configuration object.
+        */
+    export class ViewerLabs {
+            constructor(_scene: Scene);
+            assetsRootURL: string;
+            environment: PBREnvironment;
+            /**
+                        * Loads an environment map from a given URL
+                        * @param url URL of environment map
+                        * @param onSuccess Callback fired after environment successfully applied to the scene
+                        * @param onProgress Callback fired at progress events while loading the environment map
+                        * @param onError Callback fired when the load fails
+                        */
+            loadEnvironment(url: string, onSuccess?: (env: PBREnvironment) => void, onProgress?: (bytesLoaded: number, bytesTotal: number) => void, onError?: (e: any) => void): void;
+            /**
+                * Loads an environment map from a given URL
+                * @param buffer ArrayBuffer containing environment map
+                * @param onSuccess Callback fired after environment successfully applied to the scene
+                * @param onProgress Callback fired at progress events while loading the environment map
+                * @param onError Callback fired when the load fails
+                */
+            loadEnvironment(buffer: ArrayBuffer, onSuccess?: (env: PBREnvironment) => void, onProgress?: (bytesLoaded: number, bytesTotal: number) => void, onError?: (e: any) => void): void;
+            /**
+                * Sets the environment to an already loaded environment
+                * @param env PBREnvironment instance
+                * @param onSuccess Callback fired after environment successfully applied to the scene
+                * @param onProgress Callback fired at progress events while loading the environment map
+                * @param onError Callback fired when the load fails
+                */
+            loadEnvironment(env: PBREnvironment, onSuccess?: (env: PBREnvironment) => void, onProgress?: (bytesLoaded: number, bytesTotal: number) => void, onError?: (e: any) => void): void;
+            /**
+                * Applies an `EnvironmentMapConfiguration` to the scene
+                * @param environmentMapConfiguration Environment map configuration to apply
+                */
+            applyEnvironmentMapConfiguration(rotationY?: number): void;
+            /**
+                * Get an environment asset url by using the configuration if the path is not absolute.
+                * @param url Asset url
+                * @returns The Asset url using the `environmentAssetsRootURL` if the url is not an absolute path.
+                */
+            getAssetUrl(url: string): string;
+            rotateShadowLight(shadowLight: ShadowLight, amount: number, point?: Vector3, axis?: Vector3, target?: Vector3): void;
+    }
+}
+
 declare module 'babylonjs-viewer/configuration/interfaces/modelAnimationConfiguration' {
     /**
         * Defines an animation to be applied to a model (translation, scale or rotation).
@@ -1568,57 +1888,6 @@ declare module 'babylonjs-viewer/loader/plugins/extendedMaterialLoaderPlugin' {
     }
 }
 
-declare module 'babylonjs-viewer/labs/viewerLabs' {
-    import { PBREnvironment } from "babylonjs-viewer/labs/environmentSerializer";
-    import { ShadowLight, Vector3, Scene } from 'babylonjs';
-    /**
-        * The ViewerLabs class will hold functions that are not (!) backwards compatible.
-        * The APIs in all labs-related classes and configuration  might change.
-        * Once stable, lab features will be moved to the publis API and configuration object.
-        */
-    export class ViewerLabs {
-            constructor(_scene: Scene);
-            assetsRootURL: string;
-            environment: PBREnvironment;
-            /**
-                        * Loads an environment map from a given URL
-                        * @param url URL of environment map
-                        * @param onSuccess Callback fired after environment successfully applied to the scene
-                        * @param onProgress Callback fired at progress events while loading the environment map
-                        * @param onError Callback fired when the load fails
-                        */
-            loadEnvironment(url: string, onSuccess?: (env: PBREnvironment) => void, onProgress?: (bytesLoaded: number, bytesTotal: number) => void, onError?: (e: any) => void): void;
-            /**
-                * Loads an environment map from a given URL
-                * @param buffer ArrayBuffer containing environment map
-                * @param onSuccess Callback fired after environment successfully applied to the scene
-                * @param onProgress Callback fired at progress events while loading the environment map
-                * @param onError Callback fired when the load fails
-                */
-            loadEnvironment(buffer: ArrayBuffer, onSuccess?: (env: PBREnvironment) => void, onProgress?: (bytesLoaded: number, bytesTotal: number) => void, onError?: (e: any) => void): void;
-            /**
-                * Sets the environment to an already loaded environment
-                * @param env PBREnvironment instance
-                * @param onSuccess Callback fired after environment successfully applied to the scene
-                * @param onProgress Callback fired at progress events while loading the environment map
-                * @param onError Callback fired when the load fails
-                */
-            loadEnvironment(env: PBREnvironment, onSuccess?: (env: PBREnvironment) => void, onProgress?: (bytesLoaded: number, bytesTotal: number) => void, onError?: (e: any) => void): void;
-            /**
-                * Applies an `EnvironmentMapConfiguration` to the scene
-                * @param environmentMapConfiguration Environment map configuration to apply
-                */
-            applyEnvironmentMapConfiguration(rotationY?: number): void;
-            /**
-                * Get an environment asset url by using the configuration if the path is not absolute.
-                * @param url Asset url
-                * @returns The Asset url using the `environmentAssetsRootURL` if the url is not an absolute path.
-                */
-            getAssetUrl(url: string): string;
-            rotateShadowLight(shadowLight: ShadowLight, amount: number, point?: Vector3, axis?: Vector3, target?: Vector3): void;
-    }
-}
-
 declare module 'babylonjs-viewer/configuration/interfaces/cameraConfiguration' {
     export interface ICameraConfiguration {
         position?: {

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

@@ -201,6 +201,7 @@
 - trackPosition:false not working in webVRCamera/controllers ([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))
+- Particle emit rate and start size over time do not reset on every particle system start ([TrevorDev](https://github.com/TrevorDev))
 
 ### Core Engine
 

+ 10 - 3
gui/src/2D/controls/control.ts

@@ -503,7 +503,7 @@ export class Control {
         }
 
         this._isVisible = value;
-        this._markAsDirty();
+        this._markAsDirty(true);
     }
 
     /** Gets a boolean indicating that the control needs to update its rendering */
@@ -512,6 +512,13 @@ export class Control {
     }
 
     /**
+     * Gets the current linked mesh (or null if none)
+     */
+    public get linkedMesh(): Nullable<AbstractMesh> {
+        return this._linkedMesh;
+    }
+
+    /**
      * Gets or sets a value indicating the padding to use on the left of the control
      * @see http://doc.babylonjs.com/how_to/gui#position-and-size
      */
@@ -890,8 +897,8 @@ export class Control {
     }
 
     /** @hidden */
-    public _markAsDirty(): void {
-        if (!this._isVisible) {
+    public _markAsDirty(force = false): void {
+        if (!this._isVisible && !force) {
             return;
         }
 

+ 1 - 1
package.json

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

+ 10 - 4
src/Cameras/Inputs/babylon.arcRotateCameraKeyboardMoveInput.ts

@@ -61,6 +61,12 @@ module BABYLON {
         @serialize()
         public useAltToZoom: boolean = true;
 
+        /**
+         * Rotation speed of the camera
+         */
+        @serialize()
+        public angularSpeed = 0.01;
+
         private _keys = new Array<number>();
         private _ctrlPressed: boolean;
         private _altPressed: boolean;
@@ -166,7 +172,7 @@ module BABYLON {
                         if (this._ctrlPressed && this.camera._useCtrlForPanning) {
                             camera.inertialPanningX -= 1 / this.panningSensibility;
                         } else {
-                            camera.inertialAlphaOffset -= 0.01;
+                            camera.inertialAlphaOffset -= this.angularSpeed;
                         }
                     } else if (this.keysUp.indexOf(keyCode) !== -1) {
                         if (this._ctrlPressed && this.camera._useCtrlForPanning) {
@@ -176,13 +182,13 @@ module BABYLON {
                             camera.inertialRadiusOffset += 1 / this.zoomingSensibility;
                         }
                         else {
-                            camera.inertialBetaOffset -= 0.01;
+                            camera.inertialBetaOffset -= this.angularSpeed;
                         }
                     } else if (this.keysRight.indexOf(keyCode) !== -1) {
                         if (this._ctrlPressed && this.camera._useCtrlForPanning) {
                             camera.inertialPanningX += 1 / this.panningSensibility;
                         } else {
-                            camera.inertialAlphaOffset += 0.01;
+                            camera.inertialAlphaOffset += this.angularSpeed;
                         }
                     } else if (this.keysDown.indexOf(keyCode) !== -1) {
                         if (this._ctrlPressed && this.camera._useCtrlForPanning) {
@@ -192,7 +198,7 @@ module BABYLON {
                             camera.inertialRadiusOffset -= 1 / this.zoomingSensibility;
                         }
                         else {
-                            camera.inertialBetaOffset += 0.01;
+                            camera.inertialBetaOffset += this.angularSpeed;
                         }
                     } else if (this.keysReset.indexOf(keyCode) !== -1) {
                         if (camera.useInputToRestoreState) {

+ 67 - 1
src/Culling/Octrees/babylon.octree.ts

@@ -1,27 +1,66 @@
 module BABYLON {
+    /**
+     * Contains an array of blocks representing the octree
+     */
     export interface IOctreeContainer<T> {
+        /**
+         * Blocks within the octree
+         */
         blocks: Array<OctreeBlock<T>>;
     }
 
+    /**
+     * Octrees are a really powerful data structure that can quickly select entities based on space coordinates.
+     * @see https://doc.babylonjs.com/how_to/optimizing_your_scene_with_octrees
+     */
     export class Octree<T> {
+        /**
+         * Blocks within the octree containing objects
+         */
         public blocks: Array<OctreeBlock<T>>;
+        /**
+         * Content stored in the octree
+         */
         public dynamicContent = new Array<T>();
 
         private _maxBlockCapacity: number;
         private _selectionContent: SmartArrayNoDuplicate<T>;       
         private _creationFunc: (entry: T, block: OctreeBlock<T>) => void;
 
-        constructor(creationFunc: (entry: T, block: OctreeBlock<T>) => void, maxBlockCapacity?: number, public maxDepth = 2) {
+        /**
+         * Creates a octree
+         * @see https://doc.babylonjs.com/how_to/optimizing_your_scene_with_octrees
+         * @param creationFunc function to be used to instatiate the octree
+         * @param maxBlockCapacity defines the maximum number of meshes you want on your octree's leaves (default: 64)
+         * @param maxDepth defines the maximum depth (sub-levels) for your octree. Default value is 2, which means 8 8 8 = 512 blocks :) (This parameter takes precedence over capacity.)
+         */
+        constructor(creationFunc: (
+            entry: T,
+            block: OctreeBlock<T>) => void,
+            maxBlockCapacity?: number, 
+            /** Defines the maximum depth (sub-levels) for your octree. Default value is 2, which means 8 8 8 = 512 blocks :) (This parameter takes precedence over capacity.) */
+            public maxDepth = 2
+        ) {
             this._maxBlockCapacity = maxBlockCapacity || 64;
             this._selectionContent = new SmartArrayNoDuplicate<T>(1024);
             this._creationFunc = creationFunc;
         }
 
         // Methods
+        /**
+         * Updates the octree by adding blocks for the passed in meshes within the min and max world parameters
+         * @param worldMin worldMin for the octree blocks var blockSize = new Vector3((worldMax.x - worldMin.x) / 2, (worldMax.y - worldMin.y) / 2, (worldMax.z - worldMin.z) / 2);
+         * @param worldMax worldMax for the octree blocks var blockSize = new Vector3((worldMax.x - worldMin.x) / 2, (worldMax.y - worldMin.y) / 2, (worldMax.z - worldMin.z) / 2);
+         * @param entries meshes to be added to the octree blocks
+         */
         public update(worldMin: Vector3, worldMax: Vector3, entries: T[]): void {
             Octree._CreateBlocks(worldMin, worldMax, entries, this._maxBlockCapacity, 0, this.maxDepth, this, this._creationFunc);
         }
 
+        /**
+         * Adds a mesh to the octree
+         * @param entry Mesh to add to the octree
+         */
         public addMesh(entry: T): void {
             for (var index = 0; index < this.blocks.length; index++) {
                 var block = this.blocks[index];
@@ -29,6 +68,12 @@
             }
         }
 
+        /**
+         * Selects an array of meshes within the frustum
+         * @param frustumPlanes The frustum planes to use which will select all meshes within it
+         * @param allowDuplicate If duplicate objects are allowed in the resulting object array
+         * @returns array of meshes within the frustum
+         */
         public select(frustumPlanes: Plane[], allowDuplicate?: boolean): SmartArray<T> {
             this._selectionContent.reset();
 
@@ -46,6 +91,13 @@
             return this._selectionContent;
         }
 
+        /**
+         * Test if the octree intersect with the given bounding sphere and if yes, then add its content to the selection array
+         * @param sphereCenter defines the bounding sphere center
+         * @param sphereRadius defines the bounding sphere radius
+         * @param allowDuplicate defines if the selection array can contains duplicated entries
+         * @returns an array of objects that intersect the sphere
+         */
         public intersects(sphereCenter: Vector3, sphereRadius: number, allowDuplicate?: boolean): SmartArray<T> {
             this._selectionContent.reset();
 
@@ -63,6 +115,11 @@
             return this._selectionContent;
         }
 
+        /**
+        * Test if the octree intersect with the given ray and if yes, then add its content to resulting array
+         * @param ray defines the ray to test with
+         * @returns array of intersected objects
+         */
         public intersectsRay(ray: Ray): SmartArray<T> {
             this._selectionContent.reset();
 
@@ -76,6 +133,9 @@
             return this._selectionContent;
         }
 
+        /**
+         * @hidden
+         */
         public static _CreateBlocks<T>(worldMin: Vector3, worldMax: Vector3, entries: T[], maxBlockCapacity: number, currentDepth: number, maxDepth: number, target: IOctreeContainer<T>, creationFunc: (entry: T, block: OctreeBlock<T>) => void): void {
             target.blocks = new Array<OctreeBlock<T>>();
             var blockSize = new Vector3((worldMax.x - worldMin.x) / 2, (worldMax.y - worldMin.y) / 2, (worldMax.z - worldMin.z) / 2);
@@ -95,6 +155,9 @@
             }
         }
 
+        /**
+         * Adds a mesh into the octree block if it intersects the block
+         */
         public static CreationFuncForMeshes = (entry: AbstractMesh, block: OctreeBlock<AbstractMesh>): void => {
             let boundingInfo = entry.getBoundingInfo();
             if (!entry.isBlocked && boundingInfo.boundingBox.intersectsMinMax(block.minPoint, block.maxPoint)) {
@@ -102,6 +165,9 @@
             }
         }
 
+        /**
+         * Adds a submesh into the octree block if it intersects the block
+         */
         public static CreationFuncForSubMeshes = (entry: SubMesh, block: OctreeBlock<SubMesh>): void => {
             let boundingInfo = entry.getBoundingInfo();
             if (boundingInfo.boundingBox.intersectsMinMax(block.minPoint, block.maxPoint)) {

+ 40 - 52
src/Culling/babylon.boundingBox.ts

@@ -6,47 +6,47 @@
         /**
          * Gets the 8 vectors representing the bounding box in local space
          */
-        public vectors: Vector3[];
+        public vectors: Vector3[] = [Vector3.Zero(), Vector3.Zero(), Vector3.Zero(), Vector3.Zero(), Vector3.Zero(), Vector3.Zero(), Vector3.Zero(), Vector3.Zero()];
         /**
          * Gets the center of the bounding box in local space
          */
-        public center: Vector3;
+        public center: Vector3 = Vector3.Zero();
         /**
          * Gets the center of the bounding box in world space
          */
-        public centerWorld: Vector3;
+        public centerWorld: Vector3 = Vector3.Zero();
         /**
          * Gets the extend size in local space
          */
-        public extendSize: Vector3;
+        public extendSize: Vector3 = Vector3.Zero();
         /**
          * Gets the extend size in world space
          */
-        public extendSizeWorld: Vector3;
+        public extendSizeWorld: Vector3 = Vector3.Zero();
         /**
          * Gets the OBB (object bounding box) directions
          */
-        public directions: Vector3[];
+        public directions: Vector3[] = [Vector3.Zero(), Vector3.Zero(), Vector3.Zero()];
         /**
          * Gets the 8 vectors representing the bounding box in world space
-         */        
-        public vectorsWorld: Vector3[] = new Array<Vector3>();
+         */
+        public vectorsWorld: Vector3[] = [Vector3.Zero(), Vector3.Zero(), Vector3.Zero(), Vector3.Zero(), Vector3.Zero(), Vector3.Zero(), Vector3.Zero(), Vector3.Zero()];;
         /**
          * Gets the minimum vector in world space
          */
-        public minimumWorld: Vector3;
+        public minimumWorld: Vector3 = Vector3.Zero();
         /**
          * Gets the maximum vector in world space
          */
-        public maximumWorld: Vector3;
+        public maximumWorld: Vector3 = Vector3.Zero();
         /**
          * Gets the minimum vector in local space
          */
-        public minimum: Vector3;
+        public minimum: Vector3 = Vector3.Zero();
         /**
          * Gets the maximum vector in local space
          */
-        public maximum: Vector3;
+        public maximum: Vector3 = Vector3.Zero();
 
         private _worldMatrix: Matrix;
 
@@ -72,20 +72,18 @@
          * @param max defines the new maximum vector (in local space) 
          */
         public reConstruct(min: Vector3, max: Vector3) {
-            this.minimum = min.clone();
-            this.maximum = max.clone()
+            this.minimum.copyFrom(min);
+            this.maximum.copyFrom(max);
 
             // Bounding vectors
-            this.vectors = [
-                this.minimum.clone(),
-                this.maximum.clone(),
-                this.minimum.clone(),
-                this.minimum.clone(),
-                this.minimum.clone(),
-                this.maximum.clone(),
-                this.maximum.clone(),
-                this.maximum.clone()
-            ];
+            this.vectors[0].copyFrom(this.minimum);
+            this.vectors[1].copyFrom(this.maximum);
+            this.vectors[2].copyFrom(this.minimum);
+            this.vectors[3].copyFrom(this.minimum);
+            this.vectors[4].copyFrom(this.minimum);
+            this.vectors[5].copyFrom(this.maximum);
+            this.vectors[6].copyFrom(this.maximum);
+            this.vectors[7].copyFrom(this.maximum);
 
             this.vectors[2].x = this.maximum.x;
             this.vectors[3].y = this.maximum.y;
@@ -95,19 +93,21 @@
             this.vectors[7].y = this.minimum.y;
 
             // OBB
-            this.center = this.maximum.add(this.minimum).scale(0.5);
-            this.extendSize = this.maximum.subtract(this.minimum).scale(0.5);
-            this.directions = [Vector3.Zero(), Vector3.Zero(), Vector3.Zero()];
+            this.center.copyFrom(this.maximum).addInPlace(this.minimum).scaleInPlace(0.5);
+            this.extendSize.copyFrom(this.maximum).subtractInPlace(this.minimum).scaleInPlace(0.5);
+            for (var index = 0; index < 3; index++) {
+                this.directions[index].copyFromFloats(0,0,0);
+            }
 
             // World
-            for (var index = 0; index < this.vectors.length; index++) {
-                this.vectorsWorld[index] = Vector3.Zero();
+            for (var index = 0; index < 8; index++) {
+                this.vectorsWorld[index].copyFromFloats(0,0,0);
             }
 
-            this.minimumWorld = Vector3.Zero();
-            this.maximumWorld = Vector3.Zero();
-            this.centerWorld = Vector3.Zero();
-            this.extendSizeWorld = Vector3.Zero();
+            this.minimumWorld.copyFromFloats(0,0,0);
+            this.maximumWorld.copyFromFloats(0,0,0);
+            this.centerWorld.copyFromFloats(0,0,0);
+            this.extendSizeWorld.copyFromFloats(0,0,0);
 
             this._update(this._worldMatrix || Matrix.Identity());
         }
@@ -118,13 +118,13 @@
          * @returns the current bounding box
          */
         public scale(factor: number): BoundingBox {
-            let diff = this.maximum.subtract(this.minimum);
+            const diff = Tmp.Vector3[0].copyFrom(this.maximum).subtractInPlace(this.minimum);
             let distance = diff.length() * factor;
             diff.normalize();
-            let newRadius = diff.scale(distance / 2);
+            let newRadius = diff.scaleInPlace(distance * 0.5);
 
-            let min = this.center.subtract(newRadius);
-            let max = this.center.add(newRadius);
+            const min = Tmp.Vector3[1].copyFrom(this.center).subtractInPlace(newRadius);
+            const max = Tmp.Vector3[2].copyFrom(this.center).addInPlace(newRadius);
 
             this.reConstruct(min, max);
 
@@ -154,23 +154,11 @@
             Vector3.FromFloatsToRef(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE, this.minimumWorld);
             Vector3.FromFloatsToRef(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE, this.maximumWorld);
 
-            for (var index = 0; index < this.vectors.length; index++) {
+            for (var index = 0; index < 8; index++) {
                 var v = this.vectorsWorld[index];
                 Vector3.TransformCoordinatesToRef(this.vectors[index], world, v);
-
-                if (v.x < this.minimumWorld.x)
-                    this.minimumWorld.x = v.x;
-                if (v.y < this.minimumWorld.y)
-                    this.minimumWorld.y = v.y;
-                if (v.z < this.minimumWorld.z)
-                    this.minimumWorld.z = v.z;
-
-                if (v.x > this.maximumWorld.x)
-                    this.maximumWorld.x = v.x;
-                if (v.y > this.maximumWorld.y)
-                    this.maximumWorld.y = v.y;
-                if (v.z > this.maximumWorld.z)
-                    this.maximumWorld.z = v.z;
+                this.minimumWorld.minimizeInPlace(v);
+                this.maximumWorld.maximizeInPlace(v);
             }
 
             // Extend

+ 20 - 14
src/Culling/babylon.boundingInfo.ts

@@ -61,21 +61,26 @@
          * @param minimum min vector of the bounding box/sphere
          * @param maximum max vector of the bounding box/sphere
          */
-        constructor(
-            /**
-             * min vector of the bounding box/sphere
-             */
-            public minimum: Vector3, 
-            /**
-             * max vector of the bounding box/sphere
-             */
-            public maximum: Vector3
-        ) {
+        constructor(minimum: Vector3, maximum: Vector3) {
             this.boundingBox = new BoundingBox(minimum, maximum);
             this.boundingSphere = new BoundingSphere(minimum, maximum);
         }
 
         /**
+         * min vector of the bounding box/sphere
+         */
+        public get minimum(): Vector3 {
+            return this.boundingBox.minimum;
+        }
+
+        /**
+         * max vector of the bounding box/sphere
+         */
+        public get maximum(): Vector3 {
+           return this.boundingBox.maximum;
+        }
+
+        /**
          * If the info is locked and won't be updated to avoid perf overhead
          */
         public get isLocked(): boolean {
@@ -106,11 +111,12 @@
          * @returns the current bounding info
          */
         public centerOn(center: Vector3, extend: Vector3): BoundingInfo {
-            this.minimum = center.subtract(extend);
-            this.maximum = center.add(extend);
 
-            this.boundingBox = new BoundingBox(this.minimum, this.maximum);
-            this.boundingSphere = new BoundingSphere(this.minimum, this.maximum);
+            const minimum = Tmp.Vector3[0].copyFrom(center).subtractInPlace(extend);
+            const maximum = Tmp.Vector3[1].copyFrom(center).addInPlace(extend);
+
+            this.boundingBox.reConstruct(minimum, maximum);
+            this.boundingSphere.reConstruct(minimum, maximum);
 
             return this;
         }

+ 12 - 15
src/Culling/babylon.boundingSphere.ts

@@ -1,7 +1,6 @@
 module BABYLON {
     // This matrix is used as a value to reset the bounding box.
     const _identityMatrix = Matrix.Identity();
-    const _tempRadiusVector = new Vector3(0, 0, 0);
 
     /**
      * Class used to store bounding sphere information
@@ -10,7 +9,7 @@
         /**
          * Gets the center of the bounding sphere in local space
          */
-        public center: Vector3;
+        public center = Vector3.Zero();
         /**
          * Radius of the bounding sphere in local space
          */
@@ -18,7 +17,7 @@
         /**
          * Gets the center of the bounding sphere in world space
          */
-        public centerWorld: Vector3;
+        public centerWorld = Vector3.Zero();
         /**
          * Radius of the bounding sphere in world space
          */
@@ -26,11 +25,11 @@
         /**
          * Gets the minimum vector in local space
          */
-        public minimum: Vector3;
+        public minimum = Vector3.Zero();
         /**
          * Gets the maximum vector in local space
          */
-        public maximum: Vector3;
+        public maximum = Vector3.Zero();
 
         /**
          * Creates a new bounding sphere
@@ -38,8 +37,6 @@
          * @param max defines the maximum vector (in local space)
          */
         constructor(min: Vector3, max: Vector3) {
-            this.center = Vector3.Zero();
-            this.centerWorld = Vector3.Zero();
             this.reConstruct(min, max);
         }
 
@@ -49,8 +46,8 @@
          * @param max defines the new maximum vector (in local space) 
          */
         public reConstruct(min: Vector3, max: Vector3) {
-            this.minimum = min.clone();
-            this.maximum = max.clone()
+            this.minimum.copyFrom(min);
+            this.maximum.copyFrom(max);
 
             var distance = Vector3.Distance(min, max);
 
@@ -68,10 +65,9 @@
          */
         public scale(factor: number): BoundingSphere {
             let newRadius = this.radius * factor;
-            _tempRadiusVector.set(newRadius, newRadius, newRadius)
-
-            let min = this.center.subtract(_tempRadiusVector);
-            let max = this.center.add(_tempRadiusVector);
+            const tempRadiusVector = Tmp.Vector3[0].set(newRadius, newRadius, newRadius);
+            let min = Tmp.Vector3[1].copyFrom(this.center).subtractInPlace(tempRadiusVector);
+            let max = Tmp.Vector3[2].copyFrom(this.center).addInPlace(tempRadiusVector);
 
             this.reConstruct(min, max);
 
@@ -82,8 +78,9 @@
         /** @hidden */
         public _update(world: Matrix): void {
             Vector3.TransformCoordinatesToRef(this.center, world, this.centerWorld);
-            Vector3.TransformNormalFromFloatsToRef(1.0, 1.0, 1.0, world, _tempRadiusVector);
-            this.radiusWorld = Math.max(Math.abs(_tempRadiusVector.x), Math.abs(_tempRadiusVector.y), Math.abs(_tempRadiusVector.z)) * this.radius;
+            const tempVector = Tmp.Vector3[0];
+            Vector3.TransformNormalFromFloatsToRef(1.0, 1.0, 1.0, world, tempVector);
+            this.radiusWorld = Math.max(Math.abs(tempVector.x), Math.abs(tempVector.y), Math.abs(tempVector.z)) * this.radius;
         }
 
         /**

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

@@ -475,7 +475,7 @@
          * Returns the current version of the framework
          */
         public static get Version(): string {
-            return "3.3.0-rc.1";
+            return "3.3.0-rc.3";
         }
 
         // Updatable statics so stick with vars here

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

@@ -87,11 +87,11 @@ module BABYLON {
          */
         public samples: number;
         /**
-         * Gets the type of the texture
+         * Gets the type of the texture (int, float...)
          */
         public type: number;
         /**
-         * Gets the format of the texture 
+         * Gets the format of the texture (RGB, RGBA...)
          */
         public format: number;
         /**

+ 70 - 11
src/Materials/Textures/babylon.mirrorTexture.ts

@@ -1,18 +1,22 @@
 module BABYLON {
+    /**
+     * Mirror texture can be used to simulate the view from a mirror in a scene.
+     * It will dynamically be rendered every frame to adapt to the camera point of view.
+     * You can then easily use it as a reflectionTexture on a flat surface.
+     * In case the surface is not a plane, please consider relying on reflection probes.
+     * @see https://doc.babylonjs.com/how_to/reflect#mirrors
+     */
     export class MirrorTexture extends RenderTargetTexture {
+        /**
+         * Define the reflection plane we want to use. The mirrorPlane is usually set to the constructed reflector. 
+         * It is possible to directly set the mirrorPlane by directly using a BABYLON.Plane(a, b, c, d) where a, b and c give the plane normal vector (a, b, c) and d is a scalar displacement from the mirrorPlane to the origin. However in all but the very simplest of situations it is more straight forward to set it to the reflector as stated in the doc.
+         * @see https://doc.babylonjs.com/how_to/reflect#mirrors
+         */
         public mirrorPlane = new Plane(0, 1, 0, 1);
 
-        private _transformMatrix = Matrix.Zero();
-        private _mirrorMatrix = Matrix.Zero();
-        private _savedViewMatrix: Matrix;
-
-        private _blurX: Nullable<BlurPostProcess>;
-        private _blurY: Nullable<BlurPostProcess>;
-        private _adaptiveBlurKernel = 0;
-        private _blurKernelX = 0;
-        private _blurKernelY = 0;
-        private _blurRatio = 1.0;
-
+        /**
+         * Define the blur ratio used to blur the reflection if needed.
+         */
         public set blurRatio(value: number) {
             if (this._blurRatio === value) {
                 return;
@@ -26,16 +30,28 @@
             return this._blurRatio;
         }
 
+        /**
+         * Define the adaptive blur kernel used to blur the reflection if needed.
+         * This will autocompute the closest best match for the `blurKernel`
+         */
         public set adaptiveBlurKernel(value: number) {
             this._adaptiveBlurKernel = value;
             this._autoComputeBlurKernel();
         }
 
+        /**
+         * Define the blur kernel used to blur the reflection if needed.
+         * Please consider using `adaptiveBlurKernel` as it could find the closest best value for you.
+         */
         public set blurKernel(value: number) {
             this.blurKernelX = value;
             this.blurKernelY = value;
         }
 
+        /**
+         * Define the blur kernel on the X Axis used to blur the reflection if needed.
+         * Please consider using `adaptiveBlurKernel` as it could find the closest best value for you.
+         */
         public set blurKernelX(value: number) {
             if (this._blurKernelX === value) {
                 return;
@@ -49,6 +65,10 @@
             return this._blurKernelX;
         }
 
+        /**
+         * Define the blur kernel on the Y Axis used to blur the reflection if needed.
+         * Please consider using `adaptiveBlurKernel` as it could find the closest best value for you.
+         */
         public set blurKernelY(value: number) {
             if (this._blurKernelY === value) {
                 return;
@@ -83,11 +103,39 @@
                 this._autoComputeBlurKernel();
             }
         }
+
         private _updateGammaSpace(){
             this.gammaSpace = !this.scene.imageProcessingConfiguration.isEnabled || !this.scene.imageProcessingConfiguration.applyByPostProcess;
         }
 
         private _imageProcessingConfigChangeObserver:Nullable<Observer<ImageProcessingConfiguration>>;
+
+        private _transformMatrix = Matrix.Zero();
+        private _mirrorMatrix = Matrix.Zero();
+        private _savedViewMatrix: Matrix;
+
+        private _blurX: Nullable<BlurPostProcess>;
+        private _blurY: Nullable<BlurPostProcess>;
+        private _adaptiveBlurKernel = 0;
+        private _blurKernelX = 0;
+        private _blurKernelY = 0;
+        private _blurRatio = 1.0;
+
+        /**
+         * Instantiates a Mirror Texture.
+         * Mirror texture can be used to simulate the view from a mirror in a scene.
+         * It will dynamically be rendered every frame to adapt to the camera point of view.
+         * You can then easily use it as a reflectionTexture on a flat surface.
+         * In case the surface is not a plane, please consider relying on reflection probes.
+         * @see https://doc.babylonjs.com/how_to/reflect#mirrors
+         * @param name 
+         * @param size 
+         * @param scene 
+         * @param generateMipMaps 
+         * @param type 
+         * @param samplingMode 
+         * @param generateDepthBuffer 
+         */
         constructor(name: string, size: number | { width: number, height: number } | { ratio: number }, private scene: Scene, generateMipMaps?: boolean, type: number = Engine.TEXTURETYPE_UNSIGNED_INT, samplingMode = Texture.BILINEAR_SAMPLINGMODE, generateDepthBuffer = true) {
             super(name, size, scene, generateMipMaps, true, type, false, samplingMode, generateDepthBuffer);
 
@@ -160,6 +208,10 @@
             }
         }
 
+        /**
+         * Clone the mirror texture.
+         * @returns the cloned texture
+         */
         public clone(): MirrorTexture {
             let scene = this.getScene();
 
@@ -191,6 +243,10 @@
             return newTexture;
         }
 
+        /**
+         * Serialize the texture to a JSON representation you could use in Parse later on
+         * @returns the serialized JSON representation
+         */
         public serialize(): any {
             if (!this.name) {
                 return null;
@@ -203,6 +259,9 @@
             return serializationObject;
         }
 
+        /**
+         * Dispose the texture and release its associated resources.
+         */
         public dispose(){
             super.dispose();
             this.scene.imageProcessingConfiguration.onUpdateParameters.remove(this._imageProcessingConfigChangeObserver);

+ 81 - 2
src/Materials/Textures/babylon.multiRenderTarget.ts

@@ -1,34 +1,83 @@
 module BABYLON {
+    /**
+     * Creation options of the multi render target texture.
+     */
     export interface IMultiRenderTargetOptions {
+        /**
+         * Define if the texture needs to create mip maps after render.
+         */
         generateMipMaps?: boolean,
+        /**
+         * Define the types of all the draw buffers we want to create
+         */
         types?: number[],
+        /**
+         * Define the sampling modes of all the draw buffers we want to create
+         */
         samplingModes?: number[],
+        /**
+         * Define if a depth buffer is required
+         */
         generateDepthBuffer?: boolean,
+        /**
+         * Define if a stencil buffer is required
+         */
         generateStencilBuffer?: boolean,
+        /**
+         * Define if a depth texture is required instead of a depth buffer
+         */
         generateDepthTexture?: boolean,
+        /**
+         * Define the number of desired draw buffers
+         */
         textureCount?: number,
+        /**
+         * Define if aspect ratio should be adapted to the texture or stay the scene one
+         */
         doNotChangeAspectRatio?: boolean,
+        /**
+         * Define the default type of the buffers we are creating
+         */
         defaultType?: number
     };
+
+    /**
+     * A multi render target, like a render target provides the ability to render to a texture.
+     * Unlike the render target, it can render to several draw buffers in one draw.
+     * This is specially interesting in deferred rendering or for any effects requiring more than
+     * just one color from a single pass.
+     */
     export class MultiRenderTarget extends RenderTargetTexture {
 
         private _internalTextures: InternalTexture[];
         private _textures: Texture[];
+        private _multiRenderTargetOptions: IMultiRenderTargetOptions;
 
+        /**
+         * Get if draw buffers are currently supported by the used hardware and browser.
+         */
         public get isSupported(): boolean {
             return this._engine.webGLVersion > 1 || this._engine.getCaps().drawBuffersExtension;
         }
 
-        private _multiRenderTargetOptions: IMultiRenderTargetOptions;
-
+        /**
+         * Get the list of textures generated by the multi render target.
+         */
         public get textures(): Texture[] {
             return this._textures;
         }
 
+        /**
+         * Get the depth texture generated by the multi render target if options.generateDepthTexture has been set
+         */
         public get depthTexture(): Texture {
             return this._textures[this._textures.length - 1];
         }
 
+        /**
+         * Set the wrapping mode on U of all the textures we are rendering to.
+         * Can be any of the Texture. (CLAMP_ADDRESSMODE, MIRROR_ADDRESSMODE or WRAP_ADDRESSMODE)
+         */
         public set wrapU(wrap: number) {
             if (this._textures) {
                 for (var i = 0; i < this._textures.length; i++) {
@@ -37,6 +86,10 @@ module BABYLON {
             }
         }
 
+        /**
+         * Set the wrapping mode on V of all the textures we are rendering to.
+         * Can be any of the Texture. (CLAMP_ADDRESSMODE, MIRROR_ADDRESSMODE or WRAP_ADDRESSMODE)
+         */
         public set wrapV(wrap: number) {
             if (this._textures) {
                 for (var i = 0; i < this._textures.length; i++) {
@@ -45,6 +98,18 @@ module BABYLON {
             }
         }
 
+        /**
+         * Instantiate a new multi render target texture.
+         * A multi render target, like a render target provides the ability to render to a texture.
+         * Unlike the render target, it can render to several draw buffers in one draw.
+         * This is specially interesting in deferred rendering or for any effects requiring more than
+         * just one color from a single pass.
+         * @param name Define the name of the texture
+         * @param size Define the size of the buffers to render to
+         * @param count Define the number of target we are rendering into
+         * @param scene Define the scene the texture belongs to
+         * @param options Define the options used to create the multi render target
+         */
         constructor(name: string, size: any, count: number, scene: Scene, options?: IMultiRenderTargetOptions) {
             var generateMipMaps = options && options.generateMipMaps ? options.generateMipMaps : false;
             var generateDepthTexture = options && options.generateDepthTexture ? options.generateDepthTexture : false;
@@ -124,6 +189,9 @@ module BABYLON {
             this._texture = this._internalTextures[0];
         }
 
+        /**
+         * Define the number of samples used if MSAA is enabled.
+         */
         public get samples(): number {
             return this._samples;
         }
@@ -136,6 +204,11 @@ module BABYLON {
             this._samples = this._engine.updateMultipleRenderTargetTextureSampleCount(this._internalTextures, value);
         }
 
+        /**
+         * Resize all the textures in the multi render target.
+         * Be carrefull as it will recreate all the data in the new texture.
+         * @param size Define the new size
+         */
         public resize(size: any) {
             this.releaseInternalTextures();
             this._internalTextures = this._engine.createMultipleRenderTarget(size, this._multiRenderTargetOptions);
@@ -148,12 +221,18 @@ module BABYLON {
             });
         }
 
+        /**
+         * Dispose the render targets and their associated resources
+         */
         public dispose(): void {
             this.releaseInternalTextures();
 
             super.dispose();
         }
 
+        /**
+         * Release all the underlying texture used as draw buffers.
+         */
         public releaseInternalTextures(): void {
             if (!this._internalTextures) {
                 return;

+ 92 - 2
src/Materials/Textures/babylon.rawTexture.ts

@@ -1,6 +1,27 @@
 module BABYLON {
+    /**
+     * Raw texture can help creating a texture directly from an array of data.
+     * This can be super useful if you either get the data from an uncompressed source or
+     * if you wish to create your texture pixel by pixel.
+     */
     export class RawTexture extends Texture {
         private _engine: Engine;
+
+        /**
+         * Instantiates a new RawTexture.
+         * Raw texture can help creating a texture directly from an array of data.
+         * This can be super useful if you either get the data from an uncompressed source or
+         * if you wish to create your texture pixel by pixel.
+         * @param data define the array of data to use to create the texture
+         * @param width define the width of the texture
+         * @param height define the height of the texture
+         * @param format define the format of the data (RGB, RGBA... Engine.TEXTUREFORMAT_xxx)
+         * @param scene  define the scene the texture belongs to
+         * @param generateMipMaps define whether mip maps should be generated or not
+         * @param invertY define if the data should be flipped on Y when uploaded to the GPU
+         * @param samplingMode define the texture sampling mode (Texture.xxx_SAMPLINGMODE)
+         * @param type define the format of the data (int, float... Engine.TEXTURETYPE_xxx)
+         */
         constructor(data: ArrayBufferView, width: number, height: number, public format: number, scene: Scene, generateMipMaps: boolean = true, invertY: boolean = false, samplingMode: number = Texture.TRILINEAR_SAMPLINGMODE, type: number = Engine.TEXTURETYPE_UNSIGNED_INT) {
             super(null, scene, !generateMipMaps, invertY);
             this._engine = scene.getEngine();
@@ -10,33 +31,102 @@
             this.wrapV = Texture.CLAMP_ADDRESSMODE;
         }
 
+        /**
+         * Updates the texture underlying data.
+         * @param data Define the new data of the texture
+         */
         public update(data: ArrayBufferView): void {
             this._engine.updateRawTexture(this._texture, data, this._texture!.format, this._texture!.invertY, undefined, this._texture!.type);
         }
 
-        // Statics
+        /**
+         * Creates a luminance texture from some data.
+         * @param data Define the texture data
+         * @param width Define the width of the texture
+         * @param height Define the height of the texture
+         * @param scene Define the scene the texture belongs to
+         * @param generateMipMaps Define whether or not to create mip maps for the texture
+         * @param invertY define if the data should be flipped on Y when uploaded to the GPU
+         * @param samplingMode define the texture sampling mode (Texture.xxx_SAMPLINGMODE)
+         * @returns the luminance texture
+         */
         public static CreateLuminanceTexture(data: ArrayBufferView, width: number, height: number, scene: Scene, generateMipMaps: boolean = true, invertY: boolean = false, samplingMode: number = Texture.TRILINEAR_SAMPLINGMODE): RawTexture {
             return new RawTexture(data, width, height, Engine.TEXTUREFORMAT_LUMINANCE, scene, generateMipMaps, invertY, samplingMode);
         }
 
+        /**
+         * Creates a luminance alpha texture from some data.
+         * @param data Define the texture data
+         * @param width Define the width of the texture
+         * @param height Define the height of the texture
+         * @param scene Define the scene the texture belongs to
+         * @param generateMipMaps Define whether or not to create mip maps for the texture
+         * @param invertY define if the data should be flipped on Y when uploaded to the GPU
+         * @param samplingMode define the texture sampling mode (Texture.xxx_SAMPLINGMODE)
+         * @returns the luminance alpha texture
+         */
         public static CreateLuminanceAlphaTexture(data: ArrayBufferView, width: number, height: number, scene: Scene, generateMipMaps: boolean = true, invertY: boolean = false, samplingMode: number = Texture.TRILINEAR_SAMPLINGMODE): RawTexture {
             return new RawTexture(data, width, height, Engine.TEXTUREFORMAT_LUMINANCE_ALPHA, scene, generateMipMaps, invertY, samplingMode);
         }
 
+        /**
+         * Creates an alpha texture from some data.
+         * @param data Define the texture data
+         * @param width Define the width of the texture
+         * @param height Define the height of the texture
+         * @param scene Define the scene the texture belongs to
+         * @param generateMipMaps Define whether or not to create mip maps for the texture
+         * @param invertY define if the data should be flipped on Y when uploaded to the GPU
+         * @param samplingMode define the texture sampling mode (Texture.xxx_SAMPLINGMODE)
+         * @returns the alpha texture
+         */
         public static CreateAlphaTexture(data: ArrayBufferView, width: number, height: number, scene: Scene, generateMipMaps: boolean = true, invertY: boolean = false, samplingMode: number = Texture.TRILINEAR_SAMPLINGMODE): RawTexture {
             return new RawTexture(data, width, height, Engine.TEXTUREFORMAT_ALPHA, scene, generateMipMaps, invertY, samplingMode);
         }
 
+        /**
+         * Creates a RGB texture from some data.
+         * @param data Define the texture data
+         * @param width Define the width of the texture
+         * @param height Define the height of the texture
+         * @param scene Define the scene the texture belongs to
+         * @param generateMipMaps Define whether or not to create mip maps for the texture
+         * @param invertY define if the data should be flipped on Y when uploaded to the GPU
+         * @param samplingMode define the texture sampling mode (Texture.xxx_SAMPLINGMODE)
+         * @returns the RGB alpha texture
+         */
         public static CreateRGBTexture(data: ArrayBufferView, width: number, height: number, scene: Scene, generateMipMaps: boolean = true, invertY: boolean = false, samplingMode: number = Texture.TRILINEAR_SAMPLINGMODE, type: number = Engine.TEXTURETYPE_UNSIGNED_INT): RawTexture {
             return new RawTexture(data, width, height, Engine.TEXTUREFORMAT_RGB, scene, generateMipMaps, invertY, samplingMode, type);
         }
 
+        /**
+         * Creates a RGBA texture from some data.
+         * @param data Define the texture data
+         * @param width Define the width of the texture
+         * @param height Define the height of the texture
+         * @param scene Define the scene the texture belongs to
+         * @param generateMipMaps Define whether or not to create mip maps for the texture
+         * @param invertY define if the data should be flipped on Y when uploaded to the GPU
+         * @param samplingMode define the texture sampling mode (Texture.xxx_SAMPLINGMODE)
+         * @returns the RGBA texture
+         */
         public static CreateRGBATexture(data: ArrayBufferView, width: number, height: number, scene: Scene, generateMipMaps: boolean = true, invertY: boolean = false, samplingMode: number = Texture.TRILINEAR_SAMPLINGMODE, type: number = Engine.TEXTURETYPE_UNSIGNED_INT): RawTexture {
             return new RawTexture(data, width, height, Engine.TEXTUREFORMAT_RGBA, scene, generateMipMaps, invertY, samplingMode, type);
         }
 
+        /**
+         * Creates a R texture from some data.
+         * @param data Define the texture data
+         * @param width Define the width of the texture
+         * @param height Define the height of the texture
+         * @param scene Define the scene the texture belongs to
+         * @param generateMipMaps Define whether or not to create mip maps for the texture
+         * @param invertY define if the data should be flipped on Y when uploaded to the GPU
+         * @param samplingMode define the texture sampling mode (Texture.xxx_SAMPLINGMODE)
+         * @returns the R texture
+         */
         public static CreateRTexture(data: ArrayBufferView, width: number, height: number, scene: Scene, generateMipMaps: boolean = true, invertY: boolean = false, samplingMode: number = Texture.TRILINEAR_SAMPLINGMODE, type: number = Engine.TEXTURETYPE_FLOAT): RawTexture {
             return new RawTexture(data, width, height, Engine.TEXTUREFORMAT_R, scene, generateMipMaps, invertY, samplingMode, type);
-        }        
+        }
     }
 }

+ 30 - 5
src/Materials/Textures/babylon.refractionTexture.ts

@@ -1,14 +1,31 @@
 module BABYLON {
     /**
-    * Creates a refraction texture used by refraction channel of the standard material.
-    * @param name the texture name
-    * @param size size of the underlying texture
-    * @param scene root scene
-    */
+     * Creates a refraction texture used by refraction channel of the standard material.
+     * It is like a mirror but to see through a material.
+     * @see https://doc.babylonjs.com/how_to/reflect#refraction
+     */
     export class RefractionTexture extends RenderTargetTexture {
+        /**
+         * Define the reflection plane we want to use. The refractionPlane is usually set to the constructed refractor. 
+         * It is possible to directly set the refractionPlane by directly using a BABYLON.Plane(a, b, c, d) where a, b and c give the plane normal vector (a, b, c) and d is a scalar displacement from the refractionPlane to the origin. However in all but the very simplest of situations it is more straight forward to set it to the refractor as stated in the doc.
+         * @see https://doc.babylonjs.com/how_to/reflect#refraction
+         */
         public refractionPlane = new Plane(0, 1, 0, 1);
+
+        /**
+         * Define how deep under the surface we should see.
+         */
         public depth = 2.0;
 
+        /**
+         * Creates a refraction texture used by refraction channel of the standard material.
+         * It is like a mirror but to see through a material.
+         * @see https://doc.babylonjs.com/how_to/reflect#refraction
+         * @param name Define the texture name
+         * @param size Define the size of the underlying texture
+         * @param scene Define the scene the refraction belongs to
+         * @param generateMipMaps Define if we need to generate mips level for the refraction
+         */
         constructor(name: string, size: number, scene: Scene, generateMipMaps?: boolean) {
             super(name, size, scene, generateMipMaps, true);
 
@@ -21,6 +38,10 @@
             });
         }
 
+        /**
+         * Clone the refraction texture.
+         * @returns the cloned texture
+         */
         public clone(): RefractionTexture {
             let scene = this.getScene();
 
@@ -45,6 +66,10 @@
             return newTexture;
         }
 
+        /**
+         * Serialize the texture to a JSON representation you could use in Parse later on
+         * @returns the serialized JSON representation
+         */
         public serialize(): any {
             if (!this.name) {
                 return null;

+ 21 - 1
src/Materials/Textures/babylon.videoTexture.ts

@@ -24,6 +24,11 @@
         poster?: string;
     }
 
+    /**
+     * If you want to display a video in your scene, this is the special texture for that. 
+     * This special texture works similar to other textures, with the exception of a few parameters.
+     * @see https://doc.babylonjs.com/how_to/video_texture
+     */
     export class VideoTexture extends Texture {
         /**
          * Tells whether textures will be updated automatically or user is required to call `updateTexture` manually
@@ -37,6 +42,10 @@
 
         private _onUserActionRequestedObservable: Nullable<Observable<Texture>> = null;
 
+        /**
+         * Event triggerd when a dom action is required by the user to play the video.
+         * This happens due to recent changes in browser policies preventing video to auto start.
+         */
         public get onUserActionRequestedObservable(): Observable<Texture> {
             if (!this._onUserActionRequestedObservable) {
                 this._onUserActionRequestedObservable = new Observable<Texture>();
@@ -51,7 +60,9 @@
 
         /**
          * Creates a video texture.
-         * Sample : https://doc.babylonjs.com/how_to/video_texture
+         * If you want to display a video in your scene, this is the special texture for that. 
+         * This special texture works similar to other textures, with the exception of a few parameters.
+         * @see https://doc.babylonjs.com/how_to/video_texture
          * @param {string | null} name optional name, will detect from video source, if not defined
          * @param {(string | string[] | HTMLVideoElement)} src can be used to provide an url, array of urls or an already setup HTML video element.
          * @param {BABYLON.Scene} scene is obviously the current scene.
@@ -279,6 +290,9 @@
             this.video.src = url;
         }
 
+        /**
+         * Dispose the texture and release its associated resources.
+         */
         public dispose(): void {
             super.dispose();
 
@@ -294,6 +308,12 @@
             this.video.pause();
         }
 
+        /**
+         * Creates a video texture straight from your WebCam video feed.
+         * @param scene Define the scene the texture should be created in
+         * @param onReady Define a callback to triggered once the texture will be ready
+         * @param constraints Define the constraints to use to create the web cam feed from WebRTC
+         */
         public static CreateFromWebCam(
             scene: Scene,
             onReady: (videoTexture: VideoTexture) => void,

+ 29 - 7
src/Math/babylon.math.ts

@@ -1880,10 +1880,7 @@
          * @returns the current updated Vector3  
          */
         public minimizeInPlace(other: Vector3): Vector3 {
-            if (other.x < this.x) this.x = other.x;
-            if (other.y < this.y) this.y = other.y;
-            if (other.z < this.z) this.z = other.z;
-            return this;
+            return this.minimizeInPlaceFromFloats(other.x, other.y, other.z);
         }
 
         /**
@@ -1892,9 +1889,34 @@
          * @returns the current updated Vector3
          */
         public maximizeInPlace(other: Vector3): Vector3 {
-            if (other.x > this.x) this.x = other.x;
-            if (other.y > this.y) this.y = other.y;
-            if (other.z > this.z) this.z = other.z;
+            return this.maximizeInPlaceFromFloats(other.x, other.y, other.z);
+        }
+
+        /**
+         * Updates the current Vector3 with the minimal coordinate values between its and the given coordinates
+         * @param x defines the x coordinate of the operand
+         * @param y defines the y coordinate of the operand
+         * @param z defines the z coordinate of the operand
+         * @returns the current updated Vector3  
+         */
+        public minimizeInPlaceFromFloats(x: number, y: number, z: number): Vector3 {
+            this.x = Math.min(this.x, x);
+            this.y = Math.min(this.y, y);
+            this.z = Math.min(this.z, z);
+            return this;
+        }
+
+        /**
+         * Updates the current Vector3 with the maximal coordinate values between its and the given coordinates.
+         * @param x defines the x coordinate of the operand
+         * @param y defines the y coordinate of the operand
+         * @param z defines the z coordinate of the operand
+         * @returns the current updated Vector3
+         */
+        public maximizeInPlaceFromFloats(x: number, y: number, z: number): Vector3 {
+            this.x = Math.max(this.x, x);
+            this.y = Math.max(this.y, y);
+            this.z = Math.max(this.z, z);
             return this;
         }
 

+ 8 - 8
src/Mesh/babylon.abstractMesh.ts

@@ -474,9 +474,6 @@
         /** @hidden */
         public _edgesRenderer: Nullable<IEdgesRenderer>;
 
-        // Cache
-        private _collisionsTransformMatrix = Matrix.Zero();
-        private _collisionsScalingMatrix = Matrix.Zero();
         /** @hidden */
         public _masterMesh: Nullable<AbstractMesh>;
         /** @hidden */
@@ -1045,9 +1042,10 @@
             if (!this.subMeshes) {
                 return this;
             }
-            for (var subIndex = 0; subIndex < this.subMeshes.length; subIndex++) {
+            let count = this.subMeshes.length;
+            for (var subIndex = 0; subIndex < count; subIndex++) {
                 var subMesh = this.subMeshes[subIndex];
-                if (!subMesh.IsGlobal) {
+                if (count > 1 || !subMesh.IsGlobal) {
                     subMesh.updateBoundingInfo(matrix);
                 }
             }
@@ -1261,9 +1259,11 @@
                 return this;
 
             // Transformation matrix
-            Matrix.ScalingToRef(1.0 / collider._radius.x, 1.0 / collider._radius.y, 1.0 / collider._radius.z, this._collisionsScalingMatrix);
-            this.worldMatrixFromCache.multiplyToRef(this._collisionsScalingMatrix, this._collisionsTransformMatrix);
-            this._processCollisionsForSubMeshes(collider, this._collisionsTransformMatrix);
+            const collisionsScalingMatrix = Tmp.Matrix[0];
+            const collisionsTransformMatrix = Tmp.Matrix[1];
+            Matrix.ScalingToRef(1.0 / collider._radius.x, 1.0 / collider._radius.y, 1.0 / collider._radius.z, collisionsScalingMatrix);
+            this.worldMatrixFromCache.multiplyToRef(collisionsScalingMatrix, collisionsTransformMatrix);
+            this._processCollisionsForSubMeshes(collider, collisionsTransformMatrix);
             return this;
         }
 

+ 28 - 0
src/Mesh/babylon.buffer.ts

@@ -1,4 +1,7 @@
 module BABYLON {
+    /**
+     * Class used to store data that will be store in GPU memory
+     */
     export class Buffer {
         private _engine: Engine;
         private _buffer: Nullable<WebGLBuffer>;
@@ -61,14 +64,27 @@
         }
 
         // Properties
+
+        /**
+         * Gets a boolean indicating if the Buffer is updatable?
+         * @returns true if the buffer is updatable
+         */
         public isUpdatable(): boolean {
             return this._updatable;
         }
 
+        /**
+         * Gets current buffer's data
+         * @returns a DataArray or null
+         */
         public getData(): Nullable<DataArray> {
             return this._data;
         }
 
+        /**
+         * Gets underlying native buffer
+         * @returns underlying native buffer
+         */
         public getBuffer(): Nullable<WebGLBuffer> {
             return this._buffer;
         }
@@ -84,6 +100,11 @@
         }
 
         // Methods
+
+        /**
+         * Store data into the buffer. If the buffer was already used it will be either recreated or updated depending on isUpdatable property
+         * @param data defines the data to store
+         */
         public create(data: Nullable<DataArray> = null): void {
             if (!data && this._buffer) {
                 return; // nothing to do
@@ -114,6 +135,10 @@
             this.create(this._data);
         }
 
+        /**
+         * Update current buffer data
+         * @param data defines the data to store
+         */
         public update(data: DataArray): void {
             this.create(data);
         }
@@ -136,6 +161,9 @@
             }
         }
 
+        /**
+         * Release all resources
+         */
         public dispose(): void {
             if (!this._buffer) {
                 return;

+ 8 - 4
src/Mesh/babylon.geometry.ts

@@ -61,11 +61,15 @@
          *  Gets or sets the Bias Vector to apply on the bounding elements (box/sphere), the max extend is computed as v += v * bias.x + bias.y, the min is computed as v -= v * bias.x + bias.y
          */
         public set boundingBias(value: Vector2) {
-            if (this._boundingBias && this._boundingBias.equals(value)) {
-                return;
+            if (this._boundingBias) {
+                if (this._boundingBias.equals(value)) {
+                    return;
+                }
+                this._boundingBias.copyFrom(value);
+            }
+            else {
+                this._boundingBias = value.clone();
             }
-
-            this._boundingBias = value.clone();
 
             this._updateBoundingInfo(true, null);
         }

+ 1 - 0
src/Mesh/babylon.mesh.ts

@@ -5,6 +5,7 @@
      **/
     export class _CreationDataStorage {
         public closePath?: boolean;
+        public closeArray?: boolean;
         public idx: number[];
         public dashSize: number;
         public gapSize: number;

+ 17 - 19
src/Mesh/babylon.meshBuilder.ts

@@ -211,7 +211,7 @@
                 };
                 var positions = <FloatArray>instance.getVerticesData(VertexBuffer.PositionKind);
                 positionFunction(positions);
-                instance._boundingInfo = new BoundingInfo(Tmp.Vector3[0], Tmp.Vector3[1]);
+                instance._boundingInfo = new BoundingInfo(Tmp.Vector3[2], Tmp.Vector3[3]);
                 instance._boundingInfo.update(instance._worldMatrix);
                 instance.updateVerticesData(VertexBuffer.PositionKind, positions, false, false);
                 if (options.colors) {
@@ -275,7 +275,7 @@
                     ribbon._creationDataStorage.idx = (<any>vertexData)._idx;
                 }
                 ribbon._creationDataStorage.closePath = closePath;
-                (<any>ribbon)._closeArray = closeArray;
+                ribbon._creationDataStorage.closeArray = closeArray;
 
                 vertexData.applyToMesh(ribbon, updatable);
 
@@ -1027,16 +1027,16 @@
             var path3D;
             var pathArray;
             if (instance) { // tube update
-                var arc = options.arc || (<any>instance).arc;
                 let storage = instance._creationDataStorage!;
+                var arc = options.arc || storage.arc;
                 path3D =  storage.path3D.update(path);
                 pathArray = tubePathArray(path, path3D, storage.pathArray, radius, storage.tessellation, radiusFunction, storage.cap, arc);
                 instance = MeshBuilder.CreateRibbon("", { pathArray: pathArray, instance: instance });
-                instance._creationDataStorage = new _CreationDataStorage();
-                instance._creationDataStorage.path3D = path3D;
-                instance._creationDataStorage.pathArray = pathArray;
-                instance._creationDataStorage.arc = arc;
-                instance._creationDataStorage.radius = radius;
+                // Update mode, no need to recreate the storage.
+                storage.path3D = path3D;
+                storage.pathArray = pathArray;
+                storage.arc = arc;
+                storage.radius = radius;
 
                 return instance;
             }
@@ -1047,13 +1047,12 @@
             cap = (cap < 0 || cap > 3) ? 0 : cap;
             pathArray = tubePathArray(path, path3D, newPathArray, radius, tessellation, radiusFunction, cap, options.arc);
             var tube = MeshBuilder.CreateRibbon(name, { pathArray: pathArray, closePath: true, closeArray: false, updatable: updatable, sideOrientation: sideOrientation, invertUV: invertUV, frontUVs: options.frontUVs, backUVs: options.backUVs }, scene);
-            tube._creationDataStorage = new _CreationDataStorage();
-            tube._creationDataStorage.pathArray = pathArray;
-            tube._creationDataStorage.path3D = path3D;
-            tube._creationDataStorage.tessellation = tessellation;
-            tube._creationDataStorage.cap = cap;
-            tube._creationDataStorage.arc = options.arc;
-            tube._creationDataStorage.radius = radius;
+            tube._creationDataStorage!.pathArray = pathArray;
+            tube._creationDataStorage!.path3D = path3D;
+            tube._creationDataStorage!.tessellation = tessellation;
+            tube._creationDataStorage!.cap = cap;
+            tube._creationDataStorage!.arc = options.arc;
+            tube._creationDataStorage!.radius = radius;
 
             return tube;
         }
@@ -1407,10 +1406,9 @@
             cap = (cap < 0 || cap > 3) ? 0 : cap;
             pathArray = extrusionPathArray(shape, curve, path3D, newShapePaths, scale, rotation, scaleFunction, rotateFunction, cap, custom);
             var extrudedGeneric = MeshBuilder.CreateRibbon(name, { pathArray: pathArray, closeArray: rbCA, closePath: rbCP, updatable: updtbl, sideOrientation: side, invertUV: invertUV, frontUVs: frontUVs || undefined, backUVs: backUVs || undefined }, scene);
-            extrudedGeneric._creationDataStorage = new _CreationDataStorage();
-            extrudedGeneric._creationDataStorage.pathArray = pathArray;
-            extrudedGeneric._creationDataStorage.path3D = path3D;
-            extrudedGeneric._creationDataStorage.cap = cap;
+            extrudedGeneric._creationDataStorage!.pathArray = pathArray;
+            extrudedGeneric._creationDataStorage!.path3D = path3D;
+            extrudedGeneric._creationDataStorage!.cap = cap;
 
             return extrudedGeneric;
         }

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

@@ -252,7 +252,7 @@
             if (!boundingInfo) {
                 return false;
             }
-            return boundingInfo.isInFrustum(frustumPlanes);
+            return boundingInfo.isInFrustum(frustumPlanes, this._mesh.cullingStrategy);
         }
 
         /**

+ 83 - 83
src/Mesh/babylon.vertexBuffer.ts

@@ -1,4 +1,7 @@
 module BABYLON {
+    /**
+     * Specialized buffer used to store vertex data
+     */
     export class VertexBuffer {
         /** @hidden */
         public _buffer: Buffer;
@@ -148,37 +151,44 @@
         }
 
         /**
-         * Returns the kind of the VertexBuffer (string).  
+         * Returns the kind of the VertexBuffer (string)
+         * @returns a string
          */
         public getKind(): string {
             return this._kind;
         }
 
         // Properties
+
         /**
-         * Boolean : is the VertexBuffer updatable ?
+         * Gets a boolean indicating if the VertexBuffer is updatable?
+         * @returns true if the buffer is updatable
          */
         public isUpdatable(): boolean {
             return this._buffer.isUpdatable();
         }
 
         /**
-         * Returns an array of numbers or a typed array containing the VertexBuffer data.  
+         * Gets current buffer's data
+         * @returns a DataArray or null
          */
         public getData(): Nullable<DataArray> {
             return this._buffer.getData();
         }
 
         /**
-         * Returns the WebGLBuffer associated to the VertexBuffer.  
+         * Gets underlying native buffer
+         * @returns underlying native buffer
          */
         public getBuffer(): Nullable<WebGLBuffer> {
             return this._buffer.getBuffer();
         }
 
         /**
-         * Returns the stride as a multiple of the type byte length.
+         * Gets the stride in float32 units (i.e. byte stride / 4).
+         * May not be an integer if the byte stride is not divisible by 4.
          * DEPRECATED. Use byteStride instead.
+         * @returns the stride in float32 units
          */
         public getStrideSize(): number {
             return this.byteStride / VertexBuffer.GetTypeByteLength(this.type);
@@ -187,20 +197,23 @@
         /**
          * Returns the offset as a multiple of the type byte length.
          * DEPRECATED. Use byteOffset instead.
+         * @returns the offset in bytes
          */
         public getOffset(): number {
             return this.byteOffset / VertexBuffer.GetTypeByteLength(this.type);
         }
 
         /**
-         * Returns the number of components per vertex attribute (integer).  
+         * Returns the number of components per vertex attribute (integer)
+         * @returns the size in float 
          */
         public getSize(): number {
             return this._size;
         }
 
         /**
-         * Boolean : is the WebGLBuffer of the VertexBuffer instanced now ?
+         * Gets a boolean indicating is the internal buffer of the VertexBuffer is instanced
+         * @returns true if this buffer is instanced
          */
         public getIsInstanced(): boolean {
             return this._instanced;
@@ -208,6 +221,7 @@
 
         /**
          * Returns the instancing divisor, zero for non-instanced (integer).  
+         * @returns a number
          */
         public getInstanceDivisor(): number {
             return this._instanceDivisor;
@@ -216,20 +230,20 @@
         // Methods
 
         /**
-         * Creates the underlying WebGLBuffer from the passed numeric array or Float32Array.  
-         * Returns the created WebGLBuffer.   
+         * Store data into the buffer. If the buffer was already used it will be either recreated or updated depending on isUpdatable property
+         * @param data defines the data to store
          */
         public create(data?: DataArray): void {
-            return this._buffer.create(data);
+            this._buffer.create(data);
         }
 
         /**
-         * Updates the underlying WebGLBuffer according to the passed numeric array or Float32Array.  
+         * Updates the underlying buffer according to the passed numeric array or Float32Array.  
          * This function will create a new buffer if the current one is not updatable
-         * Returns the updated WebGLBuffer.  
+         * @param data defines the data to store 
          */
         public update(data: DataArray): void {
-            return this._buffer.update(data);
+            this._buffer.update(data);
         }
 
         /**
@@ -262,76 +276,62 @@
         }
 
         // Enums
-        private static _PositionKind = "position";
-        private static _NormalKind = "normal";
-        private static _TangentKind = "tangent";
-        private static _UVKind = "uv";
-        private static _UV2Kind = "uv2";
-        private static _UV3Kind = "uv3";
-        private static _UV4Kind = "uv4";
-        private static _UV5Kind = "uv5";
-        private static _UV6Kind = "uv6";
-        private static _ColorKind = "color";
-        private static _MatricesIndicesKind = "matricesIndices";
-        private static _MatricesWeightsKind = "matricesWeights";
-        private static _MatricesIndicesExtraKind = "matricesIndicesExtra";
-        private static _MatricesWeightsExtraKind = "matricesWeightsExtra";
-
-        public static get PositionKind(): string {
-            return VertexBuffer._PositionKind;
-        }
-
-        public static get NormalKind(): string {
-            return VertexBuffer._NormalKind;
-        }
-
-        public static get TangentKind(): string {
-            return VertexBuffer._TangentKind;
-        }
-
-        public static get UVKind(): string {
-            return VertexBuffer._UVKind;
-        }
-
-        public static get UV2Kind(): string {
-            return VertexBuffer._UV2Kind;
-        }
-
-        public static get UV3Kind(): string {
-            return VertexBuffer._UV3Kind;
-        }
-
-        public static get UV4Kind(): string {
-            return VertexBuffer._UV4Kind;
-        }
-
-        public static get UV5Kind(): string {
-            return VertexBuffer._UV5Kind;
-        }
-
-        public static get UV6Kind(): string {
-            return VertexBuffer._UV6Kind;
-        }
-
-        public static get ColorKind(): string {
-            return VertexBuffer._ColorKind;
-        }
-
-        public static get MatricesIndicesKind(): string {
-            return VertexBuffer._MatricesIndicesKind;
-        }
-
-        public static get MatricesWeightsKind(): string {
-            return VertexBuffer._MatricesWeightsKind;
-        }
-
-        public static get MatricesIndicesExtraKind(): string {
-            return VertexBuffer._MatricesIndicesExtraKind;
-        }
-
-        public static get MatricesWeightsExtraKind(): string {
-            return VertexBuffer._MatricesWeightsExtraKind;
-        }
+        /**
+         * Positions
+         */
+        public static readonly PositionKind = "position";
+        /**
+         * Normals
+         */
+        public static readonly NormalKind = "normal";
+        /**
+         * Tangents
+         */
+        public static readonly TangentKind = "tangent";
+        /**
+         * Texture coordinates
+         */
+        public static readonly UVKind = "uv";
+        /**
+         * Texture coordinates 2
+         */
+        public static readonly UV2Kind = "uv2";
+        /**
+         * Texture coordinates 3
+         */
+        public static readonly UV3Kind = "uv3";
+        /**
+         * Texture coordinates 4
+         */
+        public static readonly UV4Kind = "uv4";
+        /**
+         * Texture coordinates 5
+         */
+        public static readonly UV5Kind = "uv5";
+        /**
+         * Texture coordinates 6
+         */
+        public static readonly UV6Kind = "uv6";
+        /**
+         * Colors
+         */
+        public static readonly ColorKind = "color";
+        /**
+         * Matrix indices (for bones)
+         */
+        public static readonly MatricesIndicesKind = "matricesIndices";
+        /**
+         * Matrix weights (for bones)
+         */
+        public static readonly MatricesWeightsKind = "matricesWeights";
+        /**
+         * Additional matrix indices (for bones)
+         */
+        public static readonly MatricesIndicesExtraKind = "matricesIndicesExtra";
+        /**
+         * Additional matrix weights (for bones)
+         */
+        public static readonly MatricesWeightsExtraKind = "matricesWeightsExtra";
 
         /**
          * Deduces the stride given a kind.

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

@@ -81,6 +81,7 @@
 
         /** @hidden */
         public _initialStartSpriteCellID: number;
+        /** @hidden */
         public _initialEndSpriteCellID: number;
 
         /** @hidden */

+ 2 - 1
src/Particles/babylon.particleHelper.ts

@@ -88,7 +88,8 @@ module BABYLON {
         /**
          * Static function used to export a particle system to a ParticleSystemSet variable.
          * Please note that the emitter shape is not exported
-         * @param system defines the particle systems to export
+         * @param systems defines the particle systems to export
+         * @returns the created particle system set
          */
         public static ExportSet(systems: IParticleSystem[]): ParticleSystemSet {
             var set = new ParticleSystemSet();

+ 27 - 22
src/Particles/babylon.particleSystem.ts

@@ -655,17 +655,6 @@
             }
 
             this._addFactorGradient(this._emitRateGradients, gradient, factor, factor2);
-
-            if (!this._currentEmitRateGradient) {
-                this._currentEmitRateGradient = this._emitRateGradients[0];
-                this._currentEmitRate1 = this._currentEmitRateGradient.getFactor();
-                this._currentEmitRate2 = this._currentEmitRate1;
-            }
-
-            if (this._emitRateGradients.length === 2) {
-                this._currentEmitRate2 = this._emitRateGradients[1].getFactor();
-            }
-
             return this;
         }
 
@@ -693,17 +682,6 @@
             }
 
             this._addFactorGradient(this._startSizeGradients, gradient, factor, factor2);
-
-            if (!this._currentStartSizeGradient) {
-                this._currentStartSizeGradient = this._startSizeGradients[0];
-                this._currentStartSize1 = this._currentStartSizeGradient.getFactor();
-                this._currentStartSize2 = this._currentStartSize1;
-            }
-
-            if (this._startSizeGradients.length === 2) {
-                this._currentStartSize2 = this._startSizeGradients[1].getFactor();
-            }
-
             return this;
         }
 
@@ -809,6 +787,7 @@
          * @param gradient defines the gradient to use (between 0 and 1)
          * @param color1 defines the color to affect to the specified gradient
          * @param color2 defines an additional color used to define a range ([color, color2]) with main color to pick the final color from
+         * @returns this particle system
          */
         public addColorGradient(gradient: number, color1: Color4, color2?: Color4): IParticleSystem {
             if (!this._colorGradients) {
@@ -837,6 +816,7 @@
         /**
          * Remove a specific color gradient
          * @param gradient defines the gradient to remove
+         * @returns this particle system
          */
         public removeColorGradient(gradient: number): IParticleSystem {
             if (!this._colorGradients) {
@@ -1033,6 +1013,29 @@
                 this.activeSubSystems = new Array<ParticleSystem>();
             }
 
+            // Reset emit gradient so it acts the same on every start
+            if(this._emitRateGradients){
+                if(this._emitRateGradients.length > 0){
+                    this._currentEmitRateGradient = this._emitRateGradients[0];
+                    this._currentEmitRate1 = this._currentEmitRateGradient.getFactor();
+                    this._currentEmitRate2 = this._currentEmitRate1;
+                }
+                if(this._emitRateGradients.length > 1){
+                    this._currentEmitRate2 = this._emitRateGradients[1].getFactor();
+                }
+            }
+            // Reset start size gradient so it acts the same on every start
+            if(this._startSizeGradients){
+                if(this._startSizeGradients.length > 0){
+                    this._currentStartSizeGradient = this._startSizeGradients[0];
+                    this._currentStartSize1 = this._currentStartSizeGradient.getFactor();
+                    this._currentStartSize2 = this._currentStartSize1;
+                }
+                if(this._startSizeGradients.length > 1){
+                    this._currentStartSize2 = this._startSizeGradients[1].getFactor();
+                }
+            }
+
             if (this.preWarmCycles) {
                 if (this.emitter instanceof AbstractMesh) {
                     this.emitter.computeWorldMatrix(true);
@@ -1451,6 +1454,7 @@
             return attributeNamesOrOptions;
         }
 
+        /** @hidden */
         public static _GetEffectCreationOptions(isAnimationSheetEnabled = false): string[] {
             var effectCreationOption = ["invView", "view", "projection", "vClipPlane", "vClipPlane2", "vClipPlane3", "vClipPlane4", "textureMask", "translationPivot", "eyePosition"];
 
@@ -1461,6 +1465,7 @@
             return effectCreationOption;
         }
 
+        /** @hidden */
         private _getEffect(blendMode: number): Effect {
             if (this._customEffect) {
                 return this._customEffect;

+ 2 - 0
src/PostProcess/RenderPipeline/Pipelines/babylon.defaultRenderingPipeline.ts

@@ -11,10 +11,12 @@
 		 */
         private readonly SharpenPostProcessId: string = "SharpenPostProcessEffect";
         /**
+         * @ignore
 		 * ID of the image processing post process;
 		 */
         readonly ImageProcessingPostProcessId: string = "ImageProcessingPostProcessEffect";
         /**
+         * @ignore
 		 * ID of the Fast Approximate Anti-Aliasing post process;
 		 */
         readonly FxaaPostProcessId: string = "FxaaPostProcessEffect";

+ 6 - 0
src/PostProcess/RenderPipeline/Pipelines/babylon.standardRenderingPipeline.ts

@@ -1,4 +1,9 @@
 module BABYLON {
+    /**
+     * Standard rendering pipeline
+     * Default pipeline should be used going forward but the standard pipeline will be kept for backwards compatibility.
+     * @see https://doc.babylonjs.com/how_to/using_standard_rendering_pipeline
+     */
     export class StandardRenderingPipeline extends PostProcessRenderPipeline implements IDisposable, IAnimatable {
         /**
         * Public members
@@ -433,6 +438,7 @@
         }
 
         /**
+         * Default pipeline should be used going forward but the standard pipeline will be kept for backwards compatibility.
          * @constructor
          * @param {string} name - The rendering pipeline name
          * @param {BABYLON.Scene} scene - The scene linked to this pipeline

+ 29 - 0
src/PostProcess/RenderPipeline/babylon.postProcessRenderPipeline.ts

@@ -1,15 +1,27 @@
 module BABYLON {
+    /**
+     * PostProcessRenderPipeline
+     * @see https://doc.babylonjs.com/how_to/how_to_use_postprocessrenderpipeline
+     */
     export class PostProcessRenderPipeline {
 
         private _renderEffects: { [key: string]: PostProcessRenderEffect };
         private _renderEffectsForIsolatedPass: PostProcessRenderEffect[];
 
+        /**
+         * @hidden
+         */
         protected _cameras: Camera[];
 
         /** @hidden */
         @serialize()
         public _name: string;
 
+        /**
+         * Initializes a PostProcessRenderPipeline
+         * @param engine engine to add the pipeline to
+         * @param name name of the pipeline
+         */
         constructor(private engine: Engine, name: string) {
             this._name = name;
 
@@ -19,10 +31,17 @@ module BABYLON {
             this._cameras = [];
         }
 
+        /**
+         * "PostProcessRenderPipeline"
+         * @returns "PostProcessRenderPipeline"
+         */
         public getClassName(): string {
             return "PostProcessRenderPipeline";
         }
 
+        /**
+         * If all the render effects in the pipeline are support
+         */
         public get isSupported(): boolean {
             for (var renderEffectName in this._renderEffects) {
                 if (this._renderEffects.hasOwnProperty(renderEffectName)) {
@@ -35,6 +54,10 @@ module BABYLON {
             return true;
         }
 
+        /**
+         * Adds an effect to the pipeline
+         * @param renderEffect the effect to add
+         */
         public addEffect(renderEffect: PostProcessRenderEffect): void {
             (<any>this._renderEffects)[renderEffect._name] = renderEffect;
         }
@@ -61,8 +84,11 @@ module BABYLON {
             renderEffects._enable(Tools.MakeArray(cameras || this._cameras));
         }
 
+        /** @hidden */
         public _disableEffect(renderEffectName: string, cameras: Nullable<Camera[]>): void;
+        /** @hidden */
         public _disableEffect(renderEffectName: string, cameras: Nullable<Camera[]>): void;
+        /** @hidden */
         public _disableEffect(renderEffectName: string, cameras: Nullable<Camera[]>): void {
             var renderEffects: PostProcessRenderEffect = (<any>this._renderEffects)[renderEffectName];
 
@@ -168,6 +194,9 @@ module BABYLON {
             return false;
         }
 
+        /**
+         * Disposes of the pipeline
+         */
         public dispose() {
             // Must be implemented by children 
         }

+ 45 - 12
src/PostProcess/RenderPipeline/babylon.postProcessRenderPipelineManager.ts

@@ -1,18 +1,34 @@
 module BABYLON {
+    /**
+     * PostProcessRenderPipelineManager class
+     * @see https://doc.babylonjs.com/how_to/how_to_use_postprocessrenderpipeline
+     */
     export class PostProcessRenderPipelineManager {
         private _renderPipelines: { [Key: string]: PostProcessRenderPipeline };
 
+        /**
+         * Initializes a PostProcessRenderPipelineManager
+         * @see https://doc.babylonjs.com/how_to/how_to_use_postprocessrenderpipeline
+         */
         constructor() {
             this._renderPipelines = {};
         }
 
+        /**
+         * Adds a pipeline to the manager
+         * @param renderPipeline The pipeline to add
+         */
         public addPipeline(renderPipeline: PostProcessRenderPipeline): void {
             this._renderPipelines[renderPipeline._name] = renderPipeline;
         }
 
-        public attachCamerasToRenderPipeline(renderPipelineName: string, cameras: Camera, unique?: boolean): void;
-        public attachCamerasToRenderPipeline(renderPipelineName: string, cameras: Camera[], unique?: boolean): void;
-        public attachCamerasToRenderPipeline(renderPipelineName: string, cameras: any, unique: boolean = false): void {
+        /**
+         * Attaches a camera to the pipeline
+         * @param renderPipelineName The name of the pipeline to attach to
+         * @param cameras the camera to attach
+         * @param unique if the camera can be attached multiple times to the pipeline
+         */
+        public attachCamerasToRenderPipeline(renderPipelineName: string, cameras: any | Camera[] | Camera, unique: boolean = false): void {
             var renderPipeline: PostProcessRenderPipeline = this._renderPipelines[renderPipelineName];
 
             if (!renderPipeline) {
@@ -22,9 +38,12 @@ module BABYLON {
             renderPipeline._attachCameras(cameras, unique);
         }
 
-        public detachCamerasFromRenderPipeline(renderPipelineName: string, cameras: Camera): void;
-        public detachCamerasFromRenderPipeline(renderPipelineName: string, cameras: Camera[]): void;
-        public detachCamerasFromRenderPipeline(renderPipelineName: string, cameras: any): void {
+        /**
+         * Detaches a camera from the pipeline
+         * @param renderPipelineName The name of the pipeline to detach from
+         * @param cameras the camera to detach
+         */
+        public detachCamerasFromRenderPipeline(renderPipelineName: string, cameras: any | Camera[] | Camera): void {
             var renderPipeline: PostProcessRenderPipeline = this._renderPipelines[renderPipelineName];
 
             if (!renderPipeline) {
@@ -34,9 +53,13 @@ module BABYLON {
             renderPipeline._detachCameras(cameras);
         }
 
-        public enableEffectInPipeline(renderPipelineName: string, renderEffectName: string, cameras: Camera): void;
-        public enableEffectInPipeline(renderPipelineName: string, renderEffectName: string, cameras: Camera[]): void;
-        public enableEffectInPipeline(renderPipelineName: string, renderEffectName: string, cameras: any): void {
+        /**
+         * Enables an effect by name on a pipeline
+         * @param renderPipelineName the name of the pipeline to enable the effect in
+         * @param renderEffectName the name of the effect to enable
+         * @param cameras the cameras that the effect should be enabled on
+         */
+        public enableEffectInPipeline(renderPipelineName: string, renderEffectName: string, cameras: any | Camera[] | Camera): void {
             var renderPipeline: PostProcessRenderPipeline = this._renderPipelines[renderPipelineName];
 
             if (!renderPipeline) {
@@ -46,9 +69,13 @@ module BABYLON {
             renderPipeline._enableEffect(renderEffectName, cameras);
         }
 
-        public disableEffectInPipeline(renderPipelineName: string, renderEffectName: string, cameras: Camera): void;
-        public disableEffectInPipeline(renderPipelineName: string, renderEffectName: string, cameras: Camera[]): void;
-        public disableEffectInPipeline(renderPipelineName: string, renderEffectName: string, cameras: any): void {
+        /**
+         * Disables an effect by name on a pipeline
+         * @param renderPipelineName the name of the pipeline to disable the effect in
+         * @param renderEffectName the name of the effect to disable
+         * @param cameras the cameras that the effect should be disabled on
+         */
+        public disableEffectInPipeline(renderPipelineName: string, renderEffectName: string, cameras: any | Camera[] | Camera): void {
             var renderPipeline: PostProcessRenderPipeline = this._renderPipelines[renderPipelineName];
 
             if (!renderPipeline) {
@@ -58,6 +85,9 @@ module BABYLON {
             renderPipeline._disableEffect(renderEffectName, cameras);
         }
 
+        /**
+         * Updates the state of all contained render pipelines and disposes of any non supported pipelines
+         */
         public update(): void {
             for (var renderPipelineName in this._renderPipelines) {
                 if (this._renderPipelines.hasOwnProperty(renderPipelineName)) {
@@ -82,6 +112,9 @@ module BABYLON {
             }
         }
 
+        /**
+         * Disposes of the manager and pipelines
+         */
         public dispose(): void {
             for (var renderPipelineName in this._renderPipelines) {
                 if (this._renderPipelines.hasOwnProperty(renderPipelineName)) {

+ 16 - 0
src/PostProcess/babylon.blackAndWhitePostProcess.ts

@@ -1,8 +1,24 @@
 module BABYLON {
 
+    /**
+     * Post process used to render in black and white
+     */
     export class BlackAndWhitePostProcess extends PostProcess {
+        /**
+         * Linear about to convert he result to black and white (default: 1)
+         */
         public degree = 1;
     
+        /**
+         * Creates a black and white post process
+         * @see https://doc.babylonjs.com/how_to/how_to_use_postprocesses#black-and-white
+         * @param name The name of the effect.
+         * @param options The required width/height ratio to downsize to before computing the render pass.
+         * @param camera The camera to apply the render pass to.
+         * @param samplingMode The sampling mode to be used when computing the pass. (default: 0)
+         * @param engine The engine which the post process will be applied. (default: current engine)
+         * @param reusable If the post process can be reused on the same frame. (default: false)
+         */
         constructor(name: string, options: number | PostProcessOptions, camera: Camera, samplingMode?: number, engine?: Engine, reusable?: boolean) {
             super(name, "blackAndWhite", ["degree"], null, options, camera, samplingMode, engine, reusable);
 

+ 13 - 0
src/PostProcess/babylon.displayPassPostProcess.ts

@@ -1,5 +1,18 @@
 module BABYLON {
+
+    /**
+     * DisplayPassPostProcess which produces an output the same as it's input
+     */
     export class DisplayPassPostProcess extends PostProcess {
+        /**
+         * Creates the DisplayPassPostProcess
+         * @param name The name of the effect.
+         * @param options The required width/height ratio to downsize to before computing the render pass.
+         * @param camera The camera to apply the render pass to.
+         * @param samplingMode The sampling mode to be used when computing the pass. (default: 0)
+         * @param engine The engine which the post process will be applied. (default: current engine)
+         * @param reusable If the post process can be reused on the same frame. (default: false)
+         */
         constructor(name: string, options: number | PostProcessOptions, camera: Nullable<Camera>, samplingMode?: number, engine?: Engine, reusable?: boolean) {
             super(name, "displayPass", ["passSampler"], ["passSampler"], options, camera, samplingMode, engine, reusable);
         }

+ 22 - 1
src/PostProcess/babylon.filterPostProcess.ts

@@ -1,6 +1,27 @@
 module BABYLON {
+    /**
+     * Applies a kernel filter to the image
+     */
     export class FilterPostProcess extends PostProcess {
-        constructor(name: string, public kernelMatrix: Matrix, options: number | PostProcessOptions, camera: Nullable<Camera>, samplingMode?: number, engine?: Engine, reusable?: boolean) {
+        /**
+         * 
+         * @param name The name of the effect.
+         * @param kernelMatrix The matrix to be applied to the image
+         * @param options The required width/height ratio to downsize to before computing the render pass.
+         * @param camera The camera to apply the render pass to.
+         * @param samplingMode The sampling mode to be used when computing the pass. (default: 0)
+         * @param engine The engine which the post process will be applied. (default: current engine)
+         * @param reusable If the post process can be reused on the same frame. (default: false)
+         */
+        constructor(name: string,
+            /** The matrix to be applied to the image */
+            public kernelMatrix: Matrix, 
+            options: number | PostProcessOptions, 
+            camera: Nullable<Camera>, 
+            samplingMode?: number, 
+            engine?: Engine, 
+            reusable?: boolean
+        ) {
             super(name, "filter", ["kernelMatrix"], null, options, camera, samplingMode, engine, reusable);
 
             this.onApply = (effect: Effect) => {

+ 15 - 0
src/PostProcess/babylon.highlightsPostProcess.ts

@@ -1,5 +1,20 @@
 module BABYLON {
+    /**
+     * Extracts highlights from the image
+     * @see https://doc.babylonjs.com/how_to/how_to_use_postprocesses
+     */
     export class HighlightsPostProcess extends PostProcess {
+        /**
+         * Extracts highlights from the image
+         * @see https://doc.babylonjs.com/how_to/how_to_use_postprocesses 
+         * @param name The name of the effect.
+         * @param options The required width/height ratio to downsize to before computing the render pass.
+         * @param camera The camera to apply the render pass to.
+         * @param samplingMode The sampling mode to be used when computing the pass. (default: 0)
+         * @param engine The engine which the post process will be applied. (default: current engine)
+         * @param reusable If the post process can be reused on the same frame. (default: false)
+         * @param textureType Type of texture for the post process (default: Engine.TEXTURETYPE_UNSIGNED_INT)
+         */
         constructor(name: string, options: number | PostProcessOptions, camera: Nullable<Camera>, samplingMode?: number, engine?: Engine, reusable?: boolean, textureType: number = Engine.TEXTURETYPE_UNSIGNED_INT) {
             super(name, "highlights", null, null, options, camera, samplingMode, engine, reusable, null, textureType);
         }

+ 8 - 1
src/PostProcess/babylon.imageProcessingPostProcess.ts

@@ -1,4 +1,8 @@
 module BABYLON {
+    /**
+     * ImageProcessingPostProcess
+     * @see https://doc.babylonjs.com/how_to/how_to_use_postprocesses#imageprocessing
+     */
     export class ImageProcessingPostProcess extends PostProcess {
 
         /**
@@ -337,7 +341,10 @@
                 this.imageProcessingConfiguration.bind(effect, this.aspectRatio);
             };
         }
-
+        /**
+         *  "ImageProcessingPostProcess"
+         * @returns "ImageProcessingPostProcess"
+         */
         public getClassName(): string {
             return "ImageProcessingPostProcess";
         }

+ 3 - 0
src/PostProcess/babylon.postProcess.ts

@@ -1,4 +1,7 @@
 module BABYLON {
+    /**
+     * Size options for a post process
+     */
     export type PostProcessOptions = { width: number, height: number };
 
     /**

+ 38 - 2
src/PostProcess/babylon.refractionPostProcess.ts

@@ -1,4 +1,8 @@
 module BABYLON {
+    /**
+     * Post process which applies a refractin texture
+     * @see https://doc.babylonjs.com/how_to/how_to_use_postprocesses#refraction
+     */
     export class RefractionPostProcess extends PostProcess {
         private _refTexture: Texture;
         private _ownRefractionTexture = true;
@@ -19,8 +23,36 @@
             this._refTexture = value;
             this._ownRefractionTexture = false;
         }
-
-        constructor(name: string, refractionTextureUrl: string, public color: Color3, public depth: number, public colorLevel: number, options: number | PostProcessOptions, camera: Camera, samplingMode?: number, engine?: Engine, reusable?: boolean) {
+        
+        /**
+         * Initializes the RefractionPostProcess
+         * @see https://doc.babylonjs.com/how_to/how_to_use_postprocesses#refraction
+         * @param name The name of the effect.
+         * @param refractionTextureUrl Url of the refraction texture to use
+         * @param color the base color of the refraction (used to taint the rendering)
+         * @param depth simulated refraction depth
+         * @param colorLevel the coefficient of the base color (0 to remove base color tainting)
+         * @param camera The camera to apply the render pass to.
+         * @param options The required width/height ratio to downsize to before computing the render pass.
+         * @param samplingMode The sampling mode to be used when computing the pass. (default: 0)
+         * @param engine The engine which the post process will be applied. (default: current engine)
+         * @param reusable If the post process can be reused on the same frame. (default: false)
+         */
+        constructor(
+            name: string, 
+            refractionTextureUrl: string, 
+            /** the base color of the refraction (used to taint the rendering) */
+            public color: Color3, 
+            /** simulated refraction depth */
+            public depth: number, 
+            /** the coefficient of the base color (0 to remove base color tainting) */
+            public colorLevel: number, 
+            options: number | PostProcessOptions, 
+            camera: Camera, 
+            samplingMode?: number, 
+            engine?: Engine, 
+            reusable?: boolean
+        ) {
             super(name, "refraction", ["baseColor", "depth", "colorLevel"], ["refractionSampler"], options, camera, samplingMode, engine, reusable);
 
             this.onActivateObservable.add((cam: Camera) => {
@@ -37,6 +69,10 @@
         }
 
         // Methods
+        /**
+         * Disposes of the post process
+         * @param camera Camera to dispose post process on
+         */
         public dispose(camera: Camera): void {
             if (this._refTexture && this._ownRefractionTexture) {
                 this._refTexture.dispose();

+ 12 - 0
src/PostProcess/babylon.stereoscopicInterlacePostProcess.ts

@@ -1,8 +1,20 @@
 module BABYLON {
+    /**
+     * StereoscopicInterlacePostProcess used to render stereo views from a rigged camera
+     */
     export class StereoscopicInterlacePostProcess extends PostProcess {
         private _stepSize : Vector2;
         private _passedProcess : Nullable<PostProcess>;
 
+        /**
+         * Initializes a StereoscopicInterlacePostProcess
+         * @param name The name of the effect.
+         * @param rigCameras The rig cameras to be appled to the post process
+         * @param isStereoscopicHoriz If the rendered results are horizontal or verticle
+         * @param samplingMode The sampling mode to be used when computing the pass. (default: 0)
+         * @param engine The engine which the post process will be applied. (default: current engine)
+         * @param reusable If the post process can be reused on the same frame. (default: false)
+         */
         constructor(name: string, rigCameras: Camera[], isStereoscopicHoriz: boolean, samplingMode?: number, engine?: Engine, reusable?: boolean) {
             super(name, "stereoscopicInterlace", ['stepSize'], ['camASampler'], 1, rigCameras[1], samplingMode, engine, reusable, isStereoscopicHoriz ? "#define IS_STEREOSCOPIC_HORIZ 1" : undefined);
             

+ 10 - 0
src/PostProcess/babylon.vrDistortionCorrectionPostProcess.ts

@@ -1,4 +1,7 @@
 module BABYLON {
+    /**
+     * VRDistortionCorrectionPostProcess used for mobile VR 
+     */
     export class VRDistortionCorrectionPostProcess extends PostProcess {
         private _isRightEye: boolean;
         private _distortionFactors: number[];
@@ -8,6 +11,13 @@
         private _scaleFactor: Vector2;
         private _lensCenter: Vector2;
 
+        /**
+         * Initializes the VRDistortionCorrectionPostProcess
+         * @param name The name of the effect.
+         * @param camera The camera to apply the render pass to.
+         * @param isRightEye If this is for the right eye distortion
+         * @param vrMetrics All the required metrics for the VR camera
+         */
         constructor(name: string, camera: Camera, isRightEye: boolean, vrMetrics: VRCameraMetrics) {
             super(name, "vrDistortionCorrection", [
                 'LensCenter',

+ 1 - 1
src/Shaders/gpuUpdateParticles.vertex.fx

@@ -313,7 +313,7 @@ void main() {
     float power = emitPower.x + (emitPower.y - emitPower.x) * randoms.a;
 
     outPosition = (emitterWM * vec4(position, 1.)).xyz;
-    vec3 initial = (emitterWM * vec4(normalize(direction), 0.)).xyz;
+    vec3 initial = (emitterWM * vec4(direction, 0.)).xyz;
     outDirection = initial * power;
 #ifndef BILLBOARD        
     outInitialDirection = initial;

+ 13 - 10
src/Tools/babylon.tools.ts

@@ -503,10 +503,12 @@
             var maximum = new Vector3(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE);
 
             for (var index = indexStart; index < indexStart + indexCount; index++) {
-                var current = new Vector3(positions[indices[index] * 3], positions[indices[index] * 3 + 1], positions[indices[index] * 3 + 2]);
-
-                minimum = Vector3.Minimize(current, minimum);
-                maximum = Vector3.Maximize(current, maximum);
+                const offset = indices[index] * 3;
+                const x = positions[offset];
+                const y = positions[offset + 1];
+                const z = positions[offset + 2];
+                minimum.minimizeInPlaceFromFloats(x, y, z);
+                maximum.maximizeInPlaceFromFloats(x, y, z);
             }
 
             if (bias) {
@@ -541,12 +543,13 @@
                 stride = 3;
             }
 
-            for (var index = start; index < start + count; index++) {
-                var current = new Vector3(positions[index * stride], positions[index * stride + 1], positions[index * stride + 2]);
-
-                minimum = Vector3.Minimize(current, minimum);
-                maximum = Vector3.Maximize(current, maximum);
-            }
+            for (var index = start, offset = start*stride; index < start + count; index++, offset+=stride) {
+                const x = positions[offset];
+                const y = positions[offset + 1];
+                const z = positions[offset + 2];
+                minimum.minimizeInPlaceFromFloats(x, y, z);
+                maximum.maximizeInPlaceFromFloats(x, y, z);
+              }
 
             if (bias) {
                 minimum.x -= minimum.x * bias.x + bias.y;

+ 26 - 15
src/babylon.node.ts

@@ -110,6 +110,9 @@
         /** @hidden */
         public _worldMatrixDeterminant = 0;        
 
+        /** @hidden */
+        private _sceneRootNodesIndex = -1;
+
         /**
          * Gets a boolean indicating if the node has been disposed
          * @returns true if the node was disposed
@@ -136,8 +139,7 @@
                 }
 
                 if (!parent) {
-                    // Need to add this node to the rootNodes
-                    this._scene.rootNodes.push(this);
+                    this.addToSceneRootNodes();
                 }
             }
 
@@ -152,12 +154,7 @@
                 this._parentNode._children.push(this);
 
                 if (!previousParentNode) {
-                    // Need to remove from rootNodes
-                    const rootNodeIndex = this._scene.rootNodes.indexOf(this);
-
-                    if (rootNodeIndex > -1) {
-                        this._scene.rootNodes.splice(rootNodeIndex, 1);
-                    }
+                    this.removeFromSceneRootNodes();
                 }
             }
 
@@ -168,7 +165,25 @@
         public get parent(): Nullable<Node> {
             return this._parentNode;
         }
-        
+
+        private addToSceneRootNodes() {
+            if (this._sceneRootNodesIndex === -1) {
+                this._sceneRootNodesIndex = this._scene.rootNodes.length;
+                this._scene.rootNodes.push(this);
+            }
+        }
+
+        private removeFromSceneRootNodes() {
+            if (this._sceneRootNodesIndex !== -1) {
+                const rootNodes = this._scene.rootNodes;
+                const lastIdx = rootNodes.length - 1;
+                rootNodes[this._sceneRootNodesIndex] = rootNodes[lastIdx];
+                rootNodes[this._sceneRootNodesIndex]._sceneRootNodesIndex = this._sceneRootNodesIndex;
+                this._scene.rootNodes.pop();
+                this._sceneRootNodesIndex = -1;
+            }
+        }
+
         private _animationPropertiesOverride: Nullable<AnimationPropertiesOverride> = null;
 
         /**
@@ -221,7 +236,7 @@
             this.uniqueId = this._scene.getUniqueId();
             this._initCache();
 
-            this._scene.rootNodes.push(this);
+            this.addToSceneRootNodes();
         }
 
         /**
@@ -684,11 +699,7 @@
             }
 
             if (!this.parent) {
-                const rootNodeIndex = this._scene.rootNodes.indexOf(this);
-
-                if (rootNodeIndex > -1) {
-                    this._scene.rootNodes.splice(rootNodeIndex, 1);
-                }
+                this.removeFromSceneRootNodes();
             } else {
                 this.parent = null;
             }

BIN
tests/validation/ReferenceImages/ribbon morphing.png


+ 6 - 0
tests/validation/config.json

@@ -2,6 +2,12 @@
   "root": "https://rawgit.com/BabylonJS/Website/master",
   "tests": [
     {
+      "title": "Ribbon morphing",
+      "playgroundId": "#ACKC2#1",
+      "renderCount": 50,
+      "referenceImage": "ribbon morphing.png"
+    },    
+    {
       "title": "Clip planes",
       "playgroundId": "#Y6W087#0",
       "referenceImage": "clipplanes.png"