Преглед изворни кода

Merge branch 'master' into FixAudioAutoPlay

David Catuhe пре 7 година
родитељ
комит
0a769fcbd3
90 измењених фајлова са 27041 додато и 23581 уклоњено
  1. 3407 2170
      Playground/babylon.d.txt
  2. 17 3
      contributing.md
  3. 10225 8838
      dist/preview release/babylon.d.ts
  4. 1 1
      dist/preview release/babylon.js
  5. 1205 268
      dist/preview release/babylon.max.js
  6. 1205 268
      dist/preview release/babylon.no-module.max.js
  7. 1 1
      dist/preview release/babylon.worker.js
  8. 1205 268
      dist/preview release/es6.js
  9. 4 4
      dist/preview release/loaders/babylon.glTF2FileLoader.js
  10. 1 1
      dist/preview release/loaders/babylon.glTF2FileLoader.min.js
  11. 4 4
      dist/preview release/loaders/babylon.glTFFileLoader.js
  12. 1 1
      dist/preview release/loaders/babylon.glTFFileLoader.min.js
  13. 4 4
      dist/preview release/loaders/babylonjs.loaders.js
  14. 1 1
      dist/preview release/loaders/babylonjs.loaders.min.js
  15. 6078 10438
      dist/preview release/typedocValidationBaseline.json
  16. 159 2
      dist/preview release/viewer/babylon.viewer.d.ts
  17. 2 2
      dist/preview release/viewer/babylon.viewer.js
  18. 3 3
      dist/preview release/viewer/babylon.viewer.max.js
  19. 163 1
      dist/preview release/viewer/babylon.viewer.module.d.ts
  20. 1 0
      dist/preview release/what's new.md
  21. 4 4
      loaders/src/glTF/2.0/Extensions/KHR_lights_punctual.ts
  22. 20 75
      src/Actions/babylon.actionManager.ts
  23. 260 7
      src/Actions/babylon.directActions.ts
  24. 60 3
      src/Actions/babylon.interpolateValueAction.ts
  25. 181 25
      src/Animations/babylon.easing.ts
  26. 342 273
      src/Audio/babylon.audioEngine.ts
  27. 25 0
      src/Audio/babylon.sound.ts
  28. 146 129
      src/Behaviors/Cameras/babylon.autoRotationBehavior.ts
  29. 14 0
      src/Behaviors/Cameras/babylon.bouncingBehavior.ts
  30. 17 0
      src/Behaviors/Cameras/babylon.framingBehavior.ts
  31. 13 2
      src/Behaviors/Mesh/babylon.sixDofDragBehavior.ts
  32. 50 10
      src/Cameras/Inputs/babylon.arcRotateCameraGamepadInput.ts
  33. 64 8
      src/Cameras/Inputs/babylon.arcRotateCameraKeyboardMoveInput.ts
  34. 35 8
      src/Cameras/Inputs/babylon.arcRotateCameraMouseWheelInput.ts
  35. 55 7
      src/Cameras/Inputs/babylon.arcRotateCameraPointersInput.ts
  36. 48 6
      src/Cameras/Inputs/babylon.arcRotateCameraVRDeviceOrientationInput.ts
  37. 34 5
      src/Cameras/Inputs/babylon.freeCameraDeviceOrientationInput.ts
  38. 49 10
      src/Cameras/Inputs/babylon.freeCameraGamepadInput.ts
  39. 53 12
      src/Cameras/Inputs/babylon.freeCameraKeyboardMoveInput.ts
  40. 46 8
      src/Cameras/Inputs/babylon.freeCameraMouseInput.ts
  41. 48 12
      src/Cameras/Inputs/babylon.freeCameraTouchInput.ts
  42. 44 8
      src/Cameras/Inputs/babylon.freeCameraVirtualJoystickInput.ts
  43. 2 1
      src/Cameras/Stereoscopic/babylon.anaglyphArcRotateCamera.ts
  44. 1 0
      src/Cameras/Stereoscopic/babylon.anaglyphFreeCamera.ts
  45. 1 0
      src/Cameras/Stereoscopic/babylon.anaglyphGamepadCamera.ts
  46. 1 0
      src/Cameras/Stereoscopic/babylon.anaglyphUniversalCamera.ts
  47. 2 1
      src/Cameras/Stereoscopic/babylon.stereoscopicArcRotateCamera.ts
  48. 1 0
      src/Cameras/Stereoscopic/babylon.stereoscopicFreeCamera.ts
  49. 1 0
      src/Cameras/Stereoscopic/babylon.stereoscopicGamepadCamera.ts
  50. 1 0
      src/Cameras/Stereoscopic/babylon.stereoscopicUniversalCamera.ts
  51. 67 0
      src/Cameras/VR/babylon.vrCameraMetrics.ts
  52. 19 0
      src/Cameras/VR/babylon.vrDeviceOrientationArcRotateCamera.ts
  53. 16 1
      src/Cameras/VR/babylon.vrDeviceOrientationFreeCamera.ts
  54. 16 0
      src/Cameras/VR/babylon.vrDeviceOrientationGamepadCamera.ts
  55. 1 1
      src/Cameras/babylon.arcRotateCamera.ts
  56. 25 0
      src/Cameras/babylon.arcRotateCameraInputsManager.ts
  57. 308 89
      src/Cameras/babylon.camera.ts
  58. 121 15
      src/Cameras/babylon.cameraInputsManager.ts
  59. 52 18
      src/Cameras/babylon.followCamera.ts
  60. 69 4
      src/Cameras/babylon.freeCamera.ts
  61. 29 0
      src/Cameras/babylon.freeCameraInputsManager.ts
  62. 18 32
      src/Cameras/babylon.gamepadCamera.ts
  63. 51 10
      src/Cameras/babylon.targetCamera.ts
  64. 27 4
      src/Cameras/babylon.touchCamera.ts
  65. 25 3
      src/Cameras/babylon.universalCamera.ts
  66. 19 1
      src/Cameras/babylon.virtualJoysticksCamera.ts
  67. 17 1
      src/Cameras/babylon.webvr.ts
  68. 1 0
      src/Collisions/babylon.collider.ts
  69. 15 1
      src/Collisions/babylon.collisionCoordinator.ts
  70. 5 0
      src/Collisions/babylon.collisionWorker.ts
  71. 4 0
      src/Gamepad/babylon.gamepadSceneComponent.ts
  72. 9 6
      src/Gizmos/babylon.gizmoManager.ts
  73. 10 11
      src/Gizmos/babylon.scaleGizmo.ts
  74. 1 1
      src/Lights/babylon.spotLight.ts
  75. 13 1
      src/Math/babylon.math.ts
  76. 572 452
      src/Mesh/babylon.mesh.ts
  77. 1 1
      src/Mesh/babylon.meshBuilder.ts
  78. 14 1
      src/Mesh/babylon.meshLODLevel.ts
  79. 6 5
      src/Mesh/babylon.meshSimplificationSceneComponent.ts
  80. 4 2
      src/Mesh/babylon.transformNode.ts
  81. 5 1
      src/Particles/babylon.IParticleSystem.ts
  82. 10 4
      src/Particles/babylon.gpuParticleSystem.ts
  83. 5 5
      src/Particles/babylon.particle.ts
  84. 35 8
      src/Particles/babylon.particleSystem.ts
  85. 42 0
      src/Particles/babylon.particleSystemComponent.ts
  86. 1 0
      src/Particles/babylon.subEmitter.ts
  87. 29 0
      src/Shaders/gpuRenderParticles.vertex.fx
  88. 29 0
      src/Shaders/particles.vertex.fx
  89. 30 11
      src/Tools/babylon.tools.ts
  90. 15 0
      src/babylon.types.ts

Разлика између датотеке није приказан због своје велике величине
+ 3407 - 2170
Playground/babylon.d.txt


+ 17 - 3
contributing.md

@@ -1,6 +1,22 @@
 # Contributing to Babylon.js
 
-The foundation of **Babylon.js** is simplicity. 
+## Golden rules
+
+**Babylon.js** is built upon 3 golden rules:
+
+1. You cannot add code that will break backward compatibility
+2. You cannot add code that will slow down the rendering process
+3. You cannot add code that will make things complex to use
+
+### Backward compatibility
+
+The first golden rule is a really important one because we want our users to trust Babylon.js. And when we need to introduce something that will break backward compatibility, we know that it will imply more work for our customers to switch to a new version. So even if something could be simpler to do by breaking the backward compatibility, we will not do it (exceptions may apply of course if there is a problem with performance or if this is related to a bug).
+
+### Performance
+
+Babylon.js is a 3D rendering engine. So every piece of code has to be scrutinized to look for potential bottlenecks or slow downs. Ultimately the goal is to render more with less resources.
+
+### Simplicity
 
 A developer should be able to quickly and easily learn to use the API. 
 
@@ -8,8 +24,6 @@ Simplicity and a low barrier to entry are must-have features of every API. If yo
 
 You can always add to an API, you cannot ever remove anything from one. If the design does not feel right, and you ship it anyway, you are likely to regret having done so.
 
-That's why many of the guidelines of this document are obvious and serve only one purpose: Simplicity.
-
 ## Forum and Github issues
 
 Since the very beginning, Babylon.js relies on a great forum and a tremendous community: http://www.html5gamedevs.com/forum/16-babylonjs/.

Разлика између датотеке није приказан због своје велике величине
+ 10225 - 8838
dist/preview release/babylon.d.ts


Разлика између датотеке није приказан због своје велике величине
+ 1 - 1
dist/preview release/babylon.js


Разлика између датотеке није приказан због своје велике величине
+ 1205 - 268
dist/preview release/babylon.max.js


Разлика између датотеке није приказан због своје велике величине
+ 1205 - 268
dist/preview release/babylon.no-module.max.js


Разлика између датотеке није приказан због своје велике величине
+ 1 - 1
dist/preview release/babylon.worker.js


Разлика између датотеке није приказан због своје велике величине
+ 1205 - 268
dist/preview release/es6.js


+ 4 - 4
dist/preview release/loaders/babylon.glTF2FileLoader.js

@@ -3434,8 +3434,8 @@ var BABYLON;
                     return GLTF2.GLTFLoader.LoadExtensionAsync(context, node, this.name, function (extensionContext, extension) {
                         return _this._loader.loadNodeAsync(context, node, function (babylonMesh) {
                             var babylonLight;
-                            var name = babylonMesh.name;
                             var light = GLTF2.ArrayItem.Get(extensionContext, _this._lights, extension.light);
+                            var name = light.name || babylonMesh.name;
                             switch (light.type) {
                                 case LightType.DIRECTIONAL: {
                                     babylonLight = new BABYLON.DirectionalLight(name, BABYLON.Vector3.Backward(), _this._loader.babylonScene);
@@ -3446,9 +3446,9 @@ var BABYLON;
                                     break;
                                 }
                                 case LightType.SPOT: {
-                                    var babylonSpotLight = new BABYLON.SpotLight(name, BABYLON.Vector3.Zero(), BABYLON.Vector3.Backward(), 0, 2, _this._loader.babylonScene);
-                                    babylonSpotLight.angle = light.spot && light.spot.outerConeAngle || Math.PI / 4;
-                                    babylonSpotLight.innerAngle = light.spot && light.spot.innerConeAngle || 0;
+                                    var babylonSpotLight = new BABYLON.SpotLight(name, BABYLON.Vector3.Zero(), BABYLON.Vector3.Backward(), 0, 1, _this._loader.babylonScene);
+                                    babylonSpotLight.angle = ((light.spot && light.spot.outerConeAngle) || Math.PI / 4) * 2;
+                                    babylonSpotLight.innerAngle = ((light.spot && light.spot.innerConeAngle) || 0) * 2;
                                     babylonLight = babylonSpotLight;
                                     break;
                                 }

Разлика између датотеке није приказан због своје велике величине
+ 1 - 1
dist/preview release/loaders/babylon.glTF2FileLoader.min.js


+ 4 - 4
dist/preview release/loaders/babylon.glTFFileLoader.js

@@ -5641,8 +5641,8 @@ var BABYLON;
                     return GLTF2.GLTFLoader.LoadExtensionAsync(context, node, this.name, function (extensionContext, extension) {
                         return _this._loader.loadNodeAsync(context, node, function (babylonMesh) {
                             var babylonLight;
-                            var name = babylonMesh.name;
                             var light = GLTF2.ArrayItem.Get(extensionContext, _this._lights, extension.light);
+                            var name = light.name || babylonMesh.name;
                             switch (light.type) {
                                 case LightType.DIRECTIONAL: {
                                     babylonLight = new BABYLON.DirectionalLight(name, BABYLON.Vector3.Backward(), _this._loader.babylonScene);
@@ -5653,9 +5653,9 @@ var BABYLON;
                                     break;
                                 }
                                 case LightType.SPOT: {
-                                    var babylonSpotLight = new BABYLON.SpotLight(name, BABYLON.Vector3.Zero(), BABYLON.Vector3.Backward(), 0, 2, _this._loader.babylonScene);
-                                    babylonSpotLight.angle = light.spot && light.spot.outerConeAngle || Math.PI / 4;
-                                    babylonSpotLight.innerAngle = light.spot && light.spot.innerConeAngle || 0;
+                                    var babylonSpotLight = new BABYLON.SpotLight(name, BABYLON.Vector3.Zero(), BABYLON.Vector3.Backward(), 0, 1, _this._loader.babylonScene);
+                                    babylonSpotLight.angle = ((light.spot && light.spot.outerConeAngle) || Math.PI / 4) * 2;
+                                    babylonSpotLight.innerAngle = ((light.spot && light.spot.innerConeAngle) || 0) * 2;
                                     babylonLight = babylonSpotLight;
                                     break;
                                 }

Разлика између датотеке није приказан због своје велике величине
+ 1 - 1
dist/preview release/loaders/babylon.glTFFileLoader.min.js


+ 4 - 4
dist/preview release/loaders/babylonjs.loaders.js

@@ -6700,8 +6700,8 @@ var BABYLON;
                     return GLTF2.GLTFLoader.LoadExtensionAsync(context, node, this.name, function (extensionContext, extension) {
                         return _this._loader.loadNodeAsync(context, node, function (babylonMesh) {
                             var babylonLight;
-                            var name = babylonMesh.name;
                             var light = GLTF2.ArrayItem.Get(extensionContext, _this._lights, extension.light);
+                            var name = light.name || babylonMesh.name;
                             switch (light.type) {
                                 case LightType.DIRECTIONAL: {
                                     babylonLight = new BABYLON.DirectionalLight(name, BABYLON.Vector3.Backward(), _this._loader.babylonScene);
@@ -6712,9 +6712,9 @@ var BABYLON;
                                     break;
                                 }
                                 case LightType.SPOT: {
-                                    var babylonSpotLight = new BABYLON.SpotLight(name, BABYLON.Vector3.Zero(), BABYLON.Vector3.Backward(), 0, 2, _this._loader.babylonScene);
-                                    babylonSpotLight.angle = light.spot && light.spot.outerConeAngle || Math.PI / 4;
-                                    babylonSpotLight.innerAngle = light.spot && light.spot.innerConeAngle || 0;
+                                    var babylonSpotLight = new BABYLON.SpotLight(name, BABYLON.Vector3.Zero(), BABYLON.Vector3.Backward(), 0, 1, _this._loader.babylonScene);
+                                    babylonSpotLight.angle = ((light.spot && light.spot.outerConeAngle) || Math.PI / 4) * 2;
+                                    babylonSpotLight.innerAngle = ((light.spot && light.spot.innerConeAngle) || 0) * 2;
                                     babylonLight = babylonSpotLight;
                                     break;
                                 }

Разлика између датотеке није приказан због своје велике величине
+ 1 - 1
dist/preview release/loaders/babylonjs.loaders.min.js


Разлика између датотеке није приказан због своје велике величине
+ 6078 - 10438
dist/preview release/typedocValidationBaseline.json


+ 159 - 2
dist/preview release/viewer/babylon.viewer.d.ts

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

Разлика између датотеке није приказан због своје велике величине
+ 2 - 2
dist/preview release/viewer/babylon.viewer.js


Разлика између датотеке није приказан због своје велике величине
+ 3 - 3
dist/preview release/viewer/babylon.viewer.max.js


+ 163 - 1
dist/preview release/viewer/babylon.viewer.module.d.ts

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

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

@@ -17,6 +17,7 @@
   - Add uniform scaling drag support to scale gizmo ([TrevorDev](https://github.com/TrevorDev))
   - Support interacting with child elements ([TrevorDev](https://github.com/TrevorDev))
   - BoundingBox gizmo support for including/excluding descendants when computing the bounding box ([TrevorDev](https://github.com/TrevorDev))
+  - Drag start and stop events for bounding box drag and uniform scale drag ([TrevorDev](https://github.com/TrevorDev))
 - Particle system improvements ([Deltakosh](https://github.com/deltakosh))
   - Added a ParticleHelper class to create some pre-configured particle systems in a one-liner method style. [Doc](https://doc.babylonjs.com/How_To/ParticleHelper) ([Deltakosh](https://github.com/deltakosh)) / ([DevChris](https://github.com/yovanoc))
   - Improved CPU particles rendering performance (up to x2 on low end devices)

+ 4 - 4
loaders/src/glTF/2.0/Extensions/KHR_lights_punctual.ts

@@ -68,8 +68,8 @@ module BABYLON.GLTF2.Extensions {
                 return this._loader.loadNodeAsync(context, node, babylonMesh => {
                     let babylonLight: Light;
 
-                    const name = babylonMesh.name;
                     const light = ArrayItem.Get(extensionContext, this._lights, extension.light);
+                    const name = light.name || babylonMesh.name;
 
                     switch (light.type) {
                         case LightType.DIRECTIONAL: {
@@ -81,9 +81,9 @@ module BABYLON.GLTF2.Extensions {
                             break;
                         }
                         case LightType.SPOT: {
-                            const babylonSpotLight = new SpotLight(name, Vector3.Zero(), Vector3.Backward(), 0, 2, this._loader.babylonScene);
-                            babylonSpotLight.angle = light.spot && light.spot.outerConeAngle || Math.PI / 4;
-                            babylonSpotLight.innerAngle = light.spot && light.spot.innerConeAngle || 0;
+                            const babylonSpotLight = new SpotLight(name, Vector3.Zero(), Vector3.Backward(), 0, 1, this._loader.babylonScene);
+                            babylonSpotLight.angle = ((light.spot && light.spot.outerConeAngle) || Math.PI / 4) * 2;
+                            babylonSpotLight.innerAngle = ((light.spot && light.spot.innerConeAngle) || 0) * 2;
                             babylonLight = babylonSpotLight;
                             break;
                         }

+ 20 - 75
src/Actions/babylon.actionManager.ts

@@ -82,161 +82,106 @@
      * @see http://doc.babylonjs.com/how_to/how_to_use_actions
      */
     export class ActionManager {
-        // Statics
-        private static _NothingTrigger = 0;
-        private static _OnPickTrigger = 1;
-        private static _OnLeftPickTrigger = 2;
-        private static _OnRightPickTrigger = 3;
-        private static _OnCenterPickTrigger = 4;
-        private static _OnPickDownTrigger = 5;
-        private static _OnDoublePickTrigger = 6;
-        private static _OnPickUpTrigger = 7;
-        private static _OnLongPressTrigger = 8;
-        private static _OnPointerOverTrigger = 9;
-        private static _OnPointerOutTrigger = 10;
-        private static _OnEveryFrameTrigger = 11;
-        private static _OnIntersectionEnterTrigger = 12;
-        private static _OnIntersectionExitTrigger = 13;
-        private static _OnKeyDownTrigger = 14;
-        private static _OnKeyUpTrigger = 15;
-        private static _OnPickOutTrigger = 16;
-
         /**
          * Nothing
          * @see http://doc.babylonjs.com/how_to/how_to_use_actions#triggers
          */
-        public static get NothingTrigger(): number {
-            return ActionManager._NothingTrigger;
-        }
+        public static readonly NothingTrigger = 0;
 
         /** 
          * On pick 
          * @see http://doc.babylonjs.com/how_to/how_to_use_actions#triggers
          */
-        public static get OnPickTrigger(): number {
-            return ActionManager._OnPickTrigger;
-        }
+        public static readonly OnPickTrigger = 1;
 
         /** 
          * On left pick
          * @see http://doc.babylonjs.com/how_to/how_to_use_actions#triggers
          */
-        public static get OnLeftPickTrigger(): number {
-            return ActionManager._OnLeftPickTrigger;
-        }
+        public static readonly OnLeftPickTrigger  = 2;
 
         /** 
          * On right pick
          * @see http://doc.babylonjs.com/how_to/how_to_use_actions#triggers
          */
-        public static get OnRightPickTrigger(): number {
-            return ActionManager._OnRightPickTrigger;
-        }
+        public static readonly OnRightPickTrigger = 3;
 
         /** 
          * On center pick 
          * @see http://doc.babylonjs.com/how_to/how_to_use_actions#triggers
          */
-        public static get OnCenterPickTrigger(): number {
-            return ActionManager._OnCenterPickTrigger;
-        }
+        public static readonly OnCenterPickTrigger = 4;
 
         /** 
          * On pick down
          * @see http://doc.babylonjs.com/how_to/how_to_use_actions#triggers
          */
-        public static get OnPickDownTrigger(): number {
-            return ActionManager._OnPickDownTrigger;
-        }
+        public static readonly OnPickDownTrigger = 5;
 
         /** 
          * On double pick
          * @see http://doc.babylonjs.com/how_to/how_to_use_actions#triggers
          */
-        public static get OnDoublePickTrigger(): number {
-            return ActionManager._OnDoublePickTrigger;
-        }
+        public static readonly OnDoublePickTrigger = 6;
 
         /** 
          * On pick up
          * @see http://doc.babylonjs.com/how_to/how_to_use_actions#triggers
          */
-        public static get OnPickUpTrigger(): number {
-            return ActionManager._OnPickUpTrigger;
-        }
-
+        public static readonly OnPickUpTrigger = 7;
         /**
          * On pick out.
          * This trigger will only be raised if you also declared a OnPickDown
          * @see http://doc.babylonjs.com/how_to/how_to_use_actions#triggers
          */
-        public static get OnPickOutTrigger(): number {
-            return ActionManager._OnPickOutTrigger;
-        }
+        public static readonly OnPickOutTrigger = 16;
 
         /** 
          * On long press
          * @see http://doc.babylonjs.com/how_to/how_to_use_actions#triggers
          */
-        public static get OnLongPressTrigger(): number {
-            return ActionManager._OnLongPressTrigger;
-        }
+        public static readonly OnLongPressTrigger = 8;
 
         /** 
          * On pointer over
          * @see http://doc.babylonjs.com/how_to/how_to_use_actions#triggers
          */
-        public static get OnPointerOverTrigger(): number {
-            return ActionManager._OnPointerOverTrigger;
-        }
+        public static readonly OnPointerOverTrigger = 9;
 
         /** 
          * On pointer out
          * @see http://doc.babylonjs.com/how_to/how_to_use_actions#triggers
          */
-        public static get OnPointerOutTrigger(): number {
-            return ActionManager._OnPointerOutTrigger;
-        }
+        public static readonly OnPointerOutTrigger = 10;
 
         /** 
          * On every frame
          * @see http://doc.babylonjs.com/how_to/how_to_use_actions#triggers
          */
-        public static get OnEveryFrameTrigger(): number {
-            return ActionManager._OnEveryFrameTrigger;
-        }
-
+        public static readonly OnEveryFrameTrigger = 11;
         /** 
          * On intersection enter
          * @see http://doc.babylonjs.com/how_to/how_to_use_actions#triggers
          */
-        public static get OnIntersectionEnterTrigger(): number {
-            return ActionManager._OnIntersectionEnterTrigger;
-        }
+        public static readonly OnIntersectionEnterTrigger = 12;
 
         /** 
          * On intersection exit
          * @see http://doc.babylonjs.com/how_to/how_to_use_actions#triggers
          */
-        public static get OnIntersectionExitTrigger(): number {
-            return ActionManager._OnIntersectionExitTrigger;
-        }
+        public static readonly OnIntersectionExitTrigger = 13;
 
         /**
          * On key down
          * @see http://doc.babylonjs.com/how_to/how_to_use_actions#triggers
          */
-        public static get OnKeyDownTrigger(): number {
-            return ActionManager._OnKeyDownTrigger;
-        }
+        public static readonly OnKeyDownTrigger = 14;
 
         /**
          * On key up
          * @see http://doc.babylonjs.com/how_to/how_to_use_actions#triggers
          */
-        public static get OnKeyUpTrigger(): number {
-            return ActionManager._OnKeyUpTrigger;
-        }
+        public static readonly OnKeyUpTrigger = 15;
 
         /** Gets the list of active triggers */
         public static Triggers: { [key: string]: number } = {};
@@ -356,7 +301,7 @@
             for (var index = 0; index < this.actions.length; index++) {
                 var action = this.actions[index];
 
-                if (action.trigger >= ActionManager._OnPickTrigger && action.trigger <= ActionManager._OnPointerOutTrigger) {
+                if (action.trigger >= ActionManager.OnPickTrigger && action.trigger <= ActionManager.OnPointerOutTrigger) {
                     return true;
                 }
             }
@@ -371,7 +316,7 @@
             for (var index = 0; index < this.actions.length; index++) {
                 var action = this.actions[index];
 
-                if (action.trigger >= ActionManager._OnPickTrigger && action.trigger <= ActionManager._OnPickUpTrigger) {
+                if (action.trigger >= ActionManager.OnPickTrigger && action.trigger <= ActionManager.OnPickUpTrigger) {
                     return true;
                 }
             }
@@ -398,7 +343,7 @@
             for (var t in ActionManager.Triggers) {
                 if (ActionManager.Triggers.hasOwnProperty(t)) {
                     let t_int = parseInt(t);
-                    if (t_int >= ActionManager._OnPickTrigger && t_int <= ActionManager._OnPickUpTrigger) {
+                    if (t_int >= ActionManager.OnPickTrigger && t_int <= ActionManager.OnPickUpTrigger) {
                         return true;
                     }
                 }

+ 260 - 7
src/Actions/babylon.directActions.ts

@@ -1,11 +1,28 @@
 module BABYLON {
+    /**
+     * This defines an action responsible to toggle a boolean once triggered.
+     * @see http://doc.babylonjs.com/how_to/how_to_use_actions
+     */
     export class SwitchBooleanAction extends Action {
+        /**
+         * The path to the boolean property in the target object
+         */
+        public propertyPath: string;
+
         private _target: any;
         private _effectiveTarget: any;
         private _property: string;
 
-        constructor(triggerOptions: any, target: any, public propertyPath: string, condition?: Condition) {
+        /**
+         * Instantiate the action
+         * @param triggerOptions defines the trigger options
+         * @param target defines the object containing the boolean
+         * @param propertyPath defines the path to the boolean property in the target object
+         * @param condition defines the trigger related conditions
+         */
+        constructor(triggerOptions: any, target: any, propertyPath: string, condition?: Condition) {
             super(triggerOptions, condition);
+            this.propertyPath = propertyPath;
             this._target = this._effectiveTarget = target;
         }
 
@@ -15,10 +32,18 @@
             this._property = this._getProperty(this.propertyPath);
         }
 
+        /**
+         * Execute the action toggle the boolean value.
+         */
         public execute(): void {
             this._effectiveTarget[this._property] = !this._effectiveTarget[this._property];
         }
 
+        /**
+         * Serializes the actions and its related information.
+         * @param parent defines the object to serialize in
+         * @returns the serialized object
+         */
         public serialize(parent: any): any {
             return super._serialize({
                 name: "SwitchBooleanAction",
@@ -30,18 +55,44 @@
         }
     }
 
+    /**
+     * This defines an action responsible to set a the state field of the target
+     *  to a desired value once triggered.
+     * @see http://doc.babylonjs.com/how_to/how_to_use_actions
+     */
     export class SetStateAction extends Action {
+        /**
+         * The value to store in the state field.
+         */
+        public value: string;
+
         private _target: any;
 
-        constructor(triggerOptions: any, target: any, public value: string, condition?: Condition) {
+        /**
+         * Instantiate the action
+         * @param triggerOptions defines the trigger options
+         * @param target defines the object containing the state property
+         * @param value defines the value to store in the state field
+         * @param condition defines the trigger related conditions
+         */
+        constructor(triggerOptions: any, target: any, value: string, condition?: Condition) {
             super(triggerOptions, condition);
+            this.value = value;
             this._target = target;
         }
 
+        /**
+         * Execute the action and store the value on the target state property.
+         */
         public execute(): void {
             this._target.state = this.value;
         }
 
+        /**
+         * Serializes the actions and its related information.
+         * @param parent defines the object to serialize in
+         * @returns the serialized object
+         */
         public serialize(parent: any): any {
             return super._serialize({
                 name: "SetStateAction",
@@ -53,13 +104,38 @@
         }
     }
 
+    /**
+     * This defines an action responsible to set a property of the target
+     *  to a desired value once triggered.
+     * @see http://doc.babylonjs.com/how_to/how_to_use_actions
+     */
     export class SetValueAction extends Action {
+        /**
+         * The path of the property to set in the target.
+         */
+        public propertyPath: string;
+
+        /**
+         * The value to set in the property
+         */
+        public value: any;
+
         private _target: any;
         private _effectiveTarget: any;
         private _property: string;
 
-        constructor(triggerOptions: any, target: any, public propertyPath: string, public value: any, condition?: Condition) {
+        /**
+         * Instantiate the action
+         * @param triggerOptions defines the trigger options
+         * @param target defines the object containing the property
+         * @param propertyPath defines the path of the property to set in the target
+         * @param value defines the value to set in the property
+         * @param condition defines the trigger related conditions
+         */
+        constructor(triggerOptions: any, target: any, propertyPath: string, value: any, condition?: Condition) {
             super(triggerOptions, condition);
+            this.propertyPath = propertyPath;
+            this.value = value;
             this._target = this._effectiveTarget = target;
         }
 
@@ -69,6 +145,9 @@
             this._property = this._getProperty(this.propertyPath);
         }
 
+        /**
+         * Execute the action and set the targetted property to the desired value.
+         */
         public execute(): void {
             this._effectiveTarget[this._property] = this.value;
 
@@ -77,6 +156,11 @@
             }
         }
 
+        /**
+         * Serializes the actions and its related information.
+         * @param parent defines the object to serialize in
+         * @returns the serialized object
+         */
         public serialize(parent: any): any {
             return super._serialize({
                 name: "SetValueAction",
@@ -89,13 +173,38 @@
         }
     }
 
+    /**
+     * This defines an action responsible to increment the target value
+     *  to a desired value once triggered.
+     * @see http://doc.babylonjs.com/how_to/how_to_use_actions
+     */
     export class IncrementValueAction extends Action {
+        /**
+         * The path of the property to increment in the target.
+         */
+        public propertyPath: string;
+
+        /**
+         * The value we should increment the property by.
+         */
+        public value: any;
+
         private _target: any;
         private _effectiveTarget: any;
         private _property: string;
 
-        constructor(triggerOptions: any, target: any, public propertyPath: string, public value: any, condition?: Condition) {
+        /**
+         * Instantiate the action
+         * @param triggerOptions defines the trigger options
+         * @param target defines the object containing the property
+         * @param propertyPath defines the path of the property to increment in the target
+         * @param value defines the value value we should increment the property by
+         * @param condition defines the trigger related conditions
+         */
+        constructor(triggerOptions: any, target: any, propertyPath: string, value: any, condition?: Condition) {
             super(triggerOptions, condition);
+            this.propertyPath = propertyPath;
+            this.value = value;
             this._target = this._effectiveTarget = target;
         }
 
@@ -109,6 +218,9 @@
             }
         }
 
+        /**
+         * Execute the action and increment the target of the value amount.
+         */
         public execute(): void {
             this._effectiveTarget[this._property] += this.value;
 
@@ -117,6 +229,11 @@
             }
         }
 
+        /**
+         * Serializes the actions and its related information.
+         * @param parent defines the object to serialize in
+         * @returns the serialized object
+         */
         public serialize(parent: any): any {
             return super._serialize({
                 name: "IncrementValueAction",
@@ -129,11 +246,42 @@
         }
     }
 
+    /**
+     * This defines an action responsible to start an animation once triggered.
+     * @see http://doc.babylonjs.com/how_to/how_to_use_actions
+     */
     export class PlayAnimationAction extends Action {
+        /**
+         * Where the animation should start (animation frame)
+         */
+        public from: number;
+
+        /**
+         * Where the animation should stop (animation frame)
+         */
+        public to: number;
+
+        /**
+         * Define if the animation should loop or stop after the first play.
+         */
+        public loop?: boolean;
+
         private _target: any;
 
-        constructor(triggerOptions: any, target: any, public from: number, public to: number, public loop?: boolean, condition?: Condition) {
+        /**
+         * Instantiate the action
+         * @param triggerOptions defines the trigger options
+         * @param target defines the target animation or animation name
+         * @param from defines from where the animation should start (animation frame)
+         * @param end defines where the animation should stop (animation frame)
+         * @param loop defines if the animation should loop or stop after the first play
+         * @param condition defines the trigger related conditions
+         */
+        constructor(triggerOptions: any, target: any, from: number, to: number, loop?: boolean, condition?: Condition) {
             super(triggerOptions, condition);
+            this.from = from;
+            this.to = to;
+            this.loop = loop;
             this._target = target;
         }
 
@@ -141,11 +289,19 @@
         public _prepare(): void {
         }
 
+        /**
+         * Execute the action and play the animation.
+         */
         public execute(): void {
             var scene = this._actionManager.getScene();
             scene.beginAnimation(this._target, this.from, this.to, this.loop);
         }
 
+        /**
+         * Serializes the actions and its related information.
+         * @param parent defines the object to serialize in
+         * @returns the serialized object
+         */
         public serialize(parent: any): any {
             return super._serialize({
                 name: "PlayAnimationAction",
@@ -159,9 +315,19 @@
         }
     }
 
+    /**
+     * This defines an action responsible to stop an animation once triggered.
+     * @see http://doc.babylonjs.com/how_to/how_to_use_actions
+     */
     export class StopAnimationAction extends Action {
         private _target: any;
 
+        /**
+         * Instantiate the action
+         * @param triggerOptions defines the trigger options
+         * @param target defines the target animation or animation name
+         * @param condition defines the trigger related conditions
+         */
         constructor(triggerOptions: any, target: any, condition?: Condition) {
             super(triggerOptions, condition);
             this._target = target;
@@ -171,11 +337,19 @@
         public _prepare(): void {
         }
 
+        /**
+         * Execute the action and stop the animation.
+         */
         public execute(): void {
             var scene = this._actionManager.getScene();
             scene.stopAnimation(this._target);
         }
 
+        /**
+         * Serializes the actions and its related information.
+         * @param parent defines the object to serialize in
+         * @returns the serialized object
+         */
         public serialize(parent: any): any {
             return super._serialize({
                 name: "StopAnimationAction",
@@ -184,14 +358,31 @@
         }
     }
 
+    /**
+     * This defines an action responsible that does nothing once triggered.
+     * @see http://doc.babylonjs.com/how_to/how_to_use_actions
+     */
     export class DoNothingAction extends Action {
+        /**
+         * Instantiate the action
+         * @param triggerOptions defines the trigger options
+         * @param condition defines the trigger related conditions
+         */
         constructor(triggerOptions: any = ActionManager.NothingTrigger, condition?: Condition) {
             super(triggerOptions, condition);
         }
 
+        /**
+         * Execute the action and do nothing.
+         */
         public execute(): void {
         }
 
+        /**
+         * Serializes the actions and its related information.
+         * @param parent defines the object to serialize in
+         * @returns the serialized object
+         */
         public serialize(parent: any): any {
             return super._serialize({
                 name: "DoNothingAction",
@@ -200,9 +391,25 @@
         }
     }
 
+    /**
+     * This defines an action responsible to trigger several actions once triggered.
+     * @see http://doc.babylonjs.com/how_to/how_to_use_actions
+     */
     export class CombineAction extends Action {
-        constructor(triggerOptions: any, public children: Action[], condition?: Condition) {
+        /**
+         * The list of aggregated animations to run.
+         */
+        public children: Action[];
+
+        /**
+         * Instantiate the action
+         * @param triggerOptions defines the trigger options
+         * @param children defines the list of aggregated animations to run
+         * @param condition defines the trigger related conditions
+         */
+        constructor(triggerOptions: any, children: Action[], condition?: Condition) {
             super(triggerOptions, condition);
+            this.children = children;
         }
 
         /** @hidden */
@@ -213,12 +420,20 @@
             }
         }
 
+        /**
+         * Execute the action and executes all the aggregated actions.
+         */
         public execute(evt: ActionEvent): void {
             for (var index = 0; index < this.children.length; index++) {
                 this.children[index].execute(evt);
             }
         }
 
+        /**
+         * Serializes the actions and its related information.
+         * @param parent defines the object to serialize in
+         * @returns the serialized object
+         */
         public serialize(parent: any): any {
             var serializationObject = super._serialize({
                 name: "CombineAction",
@@ -234,20 +449,50 @@
         }
     }
 
+    /**
+     * This defines an action responsible to run code (external event) once triggered.
+     * @see http://doc.babylonjs.com/how_to/how_to_use_actions
+     */
     export class ExecuteCodeAction extends Action {
-        constructor(triggerOptions: any, public func: (evt: ActionEvent) => void, condition?: Condition) {
+        /**
+         * The callback function to run.
+         */
+        public func: (evt: ActionEvent) => void;
+
+        /**
+         * Instantiate the action
+         * @param triggerOptions defines the trigger options
+         * @param func defines the callback function to run
+         * @param condition defines the trigger related conditions
+         */
+        constructor(triggerOptions: any, func: (evt: ActionEvent) => void, condition?: Condition) {
             super(triggerOptions, condition);
+            this.func = func;
         }
 
+        /**
+         * Execute the action and run the attached code.
+         */
         public execute(evt: ActionEvent): void {
             this.func(evt);
         }
     }
 
+    /**
+     * This defines an action responsible to set the parent property of the target once triggered.
+     * @see http://doc.babylonjs.com/how_to/how_to_use_actions
+     */
     export class SetParentAction extends Action {
         private _parent: any;
         private _target: any;
 
+        /**
+         * Instantiate the action
+         * @param triggerOptions defines the trigger options
+         * @param target defines the target containing the parent property
+         * @param parent defines from where the animation should start (animation frame)
+         * @param condition defines the trigger related conditions
+         */
         constructor(triggerOptions: any, target: any, parent: any, condition?: Condition) {
             super(triggerOptions, condition);
             this._target = target;
@@ -258,6 +503,9 @@
         public _prepare(): void {
         }
 
+        /**
+         * Execute the action and set the parent property.
+         */
         public execute(): void {
             if (this._target.parent === this._parent) {
                 return;
@@ -271,6 +519,11 @@
             this._target.parent = this._parent;
         }
 
+        /**
+         * Serializes the actions and its related information.
+         * @param parent defines the object to serialize in
+         * @returns the serialized object
+         */
         public serialize(parent: any): any {
             return super._serialize({
                 name: "SetParentAction",

+ 60 - 3
src/Actions/babylon.interpolateValueAction.ts

@@ -1,14 +1,63 @@
 module BABYLON {
+    /**
+     * This defines an action responsible to change the value of a property
+     * by interpolating between its current value and the newly set one once triggered.
+     * @see http://doc.babylonjs.com/how_to/how_to_use_actions
+     */
     export class InterpolateValueAction extends Action {
+        /**
+         * Defines the path of the property where the value should be interpolated
+         */
+        public propertyPath: string;
+        
+        /**
+         * Defines the target value at the end of the interpolation.
+         */
+        public value: any;
+
+        /**
+         * Defines the time it will take for the property to interpolate to the value.
+         */
+        public duration: number = 1000;
+
+        /**
+         * Defines if the other scene animations should be stopped when the action has been triggered
+         */
+        public stopOtherAnimations?: boolean;
+
+        /**
+         * Defines a callback raised once the interpolation animation has been done.
+         */
+        public onInterpolationDone?: () => void;
+        
+        /**
+         * Observable triggered once the interpolation animation has been done.
+         */
+        public onInterpolationDoneObservable = new Observable<InterpolateValueAction>();
+
         private _target: any;
         private _effectiveTarget: any;
         private _property: string;
 
-        public onInterpolationDoneObservable = new Observable<InterpolateValueAction>();
-
-        constructor(triggerOptions: any, target: any, public propertyPath: string, public value: any, public duration: number = 1000, condition?: Condition, public stopOtherAnimations?: boolean, public onInterpolationDone?: () => void) {
+        /**
+         * Instantiate the action
+         * @param triggerOptions defines the trigger options
+         * @param target defines the object containing the value to interpolate
+         * @param propertyPath defines the path to the property in the target object
+         * @param value defines the target value at the end of the interpolation
+         * @param duration deines the time it will take for the property to interpolate to the value.
+         * @param condition defines the trigger related conditions
+         * @param stopOtherAnimations defines if the other scene animations should be stopped when the action has been triggered
+         * @param onInterpolationDone defines a callback raised once the interpolation animation has been done
+         */
+        constructor(triggerOptions: any, target: any, propertyPath: string, value: any, duration: number = 1000, condition?: Condition, stopOtherAnimations?: boolean, onInterpolationDone?: () => void) {
             super(triggerOptions, condition);
 
+            this.propertyPath = propertyPath;
+            this.value = value;
+            this.duration = duration;
+            this.stopOtherAnimations = stopOtherAnimations;
+            this.onInterpolationDone = onInterpolationDone;
             this._target = this._effectiveTarget = target;
         }
 
@@ -18,6 +67,9 @@
             this._property = this._getProperty(this.propertyPath);
         }
 
+        /**
+         * Execute the action starts the value interpolation.
+         */
         public execute(): void {
             var scene = this._actionManager.getScene();
             var keys = [
@@ -65,6 +117,11 @@
             scene.beginDirectAnimation(this._effectiveTarget, [animation], 0, 100, false, 1, wrapper);
         }
 
+        /**
+         * Serializes the actions and its related information.
+         * @param parent defines the object to serialize in
+         * @returns the serialized object
+         */
         public serialize(parent: any): any {
             return super._serialize({
                 name: "InterpolateValueAction",

+ 181 - 25
src/Animations/babylon.easing.ts

@@ -1,42 +1,73 @@
 module BABYLON {
 
+    /**
+     * This represents the main contract an easing function should follow.
+     * Easing functions are used throughout the animation system.
+     * @see http://doc.babylonjs.com/babylon101/animations#easing-functions
+     */
     export interface IEasingFunction {
+        /**
+         * Given an input gradient between 0 and 1, this returns the corrseponding value
+         * of the easing function. 
+         * The link below provides some of the most common examples of easing functions.
+         * @see https://easings.net/
+         * @param gradient Defines the value between 0 and 1 we want the easing value for
+         * @returns the corresponding value on the curve defined by the easing function
+         */
         ease(gradient: number): number;
     }
 
+    /**
+     * Base class used for every default easing function.
+     * @see http://doc.babylonjs.com/babylon101/animations#easing-functions
+     */
     export class EasingFunction implements IEasingFunction {
-        //Statics
-        private static _EASINGMODE_EASEIN = 0;
-        private static _EASINGMODE_EASEOUT = 1;
-        private static _EASINGMODE_EASEINOUT = 2;
+        /**
+         * Interpolation follows the mathematical formula associated with the easing function.
+         */
+        public static readonly EASINGMODE_EASEIN = 0;
 
-        public static get EASINGMODE_EASEIN(): number {
-            return EasingFunction._EASINGMODE_EASEIN;
-        }
-
-        public static get EASINGMODE_EASEOUT(): number {
-            return EasingFunction._EASINGMODE_EASEOUT;
-        }
+        /**
+         * Interpolation follows 100% interpolation minus the output of the formula associated with the easing function.
+         */
+        public static readonly EASINGMODE_EASEOUT = 1;
 
-        public static get EASINGMODE_EASEINOUT(): number {
-            return EasingFunction._EASINGMODE_EASEINOUT;
-        }
+        /**
+         * Interpolation uses EaseIn for the first half of the animation and EaseOut for the second half.
+         */
+        public static readonly EASINGMODE_EASEINOUT = 2;
 
-        // Properties
         private _easingMode = EasingFunction.EASINGMODE_EASEIN;
 
+        /**
+         * Sets the easing mode of the current function.
+         * @param easingMode Defines the willing mode (EASINGMODE_EASEIN, EASINGMODE_EASEOUT or EASINGMODE_EASEINOUT)
+         */
         public setEasingMode(easingMode: number) {
             var n = Math.min(Math.max(easingMode, 0), 2);
             this._easingMode = n;
         }
+        /**
+         * Gets the current easing mode.
+         * @returns the easing mode
+         */
         public getEasingMode(): number {
             return this._easingMode;
         }
 
+        /**
+         * @hidden
+         */
         public easeInCore(gradient: number): number {
             throw new Error('You must implement this method');
         }
 
+        /**
+         * Given an input gradient between 0 and 1, this returns the corrseponding value
+         * of the easing function.
+         * @param gradient Defines the value between 0 and 1 we want the easing value for
+         * @returns the corresponding value on the curve defined by the easing function
+         */
         public ease(gradient: number): number {
             switch (this._easingMode) {
                 case EasingFunction.EASINGMODE_EASEIN:
@@ -51,32 +82,66 @@
 
             return (this.easeInCore(gradient * 2) * 0.5);
         }
-
     }
 
+    /**
+     * Easing function with a circle shape (see link below).
+     * @see https://easings.net/#easeInCirc
+     * @see http://doc.babylonjs.com/babylon101/animations#easing-functions
+     */
     export class CircleEase extends EasingFunction implements IEasingFunction {
+        /** @hidden */
         public easeInCore(gradient: number): number {
             gradient = Math.max(0, Math.min(1, gradient));
             return (1.0 - Math.sqrt(1.0 - (gradient * gradient)));
         }
     }
 
+    /**
+     * Easing function with a ease back shape (see link below).
+     * @see https://easings.net/#easeInBack
+     * @see http://doc.babylonjs.com/babylon101/animations#easing-functions
+     */
     export class BackEase extends EasingFunction implements IEasingFunction {
-        constructor(public amplitude: number = 1) {
+        /**
+         * Instantiates a back ease easing
+         * @see https://easings.net/#easeInBack
+         * @param amplitude Defines the amplitude of the function
+         */
+        constructor(
+            /** Defines the amplitude of the function */
+            public amplitude: number = 1) {
             super();
         }
 
+        /** @hidden */
         public easeInCore(gradient: number): number {
             var num = Math.max(0, this.amplitude);
             return (Math.pow(gradient, 3.0) - ((gradient * num) * Math.sin(3.1415926535897931 * gradient)));
         }
     }
 
+    /**
+     * Easing function with a bouncing shape (see link below).
+     * @see https://easings.net/#easeInBounce
+     * @see http://doc.babylonjs.com/babylon101/animations#easing-functions
+     */
     export class BounceEase extends EasingFunction implements IEasingFunction {
-        constructor(public bounces: number= 3, public bounciness: number= 2) {
+        /**
+         * Instantiates a bounce easing
+         * @see https://easings.net/#easeInBounce
+         * @param bounces Defines the number of bounces
+         * @param bounciness Defines the amplitude of the bounce
+         */
+        constructor(
+            /** Defines the number of bounces */
+            public bounces: number= 3, 
+            /** Defines the amplitude of the bounce */
+            public bounciness: number= 2) {
             super();
         }
 
+        /** @hidden */
         public easeInCore(gradient: number): number {
             var y = Math.max(0.0, this.bounces);
             var bounciness = this.bounciness;
@@ -99,17 +164,39 @@
         }
     }
 
+    /**
+     * Easing function with a power of 3 shape (see link below).
+     * @see https://easings.net/#easeInCubic
+     * @see http://doc.babylonjs.com/babylon101/animations#easing-functions
+     */
     export class CubicEase extends EasingFunction implements IEasingFunction {
+        /** @hidden */
         public easeInCore(gradient: number): number {
             return (gradient * gradient * gradient);
         }
     }
 
+    /**
+     * Easing function with an elastic shape (see link below).
+     * @see https://easings.net/#easeInElastic
+     * @see http://doc.babylonjs.com/babylon101/animations#easing-functions
+     */
     export class ElasticEase extends EasingFunction implements IEasingFunction {
-        constructor(public oscillations: number= 3, public springiness: number= 3) {
+        /**
+         * Instantiates an elastic easing function
+         * @see https://easings.net/#easeInElastic
+         * @param oscillations Defines the number of oscillations
+         * @param springiness Defines the amplitude of the oscillations
+         */
+        constructor(
+            /** Defines the number of oscillations*/
+            public oscillations: number= 3,
+            /** Defines the amplitude of the oscillations*/
+            public springiness: number= 3) {
             super();
         }
 
+        /** @hidden */
         public easeInCore(gradient: number): number {
             var num2;
             var num3 = Math.max(0.0, this.oscillations);
@@ -124,11 +211,24 @@
         }
     }
 
+    /**
+     * Easing function with an exponential shape (see link below).
+     * @see https://easings.net/#easeInExpo
+     * @see http://doc.babylonjs.com/babylon101/animations#easing-functions
+     */
     export class ExponentialEase extends EasingFunction implements IEasingFunction {
-        constructor(public exponent: number= 2) {
+        /**
+         * Instantiates an exponential easing function
+         * @see https://easings.net/#easeInExpo
+         * @param exponent Defines the exponent of the function
+         */
+        constructor(
+            /** Defines the exponent of the function */
+            public exponent: number= 2) {
             super();
         }
 
+        /** @hidden */
         public easeInCore(gradient: number): number {
             if (this.exponent <= 0) {
                 return gradient;
@@ -138,49 +238,105 @@
         }
     }
 
+    /**
+     * Easing function with a power shape (see link below).
+     * @see https://easings.net/#easeInQuad
+     * @see http://doc.babylonjs.com/babylon101/animations#easing-functions
+     */
     export class PowerEase  extends EasingFunction implements IEasingFunction {
-        constructor(public power: number= 2) {
+        /**
+         * Instantiates an power base easing function
+         * @see https://easings.net/#easeInQuad
+         * @param power Defines the power of the function
+         */
+        constructor(
+            /** Defines the power of the function */
+            public power: number= 2) {
             super();
         }
 
+        /** @hidden */
         public easeInCore(gradient: number): number {
             var y = Math.max(0.0, this.power);
             return Math.pow(gradient, y);
         }
     }
 
+    /**
+     * Easing function with a power of 2 shape (see link below).
+     * @see https://easings.net/#easeInQuad
+     * @see http://doc.babylonjs.com/babylon101/animations#easing-functions
+     */
     export class QuadraticEase extends EasingFunction implements IEasingFunction {
+        /** @hidden */
         public easeInCore(gradient: number): number {
             return (gradient * gradient);
-
-           
-
         }
     }
 
+    /**
+     * Easing function with a power of 4 shape (see link below).
+     * @see https://easings.net/#easeInQuart
+     * @see http://doc.babylonjs.com/babylon101/animations#easing-functions
+     */
     export class QuarticEase extends EasingFunction implements IEasingFunction {
+        /** @hidden */
         public easeInCore(gradient: number): number {
             return (gradient * gradient * gradient * gradient);
         }
     }
 
+    /**
+     * Easing function with a power of 5 shape (see link below).
+     * @see https://easings.net/#easeInQuint
+     * @see http://doc.babylonjs.com/babylon101/animations#easing-functions
+     */
     export class QuinticEase extends EasingFunction implements IEasingFunction {
+        /** @hidden */
         public easeInCore(gradient: number): number {
             return (gradient * gradient * gradient * gradient * gradient);
         }
     }
 
+    /**
+     * Easing function with a sin shape (see link below).
+     * @see https://easings.net/#easeInSine
+     * @see http://doc.babylonjs.com/babylon101/animations#easing-functions
+     */
     export class SineEase  extends EasingFunction implements IEasingFunction {
+        /** @hidden */
         public easeInCore(gradient: number): number {
             return (1.0 - Math.sin(1.5707963267948966 * (1.0 - gradient)));
         }
     }
 
+    /**
+     * Easing function with a bezier shape (see link below).
+     * @see http://cubic-bezier.com/#.17,.67,.83,.67
+     * @see http://doc.babylonjs.com/babylon101/animations#easing-functions
+     */
     export class BezierCurveEase extends EasingFunction implements IEasingFunction {
-        constructor(public x1: number= 0, public y1: number= 0, public x2: number= 1, public y2: number= 1) {
+        /**
+         * Instantiates a bezier function
+         * @see http://cubic-bezier.com/#.17,.67,.83,.67
+         * @param x1 Defines the x component of the start tangent in the bezier curve
+         * @param y1 Defines the y component of the start tangent in the bezier curve
+         * @param x2 Defines the x component of the end tangent in the bezier curve
+         * @param y2 Defines the y component of the end tangent in the bezier curve
+         */
+        constructor(
+            /** Defines the x component of the start tangent in the bezier curve */
+            public x1: number= 0,
+            /** Defines the y component of the start tangent in the bezier curve */
+            public y1: number= 0,
+            /** Defines the x component of the end tangent in the bezier curve */
+            public x2: number= 1,
+            /** Defines the y component of the end tangent in the bezier curve */
+            public y2: number= 1) {
             super();
         }
 
+        /** @hidden */
         public easeInCore(gradient: number): number {
             return BezierCurve.interpolate(gradient, this.x1, this.y1, this.x2, this.y2);
         }

Разлика између датотеке није приказан због своје велике величине
+ 342 - 273
src/Audio/babylon.audioEngine.ts


+ 25 - 0
src/Audio/babylon.sound.ts

@@ -1,10 +1,35 @@
 module BABYLON {
+    /**
+     * Defines a sound that can be played in the application.
+     * The sound can either be an ambient track or a simple sound played in reaction to a user action.
+     * @see http://doc.babylonjs.com/how_to/playing_sounds_and_music
+     */
     export class Sound {
+        /**
+         * The name of the sound in the scene.
+         */
         public name: string;
+        /**
+         * Does the sound autoplay once loaded.
+         */
         public autoplay: boolean = false;
+        /**
+         * Does the sound loop after it finishes playing once.
+         */
         public loop: boolean = false;
+        /**
+         * Does the sound use a custom attenuation curve to simulate the falloff
+         * happening when the source gets further away from the camera.
+         * @see http://doc.babylonjs.com/how_to/playing_sounds_and_music#creating-your-own-custom-attenuation-function
+         */
         public useCustomAttenuation: boolean = false;
+        /**
+         * The sound track id this sound belongs to.
+         */
         public soundTrackId: number;
+        /**
+         * Does this sound enables spatial sound.
+         */
         public spatialSound: boolean = false;
         public refDistance: number = 1;
         public rolloffFactor: number = 1;

+ 146 - 129
src/Behaviors/Cameras/babylon.autoRotationBehavior.ts

@@ -1,76 +1,83 @@
 module BABYLON {
+    /**
+     * The autoRotation behavior (BABYLON.AutoRotationBehavior) is designed to create a smooth rotation of an ArcRotateCamera when there is no user interaction.
+     * @see http://doc.babylonjs.com/how_to/camera_behaviors#autorotation-behavior
+     */
     export class AutoRotationBehavior implements Behavior<ArcRotateCamera> {
+        /**
+         * Gets the name of the behavior.
+         */
         public get name(): string {
             return "AutoRotation";
         }
 
         private _zoomStopsAnimation = false;
-		private _idleRotationSpeed = 0.05;
-		private _idleRotationWaitTime = 2000;
+        private _idleRotationSpeed = 0.05;
+        private _idleRotationWaitTime = 2000;
         private _idleRotationSpinupTime = 2000;  
        
-		/**
-		* Sets the flag that indicates if user zooming should stop animation.
-		*/
-		public set zoomStopsAnimation(flag: boolean) {
-			this._zoomStopsAnimation = flag;
-		}
-
-		/**
-		* Gets the flag that indicates if user zooming should stop animation.
-		*/
-		public get zoomStopsAnimation(): boolean {
-			return this._zoomStopsAnimation;
+        /**
+        * Sets the flag that indicates if user zooming should stop animation.
+        */
+        public set zoomStopsAnimation(flag: boolean) {
+            this._zoomStopsAnimation = flag;
+        }
+
+        /**
+        * Gets the flag that indicates if user zooming should stop animation.
+        */
+        public get zoomStopsAnimation(): boolean {
+            return this._zoomStopsAnimation;
         }       
         
-		/**
-		* Sets the default speed at which the camera rotates around the model.
-		*/
-		public set idleRotationSpeed(speed: number) {
-			this._idleRotationSpeed = speed;
-		}
-
-		/**
-		* Gets the default speed at which the camera rotates around the model.
-		*/
-		public get idleRotationSpeed() {
-			return this._idleRotationSpeed;
-		}
-
-		/**
-		* Sets the time (in milliseconds) to wait after user interaction before the camera starts rotating.
-		*/
-		public set idleRotationWaitTime(time: number) {
-			this._idleRotationWaitTime = time;
-		}
-
-		/**
-		* Gets the time (milliseconds) to wait after user interaction before the camera starts rotating.
-		*/
-		public get idleRotationWaitTime() {
-			return this._idleRotationWaitTime;
-		}
-
-		/**
-		* Sets the time (milliseconds) to take to spin up to the full idle rotation speed.
-		*/
-		public set idleRotationSpinupTime(time: number) {
-			this._idleRotationSpinupTime = time;
-		}
-
-		/**
-		* Gets the time (milliseconds) to take to spin up to the full idle rotation speed.
-		*/
-		public get idleRotationSpinupTime() {
-			return this._idleRotationSpinupTime;
-		}
-
-		/**
-		 * Gets a value indicating if the camera is currently rotating because of this behavior
-		 */
-		public get rotationInProgress(): boolean {
-			return Math.abs(this._cameraRotationSpeed) > 0;
-		}
+        /**
+        * Sets the default speed at which the camera rotates around the model.
+        */
+        public set idleRotationSpeed(speed: number) {
+            this._idleRotationSpeed = speed;
+        }
+
+        /**
+        * Gets the default speed at which the camera rotates around the model.
+        */
+        public get idleRotationSpeed() {
+            return this._idleRotationSpeed;
+        }
+
+        /**
+        * Sets the time (in milliseconds) to wait after user interaction before the camera starts rotating.
+        */
+        public set idleRotationWaitTime(time: number) {
+            this._idleRotationWaitTime = time;
+        }
+
+        /**
+        * Gets the time (milliseconds) to wait after user interaction before the camera starts rotating.
+        */
+        public get idleRotationWaitTime() {
+            return this._idleRotationWaitTime;
+        }
+
+        /**
+        * Sets the time (milliseconds) to take to spin up to the full idle rotation speed.
+        */
+        public set idleRotationSpinupTime(time: number) {
+            this._idleRotationSpinupTime = time;
+        }
+
+        /**
+        * Gets the time (milliseconds) to take to spin up to the full idle rotation speed.
+        */
+        public get idleRotationSpinupTime() {
+            return this._idleRotationSpinupTime;
+        }
+
+        /**
+         * Gets a value indicating if the camera is currently rotating because of this behavior
+         */
+        public get rotationInProgress(): boolean {
+            return Math.abs(this._cameraRotationSpeed) > 0;
+        }
         
         // Default behavior functions
         private _onPrePointerObservableObserver: Nullable<Observer<PointerInfoPre>>;
@@ -78,13 +85,20 @@ module BABYLON {
         private _attachedCamera: Nullable<ArcRotateCamera>;
         private _isPointerDown = false;
         private _lastFrameTime: Nullable<number> = null;
-		private _lastInteractionTime = -Infinity;
-		private _cameraRotationSpeed: number = 0;
-
-		public init(): void {
-			// Do notihng
-		}
+        private _lastInteractionTime = -Infinity;
+        private _cameraRotationSpeed: number = 0;
+
+        /**
+         * Initializes the behavior.
+         */
+        public init(): void {
+            // Do notihng
+        }
 
+        /**
+         * Attaches the behavior to its arc rotate camera.
+         * @param camera Defines the camera to attach the behavior to
+         */
         public attach(camera: ArcRotateCamera): void {
             this._attachedCamera = camera;
             let scene = this._attachedCamera.getScene();
@@ -112,78 +126,81 @@ module BABYLON {
                 this._applyUserInteraction();
     
                 let timeToRotation = now - this._lastInteractionTime - this._idleRotationWaitTime;
-				let scale = Math.max(Math.min(timeToRotation / (this._idleRotationSpinupTime), 1), 0);
+                let scale = Math.max(Math.min(timeToRotation / (this._idleRotationSpinupTime), 1), 0);
                 this._cameraRotationSpeed = this._idleRotationSpeed * scale;
     
-				// Step camera rotation by rotation speed
-				if (this._attachedCamera) {
-					this._attachedCamera.alpha -= this._cameraRotationSpeed * (dt / 1000);
-				}
+                // Step camera rotation by rotation speed
+                if (this._attachedCamera) {
+                    this._attachedCamera.alpha -= this._cameraRotationSpeed * (dt / 1000);
+                }
             });
         }
-             
+
+        /**
+         * Detaches the behavior from its current arc rotate camera.
+         */
         public detach(): void {
-			if (!this._attachedCamera) {
-				return;
-			}
+            if (!this._attachedCamera) {
+                return;
+            }
             let scene = this._attachedCamera.getScene();
-			
-			if (this._onPrePointerObservableObserver) {
-				scene.onPrePointerObservable.remove(this._onPrePointerObservableObserver);
-			}
-			
-			this._attachedCamera.onAfterCheckInputsObservable.remove(this._onAfterCheckInputsObserver);
-			this._attachedCamera = null;
-		}
-
-		/**
-		 * Returns true if user is scrolling. 
-		 * @return true if user is scrolling.
-		 */
-		private _userIsZooming(): boolean {
-			if (!this._attachedCamera) {
-				return false;
-			}			
-			return this._attachedCamera.inertialRadiusOffset !== 0;
-		}   		
-		
-		private _lastFrameRadius = 0;
-		private _shouldAnimationStopForInteraction(): boolean {
-			if (!this._attachedCamera) {
-				return false;
-			}	
-
-			var zoomHasHitLimit = false;
-			if (this._lastFrameRadius === this._attachedCamera.radius && this._attachedCamera.inertialRadiusOffset !== 0) {
-				zoomHasHitLimit = true;
-			}
-
-			// Update the record of previous radius - works as an approx. indicator of hitting radius limits
-			this._lastFrameRadius = this._attachedCamera.radius;
-			return this._zoomStopsAnimation ? zoomHasHitLimit : this._userIsZooming();
-		}   		
-
-		/**
-		 *  Applies any current user interaction to the camera. Takes into account maximum alpha rotation.
-		 */          
+            
+            if (this._onPrePointerObservableObserver) {
+                scene.onPrePointerObservable.remove(this._onPrePointerObservableObserver);
+            }
+            
+            this._attachedCamera.onAfterCheckInputsObservable.remove(this._onAfterCheckInputsObserver);
+            this._attachedCamera = null;
+        }
+
+        /**
+         * Returns true if user is scrolling. 
+         * @return true if user is scrolling.
+         */
+        private _userIsZooming(): boolean {
+            if (!this._attachedCamera) {
+                return false;
+            }			
+            return this._attachedCamera.inertialRadiusOffset !== 0;
+        }   		
+        
+        private _lastFrameRadius = 0;
+        private _shouldAnimationStopForInteraction(): boolean {
+            if (!this._attachedCamera) {
+                return false;
+            }	
+
+            var zoomHasHitLimit = false;
+            if (this._lastFrameRadius === this._attachedCamera.radius && this._attachedCamera.inertialRadiusOffset !== 0) {
+                zoomHasHitLimit = true;
+            }
+
+            // Update the record of previous radius - works as an approx. indicator of hitting radius limits
+            this._lastFrameRadius = this._attachedCamera.radius;
+            return this._zoomStopsAnimation ? zoomHasHitLimit : this._userIsZooming();
+        }   		
+
+        /**
+         *  Applies any current user interaction to the camera. Takes into account maximum alpha rotation.
+         */          
         private _applyUserInteraction(): void {
-			if (this._userIsMoving() && !this._shouldAnimationStopForInteraction()) {
+            if (this._userIsMoving() && !this._shouldAnimationStopForInteraction()) {
                 this._lastInteractionTime = Tools.Now;
-			}
+            }
         }                
    
         // Tools
         private _userIsMoving(): boolean {
-			if (!this._attachedCamera) {
-				return false;
-			}	
-			
-			return this._attachedCamera.inertialAlphaOffset !== 0 ||
-				this._attachedCamera.inertialBetaOffset !== 0 ||
-				this._attachedCamera.inertialRadiusOffset !== 0 ||
-				this._attachedCamera.inertialPanningX !== 0 ||
-				this._attachedCamera.inertialPanningY !== 0 ||
-				this._isPointerDown;
-		}
+            if (!this._attachedCamera) {
+                return false;
+            }	
+            
+            return this._attachedCamera.inertialAlphaOffset !== 0 ||
+                this._attachedCamera.inertialBetaOffset !== 0 ||
+                this._attachedCamera.inertialRadiusOffset !== 0 ||
+                this._attachedCamera.inertialPanningX !== 0 ||
+                this._attachedCamera.inertialPanningY !== 0 ||
+                this._isPointerDown;
+        }
     }
 }

+ 14 - 0
src/Behaviors/Cameras/babylon.bouncingBehavior.ts

@@ -1,8 +1,12 @@
 module BABYLON {
     /**
      * Add a bouncing effect to an ArcRotateCamera when reaching a specified minimum and maximum radius
+     * @see http://doc.babylonjs.com/how_to/camera_behaviors#bouncing-behavior
      */
     export class BouncingBehavior implements Behavior<ArcRotateCamera> {
+        /**
+         * Gets the name of the behavior.
+         */
         public get name(): string {
             return "Bouncing";
         }
@@ -79,10 +83,17 @@ module BABYLON {
         private _onAfterCheckInputsObserver: Nullable<Observer<Camera>>;
         private _onMeshTargetChangedObserver: Nullable<Observer<Nullable<AbstractMesh>>>;
 
+        /**
+         * Initializes the behavior.
+         */
         public init(): void {
             // Do notihng
         }
 
+        /**
+         * Attaches the behavior to its arc rotate camera.
+         * @param camera Defines the camera to attach the behavior to
+         */
         public attach(camera: ArcRotateCamera): void {
             this._attachedCamera = camera;
             this._onAfterCheckInputsObserver = camera.onAfterCheckInputsObservable.add(() => {
@@ -102,6 +113,9 @@ module BABYLON {
             });
         }
 
+        /**
+         * Detaches the behavior from its current arc rotate camera.
+         */
         public detach(): void {
             if (!this._attachedCamera) {
                 return;

+ 17 - 0
src/Behaviors/Cameras/babylon.framingBehavior.ts

@@ -1,5 +1,12 @@
 module BABYLON {
+    /**
+     * The framing behavior (BABYLON.FramingBehavior) is designed to automatically position an ArcRotateCamera when its target is set to a mesh. It is also useful if you want to prevent the camera to go under a virtual horizontal plane.
+     * @see http://doc.babylonjs.com/how_to/camera_behaviors#framing-behavior
+     */
     export class FramingBehavior implements Behavior<ArcRotateCamera> {
+        /**
+         * Gets the name of the behavior.
+         */
         public get name(): string {
             return "Framing";
         }
@@ -147,10 +154,17 @@ module BABYLON {
         private _isPointerDown = false;
         private _lastInteractionTime = -Infinity;
 
+        /**
+         * Initializes the behavior.
+         */
         public init(): void {
             // Do notihng
         }
 
+        /**
+         * Attaches the behavior to its arc rotate camera.
+         * @param camera Defines the camera to attach the behavior to
+         */
         public attach(camera: ArcRotateCamera): void {
             this._attachedCamera = camera;
             let scene = this._attachedCamera.getScene();
@@ -184,6 +198,9 @@ module BABYLON {
             });
         }
 
+        /**
+         * Detaches the behavior from its current arc rotate camera.
+         */
         public detach(): void {
             if (!this._attachedCamera) {
                 return;

+ 13 - 2
src/Behaviors/Mesh/babylon.sixDofDragBehavior.ts

@@ -33,8 +33,15 @@ module BABYLON {
          * If camera controls should be detached during the drag
          */
         public detachCameraControls = true;
-
-
+        /**
+         * Fires each time a drag starts
+         */
+        public onDragStartObservable = new Observable<{}>()
+        /**
+         *  Fires each time a drag ends (eg. mouse release after drag)
+         */
+        public onDragEndObservable = new Observable<{}>()
+        
         constructor(){
         }
         
@@ -118,6 +125,7 @@ module BABYLON {
                             }
                         }
                         BoundingBoxGizmo._RestorePivotPoint(pickedMesh);
+                        this.onDragStartObservable.notifyObservers({});
                     }
                 }else if(pointerInfo.type == BABYLON.PointerEventTypes.POINTERUP){
                     if(this.currentDraggingPointerID == (<PointerEvent>pointerInfo.event).pointerId){
@@ -131,6 +139,7 @@ module BABYLON {
                         if(this.detachCameraControls && attachedElement && this._scene.activeCamera && !this._scene.activeCamera.leftCamera){
                             this._scene.activeCamera.attachControl(attachedElement, true);
                         }
+                        this.onDragEndObservable.notifyObservers({});
                     }
                 }else if(pointerInfo.type == BABYLON.PointerEventTypes.POINTERMOVE){
                     if(this.currentDraggingPointerID == (<PointerEvent>pointerInfo.event).pointerId && this.dragging && pointerInfo.pickInfo && pointerInfo.pickInfo.ray && pickedMesh){
@@ -213,6 +222,8 @@ module BABYLON {
             if(this._virtualDragMesh){
                 this._virtualDragMesh.dispose();
             }
+            this.onDragEndObservable.clear();
+            this.onDragStartObservable.clear();
         }
     }
 }

+ 50 - 10
src/Cameras/Inputs/babylon.arcRotateCameraGamepadInput.ts

@@ -1,18 +1,42 @@
 module BABYLON {
+    /**
+     * Manage the gamepad inputs to control an arc rotate camera.
+     * @see http://doc.babylonjs.com/how_to/customizing_camera_inputs
+     */
     export class ArcRotateCameraGamepadInput implements ICameraInput<ArcRotateCamera> {
-        camera: ArcRotateCamera;
+        /**
+         * Defines the camera the input is attached to.
+         */
+        public camera: ArcRotateCamera;
 
+        /**
+         * Defines the gamepad the input is gathering event from.
+         */
         public gamepad: Nullable<Gamepad>;
-        private _onGamepadConnectedObserver : Nullable<Observer<Gamepad>>;
-        private _onGamepadDisconnectedObserver : Nullable<Observer<Gamepad>>;
 
+        /**
+         * Defines the gamepad rotation sensiblity.
+         * This is the threshold from when rotation starts to be accounted for to prevent jittering.
+         */
         @serialize()
         public gamepadRotationSensibility = 80;
 
+        /**
+         * Defines the gamepad move sensiblity.
+         * This is the threshold from when moving starts to be accounted for for to prevent jittering.
+         */
         @serialize()
         public gamepadMoveSensibility = 40;
 
-        attachControl(element: HTMLElement, noPreventDefault?: boolean) {
+        private _onGamepadConnectedObserver : Nullable<Observer<Gamepad>>;
+        private _onGamepadDisconnectedObserver : Nullable<Observer<Gamepad>>;
+
+        /**
+         * Attach the input controls to a specific dom element to get the input from.
+         * @param element Defines the element the controls should be listened from
+         * @param noPreventDefault Defines whether event caught by the controls should call preventdefault() (https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault)
+         */
+        public attachControl(element: HTMLElement, noPreventDefault?: boolean): void {
             let manager = this.camera.getScene().gamepadManager;
             this._onGamepadConnectedObserver = manager.onGamepadConnectedObservable.add((gamepad) => {
                 if (gamepad.type !== Gamepad.POSE_ENABLED) {
@@ -21,24 +45,32 @@ module BABYLON {
                         this.gamepad = gamepad;
                     }
                 }
-            });  
+            });
 
             this._onGamepadDisconnectedObserver = manager.onGamepadDisconnectedObservable.add((gamepad)=> {
                 if (this.gamepad === gamepad) {
                     this.gamepad = null;
                 }
-            });            
+            });
             
             this.gamepad = manager.getGamepadByType(Gamepad.XBOX);
         }
 
-        detachControl(element: Nullable<HTMLElement>) {
+        /**
+         * Detach the current controls from the specified dom element.
+         * @param element Defines the element to stop listening the inputs from
+         */
+        public detachControl(element: Nullable<HTMLElement>): void {
             this.camera.getScene().gamepadManager.onGamepadConnectedObservable.remove(this._onGamepadConnectedObserver);            
             this.camera.getScene().gamepadManager.onGamepadDisconnectedObservable.remove(this._onGamepadDisconnectedObserver);
             this.gamepad = null;
         }
 
-        checkInputs() {
+        /**
+         * Update the current camera state depending on the inputs that have been used this frame.
+         * This is a dynamically created lambda to avoid the performance penalty of looping for inputs in the render loop.
+         */
+        public checkInputs(): void {
             if (this.gamepad) {
                 var camera = this.camera;
                 var RSValues = this.gamepad.rightStick;
@@ -70,11 +102,19 @@ module BABYLON {
             }
         }
 
-        getClassName(): string {
+        /**
+         * Gets the class name of the current intput.
+         * @returns the class name
+         */
+        public getClassName(): string {
             return "ArcRotateCameraGamepadInput";
         }
 
-        getSimpleName() {
+        /**
+         * Get the friendly name associated with the input class.
+         * @returns the input friendly name
+         */
+        public getSimpleName(): string {
             return "gamepad";
         }        
     }

+ 64 - 8
src/Cameras/Inputs/babylon.arcRotateCameraKeyboardMoveInput.ts

@@ -1,32 +1,67 @@
 module BABYLON {
+    /**
+     * Manage the keyboard inputs to control the movement of an arc rotate camera.
+     * @see http://doc.babylonjs.com/how_to/customizing_camera_inputs
+     */
     export class ArcRotateCameraKeyboardMoveInput implements ICameraInput<ArcRotateCamera> {
-        camera: ArcRotateCamera;
-        private _keys = new Array<number>();
-        
+        /**
+         * Defines the camera the input is attached to.
+         */
+        public camera: ArcRotateCamera;
+
+        /**
+         * Defines the list of key codes associated with the up action (increase alpha)
+         */
         @serialize()
         public keysUp = [38];
 
+        /**
+         * Defines the list of key codes associated with the down action (decrease alpha)
+         */
         @serialize()
         public keysDown = [40];
 
+        /**
+         * Defines the list of key codes associated with the left action (increase beta)
+         */
         @serialize()
         public keysLeft = [37];
 
+        /**
+         * Defines the list of key codes associated with the right action (decrease beta)
+         */
         @serialize()
         public keysRight = [39];
 
+        /**
+         * Defines the list of key codes associated with the reset action.
+         * Those keys reset the camera to its last stored state (with the method camera.storeState())
+         */
         @serialize()
         public keysReset = [220];
 
+        /**
+         * Defines the panning sensibility of the inputs.
+         * (How fast is the camera paning)
+         */
         @serialize()
         public panningSensibility: number = 50.0;
 
+        /**
+         * Defines the zooming sensibility of the inputs.
+         * (How fast is the camera zooming)
+         */
         @serialize()
         public zoomingSensibility: number = 25.0;
 
+        /**
+         * Defines wether maintaining the alt key down switch the movement mode from
+         * orientation to zoom.
+         */
         @serialize()
         public useAltToZoom: boolean = true;
 
+        private _keys = new Array<number>();
         private _ctrlPressed: boolean;
         private _altPressed: boolean;
         private _onCanvasBlurObserver: Nullable<Observer<Engine>>;
@@ -34,7 +69,12 @@ module BABYLON {
         private _engine: Engine;
         private _scene: Scene;
 
-        public attachControl(element: HTMLElement, noPreventDefault?: boolean) {
+        /**
+         * Attach the input controls to a specific dom element to get the input from.
+         * @param element Defines the element the controls should be listened from
+         * @param noPreventDefault Defines whether event caught by the controls should call preventdefault() (https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault)
+         */
+        public attachControl(element: HTMLElement, noPreventDefault?: boolean): void {
             if (this._onCanvasBlurObserver) {
                 return;
             }
@@ -93,6 +133,10 @@ module BABYLON {
             });    
         }
 
+        /**
+         * Detach the current controls from the specified dom element.
+         * @param element Defines the element to stop listening the inputs from
+         */
         public detachControl(element: Nullable<HTMLElement>) {
             if (this._scene) {
                 if (this._onKeyboardObserver) {
@@ -108,7 +152,11 @@ module BABYLON {
             this._keys = [];
         }
 
-        public checkInputs() {
+        /**
+         * Update the current camera state depending on the inputs that have been used this frame.
+         * This is a dynamically created lambda to avoid the performance penalty of looping for inputs in the render loop.
+         */
+        public checkInputs(): void {
             if (this._onKeyboardObserver){
                 var camera = this.camera;
 
@@ -153,11 +201,19 @@ module BABYLON {
             }
         }
 
-        getClassName(): string {
+        /**
+         * Gets the class name of the current intput.
+         * @returns the class name
+         */
+        public getClassName(): string {
             return "ArcRotateCameraKeyboardMoveInput";
         }
-        
-        getSimpleName(){
+
+        /**
+         * Get the friendly name associated with the input class.
+         * @returns the input friendly name
+         */
+        public getSimpleName(): string{
             return "keyboard";
         }
     }

+ 35 - 8
src/Cameras/Inputs/babylon.arcRotateCameraMouseWheelInput.ts

@@ -1,10 +1,17 @@
 module BABYLON {
+    /**
+     * Manage the mouse wheel inputs to control an arc rotate camera.
+     * @see http://doc.babylonjs.com/how_to/customizing_camera_inputs
+     */
     export class ArcRotateCameraMouseWheelInput implements ICameraInput<ArcRotateCamera> {
-        camera: ArcRotateCamera;
-
-        private _wheel: Nullable<(p: PointerInfo, s: EventState) => void>;
-        private _observer: Nullable<Observer<PointerInfo>>;
+        /**
+         * Defines the camera the input is attached to.
+         */
+        public camera: ArcRotateCamera;
 
+        /**
+         * Gets or Set the mouse wheel precision or how fast is the camera zooming.
+         */
         @serialize()
         public wheelPrecision = 3.0;
 
@@ -15,7 +22,15 @@ module BABYLON {
         @serialize()
         public wheelDeltaPercentage = 0;
 
-        public attachControl(element: HTMLElement, noPreventDefault?: boolean) {
+        private _wheel: Nullable<(p: PointerInfo, s: EventState) => void>;
+        private _observer: Nullable<Observer<PointerInfo>>;
+
+        /**
+         * Attach the input controls to a specific dom element to get the input from.
+         * @param element Defines the element the controls should be listened from
+         * @param noPreventDefault Defines whether event caught by the controls should call preventdefault() (https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault)
+         */
+        public attachControl(element: HTMLElement, noPreventDefault?: boolean): void {
             this._wheel = (p, s) => {
                 //sanity check - this should be a PointerWheel event.
                 if (p.type !== PointerEventTypes.POINTERWHEEL) return;
@@ -50,7 +65,11 @@ module BABYLON {
             this._observer = this.camera.getScene().onPointerObservable.add(this._wheel, PointerEventTypes.POINTERWHEEL);
         }
 
-        public detachControl(element: Nullable<HTMLElement>) {
+        /**
+         * Detach the current controls from the specified dom element.
+         * @param element Defines the element to stop listening the inputs from
+         */
+        public detachControl(element: Nullable<HTMLElement>): void {
             if (this._observer && element) {
                 this.camera.getScene().onPointerObservable.remove(this._observer);
                 this._observer = null;
@@ -58,11 +77,19 @@ module BABYLON {
             }
         }
 
-        getClassName(): string {
+        /**
+         * Gets the class name of the current intput.
+         * @returns the class name
+         */
+        public getClassName(): string {
             return "ArcRotateCameraMouseWheelInput";
         }
 
-        getSimpleName() {
+        /**
+         * Get the friendly name associated with the input class.
+         * @returns the input friendly name
+         */
+        public getSimpleName(): string {
             return "mousewheel";
         }
     }

+ 55 - 7
src/Cameras/Inputs/babylon.arcRotateCameraPointersInput.ts

@@ -1,16 +1,35 @@
 module BABYLON {
+    /**
+     * Manage the pointers inputs to control an arc rotate camera.
+     * @see http://doc.babylonjs.com/how_to/customizing_camera_inputs
+     */
     export class ArcRotateCameraPointersInput implements ICameraInput<ArcRotateCamera> {
-        camera: ArcRotateCamera;
+        /**
+         * Defines the camera the input is attached to.
+         */
+        public camera: ArcRotateCamera;
 
+        /**
+         * Defines the buttons associated with the input to handle camera move.
+         */
         @serialize()
         public buttons = [0, 1, 2];
 
+        /**
+         * Defines the pointer angular sensibility  along the X axis or how fast is the camera rotating.
+         */
         @serialize()
         public angularSensibilityX = 1000.0;
 
+        /**
+         * Defines the pointer angular sensibility along the Y axis or how fast is the camera rotating.
+         */
         @serialize()
         public angularSensibilityY = 1000.0;
 
+        /**
+         * Defines the pointer pinch precision or how fast is the camera zooming.
+         */
         @serialize()
         public pinchPrecision = 12.0;
 
@@ -21,18 +40,30 @@ module BABYLON {
         @serialize()
         public pinchDeltaPercentage = 0;
 
+        /**
+         * Defines the pointer panning sensibility or how fast is the camera moving.
+         */
         @serialize()
         public panningSensibility: number = 1000.0;
 
+        /**
+         * Defines whether panning (2 fingers swipe) is enabled through multitouch.
+         */
         @serialize()
         public multiTouchPanning: boolean = true;
 
+        /**
+         * Defines whether panning is enabled for both pan (2 fingers swipe) and zoom (pinch) through multitouch.
+         */
         @serialize()
         public multiTouchPanAndZoom: boolean = true;
 
-        private _isPanClick: boolean = false;
+        /**
+         * Revers pinch action direction.
+         */
         public pinchInwards = true;
-
+        
+        private _isPanClick: boolean = false;
         private _pointerInput: (p: PointerInfo, s: EventState) => void;
         private _observer: Nullable<Observer<PointerInfo>>;
         private _onMouseMove: Nullable<(e: MouseEvent) => any>;
@@ -42,7 +73,12 @@ module BABYLON {
         private _onLostFocus: Nullable<(e: FocusEvent) => any>;
         private _onContextMenu: Nullable<(e: PointerEvent) => void>;
 
-        public attachControl(element: HTMLElement, noPreventDefault?: boolean) {
+        /**
+         * Attach the input controls to a specific dom element to get the input from.
+         * @param element Defines the element the controls should be listened from
+         * @param noPreventDefault Defines whether event caught by the controls should call preventdefault() (https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault)
+         */
+        public attachControl(element: HTMLElement, noPreventDefault?: boolean): void {
             var engine = this.camera.getEngine();
             var cacheSoloPointer: Nullable<{ x: number, y: number, pointerId: number, type: any }>; // cache pointer object for better perf on camera rotation
             var pointA: Nullable<{ x: number, y: number, pointerId: number, type: any }> = null;
@@ -314,7 +350,11 @@ module BABYLON {
             ]);
         }
 
-        public detachControl(element: Nullable<HTMLElement>) {
+        /**
+         * Detach the current controls from the specified dom element.
+         * @param element Defines the element to stop listening the inputs from
+         */
+        public detachControl(element: Nullable<HTMLElement>): void {
             if (this._onLostFocus) {
                 Tools.UnregisterTopRootEvents([
                     { name: "blur", handler: this._onLostFocus }
@@ -353,11 +393,19 @@ module BABYLON {
             }
         }
 
-        getClassName(): string {
+        /**
+         * Gets the class name of the current intput.
+         * @returns the class name
+         */
+        public getClassName(): string {
             return "ArcRotateCameraPointersInput";
         }
 
-        getSimpleName() {
+        /**
+         * Get the friendly name associated with the input class.
+         * @returns the input friendly name
+         */
+        public getSimpleName(): string {
             return "pointers";
         }
     }

+ 48 - 6
src/Cameras/Inputs/babylon.arcRotateCameraVRDeviceOrientationInput.ts

@@ -1,9 +1,27 @@
 module BABYLON {
+    /**
+     * Manage the device orientation inputs (gyroscope) to control an arc rotate camera.
+     * @see http://doc.babylonjs.com/how_to/customizing_camera_inputs
+     */
     export class ArcRotateCameraVRDeviceOrientationInput implements ICameraInput<ArcRotateCamera> {
-        camera: ArcRotateCamera;
+        /**
+         * Defines the camera the input is attached to.
+         */
+        public camera: ArcRotateCamera;
 
+        /**
+         * Defines a correction factor applied on the alpha value retrieved from the orientation events.
+         */
         public alphaCorrection = 1;
+
+        /**
+         * Defines a correction factor applied on the beta value retrieved from the orientation events.
+         */
         public betaCorrection = 1;
+
+        /**
+         * Defines a correction factor applied on the gamma value retrieved from the orientation events.
+         */
         public gammaCorrection = 1;
 
         private _alpha = 0;
@@ -12,11 +30,19 @@ module BABYLON {
 
         private _deviceOrientationHandler: () => void;
 
+        /**
+         * Instantiate a new ArcRotateCameraVRDeviceOrientationInput.
+         */
         constructor() {
             this._deviceOrientationHandler = this._onOrientationEvent.bind(this);
         }
 
-        attachControl(element: HTMLElement, noPreventDefault?: boolean) {
+        /**
+         * Attach the input controls to a specific dom element to get the input from.
+         * @param element Defines the element the controls should be listened from
+         * @param noPreventDefault Defines whether event caught by the controls should call preventdefault() (https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault)
+         */
+        public attachControl(element: HTMLElement, noPreventDefault?: boolean): void {
             this.camera.attachControl(element, noPreventDefault);
             window.addEventListener("deviceorientation", this._deviceOrientationHandler);
         }
@@ -33,7 +59,11 @@ module BABYLON {
             this._dirty = true;
         }
 
-        public checkInputs() {
+        /**
+         * Update the current camera state depending on the inputs that have been used this frame.
+         * This is a dynamically created lambda to avoid the performance penalty of looping for inputs in the render loop.
+         */
+        public checkInputs(): void {
             if (this._dirty) {
                 this._dirty = false;
 
@@ -46,15 +76,27 @@ module BABYLON {
             }
         }
 
-        detachControl(element: Nullable<HTMLElement>) {
+        /**
+         * Detach the current controls from the specified dom element.
+         * @param element Defines the element to stop listening the inputs from
+         */
+        public detachControl(element: Nullable<HTMLElement>): void {
             window.removeEventListener("deviceorientation", this._deviceOrientationHandler);
         }
 
-        getClassName(): string {
+        /**
+         * Gets the class name of the current intput.
+         * @returns the class name
+         */
+        public getClassName(): string {
             return "ArcRotateCameraVRDeviceOrientationInput";
         }
 
-        getSimpleName() {
+        /**
+         * Get the friendly name associated with the input class.
+         * @returns the input friendly name
+         */
+        public getSimpleName(): string {
             return "VRDeviceOrientation";
         }
     }

+ 34 - 5
src/Cameras/Inputs/babylon.freeCameraDeviceOrientationInput.ts

@@ -2,6 +2,7 @@ module BABYLON {
     /**
      * Takes information about the orientation of the device as reported by the deviceorientation event to orient the camera.
      * Screen rotation is taken into account.
+     * @see http://doc.babylonjs.com/how_to/customizing_camera_inputs
      */
     export class FreeCameraDeviceOrientationInput implements ICameraInput<FreeCamera> {
         private _camera: FreeCamera;
@@ -15,11 +16,18 @@ module BABYLON {
         private _beta: number = 0;
         private _gamma: number = 0;
 
+        /**
+         * Instantiates a new input
+         * @see http://doc.babylonjs.com/how_to/customizing_camera_inputs
+         */
         constructor() {
             this._constantTranform = new Quaternion(- Math.sqrt(0.5), 0, 0, Math.sqrt(0.5));
             this._orientationChanged();
         }
 
+        /**
+         * Define the camera controlled by the input.
+         */
         public get camera(): FreeCamera {
             return this._camera;
         }
@@ -31,7 +39,12 @@ module BABYLON {
             }
         }
 
-        attachControl(element: HTMLElement, noPreventDefault?: boolean) {
+        /**
+         * Attach the input controls to a specific dom element to get the input from.
+         * @param element Defines the element the controls should be listened from
+         * @param noPreventDefault Defines whether event caught by the controls should call preventdefault() (https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault)
+         */
+        public attachControl(element: HTMLElement, noPreventDefault?: boolean): void {
             window.addEventListener("orientationchange", this._orientationChanged);
             window.addEventListener("deviceorientation", this._deviceOrientation);
             //In certain cases, the attach control is called AFTER orientation was changed,
@@ -51,12 +64,20 @@ module BABYLON {
             this._gamma = evt.gamma !== null ? evt.gamma : 0;
         }
 
-        detachControl(element: Nullable<HTMLElement>) {
+        /**
+         * Detach the current controls from the specified dom element.
+         * @param element Defines the element to stop listening the inputs from
+         */
+        public detachControl(element: Nullable<HTMLElement>): void {
             window.removeEventListener("orientationchange", this._orientationChanged);
             window.removeEventListener("deviceorientation", this._deviceOrientation);
         }
 
-        public checkInputs() {
+        /**
+         * Update the current camera state depending on the inputs that have been used this frame.
+         * This is a dynamically created lambda to avoid the performance penalty of looping for inputs in the render loop.
+         */
+        public checkInputs(): void {
             //if no device orientation provided, don't update the rotation.
             //Only testing against alpha under the assumption thatnorientation will never be so exact when set.
             if (!this._alpha) return;
@@ -68,11 +89,19 @@ module BABYLON {
             this._camera.rotationQuaternion.w *= -1;
         }
 
-        getClassName(): string {
+        /**
+         * Gets the class name of the current intput.
+         * @returns the class name
+         */
+        public getClassName(): string {
             return "FreeCameraDeviceOrientationInput";
         }
 
-        getSimpleName() {
+        /**
+         * Get the friendly name associated with the input class.
+         * @returns the input friendly name
+         */
+        public getSimpleName(): string {
             return "deviceOrientation";
         }
     }

+ 49 - 10
src/Cameras/Inputs/babylon.freeCameraGamepadInput.ts

@@ -1,24 +1,47 @@
 module BABYLON {
+    /**
+     * Manage the gamepad inputs to control a free camera.
+     * @see http://doc.babylonjs.com/how_to/customizing_camera_inputs
+     */
     export class FreeCameraGamepadInput implements ICameraInput<FreeCamera> {
-        camera: FreeCamera;
+        /**
+         * Define the camera the input is attached to.
+         */
+        public camera: FreeCamera;
 
-        public gamepad: Nullable<Gamepad>;        
-        private _onGamepadConnectedObserver : Nullable<Observer<Gamepad>>;
-        private _onGamepadDisconnectedObserver : Nullable<Observer<Gamepad>>;
+        /**
+         * Define the Gamepad controlling the input
+         */
+        public gamepad: Nullable<Gamepad>;
 
+        /**
+         * Defines the gamepad rotation sensiblity.
+         * This is the threshold from when rotation starts to be accounted for to prevent jittering.
+         */
         @serialize()
         public gamepadAngularSensibility = 200;
 
+        /**
+         * Defines the gamepad move sensiblity.
+         * This is the threshold from when moving starts to be accounted for for to prevent jittering.
+         */
         @serialize()
         public gamepadMoveSensibility = 40;
-
+        
         // private members
+        private _onGamepadConnectedObserver : Nullable<Observer<Gamepad>>;
+        private _onGamepadDisconnectedObserver : Nullable<Observer<Gamepad>>;
         private _cameraTransform: Matrix = Matrix.Identity();
         private _deltaTransform: Vector3 = Vector3.Zero();
         private _vector3: Vector3 = Vector3.Zero();
         private _vector2: Vector2 = Vector2.Zero();
 
-        attachControl(element: HTMLElement, noPreventDefault?: boolean) {
+        /**
+         * Attach the input controls to a specific dom element to get the input from.
+         * @param element Defines the element the controls should be listened from
+         * @param noPreventDefault Defines whether event caught by the controls should call preventdefault() (https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault)
+         */
+        public attachControl(element: HTMLElement, noPreventDefault?: boolean): void {
             let manager = this.camera.getScene().gamepadManager;
             this._onGamepadConnectedObserver = manager.onGamepadConnectedObservable.add((gamepad) => {
                 if (gamepad.type !== Gamepad.POSE_ENABLED) {
@@ -38,13 +61,21 @@ module BABYLON {
             this.gamepad = manager.getGamepadByType(Gamepad.XBOX);
         }
 
-        detachControl(element: Nullable<HTMLElement>) {
+        /**
+         * Detach the current controls from the specified dom element.
+         * @param element Defines the element to stop listening the inputs from
+         */
+        public detachControl(element: Nullable<HTMLElement>): void {
             this.camera.getScene().gamepadManager.onGamepadConnectedObservable.remove(this._onGamepadConnectedObserver);
             this.camera.getScene().gamepadManager.onGamepadDisconnectedObservable.remove(this._onGamepadDisconnectedObserver);
             this.gamepad = null;
         }
 
-        checkInputs() {
+        /**
+         * Update the current camera state depending on the inputs that have been used this frame.
+         * This is a dynamically created lambda to avoid the performance penalty of looping for inputs in the render loop.
+         */
+        public checkInputs(): void {
             if (this.gamepad && this.gamepad.leftStick) {
                 var camera = this.camera;
                 var LSValues = this.gamepad.leftStick;
@@ -80,11 +111,19 @@ module BABYLON {
             }
         }
 
-        getClassName(): string {
+        /**
+         * Gets the class name of the current intput.
+         * @returns the class name
+         */
+        public getClassName(): string {
             return "FreeCameraGamepadInput";
         }
 
-        getSimpleName() {
+        /**
+         * Get the friendly name associated with the input class.
+         * @returns the input friendly name
+         */
+        public getSimpleName(): string {
             return "gamepad";
         }
     }

+ 53 - 12
src/Cameras/Inputs/babylon.freeCameraKeyboardMoveInput.ts

@@ -1,25 +1,50 @@
 module BABYLON {
+    /**
+     * Manage the keyboard inputs to control the movement of a free camera.
+     * @see http://doc.babylonjs.com/how_to/customizing_camera_inputs
+     */
     export class FreeCameraKeyboardMoveInput implements ICameraInput<FreeCamera> {
-        camera: FreeCamera;
-        private _keys = new Array<number>();
-        private _onCanvasBlurObserver: Nullable<Observer<Engine>>;
-        private _onKeyboardObserver: Nullable<Observer<KeyboardInfo>>;
-        private _engine: Engine;
-        private _scene: Scene;
-
+        /**
+         * Defines the camera the input is attached to.
+         */
+        public camera: FreeCamera;
+
+        /**
+         * Gets or Set the list of keyboard keys used to control the forward move of the camera.
+         */
         @serialize()
         public keysUp = [38];
 
+        /**
+         * Gets or Set the list of keyboard keys used to control the backward move of the camera.
+         */
         @serialize()
         public keysDown = [40];
 
+        /**
+         * Gets or Set the list of keyboard keys used to control the left strafe move of the camera.
+         */
         @serialize()
         public keysLeft = [37];
 
+        /**
+         * Gets or Set the list of keyboard keys used to control the right strafe move of the camera.
+         */
         @serialize()
         public keysRight = [39];
 
-        attachControl(element: HTMLElement, noPreventDefault?: boolean) {
+        private _keys = new Array<number>();
+        private _onCanvasBlurObserver: Nullable<Observer<Engine>>;
+        private _onKeyboardObserver: Nullable<Observer<KeyboardInfo>>;
+        private _engine: Engine;
+        private _scene: Scene;
+
+        /**
+         * Attach the input controls to a specific dom element to get the input from.
+         * @param element Defines the element the controls should be listened from
+         * @param noPreventDefault Defines whether event caught by the controls should call preventdefault() (https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault)
+         */
+        public attachControl(element: HTMLElement, noPreventDefault?: boolean): void {
             if (this._onCanvasBlurObserver) {
                 return;
             }
@@ -66,7 +91,11 @@ module BABYLON {
             });
         }
 
-        detachControl(element: Nullable<HTMLElement>) {
+        /**
+         * Detach the current controls from the specified dom element.
+         * @param element Defines the element to stop listening the inputs from
+         */
+        public detachControl(element: Nullable<HTMLElement>): void {
             if (this._scene) {
                 if (this._onKeyboardObserver) {
                     this._scene.onKeyboardObservable.remove(this._onKeyboardObserver);
@@ -81,7 +110,11 @@ module BABYLON {
             this._keys = [];
         }
 
-        public checkInputs() {
+        /**
+         * Update the current camera state depending on the inputs that have been used this frame.
+         * This is a dynamically created lambda to avoid the performance penalty of looping for inputs in the render loop.
+         */
+        public checkInputs(): void {
             if (this._onKeyboardObserver) {
                 var camera = this.camera;
                 // Keyboard
@@ -110,7 +143,11 @@ module BABYLON {
             }
         }
 
-        getClassName(): string {
+        /**
+         * Gets the class name of the current intput.
+         * @returns the class name
+         */
+        public getClassName(): string {
             return "FreeCameraKeyboardMoveInput";
         }
 
@@ -119,7 +156,11 @@ module BABYLON {
             this._keys = [];
         }
 
-        getSimpleName() {
+        /**
+         * Get the friendly name associated with the input class.
+         * @returns the input friendly name
+         */
+        public getSimpleName(): string {
             return "keyboard";
         }
     }

+ 46 - 8
src/Cameras/Inputs/babylon.freeCameraMouseInput.ts

@@ -1,23 +1,49 @@
 module BABYLON {
+    /**
+     * Manage the mouse inputs to control the movement of a free camera.
+     * @see http://doc.babylonjs.com/how_to/customizing_camera_inputs
+     */
     export class FreeCameraMouseInput implements ICameraInput<FreeCamera> {
-        camera: FreeCamera;
-
+        /**
+         * Defines the camera the input is attached to.
+         */
+        public camera: FreeCamera;
+
+        /**
+         * Defines the buttons associated with the input to handle camera move.
+         */
         @serialize()
         public buttons = [0, 1, 2];
 
+        /**
+         * Defines the pointer angular sensibility  along the X and Y axis or how fast is the camera rotating.
+         */
         @serialize()
         public angularSensibility = 2000.0;
 
         private _pointerInput: (p: PointerInfo, s: EventState) => void;
         private _onMouseMove: Nullable<(e: MouseEvent) => any>;
         private _observer: Nullable<Observer<PointerInfo>>;
-
         private previousPosition: Nullable<{ x: number, y: number }> = null;
 
-        constructor(public touchEnabled = true) {
+        /**
+         * Manage the mouse inputs to control the movement of a free camera.
+         * @see http://doc.babylonjs.com/how_to/customizing_camera_inputs
+         * @param touchEnabled Defines if touch is enabled or not
+         */
+        constructor(
+            /**
+             * Define if touch is enabled in the mouse input
+             */
+            public touchEnabled = true) {
         }
 
-        attachControl(element: HTMLElement, noPreventDefault?: boolean) {
+        /**
+         * Attach the input controls to a specific dom element to get the input from.
+         * @param element Defines the element the controls should be listened from
+         * @param noPreventDefault Defines whether event caught by the controls should call preventdefault() (https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault)
+         */
+        public attachControl(element: HTMLElement, noPreventDefault?: boolean):void {
             var engine = this.camera.getEngine();
 
             if (!this._pointerInput) {
@@ -122,7 +148,11 @@ module BABYLON {
 
         }
 
-        detachControl(element: Nullable<HTMLElement>) {
+        /**
+         * Detach the current controls from the specified dom element.
+         * @param element Defines the element to stop listening the inputs from
+         */
+        public detachControl(element: Nullable<HTMLElement>):void {
             if (this._observer && element) {
                 this.camera.getScene().onPointerObservable.remove(this._observer);
 
@@ -136,11 +166,19 @@ module BABYLON {
             }
         }
 
-        getClassName(): string {
+        /**
+         * Gets the class name of the current intput.
+         * @returns the class name
+         */
+        public getClassName(): string {
             return "FreeCameraMouseInput";
         }
 
-        getSimpleName() {
+        /**
+         * Get the friendly name associated with the input class.
+         * @returns the input friendly name
+         */
+        public getSimpleName(): string {
             return "mouse";
         }
     }

+ 48 - 12
src/Cameras/Inputs/babylon.freeCameraTouchInput.ts

@@ -1,6 +1,27 @@
 module BABYLON {
+    /**
+     * Manage the touch inputs to control the movement of a free camera.
+     * @see http://doc.babylonjs.com/how_to/customizing_camera_inputs
+     */
     export class FreeCameraTouchInput implements ICameraInput<FreeCamera> {
-        camera: FreeCamera;
+        /**
+         * Defines the camera the input is attached to.
+         */
+        public camera: FreeCamera;
+
+        /**
+         * Defines the touch sensibility for rotation.
+         * The higher the faster.
+         */
+        @serialize()
+        public touchAngularSensibility: number = 200000.0;
+
+        /**
+         * Defines the touch sensibility for move.
+         * The higher the faster.
+         */
+        @serialize()
+        public touchMoveSensibility: number = 250.0;
 
         private _offsetX: Nullable<number> = null;
         private _offsetY: Nullable<number> = null;
@@ -10,13 +31,12 @@ module BABYLON {
         private _observer: Nullable<Observer<PointerInfo>>;
         private _onLostFocus: Nullable<(e: FocusEvent) => any>;
 
-        @serialize()
-        public touchAngularSensibility: number = 200000.0;
-
-        @serialize()
-        public touchMoveSensibility: number = 250.0;
-
-        attachControl(element: HTMLElement, noPreventDefault?: boolean) {
+        /**
+         * Attach the input controls to a specific dom element to get the input from.
+         * @param element Defines the element the controls should be listened from
+         * @param noPreventDefault Defines whether event caught by the controls should call preventdefault() (https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault)
+         */
+        public attachControl(element: HTMLElement, noPreventDefault?: boolean): void {
             var previousPosition: Nullable<{ x: number, y: number }> = null;
 
             if (this._pointerInput === undefined) {
@@ -98,7 +118,11 @@ module BABYLON {
             }
         }
 
-        detachControl(element: Nullable<HTMLElement>) {
+        /**
+         * Detach the current controls from the specified dom element.
+         * @param element Defines the element to stop listening the inputs from
+         */
+        public detachControl(element: Nullable<HTMLElement>): void {
             if (this._pointerInput && element) {
                 if (this._observer) {
                     this.camera.getScene().onPointerObservable.remove(this._observer);
@@ -115,7 +139,11 @@ module BABYLON {
             }
         }
 
-        checkInputs() {
+        /**
+         * Update the current camera state depending on the inputs that have been used this frame.
+         * This is a dynamically created lambda to avoid the performance penalty of looping for inputs in the render loop.
+         */
+        public checkInputs(): void {
             if (this._offsetX && this._offsetY) {
                 var camera = this.camera;
                 camera.cameraRotation.y += this._offsetX / this.touchAngularSensibility;
@@ -132,11 +160,19 @@ module BABYLON {
             }
         }
 
-        getClassName(): string {
+        /**
+         * Gets the class name of the current intput.
+         * @returns the class name
+         */
+        public getClassName(): string {
             return "FreeCameraTouchInput";
         }
 
-        getSimpleName() {
+        /**
+         * Get the friendly name associated with the input class.
+         * @returns the input friendly name
+         */
+        public getSimpleName(): string {
             return "touch";
         }
     }

+ 44 - 8
src/Cameras/Inputs/babylon.freeCameraVirtualJoystickInput.ts

@@ -1,18 +1,37 @@
 module BABYLON {
+    /**
+     * Manage the Virtual Joystick inputs to control the movement of a free camera.
+     * @see http://doc.babylonjs.com/how_to/customizing_camera_inputs
+     */
     export class FreeCameraVirtualJoystickInput implements ICameraInput<FreeCamera> {
-        camera: FreeCamera;
+        /**
+         * Defines the camera the input is attached to.
+         */
+        public camera: FreeCamera;
 
         private _leftjoystick: VirtualJoystick;
         private _rightjoystick: VirtualJoystick;
-        
+
+        /**
+         * Gets the left stick of the virtual joystick.
+         * @returns The virtual Joystick
+         */
         public getLeftJoystick(): VirtualJoystick {
             return this._leftjoystick;
         }
 
+        /**
+         * Gets the right stick of the virtual joystick.
+         * @returns The virtual Joystick
+         */
         public getRightJoystick(): VirtualJoystick {
             return this._rightjoystick;
         }
 
+        /**
+         * Update the current camera state depending on the inputs that have been used this frame.
+         * This is a dynamically created lambda to avoid the performance penalty of looping for inputs in the render loop.
+         */
         public checkInputs() {
             if (this._leftjoystick){
                 var camera = this.camera;
@@ -30,8 +49,13 @@ module BABYLON {
                 }
             }
         }
-        
-        attachControl(element : HTMLElement, noPreventDefault?: boolean) {
+
+        /**
+         * Attach the input controls to a specific dom element to get the input from.
+         * @param element Defines the element the controls should be listened from
+         * @param noPreventDefault Defines whether event caught by the controls should call preventdefault() (https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault)
+         */
+        public attachControl(element : HTMLElement, noPreventDefault?: boolean): void {
             this._leftjoystick = new VirtualJoystick(true);
             this._leftjoystick.setAxisForUpDown(JoystickAxis.Z);
             this._leftjoystick.setAxisForLeftRight(JoystickAxis.X);
@@ -44,16 +68,28 @@ module BABYLON {
             this._rightjoystick.setJoystickColor("yellow");
         }
 
-        detachControl(element: Nullable<HTMLElement>) {
+        /**
+         * Detach the current controls from the specified dom element.
+         * @param element Defines the element to stop listening the inputs from
+         */
+        public detachControl(element: Nullable<HTMLElement>): void {
             this._leftjoystick.releaseCanvas();
             this._rightjoystick.releaseCanvas();
         }
 
-        getClassName(): string {
+        /**
+         * Gets the class name of the current intput.
+         * @returns the class name
+         */
+        public getClassName(): string {
             return "FreeCameraVirtualJoystickInput";
         }
-        
-        getSimpleName(){
+
+        /**
+         * Get the friendly name associated with the input class.
+         * @returns the input friendly name
+         */
+        public getSimpleName(): string {
             return "virtualJoystick";
         }
     }

+ 2 - 1
src/Cameras/Stereoscopic/babylon.anaglyphArcRotateCamera.ts

@@ -5,7 +5,8 @@ module BABYLON {
 
     /**
      * Camera used to simulate anaglyphic rendering (based on ArcRotateCamera)
-     */    
+     * @see http://doc.babylonjs.com/features/cameras#anaglyph-cameras
+     */
     export class AnaglyphArcRotateCamera extends ArcRotateCamera {
 
         /**

+ 1 - 0
src/Cameras/Stereoscopic/babylon.anaglyphFreeCamera.ts

@@ -5,6 +5,7 @@ module BABYLON {
 
     /**
      * Camera used to simulate anaglyphic rendering (based on FreeCamera)
+     * @see http://doc.babylonjs.com/features/cameras#anaglyph-cameras
      */
     export class AnaglyphFreeCamera extends FreeCamera {
         /**

+ 1 - 0
src/Cameras/Stereoscopic/babylon.anaglyphGamepadCamera.ts

@@ -5,6 +5,7 @@ module BABYLON {
 
     /**
      * Camera used to simulate anaglyphic rendering (based on GamepadCamera)
+     * @see http://doc.babylonjs.com/features/cameras#anaglyph-cameras
      */       
     export class AnaglyphGamepadCamera extends GamepadCamera {
         /**

+ 1 - 0
src/Cameras/Stereoscopic/babylon.anaglyphUniversalCamera.ts

@@ -5,6 +5,7 @@ module BABYLON {
 
     /**
      * Camera used to simulate anaglyphic rendering (based on UniversalCamera)
+     * @see http://doc.babylonjs.com/features/cameras#anaglyph-cameras
      */        
     export class AnaglyphUniversalCamera extends UniversalCamera {
         /**

+ 2 - 1
src/Cameras/Stereoscopic/babylon.stereoscopicArcRotateCamera.ts

@@ -5,7 +5,8 @@ module BABYLON {
 
     /**
      * Camera used to simulate stereoscopic rendering (based on ArcRotateCamera)
-     */      
+     * @see http://doc.babylonjs.com/features/cameras
+     */
     export class StereoscopicArcRotateCamera extends ArcRotateCamera {
         /**
          * Creates a new StereoscopicArcRotateCamera

+ 1 - 0
src/Cameras/Stereoscopic/babylon.stereoscopicFreeCamera.ts

@@ -5,6 +5,7 @@ module BABYLON {
 
     /**
      * Camera used to simulate stereoscopic rendering (based on FreeCamera)
+     * @see http://doc.babylonjs.com/features/cameras
      */    
     export class StereoscopicFreeCamera extends FreeCamera {
         /**

+ 1 - 0
src/Cameras/Stereoscopic/babylon.stereoscopicGamepadCamera.ts

@@ -5,6 +5,7 @@ module BABYLON {
 
     /**
      * Camera used to simulate stereoscopic rendering (based on GamepadCamera)
+     * @see http://doc.babylonjs.com/features/cameras
      */      
     export class StereoscopicGamepadCamera extends GamepadCamera {
         /**

+ 1 - 0
src/Cameras/Stereoscopic/babylon.stereoscopicUniversalCamera.ts

@@ -4,6 +4,7 @@ module BABYLON {
     });    
     /**
      * Camera used to simulate stereoscopic rendering (based on UniversalCamera)
+     * @see http://doc.babylonjs.com/features/cameras
      */      
     export class StereoscopicUniversalCamera extends UniversalCamera {
         /**

+ 67 - 0
src/Cameras/VR/babylon.vrCameraMetrics.ts

@@ -1,27 +1,81 @@
 module BABYLON {
+    /**
+     * This represents all the required metrics to create a VR camera.
+     * @see http://doc.babylonjs.com/babylon101/cameras#device-orientation-camera
+     */
     export class VRCameraMetrics {
+        /**
+         * Define the horizontal resolution off the screen.
+         */
         public hResolution: number;
+        /**
+         * Define the vertical resolution off the screen.
+         */
         public vResolution: number;
+        /**
+         * Define the horizontal screen size.
+         */
         public hScreenSize: number;
+        /**
+         * Define the vertical screen size.
+         */
         public vScreenSize: number;
+        /**
+         * Define the vertical screen center position.
+         */
         public vScreenCenter: number;
+        /**
+         * Define the distance of the eyes to the screen.
+         */
         public eyeToScreenDistance: number;
+        /**
+         * Define the distance between both lenses
+         */
         public lensSeparationDistance: number;
+        /**
+         * Define the distance between both viewer's eyes.
+         */
         public interpupillaryDistance: number;
+        /**
+         * Define the distortion factor of the VR postprocess.
+         * Please, touch with care.
+         */
         public distortionK: number[];
+        /**
+         * Define the chromatic aberration correction factors for the VR post process.
+         */
         public chromaAbCorrection: number[];
+        /**
+         * Define the scale factor of the post process.
+         * The smaller the better but the slower.
+         */
         public postProcessScaleFactor: number;
+        /**
+         * Define an offset for the lens center.
+         */
         public lensCenterOffset: number;
+        /**
+         * Define if the current vr camera should compensate the distortion of the lense or not.
+         */
         public compensateDistortion = true;
 
+        /**
+         * Gets the rendering aspect ratio based on the provided resolutions.
+         */
         public get aspectRatio(): number {
             return this.hResolution / (2 * this.vResolution);
         }
 
+        /**
+         * Gets the aspect ratio based on the FOV, scale factors, and real screen sizes.
+         */
         public get aspectRatioFov(): number {
             return (2 * Math.atan((this.postProcessScaleFactor * this.vScreenSize) / (2 * this.eyeToScreenDistance)));
         }
 
+        /**
+         * @hidden
+         */
         public get leftHMatrix(): Matrix {
             var meters = (this.hScreenSize / 4) - (this.lensSeparationDistance / 2);
             var h = (4 * meters) / this.hScreenSize;
@@ -29,6 +83,9 @@
             return Matrix.Translation(h, 0, 0);
         }
 
+        /**
+         * @hidden
+         */
         public get rightHMatrix(): Matrix {
             var meters = (this.hScreenSize / 4) - (this.lensSeparationDistance / 2);
             var h = (4 * meters) / this.hScreenSize;
@@ -36,14 +93,24 @@
             return Matrix.Translation(-h, 0, 0);
         }
 
+        /**
+         * @hidden
+         */
         public get leftPreViewMatrix(): Matrix {
             return Matrix.Translation(0.5 * this.interpupillaryDistance, 0, 0);
         }
 
+        /**
+         * @hidden
+         */
         public get rightPreViewMatrix(): Matrix {
             return Matrix.Translation(-0.5 * this.interpupillaryDistance, 0, 0);
         }
 
+        /**
+         * Get the default VRMetrics based on the most generic setup.
+         * @returns the default vr metrics
+         */
         public static GetDefault(): VRCameraMetrics {
             var result = new VRCameraMetrics();
 

+ 19 - 0
src/Cameras/VR/babylon.vrDeviceOrientationArcRotateCamera.ts

@@ -3,8 +3,23 @@ module BABYLON {
         return () => new VRDeviceOrientationArcRotateCamera(name, 0, 0, 1.0, Vector3.Zero(), scene);
     });
 
+    /**
+     * Camera used to simulate VR rendering (based on ArcRotateCamera)
+     * @see http://doc.babylonjs.com/babylon101/cameras#vr-device-orientation-cameras
+     */
     export class VRDeviceOrientationArcRotateCamera extends ArcRotateCamera {
 
+        /**
+         * Creates a new VRDeviceOrientationArcRotateCamera
+         * @param name defines camera name
+         * @param alpha defines the camera rotation along the logitudinal axis
+         * @param beta defines the camera rotation along the latitudinal axis
+         * @param radius defines the camera distance from its target
+         * @param target defines the camera target
+         * @param scene defines the scene the camera belongs to
+         * @param compensateDistortion defines if the camera needs to compensate the lens distorsion
+         * @param vrCameraMetrics defines the vr metrics associated to the camera
+         */
         constructor(name: string, alpha: number, beta: number, radius: number, target: Vector3, scene: Scene, compensateDistortion = true, vrCameraMetrics: VRCameraMetrics = VRCameraMetrics.GetDefault()) {
             super(name, alpha, beta, radius, target, scene);
 
@@ -14,6 +29,10 @@ module BABYLON {
             this.inputs.addVRDeviceOrientation();
         }
 
+        /**
+         * Gets camera class name
+         * @returns VRDeviceOrientationArcRotateCamera
+         */
         public getClassName(): string {
             return "VRDeviceOrientationArcRotateCamera";
         }

+ 16 - 1
src/Cameras/VR/babylon.vrDeviceOrientationFreeCamera.ts

@@ -3,8 +3,20 @@ module BABYLON {
         return () => new VRDeviceOrientationFreeCamera(name, Vector3.Zero(), scene);
     });
 
+    /**
+     * Camera used to simulate VR rendering (based on FreeCamera)
+     * @see http://doc.babylonjs.com/babylon101/cameras#vr-device-orientation-cameras
+     */
     export class VRDeviceOrientationFreeCamera extends DeviceOrientationCamera {
 
+        /**
+         * Creates a new VRDeviceOrientationFreeCamera
+         * @param name defines camera name
+         * @param position defines the start position of the camera
+         * @param scene defines the scene the camera belongs to
+         * @param compensateDistortion defines if the camera needs to compensate the lens distorsion
+         * @param vrCameraMetrics defines the vr metrics associated to the camera
+         */
         constructor(name: string, position: Vector3, scene: Scene, compensateDistortion = true, vrCameraMetrics: VRCameraMetrics = VRCameraMetrics.GetDefault()) {
             super(name, position, scene);
 
@@ -12,7 +24,10 @@ module BABYLON {
             this.setCameraRigMode(Camera.RIG_MODE_VR, { vrCameraMetrics: vrCameraMetrics });
         }
 
-
+        /**
+         * Gets camera class name
+         * @returns VRDeviceOrientationFreeCamera
+         */
         public getClassName(): string {
             return "VRDeviceOrientationFreeCamera";
         }

+ 16 - 0
src/Cameras/VR/babylon.vrDeviceOrientationGamepadCamera.ts

@@ -3,14 +3,30 @@ module BABYLON {
         return () => new VRDeviceOrientationGamepadCamera(name, Vector3.Zero(), scene);
     });
 
+    /**
+     * Camera used to simulate VR rendering (based on VRDeviceOrientationFreeCamera)
+     * @see http://doc.babylonjs.com/babylon101/cameras#vr-device-orientation-cameras
+     */
     export class VRDeviceOrientationGamepadCamera extends VRDeviceOrientationFreeCamera {
 
+        /**
+         * Creates a new VRDeviceOrientationGamepadCamera
+         * @param name defines camera name
+         * @param position defines the start position of the camera
+         * @param scene defines the scene the camera belongs to
+         * @param compensateDistortion defines if the camera needs to compensate the lens distorsion
+         * @param vrCameraMetrics defines the vr metrics associated to the camera
+         */
         constructor(name: string, position: Vector3, scene: Scene, compensateDistortion = true, vrCameraMetrics: VRCameraMetrics = VRCameraMetrics.GetDefault()) {
             super(name, position, scene, compensateDistortion, vrCameraMetrics);
             
             this.inputs.addGamepad();
         }
 
+        /**
+         * Gets camera class name
+         * @returns VRDeviceOrientationGamepadCamera
+         */
         public getClassName(): string {
             return "VRDeviceOrientationGamepadCamera";
         }

+ 1 - 1
src/Cameras/babylon.arcRotateCamera.ts

@@ -150,7 +150,7 @@
         //-- begin properties for backward compatibility for inputs
 
         /**
-         * Gets or Set the pointer angular sensibility  along the X axis  or how fast is the camera rotating.
+         * Gets or Set the pointer angular sensibility  along the X axis or how fast is the camera rotating.
          */
         public get angularSensibilityX(): number {
             var pointers = <ArcRotateCameraPointersInput>this.inputs.attached["pointers"];

+ 25 - 0
src/Cameras/babylon.arcRotateCameraInputsManager.ts

@@ -1,24 +1,49 @@
 module BABYLON {
+    /**
+     * Default Inputs manager for the ArcRotateCamera.
+     * It groups all the default supported inputs for ease of use.
+     * @see http://doc.babylonjs.com/how_to/customizing_camera_inputs
+     */
     export class ArcRotateCameraInputsManager extends CameraInputsManager<ArcRotateCamera> {
+        /**
+         * Instantiates a new ArcRotateCameraInputsManager.
+         * @param camera Defines the camera the inputs belong to
+         */
         constructor(camera: ArcRotateCamera) {
             super(camera);
         }
 
+        /**
+         * Add mouse wheel input support to the input manager.
+         * @returns the current input manager
+         */
         public addMouseWheel(): ArcRotateCameraInputsManager {
             this.add(new ArcRotateCameraMouseWheelInput());
             return this;
         }
 
+        /**
+         * Add pointers input support to the input manager.
+         * @returns the current input manager
+         */
         public addPointers(): ArcRotateCameraInputsManager {
             this.add(new ArcRotateCameraPointersInput());
             return this;
         }
 
+        /**
+         * Add keyboard input support to the input manager.
+         * @returns the current input manager
+         */
         public addKeyboard(): ArcRotateCameraInputsManager {
             this.add(new ArcRotateCameraKeyboardMoveInput());
             return this;
         }
 
+        /**
+         * Add orientation input support to the input manager.
+         * @returns the current input manager
+         */
         public addVRDeviceOrientation(): ArcRotateCameraInputsManager {
             this.add(new ArcRotateCameraVRDeviceOrientationInput());
             return this;

+ 308 - 89
src/Cameras/babylon.camera.ts

@@ -1,80 +1,81 @@
 module BABYLON {
+    /**
+     * This is the base class of all the camera used in the application.
+     * @see http://doc.babylonjs.com/features/cameras
+     */
     export class Camera extends Node {
-        public inputs: CameraInputsManager<Camera>;
-
-        // Statics
-        private static _PERSPECTIVE_CAMERA = 0;
-        private static _ORTHOGRAPHIC_CAMERA = 1;
-
-        private static _FOVMODE_VERTICAL_FIXED = 0;
-        private static _FOVMODE_HORIZONTAL_FIXED = 1;
-
-        private static _RIG_MODE_NONE = 0;
-        private static _RIG_MODE_STEREOSCOPIC_ANAGLYPH = 10;
-        private static _RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_PARALLEL = 11;
-        private static _RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_CROSSEYED = 12;
-        private static _RIG_MODE_STEREOSCOPIC_OVERUNDER = 13;
-        private static _RIG_MODE_VR = 20;
-        private static _RIG_MODE_WEBVR = 21;
-
-        public static get PERSPECTIVE_CAMERA(): number {
-            return Camera._PERSPECTIVE_CAMERA;
-        }
-
-        public static get ORTHOGRAPHIC_CAMERA(): number {
-            return Camera._ORTHOGRAPHIC_CAMERA;
-        }
+        /**
+         * This is the default projection mode used by the cameras.
+         * It helps recreating a feeling of perspective and better appreciate depth.
+         * This is the best way to simulate real life cameras.
+         */
+        public static readonly PERSPECTIVE_CAMERA = 0;
+        /**
+         * This helps creating camera with an orthographic mode.
+         * Orthographic is commonly used in engineering as a means to produce object specifications that communicate dimensions unambiguously, each line of 1 unit length (cm, meter..whatever) will appear to have the same length everywhere on the drawing. This allows the drafter to dimension only a subset of lines and let the reader know that other lines of that length on the drawing are also that length in reality. Every parallel line in the drawing is also parallel in the object.
+         */
+        public static readonly ORTHOGRAPHIC_CAMERA = 1;
 
         /**
          * This is the default FOV mode for perspective cameras.
          * This setting aligns the upper and lower bounds of the viewport to the upper and lower bounds of the camera frustum.
-         *
          */
-        public static get FOVMODE_VERTICAL_FIXED(): number {
-            return Camera._FOVMODE_VERTICAL_FIXED;
-        }
-
+        public static readonly FOVMODE_VERTICAL_FIXED = 0;
         /**
          * This setting aligns the left and right bounds of the viewport to the left and right bounds of the camera frustum.
-         *
          */
-        public static get FOVMODE_HORIZONTAL_FIXED(): number {
-            return Camera._FOVMODE_HORIZONTAL_FIXED;
-        }
-
-        public static get RIG_MODE_NONE(): number {
-            return Camera._RIG_MODE_NONE;
-        }
-
-        public static get RIG_MODE_STEREOSCOPIC_ANAGLYPH(): number {
-            return Camera._RIG_MODE_STEREOSCOPIC_ANAGLYPH;
-        }
-
-        public static get RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_PARALLEL(): number {
-            return Camera._RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_PARALLEL;
-        }
+        public static readonly FOVMODE_HORIZONTAL_FIXED = 1;
 
-        public static get RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_CROSSEYED(): number {
-            return Camera._RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_CROSSEYED;
-        }
-
-        public static get RIG_MODE_STEREOSCOPIC_OVERUNDER(): number {
-            return Camera._RIG_MODE_STEREOSCOPIC_OVERUNDER;
-        }
-
-        public static get RIG_MODE_VR(): number {
-            return Camera._RIG_MODE_VR;
-        }
-
-        public static get RIG_MODE_WEBVR(): number {
-            return Camera._RIG_MODE_WEBVR;
-        }
+        /**
+         * This specifies ther is no need for a camera rig.
+         * Basically only one eye is rendered corresponding to the camera.
+         */
+        public static readonly RIG_MODE_NONE = 0;
+        /**
+         * Simulates a camera Rig with one blue eye and one red eye.
+         * This can be use with 3d blue and red glasses.
+         */
+        public static readonly RIG_MODE_STEREOSCOPIC_ANAGLYPH = 10;
+        /**
+         * Defines that both eyes of the camera will be rendered side by side with a parallel target.
+         */
+        public static readonly RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_PARALLEL = 11;
+        /**
+         * Defines that both eyes of the camera will be rendered side by side with a none parallel target.
+         */
+        public static readonly RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_CROSSEYED = 12;
+        /**
+         * Defines that both eyes of the camera will be rendered over under each other.
+         */
+        public static readonly RIG_MODE_STEREOSCOPIC_OVERUNDER = 13;
+        /**
+         * Defines that both eyes of the camera should be renderered in a VR mode (carbox).
+         */
+        public static readonly RIG_MODE_VR = 20;
+        /**
+         * Defines that both eyes of the camera should be renderered in a VR mode (webVR).
+         */
+        public static readonly RIG_MODE_WEBVR = 21;
 
+        /**
+         * Defines if by default attaching controls should prevent the default javascript event to continue.
+         */
         public static ForceAttachControlToAlwaysPreventDefault = false;
 
+        /**
+         * @hidden
+         * Might be removed once multiview will be a thing
+         */
         public static UseAlternateWebVRRendering = false;
 
-        // Members
+        /**
+         * Define the input manager associated with the camera.
+         */
+        public inputs: CameraInputsManager<Camera>;
+
+        /**
+         * Define the current local position of the camera in the scene
+         */
         @serializeAsVector3()
         public position: Vector3;
 
@@ -85,37 +86,79 @@
         @serializeAsVector3()
         public upVector = Vector3.Up();
 
+        /**
+         * Define the current limit on the left side for an orthographic camera
+         * In scene unit
+         */
         @serialize()
         public orthoLeft: Nullable<number> = null;
 
+        /**
+         * Define the current limit on the right side for an orthographic camera
+         * In scene unit
+         */
         @serialize()
         public orthoRight: Nullable<number> = null;
 
+        /**
+         * Define the current limit on the bottom side for an orthographic camera
+         * In scene unit
+         */
         @serialize()
         public orthoBottom: Nullable<number> = null;
 
+        /**
+         * Define the current limit on the top side for an orthographic camera
+         * In scene unit
+         */
         @serialize()
         public orthoTop: Nullable<number> = null;
 
         /**
-         * FOV is set in Radians. (default is 0.8)
+         * Field Of View is set in Radians. (default is 0.8)
          */
         @serialize()
         public fov = 0.8;
 
+        /**
+         * Define the minimum distance the camera can see from.
+         * This is important to note that the depth buffer are not infinite and the closer it starts 
+         * the more your scene might encounter depth fighting issue.
+         */
         @serialize()
         public minZ = 1;
 
+        /**
+         * Define the maximum distance the camera can see to.
+         * This is important to note that the depth buffer are not infinite and the further it end 
+         * the more your scene might encounter depth fighting issue.
+         */
         @serialize()
         public maxZ = 10000.0;
 
+        /**
+         * Define the default inertia of the camera.
+         * This helps giving a smooth feeling to the camera movement.
+         */
         @serialize()
         public inertia = 0.9;
 
+        /**
+         * Define the mode of the camera (Camera.PERSPECTIVE_CAMERA or Camera.PERSPECTIVE_ORTHOGRAPHIC)
+         */
         @serialize()
         public mode = Camera.PERSPECTIVE_CAMERA;
+
+        /**
+         * Define wether the camera is intermediate.
+         * This is usefull to not present the output directly to the screen in case of rig without post process for instance
+         */
         public isIntermediate = false;
 
+        /**
+         * Define the viewport of the camera.
+         * This correspond to the portion of the screen the camera will render to in normalized 0 to 1 unit.
+         */
         public viewport = new Viewport(0, 0, 1.0, 1.0);
 
         /**
@@ -131,16 +174,50 @@
         @serialize()
         public fovMode: number = Camera.FOVMODE_VERTICAL_FIXED;
 
-        // Camera rig members
+        /**
+         * Rig mode of the camera.
+         * This is usefull to create the camera with two "eyes" instead of one to create VR or stereoscopic scenes.
+         * This is normally controlled byt the camera themselves as internal use.
+         */
         @serialize()
         public cameraRigMode = Camera.RIG_MODE_NONE;
 
+        /**
+         * Defines the distance between both "eyes" in case of a RIG
+         */
         @serialize()
         public interaxialDistance: number
 
+        /**
+         * Defines if stereoscopic rendering is done side by side or over under.
+         */
         @serialize()
         public isStereoscopicSideBySide: boolean
 
+        /**
+         * Defines the list of custom render target the camera should render to.
+         * This is pretty helpfull if you wish to make a camera render to a texture you could reuse somewhere 
+         * else in the scene.
+         */
+        public customRenderTargets = new Array<RenderTargetTexture>();
+
+        /**
+         * Observable triggered when the camera view matrix has changed.
+         */
+        public onViewMatrixChangedObservable = new Observable<Camera>();
+        /**
+         * Observable triggered when the camera Projection matrix has changed.
+         */
+        public onProjectionMatrixChangedObservable = new Observable<Camera>();
+        /**
+         * Observable triggered when the inputs have been processed.
+         */
+        public onAfterCheckInputsObservable = new Observable<Camera>();
+        /**
+         * Observable triggered when reset has been called and applied to the camera.
+         */
+        public onRestoreStateObservable = new Observable<Camera>();
+
         /** @hidden */
         public _cameraRigParams: any;
         /** @hidden */
@@ -154,27 +231,34 @@
         /** @hidden */
         public _alternateCamera: Camera;
 
-        public customRenderTargets = new Array<RenderTargetTexture>();
-
-        // Observables
-        public onViewMatrixChangedObservable = new Observable<Camera>();
-        public onProjectionMatrixChangedObservable = new Observable<Camera>();
-        public onAfterCheckInputsObservable = new Observable<Camera>();
-        public onRestoreStateObservable = new Observable<Camera>();
-
-        // Cache
-        private _computedViewMatrix = Matrix.Identity();
+        /** @hidden */
         public _projectionMatrix = new Matrix();
-        private _doNotComputeProjectionMatrix = false;
+
+        /** @hidden */
         public _postProcesses = new Array<Nullable<PostProcess>>();
-        private _transformMatrix = Matrix.Zero();
 
+        /** @hidden */
         public _activeMeshes = new SmartArray<AbstractMesh>(256);
 
         protected _globalPosition = Vector3.Zero();
+
+        private _computedViewMatrix = Matrix.Identity();
+        private _doNotComputeProjectionMatrix = false;
+        private _transformMatrix = Matrix.Zero();
         private _frustumPlanes: Plane[];
         private _refreshFrustumPlanes = true;
+        private _storedFov: number;
+        private _stateStored: boolean;
 
+        /**
+         * Instantiates a new camera object.
+         * This should not be used directly but through the inherited cameras: ArcRotate, Free...
+         * @see http://doc.babylonjs.com/features/cameras
+         * @param name Defines the name of the camera in the scene
+         * @param position Defines the position of the camera
+         * @param scene Defines the scene the camera belongs too
+         * @param setActiveOnSceneIfNoneActive Defines if the camera should be set as active after creation if no other camera have been defined in the scene
+         */
         constructor(name: string, position: Vector3, scene: Scene, setActiveOnSceneIfNoneActive = true) {
             super(name, scene);
 
@@ -187,11 +271,9 @@
             this.position = position;
         }
 
-        private _storedFov: number;
-        private _stateStored: boolean;
-
         /**
          * Store current camera state (fov, position, etc..)
+         * @returns the camera
          */
         public storeState(): Camera {
             this._stateStored = true;
@@ -214,7 +296,8 @@
         }
 
         /**
-         * Restored camera state. You must call storeState() first
+         * Restored camera state. You must call storeState() first.
+         * @returns true if restored and false otherwise
          */
         public restoreState(): boolean {
             if (this._restoreStateValues()) {
@@ -225,12 +308,18 @@
             return false;
         }
 
+        /**
+         * Gets the class name of the camera.
+         * @returns the class name
+         */
         public getClassName(): string {
             return "Camera";
         }
 
         /**
-         * @param {boolean} fullDetails - support for multiple levels of logging within scene loading
+         * Gets a string representation of the camera usefull for debug purpose.
+         * @param fullDetails Defines that a more verboe level of logging is required
+         * @returns the string representation
          */
         public toString(fullDetails?: boolean): string {
             var ret = "Name: " + this.name;
@@ -245,14 +334,26 @@
             return ret;
         }
 
+        /**
+         * Gets the current world space position of the camera.
+         */
         public get globalPosition(): Vector3 {
             return this._globalPosition;
         }
 
+        /**
+         * Gets the list of active meshes this frame (meshes no culled or excluded by lod s in the frame)
+         * @returns the active meshe list
+         */
         public getActiveMeshes(): SmartArray<AbstractMesh> {
             return this._activeMeshes;
         }
 
+        /**
+         * Check wether a mesh is part of the current active mesh list of the camera
+         * @param mesh Defines the mesh to check 
+         * @returns true if active, false otherwise
+         */
         public isActiveMesh(mesh: Mesh): boolean {
             return (this._activeMeshes.indexOf(mesh) !== -1);
         }
@@ -273,7 +374,6 @@
             return super.isReady(completeCheck);
         }
 
-        //Cache
         /** @hidden */
         public _initCache() {
             super._initCache();
@@ -307,7 +407,6 @@
             this._cache.upVector.copyFrom(this.upVector);
         }
 
-        // Synchronized
         /** @hidden */
         public _isSynchronized(): boolean {
             return this._isSynchronizedViewMatrix() && this._isSynchronizedProjectionMatrix();
@@ -352,13 +451,24 @@
             return check;
         }
 
-        // Controls
+        /**
+         * Attach the input controls to a specific dom element to get the input from.
+         * @param element Defines the element the controls should be listened from
+         * @param noPreventDefault Defines whether event caught by the controls should call preventdefault() (https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault)
+         */
         public attachControl(element: HTMLElement, noPreventDefault?: boolean): void {
         }
 
+        /**
+         * Detach the current controls from the specified dom element.
+         * @param element Defines the element to stop listening the inputs from
+         */
         public detachControl(element: HTMLElement): void {
         }
 
+        /**
+         * Update the camera state according to the different inputs gathered during the frame.
+         */
         public update(): void {
             this._checkInputs();
             if (this.cameraRigMode !== Camera.RIG_MODE_NONE) {
@@ -371,6 +481,7 @@
             this.onAfterCheckInputsObservable.notifyObservers(this);
         }
 
+        /** @hidden */
         public get rigCameras(): Camera[] {
             return this._rigCameras;
         }
@@ -420,6 +531,13 @@
             }
         }
 
+        /**
+         * Attach a post process to the camera.
+         * @see http://doc.babylonjs.com/how_to/how_to_use_postprocesses#attach-postprocess
+         * @param postProcess The post process to attach to the camera
+         * @param insertAt The position of the post process in case several of them are in use in the scene
+         * @returns the position the post process has been inserted at
+         */
         public attachPostProcess(postProcess: PostProcess, insertAt: Nullable<number> = null): number {
             if (!postProcess.isReusable() && this._postProcesses.indexOf(postProcess) > -1) {
                 Tools.Error("You're trying to reuse a post process not defined as reusable.");
@@ -437,6 +555,11 @@
             return this._postProcesses.indexOf(postProcess);
         }
 
+        /**
+         * Detach a post process to the camera.
+         * @see http://doc.babylonjs.com/how_to/how_to_use_postprocesses#attach-postprocess
+         * @param postProcess The post process to detach from the camera
+         */
         public detachPostProcess(postProcess: PostProcess): void {
             var idx = this._postProcesses.indexOf(postProcess);
             if (idx !== -1) {
@@ -445,6 +568,9 @@
             this._cascadePostProcessesToRigCams(); // also ensures framebuffer invalidated
         }
 
+        /**
+         * Gets the current world matrix of the camera
+         */
         public getWorldMatrix(): Matrix {
             if (this._isSynchronizedViewMatrix()) {
                 return this._worldMatrix;
@@ -457,10 +583,15 @@
         }
 
         /** @hidden */
-        public _getViewMatrix(): Matrix {
+        protected _getViewMatrix(): Matrix {
             return Matrix.Identity();
         }
 
+        /**
+         * Gets the current view matrix of the camera.
+         * @param force forces the camera to recompute the matrix without looking at the cached state
+         * @returns the view matrix
+         */
         public getViewMatrix(force?: boolean): Matrix {
             if (!force && this._isSynchronizedViewMatrix()) {
                 return this._computedViewMatrix;
@@ -484,7 +615,12 @@
             return this._computedViewMatrix;
         }
 
-
+        /**
+         * Freeze the projection matrix.
+         * It will prevent the cache check of the camera projection compute and can speed up perf 
+         * if no parameter of the camera are meant to change
+         * @param projection Defines manually a projection if necessary
+         */
         public freezeProjectionMatrix(projection?: Matrix): void {
             this._doNotComputeProjectionMatrix = true;
             if (projection !== undefined) {
@@ -492,10 +628,18 @@
             }
         };
 
+        /**
+         * Unfreeze the projection matrix if it has previously been freezed by freezeProjectionMatrix.
+         */
         public unfreezeProjectionMatrix(): void {
             this._doNotComputeProjectionMatrix = false;
         };
 
+        /**
+         * Gets the current projection matrix of the camera.
+         * @param force forces the camera to recompute the matrix without looking at the cached state
+         * @returns the projection matrix
+         */
         public getProjectionMatrix(force?: boolean): Matrix {
             if (this._doNotComputeProjectionMatrix || (!force && this._isSynchronizedProjectionMatrix())) {
                 return this._projectionMatrix;
@@ -578,7 +722,7 @@
             return this._transformMatrix;
         }
 
-        private updateFrustumPlanes(): void {
+        private _updateFrustumPlanes(): void {
             if (!this._refreshFrustumPlanes) {
                 return;
             }
@@ -594,18 +738,37 @@
             this._refreshFrustumPlanes = false;
         }
 
+        /**
+         * Checks if a cullable object (mesh...) is in the camera frustum
+         * This checks the bounding box center. See isCompletelyInFrustum for a full bounding check
+         * @param target The object to check
+         * @returns true if the object is in frustum otherwise false
+         */
         public isInFrustum(target: ICullable): boolean {
-            this.updateFrustumPlanes();
+            this._updateFrustumPlanes();
 
             return target.isInFrustum(this._frustumPlanes);
         }
 
+        /**
+         * Checks if a cullable object (mesh...) is in the camera frustum
+         * Unlike isInFrustum this cheks the full bounding box
+         * @param target The object to check
+         * @returns true if the object is in frustum otherwise false
+         */
         public isCompletelyInFrustum(target: ICullable): boolean {
-            this.updateFrustumPlanes();
+            this._updateFrustumPlanes();
 
             return target.isCompletelyInFrustum(this._frustumPlanes);
         }
 
+        /**
+         * Gets a ray in the forward direction from the camera.
+         * @param length Defines the length of the ray to create
+         * @param transform Defines the transform to apply to the ray, by default the world matrx is used to create a workd space ray
+         * @param origin Defines the start point of the ray which defaults to the camera position
+         * @returns the forward ray
+         */
         public getForwardRay(length = 100, transform?: Matrix, origin?: Vector3): Ray {
             if (!transform) {
                 transform = this.getWorldMatrix();
@@ -683,7 +846,9 @@
             super.dispose(doNotRecurse, disposeMaterialAndTextures);
         }
 
-        // ---- Camera rigs section ----
+        /**
+         * Gets the left camera of a rig setup in case of Rigged Camera
+         */
         public get leftCamera(): Nullable<FreeCamera> {
             if (this._rigCameras.length < 1) {
                 return null;
@@ -691,6 +856,9 @@
             return (<FreeCamera>this._rigCameras[0]);
         }
 
+        /**
+         * Gets the right camera of a rig setup in case of Rigged Camera
+         */
         public get rightCamera(): Nullable<FreeCamera> {
             if (this._rigCameras.length < 2) {
                 return null;
@@ -698,6 +866,10 @@
             return (<FreeCamera>this._rigCameras[1]);
         }
 
+        /**
+         * Gets the left camera target of a rig setup in case of Rigged Camera
+         * @returns the target position
+         */
         public getLeftTarget(): Nullable<Vector3> {
             if (this._rigCameras.length < 1) {
                 return null;
@@ -705,6 +877,10 @@
             return (<TargetCamera>this._rigCameras[0]).getTarget();
         }
 
+        /**
+         * Gets the right camera target of a rig setup in case of Rigged Camera
+         * @returns the target position
+         */
         public getRightTarget(): Nullable<Vector3> {
             if (this._rigCameras.length < 2) {
                 return null;
@@ -712,6 +888,9 @@
             return (<TargetCamera>this._rigCameras[1]).getTarget();
         }
 
+        /**
+         * @hidden
+         */
         public setCameraRigMode(mode: number, rigParams: any): void {
             if (this.cameraRigMode === mode) {
                 return;
@@ -850,6 +1029,7 @@
             return Matrix.Identity();
         }
 
+        /** @hidden */
         public setCameraRigParameter(name: string, value: any) {
             if (!this._cameraRigParams) {
                 this._cameraRigParams = {};
@@ -863,6 +1043,7 @@
 
         /**
          * needs to be overridden by children so sub has required properties to be copied
+         * @hidden
          */
         public createRigCamera(name: string, cameraIndex: number): Nullable<Camera> {
             return null;
@@ -889,6 +1070,10 @@
         public _setupInputs() {
         }
 
+        /**
+         * Serialiaze the camera setup to a json represention
+         * @returns the JSON representation
+         */
         public serialize(): any {
             var serializationObject = SerializationHelper.Serialize(this);
 
@@ -910,10 +1095,20 @@
             return serializationObject;
         }
 
+        /**
+         * Clones the current camera.
+         * @param name The cloned camera name
+         * @returns the cloned camera
+         */
         public clone(name: string): Camera {
             return SerializationHelper.Clone(Camera.GetConstructorFromName(this.getClassName(), name, this.getScene(), this.interaxialDistance, this.isStereoscopicSideBySide), this);
         }
 
+        /**
+         * Gets the direction of the camera relative to a given local axis.
+         * @param localAxis Defines the reference axis to provide a relative direction.
+         * @return the direction
+         */
         public getDirection(localAxis: Vector3): Vector3 {
             var result = Vector3.Zero();
 
@@ -922,10 +1117,24 @@
             return result;
         }
 
+        /**
+         * Gets the direction of the camera relative to a given local axis into a passed vector.
+         * @param localAxis Defines the reference axis to provide a relative direction.
+         * @param result Defines the vector to store the result in
+         */
         public getDirectionToRef(localAxis: Vector3, result: Vector3): void {
             Vector3.TransformNormalToRef(localAxis, this.getWorldMatrix(), result);
         }
 
+        /**
+         * Gets a camera constructor for a given camera type
+         * @param type The type of the camera to construct (should be equal to one of the camera class name)
+         * @param name The name of the camera the result will be able to instantiate
+         * @param scene The scene the result will construct the camera in
+         * @param interaxial_distance In case of stereoscopic setup, the distance between both eyes
+         * @param isStereoscopicSideBySide In case of stereoscopic setup, should the sereo be side b side
+         * @returns a factory method to construc the camera
+         */
         static GetConstructorFromName(type: string, name: string, scene: Scene, interaxial_distance: number = 0, isStereoscopicSideBySide: boolean = true): () => Camera {
             let constructorFunc = Node.Construct(type, name, scene, {
                 interaxial_distance: interaxial_distance,
@@ -940,10 +1149,20 @@
             return () => new UniversalCamera(name, Vector3.Zero(), scene);
         }
 
+        /**
+         * Compute the world  matrix of the camera.
+         * @returns the camera workd matrix
+         */
         public computeWorldMatrix(): Matrix {
             return this.getWorldMatrix();
         }
 
+        /**
+         * Parse a JSON and creates the camera from the parsed information
+         * @param parsedCamera The JSON to parse
+         * @param scene The scene to instantiate the camera in
+         * @returns the newly constructed camera
+         */
         public static Parse(parsedCamera: any, scene: Scene): Camera {
             var type = parsedCamera.type;
             var construct = Camera.GetConstructorFromName(type, parsedCamera.name, scene, parsedCamera.interaxial_distance, parsedCamera.isStereoscopicSideBySide);

+ 121 - 15
src/Cameras/babylon.cameraInputsManager.ts

@@ -1,27 +1,98 @@
 module BABYLON {
+    /**
+     * This is a list of all the different input types that are available in the application.
+     * Fo instance: ArcRotateCameraGamepadInput...
+     */
     export var CameraInputTypes = {};
 
+    /**
+     * This is the contract to implement in order to create a new input class.
+     * Inputs are dealing with listening to user actions and moving the camera accordingly.
+     */
     export interface ICameraInput<TCamera extends Camera> {
+        /**
+         * Defines the camera the input is attached to.
+         */
         camera: Nullable<TCamera>;
+        /**
+         * Gets the class name of the current intput.
+         * @returns the class name
+         */
         getClassName(): string;
+        /**
+         * Get the friendly name associated with the input class.
+         * @returns the input friendly name
+         */
         getSimpleName(): string;
-        attachControl: (element: HTMLElement, noPreventDefault?: boolean) => void;
-        detachControl: (element: Nullable<HTMLElement>) => void;
+        /**
+         * Attach the input controls to a specific dom element to get the input from.
+         * @param element Defines the element the controls should be listened from
+         * @param noPreventDefault Defines whether event caught by the controls should call preventdefault() (https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault)
+         */
+        attachControl(element: HTMLElement, noPreventDefault?: boolean): void;
+        /**
+         * Detach the current controls from the specified dom element.
+         * @param element Defines the element to stop listening the inputs from
+         */
+        detachControl(element: Nullable<HTMLElement>): void;
+        /**
+         * Update the current camera state depending on the inputs that have been used this frame.
+         * This is a dynamically created lambda to avoid the performance penalty of looping for inputs in the render loop.
+         */
         checkInputs?: () => void;
     }
 
+    /**
+     * Represents a map of input types to input instance or input index to input instance.
+     */
     export interface CameraInputsMap<TCamera extends Camera> {
+        /**
+         * Accessor to the input by input type.
+         */
         [name: string]: ICameraInput<TCamera>;
+        /**
+         * Accessor to the input by input index.
+         */
         [idx: number]: ICameraInput<TCamera>;
     }
 
+    /**
+     * This represents the input manager used within a camera.
+     * It helps dealing with all the different kind of input attached to a camera.
+     * @see http://doc.babylonjs.com/how_to/customizing_camera_inputs
+     */
     export class CameraInputsManager<TCamera extends Camera> {
-        attached: CameraInputsMap<TCamera>;
+        /**
+         * Defines the list of inputs attahed to the camera.
+         */
+        public attached: CameraInputsMap<TCamera>;
+
+        /**
+         * Defines the dom element the camera is collecting inputs from.
+         * This is null if the controls have not been attached.
+         */
         public attachedElement: Nullable<HTMLElement>;
+
+        /**
+         * Defines whether event caught by the controls should call preventdefault() (https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault)
+         */
         public noPreventDefault: boolean;
-        camera: TCamera;
-        checkInputs: () => void;
 
+        /**
+         * Defined the camera the input manager belongs to.
+         */
+        public camera: TCamera;
+
+        /**
+         * Update the current camera state depending on the inputs that have been used this frame.
+         * This is a dynamically created lambda to avoid the performance penalty of looping for inputs in the render loop.
+         */
+        public checkInputs: () => void;
+
+        /**
+         * Instantiate a new Camera Input Manager.
+         * @param camera Defines the camera the input manager blongs to
+         */
         constructor(camera: TCamera) {
             this.attached = {};
             this.camera = camera;
@@ -33,7 +104,7 @@ module BABYLON {
          * @see http://doc.babylonjs.com/how_to/customizing_camera_inputs
          * @param input camera input method
          */
-        public add(input: ICameraInput<TCamera>) {
+        public add(input: ICameraInput<TCamera>): void {
             var type = input.getSimpleName();
             if (this.attached[type]) {
                 Tools.Warn("camera input of type " + type + " already exists on camera");
@@ -54,12 +125,13 @@ module BABYLON {
                 input.attachControl(this.attachedElement);
             }
         }
+
         /**
          * Remove a specific input method from a camera
          * example: camera.inputs.remove(camera.inputs.attached.mouse);
          * @param inputToRemove camera input method
          */
-        public remove(inputToRemove: ICameraInput<TCamera>) {
+        public remove(inputToRemove: ICameraInput<TCamera>): void {
             for (var cam in this.attached) {
                 var input = this.attached[cam];
                 if (input === inputToRemove) {
@@ -71,7 +143,12 @@ module BABYLON {
             }
         }
 
-        public removeByType(inputType: string) {
+        /**
+         * Remove a specific input type from a camera
+         * example: camera.inputs.remove("ArcRotateCameraGamepadInput");
+         * @param inputType the type of the input to remove
+         */
+        public removeByType(inputType: string): void {
             for (var cam in this.attached) {
                 var input = this.attached[cam];
                 if (input.getClassName() === inputType) {
@@ -91,13 +168,22 @@ module BABYLON {
             }
         }
 
-        public attachInput(input: ICameraInput<TCamera>) {
+        /**
+         * Attach the input controls to the currently attached dom element to listen the events from.
+         * @param input Defines the input to attach
+         */
+        public attachInput(input: ICameraInput<TCamera>): void {
             if (this.attachedElement) {
                 input.attachControl(this.attachedElement, this.noPreventDefault);
             }
         }
 
-        public attachElement(element: HTMLElement, noPreventDefault: boolean = false) {
+        /**
+         * Attach the current manager inputs controls to a specific dom element to listen the events from.
+         * @param element Defines the dom element to collect the events from
+         * @param noPreventDefault Defines whether event caught by the controls should call preventdefault() (https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault)
+         */
+        public attachElement(element: HTMLElement, noPreventDefault: boolean = false): void {
             if (this.attachedElement) {
                 return;
             }
@@ -111,7 +197,12 @@ module BABYLON {
             }
         }
 
-        public detachElement(element: HTMLElement, disconnect = false) {
+        /**
+         * Detach the current manager inputs controls from a specific dom element.
+         * @param element Defines the dom element to collect the events from
+         * @param disconnect Defines whether the input should be removed from the current list of attached inputs
+         */
+        public detachElement(element: HTMLElement, disconnect = false): void {
             if (this.attachedElement !== element) {
                 return;
             }
@@ -127,7 +218,11 @@ module BABYLON {
             this.attachedElement = null;
         }
 
-        public rebuildInputCheck() {
+        /**
+         * Rebuild the dynamic inputCheck function from the current list of 
+         * defined inputs in the manager.
+         */
+        public rebuildInputCheck(): void {
             this.checkInputs = () => { };
 
             for (var cam in this.attached) {
@@ -141,7 +236,7 @@ module BABYLON {
         /**
          * Remove all attached input methods from a camera
          */
-        public clear() {
+        public clear(): void {
             if (this.attachedElement) {
                 this.detachElement(this.attachedElement, true);
             }
@@ -150,7 +245,13 @@ module BABYLON {
             this.checkInputs = () => { };
         }
 
-        public serialize(serializedCamera: any) {
+        /**
+         * Serialize the current input manager attached to a camera.
+         * This ensures than once parsed, 
+         * the input associated to the camera will be identical to the current ones
+         * @param serializedCamera Defines the camera serialization JSON the input serialization should write to
+         */
+        public serialize(serializedCamera: any): void {
             var inputs: { [key: string]: any } = {};
             for (var cam in this.attached) {
                 var input = this.attached[cam];
@@ -161,7 +262,12 @@ module BABYLON {
             serializedCamera.inputsmgr = inputs;
         }
 
-        public parse(parsedCamera: any) {
+        /**
+         * Parses an input manager serialized JSON to restore the previous list of inputs
+         * and states associated to a camera.
+         * @param parsedCamera Defines the JSON to parse
+         */
+        public parse(parsedCamera: any): void {
             var parsedInputs = parsedCamera.inputsmgr;
             if (parsedInputs) {
                 this.clear();

+ 52 - 18
src/Cameras/babylon.followCamera.ts

@@ -7,36 +7,64 @@
         return () => new ArcFollowCamera(name, 0, 0, 1.0, null, scene);
     });
 
+    /**
+     * A follow camera takes a mesh as a target and follows it as it moves. Both a free camera version followCamera and 
+     * an arc rotate version arcFollowCamera are available.
+     * @see http://doc.babylonjs.com/features/cameras#follow-camera
+     */
     export class FollowCamera extends TargetCamera {
+        /**
+         * Distance the follow camera should follow an object at
+         */
         @serialize()
         public radius: number = 12;
 
+        /**
+         * Define a rotation offset between the camera and the object it follows
+         */
         @serialize()
         public rotationOffset: number = 0;
 
+        /**
+         * Define a height offset between the camera and the object it follows.
+         * It can help following an object from the top (like a car chaing a plane)
+         */
         @serialize()
         public heightOffset: number = 4;
 
+        /**
+         * Define how fast the camera can accelerate to follow it s target.
+         */
         @serialize()
         public cameraAcceleration: number = 0.05;
 
+        /**
+         * Define the speed limit of the camera following an object.
+         */
         @serialize()
         public maxCameraSpeed: number = 20;
 
+        /**
+         * Define the target of the camera.
+         */
         @serializeAsMeshReference("lockedTargetId")
         public lockedTarget: Nullable<AbstractMesh>;
 
+        /**
+         * Instantiates the follow camera.
+         * @see http://doc.babylonjs.com/features/cameras#follow-camera
+         * @param name Define the name of the camera in the scene
+         * @param position Define the position of the camera
+         * @param scene Define the scene the camera belong to
+         * @param lockedTarget Define the target of the camera
+         */
         constructor(name: string, position: Vector3, scene: Scene, lockedTarget: Nullable<AbstractMesh> = null) {
             super(name, position, scene);
 
             this.lockedTarget = lockedTarget;
         }
 
-        private getRadians(degrees: number): number {
-            return degrees * Math.PI / 180;
-        }
-
-        private follow(cameraTarget: AbstractMesh) {
+        private _follow(cameraTarget: AbstractMesh) {
             if (!cameraTarget)
                 return;
 
@@ -48,7 +76,7 @@
             } else {
                 yRotation = cameraTarget.rotation.y;
             }
-            var radians = this.getRadians(this.rotationOffset) + yRotation;
+            var radians = Tools.ToRadians(this.rotationOffset) + yRotation;
             var targetPosition = cameraTarget.getAbsolutePosition();
             var targetX: number = targetPosition.x + Math.sin(radians) * this.radius;
 
@@ -80,10 +108,14 @@
         public _checkInputs(): void {
             super._checkInputs();
             if (this.lockedTarget) {
-                this.follow(this.lockedTarget);
+                this._follow(this.lockedTarget);
             }
         }
 
+        /**
+         * Gets the camera class name.
+         * @returns the class name
+         */
         public getClassName(): string {
             return "FollowCamera";
         }
@@ -91,7 +123,8 @@
 
     /**
      * Arc Rotate version of the follow camera.
-     * It still follows a defined mesh but in an Arc Rotate Camera fashion.
+     * It still follows a Defined mesh but in an Arc Rotate Camera fashion.
+     * @see http://doc.babylonjs.com/features/cameras#follow-camera
      */
     export class ArcFollowCamera extends TargetCamera {
 
@@ -99,12 +132,13 @@
 
         /**
          * Instantiates a new ArcFollowCamera
-         * @param name Defines the name of the camera
-         * @param alpha Defines the rotation angle of the camera around the logitudinal axis
-         * @param beta Defines the rotation angle of the camera around the elevation axis
-         * @param radius Defines the radius of the camera from its target point
-         * @param target Defines the target of the camera
-         * @param scene Defines the scene the camera belongs to
+         * @see http://doc.babylonjs.com/features/cameras#follow-camera
+         * @param name Define the name of the camera
+         * @param alpha Define the rotation angle of the camera around the logitudinal axis
+         * @param beta Define the rotation angle of the camera around the elevation axis
+         * @param radius Define the radius of the camera from its target point
+         * @param target Define the target of the camera
+         * @param scene Define the scene the camera belongs to
          */
         constructor(name: string, 
             /** The longitudinal angle of the camera */
@@ -113,14 +147,14 @@
             public beta: number, 
             /** The radius of the camera from its target */
             public radius: number, 
-            /** Defines the camera target (the messh it should follow) */
+            /** Define the camera target (the messh it should follow) */
             public target: Nullable<AbstractMesh>, 
             scene: Scene) {
             super(name, Vector3.Zero(), scene);
-            this.follow();
+            this._follow();
         }
 
-        private follow(): void {
+        private _follow(): void {
             if (!this.target) {
                 return;
             }
@@ -136,7 +170,7 @@
         /** @hidden */
         public _checkInputs(): void {
             super._checkInputs();
-            this.follow();
+            this._follow();
         }
 
         /**

+ 69 - 4
src/Cameras/babylon.freeCamera.ts

@@ -4,22 +4,45 @@
         return () => new UniversalCamera(name, Vector3.Zero(), scene);
     });
 
+    /**
+     * This represents a free type of camera. It can be usefull in First Person Shooter game for instance.
+     * Please consider using the new UniversalCamera instead as it adds more functionality like the gamepad.
+     * @see http://doc.babylonjs.com/features/cameras#universal-camera
+     */
     export class FreeCamera extends TargetCamera {
+        /**
+         * Define the collision ellipsoid of the camera.
+         * This is helpful to simulate a camera body like the player body around the camera
+         * @see http://doc.babylonjs.com/babylon101/cameras,_mesh_collisions_and_gravity#arcrotatecamera
+         */
         @serializeAsVector3()
         public ellipsoid = new Vector3(0.5, 1, 0.5);
 
+        /**
+         * Define an offset for the position of the ellipsoid around the camera.
+         * This can be helpful to determine the center of the body near the gravity center of the body 
+         * instead of its head.
+         */
         @serializeAsVector3()
         public ellipsoidOffset = new Vector3(0, 0, 0);
 
+        /**
+         * Enable or disable collisions of the camera with the rest of the scene objects.
+         */
         @serialize()
         public checkCollisions = false;
 
+        /**
+         * Enable or disable gravity on the camera.
+         */
         @serialize()
         public applyGravity = false;
 
+        /**
+         * Define the input manager associated to the camera.
+         */
         public inputs: FreeCameraInputsManager;
 
-        //-- begin properties for backward compatibility for inputs
         /**
          * Gets the input sensibility for a mouse input. (default is 2000.0)
          * Higher values reduce sensitivity.
@@ -42,6 +65,9 @@
                 mouse.angularSensibility = value;
         }
 
+        /**
+         * Gets or Set the list of keyboard keys used to control the forward move of the camera.
+         */
         public get keysUp(): number[] {
             var keyboard = <FreeCameraKeyboardMoveInput>this.inputs.attached["keyboard"];
             if (keyboard)
@@ -56,6 +82,9 @@
                 keyboard.keysUp = value;
         }
 
+        /**
+         * Gets or Set the list of keyboard keys used to control the backward move of the camera.
+         */
         public get keysDown(): number[] {
             var keyboard = <FreeCameraKeyboardMoveInput>this.inputs.attached["keyboard"];
             if (keyboard)
@@ -70,6 +99,9 @@
                 keyboard.keysDown = value;
         }
 
+        /**
+         * Gets or Set the list of keyboard keys used to control the left strafe move of the camera.
+         */
         public get keysLeft(): number[] {
             var keyboard = <FreeCameraKeyboardMoveInput>this.inputs.attached["keyboard"];
             if (keyboard)
@@ -84,6 +116,9 @@
                 keyboard.keysLeft = value;
         }
 
+        /**
+         * Gets or Set the list of keyboard keys used to control the right strafe move of the camera.
+         */
         public get keysRight(): number[] {
             var keyboard = <FreeCameraKeyboardMoveInput>this.inputs.attached["keyboard"];
             if (keyboard)
@@ -98,8 +133,9 @@
                 keyboard.keysRight = value;
         }
 
-        //-- end properties for backward compatibility for inputs
-
+        /**
+         * Event raised when the camera collide with a mesh in the scene.
+         */
         public onCollide: (collidedMesh: AbstractMesh) => void;
 
         private _collider: Collider;
@@ -113,17 +149,36 @@
         /** @hidden */
         public _transformedDirection: Vector3;
 
+        /**
+         * Instantiates a Free Camera.
+         * This represents a free type of camera. It can be usefull in First Person Shooter game for instance.
+         * Please consider using the new UniversalCamera instead as it adds more functionality like touch to this camera.
+         * @see http://doc.babylonjs.com/features/cameras#universal-camera
+         * @param name Define the name of the camera in the scene
+         * @param position Define the start position of the camera in the scene
+         * @param scene Define the scene the camera belongs to
+         * @param setActiveOnSceneIfNoneActive Defines wheter the camera should be marked as active if not other active cameras have been defined
+         */
         constructor(name: string, position: Vector3, scene: Scene, setActiveOnSceneIfNoneActive = true) {
             super(name, position, scene, setActiveOnSceneIfNoneActive);
             this.inputs = new FreeCameraInputsManager(this);
             this.inputs.addKeyboard().addMouse();
         }
 
-        // Controls
+        /**
+         * Attached controls to the current camera.
+         * @param element Defines the element the controls should be listened from
+         * @param noPreventDefault Defines whether event caught by the controls should call preventdefault() (https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault)
+         */
         public attachControl(element: HTMLElement, noPreventDefault?: boolean): void {
             this.inputs.attachElement(element, noPreventDefault);
         }
 
+        /**
+         * Detach the current controls from the camera.
+         * The camera will stop reacting to inputs.
+         * @param element Defines the element to stop listening the inputs from
+         */
         public detachControl(element: HTMLElement): void {
             this.inputs.detachElement(element);
 
@@ -134,6 +189,9 @@
         // Collisions
         private _collisionMask = -1;
 
+        /**
+         * Define a collision mask to limit the list of object the camera can collide with
+         */
         public get collisionMask(): number {
             return this._collisionMask;
         }
@@ -222,11 +280,18 @@
             }
         }
 
+        /**
+         * Destroy the camera and release the current resources hold by it.
+         */
         public dispose(): void {
             this.inputs.clear();
             super.dispose();
         }
 
+        /**
+         * Gets the current object class name.
+         * @return the class name
+         */
         public getClassName(): string {
             return "FreeCamera";
         }

+ 29 - 0
src/Cameras/babylon.freeCameraInputsManager.ts

@@ -1,29 +1,58 @@
 module BABYLON {
+    /**
+     * Default Inputs manager for the FreeCamera.
+     * It groups all the default supported inputs for ease of use.
+     * @see http://doc.babylonjs.com/how_to/customizing_camera_inputs
+     */
     export class FreeCameraInputsManager extends CameraInputsManager<FreeCamera> {
+        /**
+         * Instantiates a new FreeCameraInputsManager.
+         * @param camera Defines the camera the inputs belong to
+         */
         constructor(camera: FreeCamera) {
             super(camera);
         }
 
+        /**
+         * Add keyboard input support to the input manager.
+         * @returns the current input manager
+         */
         addKeyboard(): FreeCameraInputsManager {
             this.add(new FreeCameraKeyboardMoveInput());
             return this;
         }
 
+        /**
+         * Add mouse input support to the input manager.
+         * @returns the current input manager
+         */
         addMouse(touchEnabled = true): FreeCameraInputsManager {
             this.add(new FreeCameraMouseInput(touchEnabled));
             return this;
         }
 
+        /**
+         * Add orientation input support to the input manager.
+         * @returns the current input manager
+         */
         addDeviceOrientation(): FreeCameraInputsManager {
             this.add(new FreeCameraDeviceOrientationInput());
             return this;
         }
 
+        /**
+         * Add touch input support to the input manager.
+         * @returns the current input manager
+         */
         addTouch(): FreeCameraInputsManager {
             this.add(new FreeCameraTouchInput());
             return this;
         }
 
+        /**
+         * Add virtual joystick input support to the input manager.
+         * @returns the current input manager
+         */
         addVirtualJoystick(): FreeCameraInputsManager {
             this.add(new FreeCameraVirtualJoystickInput());
             return this;

+ 18 - 32
src/Cameras/babylon.gamepadCamera.ts

@@ -3,43 +3,29 @@ module BABYLON {
         return () => new GamepadCamera(name, Vector3.Zero(), scene);
     });
 
-    // We're mainly based on the logic defined into the FreeCamera code
+    /**
+     * This represents a FPS type of camera. This is only here for back compat purpose.
+     * Please use the UniversalCamera instead as both are identical.
+     * @see http://doc.babylonjs.com/features/cameras#universal-camera
+     */
     export class GamepadCamera extends UniversalCamera {
-        //-- Begin properties for backward compatibility for inputs
-        public get gamepadAngularSensibility(): number {
-            var gamepad = <FreeCameraGamepadInput>this.inputs.attached["gamepad"];
-            if (gamepad)
-                return gamepad.gamepadAngularSensibility;
-
-            return 0;
-        }
-
-        public set gamepadAngularSensibility(value: number) {
-            var gamepad = <FreeCameraGamepadInput>this.inputs.attached["gamepad"];
-            if (gamepad)
-                gamepad.gamepadAngularSensibility = value;
-        }
-
-        public get gamepadMoveSensibility(): number {
-            var gamepad = <FreeCameraGamepadInput>this.inputs.attached["gamepad"];
-            if (gamepad)
-                return gamepad.gamepadMoveSensibility;
-
-            return 0;
-        }
-
-        public set gamepadMoveSensibility(value: number) {
-            var gamepad = <FreeCameraGamepadInput>this.inputs.attached["gamepad"];
-            if (gamepad)
-                gamepad.gamepadMoveSensibility = value;
-        }
-        //-- end properties for backward compatibility for inputs
-
-
+        /**
+         * Instantiates a new Gamepad Camera
+         * This represents a FPS type of camera. This is only here for back compat purpose.
+         * Please use the UniversalCamera instead as both are identical.
+         * @see http://doc.babylonjs.com/features/cameras#universal-camera
+         * @param name Define the name of the camera in the scene
+         * @param position Define the start position of the camera in the scene
+         * @param scene Define the scene the camera belongs to
+         */
         constructor(name: string, position: Vector3, scene: Scene) {
             super(name, position, scene);
         }
 
+        /**
+         * Gets the current object class name.
+         * @return the class name
+         */
         public getClassName(): string {
             return "GamepadCamera";
         }

+ 51 - 10
src/Cameras/babylon.targetCamera.ts

@@ -1,19 +1,46 @@
 module BABYLON {
+    /**
+     * A target camera takes a mesh or position as a target and continues to look at it while it moves. 
+     * This is the base of the follow, arc rotate cameras and Free camera
+     * @see http://doc.babylonjs.com/features/cameras
+     */
     export class TargetCamera extends Camera {
 
+        /**
+         * Define the current direction the camera is moving to
+         */
         public cameraDirection = new Vector3(0, 0, 0);
+        /**
+         * Define the current rotation the camera is rotating to
+         */
         public cameraRotation = new Vector2(0, 0);
 
+        /**
+         * Define the current rotation of the camera
+         */
         @serializeAsVector3()
         public rotation = new Vector3(0, 0, 0);
 
+        /**
+         * Define the current rotation of the camera as a quaternion to prevent Gimbal lock
+         */
         public rotationQuaternion: Quaternion;
 
+        /**
+         * Define the current speed of the camera
+         */
         @serialize()
         public speed = 2.0;
 
+        /**
+         * Add cconstraint to the camera to prevent it to move freely in all directions and
+         * around all axis.
+         */
         public noRotationConstraint = false;
 
+        /**
+         * Define the current target of the camera as an object or a position.
+         */
         @serializeAsMeshReference("lockedTargetId")
         public lockedTarget: any = null;
 
@@ -42,10 +69,24 @@
 
         private _defaultUp = BABYLON.Vector3.Up();
 
+        /**
+         * Instantiates a target camera that takes a meshor position as a target and continues to look at it while it moves. 
+         * This is the base of the follow, arc rotate cameras and Free camera
+         * @see http://doc.babylonjs.com/features/cameras
+         * @param name Defines the name of the camera in the scene
+         * @param position Defines the start position of the camera in the scene
+         * @param scene Defines the scene the camera belongs to
+         * @param setActiveOnSceneIfNoneActive Defines wheter the camera should be marked as active if not other active cameras have been defined
+         */
         constructor(name: string, position: Vector3, scene: Scene, setActiveOnSceneIfNoneActive = true) {
             super(name, position, scene, setActiveOnSceneIfNoneActive);
         }
 
+        /**
+         * Gets the position in front of the camera at a given distance.
+         * @param distance The distance from the camera we want the position to be
+         * @returns the position
+         */
         public getFrontPosition(distance: number): Vector3 {
             this.getWorldMatrix();
             var direction = this.getTarget().subtract(this.position);
@@ -67,15 +108,14 @@
             return this.lockedTarget.absolutePosition || this.lockedTarget;
         }
 
-        // State
-
-        /**
-         * Store current camera state (fov, position, etc..)
-         */
         private _storedPosition: Vector3;
         private _storedRotation: Vector3;
         private _storedRotationQuaternion: Quaternion;
 
+        /**
+         * Store current camera state of the camera (fov, position, rotation, etc..)
+         * @returns the camera
+         */
         public storeState(): Camera {
             this._storedPosition = this.position.clone();
             this._storedRotation = this.rotation.clone();
@@ -109,7 +149,6 @@
             return true;
         }
 
-        // Cache
         /** @hidden */
         public _initCache() {
             super._initCache();
@@ -206,6 +245,7 @@
 
         /**
          * Return the current target position of the camera. This value is expressed in local space.
+         * @returns the target position
          */
         public getTarget(): Vector3 {
             return this._currentTarget;
@@ -355,8 +395,7 @@
         }
 
         /**
-         * @override
-         * Override Camera.createRigCamera
+         * @hidden
          */
         public createRigCamera(name: string, cameraIndex: number): Nullable<Camera> {
             if (this.cameraRigMode !== Camera.RIG_MODE_NONE) {
@@ -375,8 +414,6 @@
 
         /**
          * @hidden
-         * @override
-         * Override Camera._updateRigCameras
          */
         public _updateRigCameras() {
             var camLeft = <TargetCamera>this._rigCameras[0];
@@ -425,6 +462,10 @@
             Vector3.TransformCoordinatesToRef(this.position, this._rigCamTransformMatrix, result);
         }
 
+        /**
+         * Gets the current object class name.
+         * @return the class name
+         */
         public getClassName(): string {
             return "TargetCamera";
         }

+ 27 - 4
src/Cameras/babylon.touchCamera.ts

@@ -3,9 +3,16 @@ module BABYLON {
         return () => new TouchCamera(name, Vector3.Zero(), scene);
     });
 
-    // We're mainly based on the logic defined into the FreeCamera code
+    /**
+     * This represents a FPS type of camera controlled by touch.
+     * This is like a universal camera minus the Gamepad controls.
+     * @see http://doc.babylonjs.com/features/cameras#universal-camera
+     */
     export class TouchCamera extends FreeCamera {
-        //-- Begin properties for backward compatibility for inputs
+        /**
+         * Defines the touch sensibility for rotation.
+         * The higher the faster.
+         */
         public get touchAngularSensibility(): number {
             var touch = <FreeCameraTouchInput>this.inputs.attached["touch"];
             if (touch)
@@ -20,6 +27,10 @@ module BABYLON {
                 touch.touchAngularSensibility = value;
         }
 
+        /**
+         * Defines the touch sensibility for move.
+         * The higher the faster.
+         */
         public get touchMoveSensibility(): number {
             var touch = <FreeCameraTouchInput>this.inputs.attached["touch"];
             if (touch)
@@ -33,8 +44,16 @@ module BABYLON {
             if (touch)
                 touch.touchMoveSensibility = value;
         }
-        //-- end properties for backward compatibility for inputs
-
+        
+        /**
+         * Instantiates a new touch camera.
+         * This represents a FPS type of camera controlled by touch.
+         * This is like a universal camera minus the Gamepad controls.
+         * @see http://doc.babylonjs.com/features/cameras#universal-camera
+         * @param name Define the name of the camera in the scene
+         * @param position Define the start position of the camera in the scene
+         * @param scene Define the scene the camera belongs to
+         */
         constructor(name: string, position: Vector3, scene: Scene) {
             super(name, position, scene);
             this.inputs.addTouch();
@@ -42,6 +61,10 @@ module BABYLON {
             this._setupInputs();
         }
 
+        /**
+         * Gets the current object class name.
+         * @return the class name
+         */
         public getClassName(): string {
             return "TouchCamera";
         }

+ 25 - 3
src/Cameras/babylon.universalCamera.ts

@@ -1,7 +1,14 @@
 module BABYLON {
-    // We're mainly based on the logic defined into the FreeCamera code
+    /**
+     * The Universal Camera is the one to choose for first person shooter type games, and works with all the keyboard, mouse, touch and gamepads. This replaces the earlier Free Camera, 
+     * which still works and will still be found in many Playgrounds.
+     * @see http://doc.babylonjs.com/features/cameras#universal-camera
+     */
     export class UniversalCamera extends TouchCamera {
-        //-- Begin properties for backward compatibility for inputs
+        /**
+         * Defines the gamepad rotation sensiblity.
+         * This is the threshold from when rotation starts to be accounted for to prevent jittering.
+         */
         public get gamepadAngularSensibility(): number {
             var gamepad = <FreeCameraGamepadInput>this.inputs.attached["gamepad"];
             if (gamepad)
@@ -16,6 +23,10 @@ module BABYLON {
                 gamepad.gamepadAngularSensibility = value;
         }
 
+        /**
+         * Defines the gamepad move sensiblity.
+         * This is the threshold from when moving starts to be accounted for for to prevent jittering.
+         */
         public get gamepadMoveSensibility(): number {
             var gamepad = <FreeCameraGamepadInput>this.inputs.attached["gamepad"];
             if (gamepad)
@@ -29,13 +40,24 @@ module BABYLON {
             if (gamepad)
                 gamepad.gamepadMoveSensibility = value;
         }
-        //-- end properties for backward compatibility for inputs
 
+        /**
+         * The Universal Camera is the one to choose for first person shooter type games, and works with all the keyboard, mouse, touch and gamepads. This replaces the earlier Free Camera, 
+         * which still works and will still be found in many Playgrounds.
+         * @see http://doc.babylonjs.com/features/cameras#universal-camera
+         * @param name Define the name of the camera in the scene
+         * @param position Define the start position of the camera in the scene
+         * @param scene Define the scene the camera belongs to
+         */
         constructor(name: string, position: Vector3, scene: Scene) {
             super(name, position, scene);
             this.inputs.addGamepad();
         }
 
+        /**
+         * Gets the current object class name.
+         * @return the class name
+         */
         public getClassName(): string {
             return "UniversalCamera";
         }

+ 19 - 1
src/Cameras/babylon.virtualJoysticksCamera.ts

@@ -3,14 +3,32 @@
         return () => new VirtualJoysticksCamera(name, Vector3.Zero(), scene);
     });
 
-    // We're mainly based on the logic defined into the FreeCamera code
+    /**
+     * This represents a free type of camera. It can be usefull in First Person Shooter game for instance.
+     * It is identical to the Free Camera and simply adds by default a virtual joystick.
+     * Virtual Joysticks are on-screen 2D graphics that are used to control the camera or other scene items.
+     * @see http://doc.babylonjs.com/features/cameras#virtual-joysticks-camera
+     */
     export class VirtualJoysticksCamera extends FreeCamera {
         
+        /**
+         * Intantiates a VirtualJoysticksCamera. It can be usefull in First Person Shooter game for instance.
+         * It is identical to the Free Camera and simply adds by default a virtual joystick.
+         * Virtual Joysticks are on-screen 2D graphics that are used to control the camera or other scene items.
+         * @see http://doc.babylonjs.com/features/cameras#virtual-joysticks-camera
+         * @param name Define the name of the camera in the scene
+         * @param position Define the start position of the camera in the scene
+         * @param scene Define the scene the camera belongs to
+         */
         constructor(name: string, position: Vector3, scene: Scene) {
             super(name, position, scene);
             this.inputs.addVirtualJoystick();
         }
 
+        /**
+         * Gets the current object class name.
+         * @return the class name
+         */
         public getClassName(): string {
             return "VirtualJoysticksCamera";
         }

+ 17 - 1
src/Cameras/babylon.webvr.ts

@@ -46,25 +46,34 @@ interface VRDisplay extends EventTarget {
     /**
      * Passing the value returned by `requestAnimationFrame` to
      * `cancelAnimationFrame` will unregister the callback.
+     * @param handle Define the hanle of the request to cancel
      */
     cancelAnimationFrame(handle: number): void;
 
     /**
      * Stops presenting to the VRDisplay.
+     * @returns a promise to know when it stopped
      */
     exitPresent(): Promise<void>;
 
-    /* Return the current VREyeParameters for the given eye. */
+    /**
+     * Return the current VREyeParameters for the given eye.
+     * @param whichEye Define the eye we want the parameter for
+     * @returns the eye parameters
+     */
     getEyeParameters(whichEye: string): VREyeParameters;
 
     /**
      * Populates the passed VRFrameData with the information required to render
      * the current frame.
+     * @param frameData Define the data structure to populate
+     * @returns true if ok otherwise false
      */
     getFrameData(frameData: VRFrameData): boolean;
 
     /**
      * Get the layers currently being presented.
+     * @returns the list of VR layers
      */
     getLayers(): VRLayer[];
 
@@ -75,12 +84,14 @@ interface VRDisplay extends EventTarget {
      *
      * The VRPose will contain the position, orientation, velocity,
      * and acceleration of each of these properties.
+     * @returns the pose object
      */
     getPose(): VRPose;
 
     /**
      * Return the current instantaneous pose of the VRDisplay, with no
      * prediction applied.
+     * @returns the current instantaneous pose
      */
     getImmediatePose(): VRPose;
 
@@ -92,12 +103,16 @@ interface VRDisplay extends EventTarget {
      * identically to how window.requestAnimationFrame acts. Content should
      * make no assumptions of frame rate or vsync behavior as the HMD runs
      * asynchronously from other displays and at differing refresh rates.
+     * @param callback Define the eaction to run next frame
+     * @returns the request handle it
      */
     requestAnimationFrame(callback: FrameRequestCallback): number;
 
     /**
      * Begin presenting to the VRDisplay. Must be called in response to a user gesture.
      * Repeat calls while already presenting will update the VRLayers being displayed.
+     * @param layers Define the list of layer to present
+     * @returns a promise to know when the request has been fulfilled
      */
     requestPresent(layers: VRLayer[]): Promise<void>;
 
@@ -115,6 +130,7 @@ interface VRDisplay extends EventTarget {
      * in the HMD. Calling this function has the same effect on the source
      * canvas as any other operation that uses its source image, and canvases
      * created without preserveDrawingBuffer set to true will be cleared.
+     * @param pose Define the pose to submit
      */
     submitFrame(pose?: VRPose): void;
 }

+ 1 - 0
src/Collisions/babylon.collider.ts

@@ -57,6 +57,7 @@
         }
         )();
 
+    /** @hidden */
     export class Collider {
         /** Define if a collision was found */
         public collisionFound: boolean;

+ 15 - 1
src/Collisions/babylon.collisionCoordinator.ts

@@ -1,8 +1,10 @@
 module BABYLON {
 
     //WebWorker code will be inserted to this variable.
+    /** @hidden */
     export var CollisionWorker = "";
 
+    /** @hidden */
     export interface ICollisionCoordinator {
         getNewPosition(position: Vector3, displacement: Vector3, collider: Collider, maximumRetry: number, excludedMesh: Nullable<AbstractMesh>, onNewPosition: (collisionIndex: number, newPosition: Vector3, collidedMesh: Nullable<AbstractMesh>) => void, collisionIndex: number): void;
         init(scene: Scene): void;
@@ -17,6 +19,7 @@ module BABYLON {
         onGeometryDeleted(geometry: Geometry): void;
     }
 
+    /** @hidden */
     export interface SerializedMesh {
         id: string;
         name: string;
@@ -31,6 +34,7 @@ module BABYLON {
         checkCollisions: boolean;
     }
 
+    /** @hidden */
     export interface SerializedSubMesh {
         position: number;
         verticesStart: number;
@@ -45,7 +49,8 @@ module BABYLON {
     }
 
     /**
-     * Interface describing the value associated with a geometry
+     * Interface describing the value associated with a geometry.
+     * @hidden
      */
     export interface SerializedGeometry {
         /**
@@ -66,11 +71,13 @@ module BABYLON {
         normals: Float32Array;
     }
 
+    /** @hidden */
     export interface BabylonMessage {
         taskType: WorkerTaskType;
         payload: InitPayload | CollidePayload | UpdatePayload /*any for TS under 1.4*/;
     }
 
+    /** @hidden */
     export interface SerializedColliderToWorker {
         position: Array<number>;
         velocity: Array<number>;
@@ -87,22 +94,26 @@ module BABYLON {
         COLLIDE
     }
 
+    /** @hidden */
     export interface WorkerReply {
         error: WorkerReplyType;
         taskType: WorkerTaskType;
         payload?: any;
     }
 
+    /** @hidden */
     export interface CollisionReplyPayload {
         newPosition: Array<number>;
         collisionId: number;
         collidedMeshUniqueId: number;
     }
 
+    /** @hidden */
     export interface InitPayload {
 
     }
 
+    /** @hidden */
     export interface CollidePayload {
         collisionId: number;
         collider: SerializedColliderToWorker;
@@ -110,6 +121,7 @@ module BABYLON {
         excludedMeshUniqueId: Nullable<number>;
     }
 
+    /** @hidden */
     export interface UpdatePayload {
         updatedMeshes: { [n: number]: SerializedMesh; };
         updatedGeometries: { [s: string]: SerializedGeometry; };
@@ -125,6 +137,7 @@ module BABYLON {
         UNKNOWN_ERROR
     }
 
+    /** @hidden */
     export class CollisionCoordinatorWorker implements ICollisionCoordinator {
 
         private _scene: Scene;
@@ -371,6 +384,7 @@ module BABYLON {
         }
     }
 
+    /** @hidden */
     export class CollisionCoordinatorLegacy implements ICollisionCoordinator {
 
         private _scene: Scene;

+ 5 - 0
src/Collisions/babylon.collisionWorker.ts

@@ -6,8 +6,10 @@ const safePostMessage: any = self.postMessage;
 module BABYLON {
 
     //If this file is included in the main thread, this will be initialized.
+    /** @hidden */
     export var WorkerIncluded: boolean = true;
 
+    /** @hidden */
     export class CollisionCache {
         private _meshes: { [n: string]: SerializedMesh; } = {};
         private _geometries: { [s: string]: SerializedGeometry; } = {};
@@ -45,6 +47,7 @@ module BABYLON {
         }
     }
 
+    /** @hidden */
     export class CollideWorker {
 
         private collisionsScalingMatrix = Matrix.Zero();
@@ -181,12 +184,14 @@ module BABYLON {
         }
     }
 
+    /** @hidden */
     export interface ICollisionDetector {
         onInit(payload: InitPayload): void;
         onUpdate(payload: UpdatePayload): void;
         onCollision(payload: CollidePayload): void;
     }
 
+    /** @hidden */
     export class CollisionDetectorTransferable implements ICollisionDetector {
         private _collisionCache: CollisionCache;
 

+ 4 - 0
src/Gamepad/babylon.gamepadSceneComponent.ts

@@ -37,6 +37,10 @@ module BABYLON {
     }
 
     export interface ArcRotateCameraInputsManager {
+        /**
+         * Adds gamepad input support to the ArcRotateCamera InputManager.
+         * @returns the camera inputs manager
+         */
         addGamepad(): ArcRotateCameraInputsManager;
     }
     

+ 9 - 6
src/Gizmos/babylon.gizmoManager.ts

@@ -11,7 +11,10 @@ module BABYLON {
         private _pointerObserver:Nullable<Observer<PointerInfo>> = null;
         private _attachedMesh:Nullable<AbstractMesh> = null;
         private _boundingBoxColor = BABYLON.Color3.FromHexString("#0984e3");
-        private _dragBehavior = new BABYLON.SixDofDragBehavior();
+        /**
+         * When bounding box gizmo is enabled, this can be used to track drag/end events
+         */
+        public boundingBoxDragBehavior = new BABYLON.SixDofDragBehavior();
         /**
          * Array of meshes which will have the gizmo attached when a pointer selected them. If null, all meshes are attachable. (Default: null)
          */
@@ -72,7 +75,7 @@ module BABYLON {
          */
         public attachToMesh(mesh:Nullable<AbstractMesh>){
             if(this._attachedMesh){
-                this._attachedMesh.removeBehavior(this._dragBehavior);
+                this._attachedMesh.removeBehavior(this.boundingBoxDragBehavior);
             }
             this._attachedMesh = mesh;
             for(var key in this.gizmos){
@@ -82,7 +85,7 @@ module BABYLON {
                 }
             }
             if(this.boundingBoxGizmoEnabled && this._attachedMesh){
-                this._attachedMesh.addBehavior(this._dragBehavior);
+                this._attachedMesh.addBehavior(this.boundingBoxDragBehavior);
             }
         }
 
@@ -145,8 +148,8 @@ module BABYLON {
                 this.gizmos.boundingBoxGizmo = this.gizmos.boundingBoxGizmo || new BoundingBoxGizmo(this._boundingBoxColor);
                 this.gizmos.boundingBoxGizmo.attachedMesh = this._attachedMesh;
                 if(this._attachedMesh){
-                    this._attachedMesh.removeBehavior(this._dragBehavior);
-                    this._attachedMesh.addBehavior(this._dragBehavior);
+                    this._attachedMesh.removeBehavior(this.boundingBoxDragBehavior);
+                    this._attachedMesh.addBehavior(this.boundingBoxDragBehavior);
                 }
             }else if(this.gizmos.boundingBoxGizmo){
                 this.gizmos.boundingBoxGizmo.attachedMesh = null;
@@ -168,7 +171,7 @@ module BABYLON {
                     gizmo.dispose();
                 }
             }
-            this._dragBehavior.detach();
+            this.boundingBoxDragBehavior.detach();
         }
     }
 }

+ 10 - 11
src/Gizmos/babylon.scaleGizmo.ts

@@ -17,17 +17,16 @@ module BABYLON {
         public zGizmo:AxisScaleGizmo;
 
         /**
-         * @hidden
          * Internal gizmo used to scale all axis equally
          */
-        private _uniformGizmo:AxisScaleGizmo;
+        public uniformScaleGizmo:AxisScaleGizmo;
 
         public set attachedMesh(mesh:Nullable<AbstractMesh>){
             if(this.xGizmo){
                 this.xGizmo.attachedMesh = mesh;
                 this.yGizmo.attachedMesh = mesh;
                 this.zGizmo.attachedMesh = mesh;
-                this._uniformGizmo.attachedMesh = mesh;
+                this.uniformScaleGizmo.attachedMesh = mesh;
             }
         }
         /**
@@ -41,12 +40,12 @@ module BABYLON {
             this.zGizmo = new AxisScaleGizmo(new Vector3(0,0,1), BABYLON.Color3.Blue().scale(0.5), gizmoLayer);
 
             // Create uniform scale gizmo
-            this._uniformGizmo = new AxisScaleGizmo(new Vector3(0,1,0), BABYLON.Color3.Yellow().scale(0.5), gizmoLayer);
-            this._uniformGizmo.updateGizmoRotationToMatchAttachedMesh = false;
-            this._uniformGizmo.uniformScaling = true
-            var octahedron = BABYLON.Mesh.CreatePolyhedron("", {type: 1}, this._uniformGizmo.gizmoLayer.utilityLayerScene);
+            this.uniformScaleGizmo = new AxisScaleGizmo(new Vector3(0,1,0), BABYLON.Color3.Yellow().scale(0.5), gizmoLayer);
+            this.uniformScaleGizmo.updateGizmoRotationToMatchAttachedMesh = false;
+            this.uniformScaleGizmo.uniformScaling = true
+            var octahedron = BABYLON.Mesh.CreatePolyhedron("", {type: 1}, this.uniformScaleGizmo.gizmoLayer.utilityLayerScene);
             octahedron.scaling.scaleInPlace(0.007);
-            this._uniformGizmo.setCustomMesh(octahedron, true);
+            this.uniformScaleGizmo.setCustomMesh(octahedron, true);
             
             this.attachedMesh = null;
         }
@@ -70,7 +69,7 @@ module BABYLON {
                 this.xGizmo.snapDistance = value;
                 this.yGizmo.snapDistance = value;
                 this.zGizmo.snapDistance = value;
-                this._uniformGizmo.snapDistance = value;
+                this.uniformScaleGizmo.snapDistance = value;
             }
         }
         public get snapDistance(){
@@ -85,7 +84,7 @@ module BABYLON {
                 this.xGizmo.scaleRatio = value;
                 this.yGizmo.scaleRatio = value;
                 this.zGizmo.scaleRatio = value;
-                this._uniformGizmo.scaleRatio = value;
+                this.uniformScaleGizmo.scaleRatio = value;
             }
         }
         public get scaleRatio(){
@@ -99,7 +98,7 @@ module BABYLON {
             this.xGizmo.dispose();
             this.yGizmo.dispose();
             this.zGizmo.dispose();
-            this._uniformGizmo.dispose();
+            this.uniformScaleGizmo.dispose();
         }
     }
 }

+ 1 - 1
src/Lights/babylon.spotLight.ts

@@ -56,7 +56,7 @@
          */
         @serialize()
         public get innerAngle(): number {
-            return this._angle
+            return this._innerAngle;
         }
         /**
          * Only used in gltf falloff mode, this defines the angle where 

+ 13 - 1
src/Math/babylon.math.ts

@@ -1,6 +1,18 @@
 module BABYLON {
+    /** 
+     * Constant used to convert a value to gamma space 
+     * @ignorenaming
+     */
     export const ToGammaSpace = 1 / 2.2;
-    export const ToLinearSpace = 2.2;
+    /** 
+     * Constant used to convert a value to linear space 
+     * @ignorenaming
+     */
+     export const ToLinearSpace = 2.2;
+    /** 
+     * Constant used to define the minimal number value in Babylon.js 
+     * @ignorenaming
+     */
     export const Epsilon = 0.001;
 
     /**

Разлика између датотеке није приказан због своје велике величине
+ 572 - 452
src/Mesh/babylon.mesh.ts


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

@@ -970,7 +970,7 @@
                 var normal: Vector3;
                 var rotated: Vector3;
                 var rotationMatrix: Matrix = Tmp.Matrix[0];
-                var index = (cap === Mesh._NO_CAP || cap === Mesh.CAP_END) ? 0 : 2;
+                var index = (cap === Mesh.NO_CAP || cap === Mesh.CAP_END) ? 0 : 2;
                 for (var i = 0; i < path.length; i++) {
                     rad = radiusFunctionFinal(i, distances[i]); // current radius
                     circlePath = Array<Vector3>();              // current circle array

+ 14 - 1
src/Mesh/babylon.meshLODLevel.ts

@@ -1,6 +1,19 @@
 module BABYLON {
+    /**
+     * Class used to represent a specific level of detail of a mesh
+     * @see http://doc.babylonjs.com/how_to/how_to_use_lod
+     */
     export class MeshLODLevel {
-        constructor(public distance: number, public mesh: Nullable<Mesh>) {
+        /**
+         * Creates a new LOD level
+         * @param distance defines the distance where this level should star being displayed
+         * @param mesh defines the mesh to use to render this level
+         */
+        constructor(
+            /** Defines the distance where this level should star being displayed */
+            public distance: number, 
+            /** Defines the mesh to use to render this level */
+            public mesh: Nullable<Mesh>) {
         }
     }
 } 

+ 6 - 5
src/Mesh/babylon.meshSimplificationSceneComponent.ts

@@ -32,11 +32,12 @@
     export interface Mesh {
         /**
          * Simplify the mesh according to the given array of settings.
-         * Function will return immediately and will simplify async. It returns the Mesh.  
-         * @param settings a collection of simplification settings.
-         * @param parallelProcessing should all levels calculate parallel or one after the other.
-         * @param type the type of simplification to run.
-         * @param successCallback optional success callback to be called after the simplification finished processing all settings.
+         * Function will return immediately and will simplify async
+         * @param settings a collection of simplification settings
+         * @param parallelProcessing should all levels calculate parallel or one after the other
+         * @param simplificationType the type of simplification to run
+         * @param successCallback optional success callback to be called after the simplification finished processing all settings
+         * @returns the current mesh
          */
         simplify(settings: Array<ISimplificationSettings>, parallelProcessing?: boolean, simplificationType?: SimplificationType, successCallback?: (mesh?: Mesh, submeshIndex?: number) => void): Mesh;
     }

+ 4 - 2
src/Mesh/babylon.transformNode.ts

@@ -212,8 +212,10 @@ module BABYLON {
             if (this._rotationQuaternion) {
                 if (!this._cache.rotationQuaternion.equals(this._rotationQuaternion))
                     return false;
-            } else if (!this._cache.rotation.equals(this._rotation))
-                return false;
+            }
+
+            if (!this._cache.rotation.equals(this._rotation))
+                return false;                
 
             if (!this._cache.scaling.equals(this._scaling))
                 return false;

+ 5 - 1
src/Particles/babylon.IParticleSystem.ts

@@ -143,6 +143,10 @@ module BABYLON {
          * It can be for example box, sphere, or cone...
          */
         particleEmitterType: Nullable<IParticleEmitterType>;  
+        /**
+         * Defines the delay in milliseconds before starting the system (0 by default)
+         */
+        startDelay: number;        
         /** 
          * Gets or sets a value indicating how many cycles (or frames) must be executed before first rendering (this value has to be set before starting the system). Default is 0 
          */
@@ -264,7 +268,7 @@ module BABYLON {
         /**
          * Adds a new color gradient
          * @param gradient defines the gradient to use (between 0 and 1)
-         * @param color defines the color to affect to the specified gradient
+         * @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 the current particle system
          */

+ 10 - 4
src/Particles/babylon.gpuParticleSystem.ts

@@ -171,7 +171,7 @@
         /**
          * Adds a new color gradient
          * @param gradient defines the gradient to use (between 0 and 1)
-         * @param color defines the color to affect to the specified gradient
+         * @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 the current particle system
          */
@@ -697,6 +697,9 @@
                 offset += 4;
             }
             
+            if (this.billboardMode === ParticleSystem.BILLBOARDMODE_STRETCHED) {
+                renderVertexBuffers["direction"] = source.createVertexBuffer("direction", offset, 3, this._attributesStrideSize, true);
+            }
             offset += 3; // Direction
 
             if (!this._isBillboardBased) {
@@ -960,10 +963,13 @@
                 defines += "\n#define BILLBOARD";
 
                 switch (this.billboardMode) {
-                    case AbstractMesh.BILLBOARDMODE_Y:
+                    case ParticleSystem.BILLBOARDMODE_Y:
                         defines += "\n#define BILLBOARDY";
                         break;
-                    case AbstractMesh.BILLBOARDMODE_ALL:
+                    case ParticleSystem.BILLBOARDMODE_STRETCHED:
+                        defines += "\n#define BILLBOARDSTRETCHED";
+                        break;                          
+                    case ParticleSystem.BILLBOARDMODE_ALL:
                     default:
                         break;
                 }                
@@ -995,7 +1001,7 @@
             }
 
             this._renderEffect = new Effect("gpuRenderParticles", 
-                                            ["position", "age", "life", "size", "color", "offset", "uv", "initialDirection", "angle", "cellIndex"], 
+                                            ["position", "age", "life", "size", "color", "offset", "uv", "direction", "initialDirection", "angle", "cellIndex"], 
                                             uniforms, 
                                             samplers, this._scene.getEngine(), defines);
         }        

+ 5 - 5
src/Particles/babylon.particle.ts

@@ -239,7 +239,7 @@
             other.colorStep.copyFrom(this.colorStep);
             other.lifeTime = this.lifeTime;
             other.age = this.age;
-            other._randomCellOffset = undefined;
+            other._randomCellOffset = this._randomCellOffset;
             other.size = this.size;
             other.scale.copyFrom(this.scale);
             other.angle = this.angle;
@@ -287,11 +287,11 @@
             }
             if (this._randomNoiseCoordinates1) {
                 if (other._randomNoiseCoordinates1) {
-                    other._randomNoiseCoordinates1.copyFromFloats(Math.random(), Math.random(), Math.random());
-                    other._randomNoiseCoordinates2.copyFromFloats(Math.random(), Math.random(), Math.random());
+                    other._randomNoiseCoordinates1.copyFrom(this._randomNoiseCoordinates1);
+                    other._randomNoiseCoordinates2.copyFrom(this._randomNoiseCoordinates2);
                 } else {
-                    other._randomNoiseCoordinates1 = new Vector3(Math.random(), Math.random(), Math.random());
-                    other._randomNoiseCoordinates2 = new Vector3(Math.random(), Math.random(), Math.random());
+                    other._randomNoiseCoordinates1 = this._randomNoiseCoordinates1.clone();
+                    other._randomNoiseCoordinates2 = this._randomNoiseCoordinates2.clone();
                 }
             }
         }

+ 35 - 8
src/Particles/babylon.particleSystem.ts

@@ -6,6 +6,20 @@
      * @example https://doc.babylonjs.com/babylon101/particles
      */
     export class ParticleSystem extends BaseParticleSystem implements IDisposable, IAnimatable, IParticleSystem {
+
+        /**
+         * Billboard mode will only apply to Y axis
+         */
+        public static readonly BILLBOARDMODE_Y = 2;
+        /**
+         * Billboard mode will apply to all axes
+         */
+        public static readonly BILLBOARDMODE_ALL = 7;
+        /**
+         * Special billboard mode where the particle will be biilboard to the camera but rotated to align with direction
+         */
+        public static readonly BILLBOARDMODE_STRETCHED = 8;
+
         /**
          * This function can be defined to provide custom update for active particles.
          * This function will be called instead of regular update (age, position, color, etc.).
@@ -781,17 +795,17 @@
         /**
          * Adds a new color gradient
          * @param gradient defines the gradient to use (between 0 and 1)
-         * @param color defines the color to affect to the specified gradient
+         * @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
          */
-        public addColorGradient(gradient: number, color: Color4, color2?: Color4): IParticleSystem {
+        public addColorGradient(gradient: number, color1: Color4, color2?: Color4): IParticleSystem {
             if (!this._colorGradients) {
                 this._colorGradients = [];
             }
 
             let colorGradient = new ColorGradient();
             colorGradient.gradient = gradient;
-            colorGradient.color1 = color;
+            colorGradient.color1 = color1;
             colorGradient.color2 = color2;
             this._colorGradients.push(colorGradient);
 
@@ -865,7 +879,7 @@
                 this._vertexBufferSize += 1;
             }
 
-            if (!this._isBillboardBased) {
+            if (!this._isBillboardBased || this.billboardMode === ParticleSystem.BILLBOARDMODE_STRETCHED) {
                 this._vertexBufferSize += 3;
             }
 
@@ -900,7 +914,7 @@
                 dataOffset += 1;
             }
 
-            if (!this._isBillboardBased) {
+            if (!this._isBillboardBased || this.billboardMode === ParticleSystem.BILLBOARDMODE_STRETCHED) {
                 var directionBuffer = this._vertexBuffer.createVertexBuffer("direction", dataOffset, 3, this._vertexBufferSize, this._useInstancing);
                 this._vertexBuffers["direction"] = directionBuffer;
                 dataOffset += 3;
@@ -1009,6 +1023,10 @@
             }
 
             if (this.preWarmCycles) {
+                if (this.emitter instanceof AbstractMesh) {
+                    this.emitter.computeWorldMatrix(true);
+                }
+
                 let noiseTextureAsProcedural = this.noiseTexture as ProceduralTexture;
 
                 if (noiseTextureAsProcedural && noiseTextureAsProcedural.onGeneratedObservable) {
@@ -1082,6 +1100,10 @@
                     this._vertexData[offset++] = particle.direction.y;
                     this._vertexData[offset++] = particle.direction.z;
                 }
+            } else if (this.billboardMode === ParticleSystem.BILLBOARDMODE_STRETCHED) {
+                this._vertexData[offset++] = particle.direction.x;
+                this._vertexData[offset++] = particle.direction.y;
+                this._vertexData[offset++] = particle.direction.z;
             }
 
             if (this._useRampGradients) {
@@ -1460,10 +1482,13 @@
                 defines.push("#define BILLBOARD");
 
                 switch (this.billboardMode) {
-                    case AbstractMesh.BILLBOARDMODE_Y:
+                    case ParticleSystem.BILLBOARDMODE_Y:
                         defines.push("#define BILLBOARDY");
                         break;
-                    case AbstractMesh.BILLBOARDMODE_ALL:
+                    case ParticleSystem.BILLBOARDMODE_STRETCHED:
+                        defines.push("#define BILLBOARDSTRETCHED");
+                        break;                        
+                    case ParticleSystem.BILLBOARDMODE_ALL:
                     default:
                         break;
                 }
@@ -1479,7 +1504,7 @@
             if (this._cachedDefines !== join) {
                 this._cachedDefines = join;
 
-                var attributesNamesOrOptions = ParticleSystem._GetAttributeNamesOrOptions(this._isAnimationSheetEnabled, this._isBillboardBased, this._useRampGradients);
+                var attributesNamesOrOptions = ParticleSystem._GetAttributeNamesOrOptions(this._isAnimationSheetEnabled, this._isBillboardBased && this.billboardMode !== ParticleSystem.BILLBOARDMODE_STRETCHED, this._useRampGradients);
                 var effectCreationOption = ParticleSystem._GetEffectCreationOptions(this._isAnimationSheetEnabled);
 
                 var samplers = ["diffuseSampler", "rampSampler"];
@@ -1940,6 +1965,7 @@
             Animation.AppendSerializedAnimations(particleSystem, serializationObject);
 
             // Particle system
+            serializationObject.startDelay = particleSystem.startDelay;
             serializationObject.renderingGroupId = particleSystem.renderingGroupId;
             serializationObject.isBillboardBased = particleSystem.isBillboardBased;
             serializationObject.minAngularSpeed = particleSystem.minAngularSpeed;
@@ -2212,6 +2238,7 @@
             }
 
             // Particle system
+            particleSystem.startDelay = parsedParticleSystem.startDelay | 0;
             particleSystem.minAngularSpeed = parsedParticleSystem.minAngularSpeed;
             particleSystem.maxAngularSpeed = parsedParticleSystem.maxAngularSpeed;
             particleSystem.minSize = parsedParticleSystem.minSize;

+ 42 - 0
src/Particles/babylon.particleSystemComponent.ts

@@ -67,4 +67,46 @@
             effectCreationOption.concat(uniformsNames),
             samplers, defines, fallbacks, onCompiled, onError);
     }
+
+    export interface Mesh {
+        /**
+         * Returns an array populated with IParticleSystem objects whose the mesh is the emitter
+         * @returns an array of IParticleSystem
+         */
+        getEmittedParticleSystems(): IParticleSystem[];
+    
+        /**
+         * Returns an array populated with IParticleSystem objects whose the mesh or its children are the emitter
+         * @returns an array of IParticleSystem
+         */
+        getHierarchyEmittedParticleSystems(): IParticleSystem[];
+    }
+
+    Mesh.prototype.getEmittedParticleSystems = function(): IParticleSystem[] {
+        var results = new Array<IParticleSystem>();
+        for (var index = 0; index < this.getScene().particleSystems.length; index++) {
+            var particleSystem = this.getScene().particleSystems[index];
+            if (particleSystem.emitter === this) {
+                results.push(particleSystem);
+            }
+        }
+        return results;
+    }
+
+    Mesh.prototype.getHierarchyEmittedParticleSystems = function(): IParticleSystem[] {
+        var results = new Array<IParticleSystem>();
+        var descendants = this.getDescendants();
+        descendants.push(this);
+
+        for (var index = 0; index < this.getScene().particleSystems.length; index++) {
+            var particleSystem = this.getScene().particleSystems[index];
+            let emitter: any = particleSystem.emitter;
+
+            if (emitter.position && descendants.indexOf(emitter) !== -1) {
+                results.push(particleSystem);
+            }
+        }
+
+        return results;
+    }
 } 

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

@@ -53,6 +53,7 @@ module BABYLON {
                 emitter = emitter.clone();
             } else if (emitter instanceof AbstractMesh) {
                 emitter = new Mesh("", emitter.getScene());
+                emitter.isVisible = false;
             }
             var clone = new SubEmitter(this.particleSystem.clone("", emitter));
 

+ 29 - 0
src/Shaders/gpuRenderParticles.vertex.fx

@@ -13,6 +13,9 @@ in vec3 size;
 #ifndef BILLBOARD
 in vec3 initialDirection;
 #endif
+#ifdef BILLBOARDSTRETCHED
+in vec3 direction;
+#endif
 in float angle;
 #ifdef ANIMATESHEET
 in float cellIndex;
@@ -59,6 +62,23 @@ vec3 rotate(vec3 yaxis, vec3 rotatedCorner) {
 	return position + alignedCorner;
 }
 
+#ifdef BILLBOARDSTRETCHED
+vec3 rotateAlign(vec3 toCamera, vec3 rotatedCorner) {
+	vec3 normalizedToCamera = normalize(toCamera);
+	vec3 normalizedCrossDirToCamera = normalize(cross(normalize(direction), normalizedToCamera));
+	vec3 crossProduct = normalize(cross(normalizedToCamera, normalizedCrossDirToCamera));
+
+	vec3 row0 = vec3(normalizedCrossDirToCamera.x, normalizedCrossDirToCamera.y, normalizedCrossDirToCamera.z);
+	vec3 row1 = vec3(crossProduct.x, crossProduct.y, crossProduct.z);
+	vec3 row2 = vec3(normalizedToCamera.x, normalizedToCamera.y, normalizedToCamera.z);
+
+	mat3 rotMatrix =  mat3(row0, row1, row2);
+
+	vec3 alignedCorner = rotMatrix * rotatedCorner;
+	return position + alignedCorner; 
+}
+#endif
+
 void main() {
 
 	#ifdef ANIMATESHEET
@@ -94,6 +114,15 @@ void main() {
 		vec3 worldPos = rotate(normalize(yaxis), rotatedCorner.xyz);
 
 		vec4 viewPosition = (view * vec4(worldPos, 1.0)); 
+	#elif defined(BILLBOARDSTRETCHED)
+		rotatedCorner.x = cornerPos.x * cos(angle) - cornerPos.y * sin(angle);
+		rotatedCorner.y = cornerPos.x * sin(angle) + cornerPos.y * cos(angle);
+		rotatedCorner.z = 0.;
+
+		vec3 toCamera = position - eyePosition;	
+		vec3 worldPos = rotateAlign(toCamera, rotatedCorner.xyz);
+		
+		vec4 viewPosition = (view * vec4(worldPos, 1.0)); 	
 	#else
 		// Rotate
 		rotatedCorner.x = cornerPos.x * cos(angle) - cornerPos.y * sin(angle);

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

@@ -9,6 +9,9 @@ attribute float cellIndex;
 #ifndef BILLBOARD	
 attribute vec3 direction;
 #endif
+#ifdef BILLBOARDSTRETCHED
+attribute vec3 direction; 
+#endif
 #ifdef RAMPGRADIENT
 attribute vec4 remapData;
 #endif
@@ -54,6 +57,23 @@ vec3 rotate(vec3 yaxis, vec3 rotatedCorner) {
 	return position + alignedCorner; 
 }
 
+#ifdef BILLBOARDSTRETCHED
+vec3 rotateAlign(vec3 toCamera, vec3 rotatedCorner) {
+	vec3 normalizedToCamera = normalize(toCamera);
+	vec3 normalizedCrossDirToCamera = normalize(cross(normalize(direction), normalizedToCamera));
+	vec3 crossProduct = normalize(cross(normalizedToCamera, normalizedCrossDirToCamera));
+
+	vec3 row0 = vec3(normalizedCrossDirToCamera.x, normalizedCrossDirToCamera.y, normalizedCrossDirToCamera.z);
+	vec3 row1 = vec3(crossProduct.x, crossProduct.y, crossProduct.z);
+	vec3 row2 = vec3(normalizedToCamera.x, normalizedToCamera.y, normalizedToCamera.z);
+
+	mat3 rotMatrix =  mat3(row0, row1, row2);
+
+	vec3 alignedCorner = rotMatrix * rotatedCorner;
+	return position + alignedCorner; 
+}
+#endif
+
 void main(void) {	
 	vec2 cornerPos;
 	
@@ -74,6 +94,15 @@ void main(void) {
 	vec3 worldPos = rotate(normalize(yaxis), rotatedCorner);
 	
 	vec3 viewPos = (view * vec4(worldPos, 1.0)).xyz; 
+#elif defined(BILLBOARDSTRETCHED)
+	rotatedCorner.x = cornerPos.x * cos(angle) - cornerPos.y * sin(angle);
+	rotatedCorner.y = cornerPos.x * sin(angle) + cornerPos.y * cos(angle);
+	rotatedCorner.z = 0.;
+
+	vec3 toCamera = position - eyePosition;	
+	vec3 worldPos = rotateAlign(toCamera, rotatedCorner);
+	
+	vec3 viewPos = (view * vec4(worldPos, 1.0)).xyz; 
 #else
 	rotatedCorner.x = cornerPos.x * cos(angle) - cornerPos.y * sin(angle);
 	rotatedCorner.y = cornerPos.x * sin(angle) + cornerPos.y * cos(angle);

+ 30 - 11
src/Tools/babylon.tools.ts

@@ -1944,22 +1944,37 @@
     }
 
     /**
-    * An implementation of a loop for asynchronous functions.
-    */
+     * An implementation of a loop for asynchronous functions.
+     */
     export class AsyncLoop {
+        /**
+         * Defines the current index of the loop.
+         */
         public index: number;
         private _done: boolean;
+        private _fn: (asyncLoop: AsyncLoop) => void;
+        private _successCallback: () => void;
 
         /**
-         * Constroctor.
+         * Constructor.
          * @param iterations the number of iterations.
-         * @param _fn the function to run each iteration
-         * @param _successCallback the callback that will be called upon succesful execution
+         * @param func the function to run each iteration
+         * @param successCallback the callback that will be called upon succesful execution
          * @param offset starting offset.
          */
-        constructor(public iterations: number, private _fn: (asyncLoop: AsyncLoop) => void, private _successCallback: () => void, offset: number = 0) {
+        constructor(
+            /**
+             * Defines the number of iterations for the loop
+             */
+            public iterations: number, 
+            func: (asyncLoop: AsyncLoop) => void, 
+            successCallback: () => void, 
+            offset: number = 0) {
+
             this.index = offset - 1;
             this._done = false;
+            this._fn = func;
+            this._successCallback = successCallback;
         }
 
         /**
@@ -1985,7 +2000,12 @@
         }
 
         /**
-         * Helper function
+         * Create and run an async loop.
+         * @param iterations the number of iterations.
+         * @param _fn the function to run each iteration
+         * @param _successCallback the callback that will be called upon succesful execution
+         * @param offset starting offset.
+         * @returns the created async loop object
          */
         public static Run(iterations: number, _fn: (asyncLoop: AsyncLoop) => void, _successCallback: () => void, offset: number = 0): AsyncLoop {
             var loop = new AsyncLoop(iterations, _fn, _successCallback, offset);
@@ -1995,7 +2015,6 @@
             return loop;
         }
 
-
         /**
          * A for-loop that will run a given number of iterations synchronous and the rest async.
          * @param iterations total number of iterations
@@ -2004,10 +2023,10 @@
          * @param callback a success call back that will be called when iterating stops.
          * @param breakFunction a break condition (optional)
          * @param timeout timeout settings for the setTimeout function. default - 0.
-         * @constructor
+         * @returns the created async loop object
          */
-        public static SyncAsyncForLoop(iterations: number, syncedIterations: number, fn: (iteration: number) => void, callback: () => void, breakFunction?: () => boolean, timeout: number = 0) {
-            AsyncLoop.Run(Math.ceil(iterations / syncedIterations), (loop: AsyncLoop) => {
+        public static SyncAsyncForLoop(iterations: number, syncedIterations: number, fn: (iteration: number) => void, callback: () => void, breakFunction?: () => boolean, timeout: number = 0): AsyncLoop {
+            return AsyncLoop.Run(Math.ceil(iterations / syncedIterations), (loop: AsyncLoop) => {
                 if (breakFunction && breakFunction()) loop.breakLoop();
                 else {
                     setTimeout(() => {

+ 15 - 0
src/babylon.types.ts

@@ -1,10 +1,25 @@
 module BABYLON {
+    /** Alias type for value that can be null */
     export type Nullable<T> = T | null;
+    /** 
+     * Alias type for number that are floats
+     * @ignorenaming
+     */
     export type float = number;
+    /** 
+     * Alias type for number that are doubles.
+     * @ignorenaming
+     */
     export type double = number;
+    /** 
+     * Alias type for number that are integer
+     * @ignorenaming 
+     */
     export type int = number;
 
+    /** Alias type for number array or Float32Array */
     export type FloatArray = number[] | Float32Array;
+    /** Alias type for number array or Float32Array or Int32Array or Uint32Array or Uint16Array */
     export type IndicesArray = number[] | Int32Array | Uint32Array | Uint16Array;
 
     /**