瀏覽代碼

New onPointerDown for handling mouse over

David Catuhe 11 年之前
父節點
當前提交
f932db12f8

+ 16 - 6
Babylon/Actions/babylon.action.js

@@ -12,8 +12,22 @@
 
         Action.prototype._executeCurrent = function () {
             if (this._condition) {
-                if (!this._condition.isValid()) {
-                    return;
+                var currentRenderId = this._actionManager.getScene().getRenderId();
+
+                // We cache the current evaluation for the current frame
+                if (this._condition._evaluationId === currentRenderId) {
+                    if (!this._condition._currentResult) {
+                        return;
+                    }
+                } else {
+                    this._condition._evaluationId = currentRenderId;
+
+                    if (!this._condition.isValid()) {
+                        this._condition._currentResult = false;
+                        return;
+                    }
+
+                    this._condition._currentResult = true;
                 }
             }
 
@@ -38,10 +52,6 @@
             return action;
         };
 
-        Action.prototype._getTarget = function (targetType, targetName) {
-            return this._actionManager._getTarget(targetType, targetName);
-        };
-
         Action.prototype._getProperty = function (propertyPath) {
             return this._actionManager._getProperty(propertyPath);
         };

+ 16 - 6
Babylon/Actions/babylon.action.ts

@@ -17,8 +17,22 @@
 
         public _executeCurrent(): void {
             if (this._condition) {
-                if (!this._condition.isValid()) {
-                    return;
+                var currentRenderId = this._actionManager.getScene().getRenderId();
+
+                // We cache the current evaluation for the current frame
+                if (this._condition._evaluationId === currentRenderId) {
+                    if (!this._condition._currentResult) {
+                        return;
+                    }
+                } else {
+                    this._condition._evaluationId = currentRenderId;
+
+                    if (!this._condition.isValid()) {
+                        this._condition._currentResult = false;
+                        return;
+                    }
+
+                    this._condition._currentResult = true;
                 }
             }
 
@@ -44,10 +58,6 @@
             return action;
         }
 
-        public _getTarget(targetType: number, targetName: string): any {
-            return this._actionManager._getTarget(targetType, targetName);
-        }
-
         public _getProperty(propertyPath: string): string {
             return this._actionManager._getProperty(propertyPath);
         }

+ 11 - 26
Babylon/Actions/babylon.actionManager.js

@@ -12,6 +12,13 @@
         };
 
         ActionManager.prototype.registerAction = function (action) {
+            if (action.trigger === ActionManager.OnEveryFrameTrigger) {
+                if (this.getScene().actionManager !== this) {
+                    console.warn("OnEveryFrameTrigger can only be used with scene.actionManager");
+                    return null;
+                }
+            }
+
             this.actions.push(action);
 
             action._actionManager = this;
@@ -30,25 +37,6 @@
             }
         };
 
-        ActionManager.prototype._getTarget = function (targetType, targetName) {
-            var scene = this._scene;
-
-            switch (targetType) {
-                case ActionManager.SceneTarget:
-                    return scene;
-                case ActionManager.MeshTarget:
-                    return scene.getMeshByName(targetName);
-                case ActionManager.LightTarget:
-                    return scene.getLightByName(targetName);
-                case ActionManager.CameraTarget:
-                    return scene.getCameraByName(targetName);
-                case ActionManager.MaterialTarget:
-                    return scene.getMaterialByName(targetName);
-            }
-
-            return null;
-        };
-
         ActionManager.prototype._getEffectiveTarget = function (target, propertyPath) {
             var properties = propertyPath.split(".");
 
@@ -64,14 +52,11 @@
 
             return properties[properties.length - 1];
         };
-        ActionManager.AlwaysTrigger = 0;
+        ActionManager.NoneTrigger = 0;
         ActionManager.OnPickTrigger = 1;
-
-        ActionManager.SceneTarget = 0;
-        ActionManager.MeshTarget = 1;
-        ActionManager.LightTarget = 2;
-        ActionManager.CameraTarget = 3;
-        ActionManager.MaterialTarget = 4;
+        ActionManager.OnPointerOverTrigger = 2;
+        ActionManager.OnPointerOutTrigger = 3;
+        ActionManager.OnEveryFrameTrigger = 4;
         return ActionManager;
     })();
     BABYLON.ActionManager = ActionManager;

+ 12 - 26
Babylon/Actions/babylon.actionManager.ts

@@ -1,14 +1,11 @@
 module BABYLON {
     export class ActionManager {
         // Statics
-        public static AlwaysTrigger = 0;
+        public static NoneTrigger = 0;
         public static OnPickTrigger = 1;
-
-        public static SceneTarget = 0;
-        public static MeshTarget = 1;
-        public static LightTarget = 2;
-        public static CameraTarget = 3;
-        public static MaterialTarget = 4;
+        public static OnPointerOverTrigger = 2;
+        public static OnPointerOutTrigger = 3;
+        public static OnEveryFrameTrigger = 4;
 
         // Members
         public actions = new Array<Action>();
@@ -25,6 +22,14 @@
         }
 
         public registerAction(action: Action): Action {
+            if (action.trigger === ActionManager.OnEveryFrameTrigger) {
+                if (this.getScene().actionManager !== this) {
+                    console.warn("OnEveryFrameTrigger can only be used with scene.actionManager");
+                    return null;
+                }
+            }
+
+
             this.actions.push(action);
 
             action._actionManager = this;
@@ -43,25 +48,6 @@
             }
         }
 
-        public _getTarget(targetType: number, targetName: string): any {
-            var scene = this._scene;
-
-            switch (targetType) {
-                case ActionManager.SceneTarget:
-                    return scene;
-                case ActionManager.MeshTarget:
-                    return scene.getMeshByName(targetName);
-                case ActionManager.LightTarget:
-                    return scene.getLightByName(targetName);
-                case ActionManager.CameraTarget:
-                    return scene.getCameraByName(targetName);
-                case ActionManager.MaterialTarget:
-                    return scene.getMaterialByName(targetName);
-            }
-
-            return null;
-        }
-
         public _getEffectiveTarget(target: any, propertyPath: string): any {
             var properties = propertyPath.split(".");
 

+ 2 - 9
Babylon/Actions/babylon.condition.js

@@ -14,10 +14,6 @@ var BABYLON;
             return true;
         };
 
-        Condition.prototype._getTarget = function (targetType, targetName) {
-            return this._actionManager._getTarget(targetType, targetName);
-        };
-
         Condition.prototype._getProperty = function (propertyPath) {
             return this._actionManager._getProperty(propertyPath);
         };
@@ -31,17 +27,14 @@ var BABYLON;
 
     var StateCondition = (function (_super) {
         __extends(StateCondition, _super);
-        function StateCondition(actionManager, targetType, targetName, propertyPath, value, operator) {
+        function StateCondition(actionManager, target, propertyPath, value, operator) {
             if (typeof operator === "undefined") { operator = StateCondition.IsEqual; }
             _super.call(this, actionManager);
-            this.targetType = targetType;
-            this.targetName = targetName;
             this.propertyPath = propertyPath;
             this.value = value;
             this.operator = operator;
 
-            this._target = this._getTarget(this.targetType, this.targetName);
-            this._target = this._getEffectiveTarget(this._target, this.propertyPath);
+            this._target = this._getEffectiveTarget(target, this.propertyPath);
             this._property = this._getProperty(this.propertyPath);
         }
         // Methods

+ 5 - 7
Babylon/Actions/babylon.condition.ts

@@ -2,6 +2,9 @@
     export class Condition {
         public _actionManager: ActionManager;
 
+        public _evaluationId: number;
+        public _currentResult: boolean;
+
         constructor(actionManager: ActionManager) {
             this._actionManager = actionManager;
         }
@@ -10,10 +13,6 @@
             return true;
         }
 
-        public _getTarget(targetType: number, targetName: string): any {
-            return this._actionManager._getTarget(targetType, targetName);
-        }
-
         public _getProperty(propertyPath: string): string {
             return this._actionManager._getProperty(propertyPath);
         }
@@ -36,11 +35,10 @@
         private _target: any;
         private _property: string;
 
-        constructor(actionManager: ActionManager, public targetType: number, public targetName: string, public propertyPath: string, public value: any, public operator: number = StateCondition.IsEqual) {
+        constructor(actionManager: ActionManager, target: any, public propertyPath: string, public value: any, public operator: number = StateCondition.IsEqual) {
             super(actionManager);
 
-            this._target = this._getTarget(this.targetType, this.targetName);
-            this._target = this._getEffectiveTarget(this._target, this.propertyPath);
+            this._target = this._getEffectiveTarget(target, this.propertyPath);
             this._property = this._getProperty(this.propertyPath);
         }
 

+ 69 - 23
Babylon/Actions/babylon.directActions.js

@@ -8,14 +8,12 @@ var BABYLON;
 (function (BABYLON) {
     var SwitchBooleanAction = (function (_super) {
         __extends(SwitchBooleanAction, _super);
-        function SwitchBooleanAction(trigger, targetType, targetName, propertyPath, condition) {
+        function SwitchBooleanAction(trigger, target, propertyPath, condition) {
             _super.call(this, trigger, condition);
-            this.targetType = targetType;
-            this.targetName = targetName;
             this.propertyPath = propertyPath;
+            this._target = target;
         }
         SwitchBooleanAction.prototype._prepare = function () {
-            this._target = this._getTarget(this.targetType, this.targetName);
             this._target = this._getEffectiveTarget(this._target, this.propertyPath);
             this._property = this._getProperty(this.propertyPath);
         };
@@ -29,15 +27,13 @@ var BABYLON;
 
     var SetValueAction = (function (_super) {
         __extends(SetValueAction, _super);
-        function SetValueAction(trigger, targetType, targetName, propertyPath, value, condition) {
+        function SetValueAction(trigger, target, propertyPath, value, condition) {
             _super.call(this, trigger, condition);
-            this.targetType = targetType;
-            this.targetName = targetName;
             this.propertyPath = propertyPath;
             this.value = value;
+            this._target = target;
         }
         SetValueAction.prototype._prepare = function () {
-            this._target = this._getTarget(this.targetType, this.targetName);
             this._target = this._getEffectiveTarget(this._target, this.propertyPath);
             this._property = this._getProperty(this.propertyPath);
         };
@@ -49,18 +45,40 @@ var BABYLON;
     })(BABYLON.Action);
     BABYLON.SetValueAction = SetValueAction;
 
+    var IncrementValueAction = (function (_super) {
+        __extends(IncrementValueAction, _super);
+        function IncrementValueAction(trigger, target, propertyPath, value, condition) {
+            _super.call(this, trigger, condition);
+            this.propertyPath = propertyPath;
+            this.value = value;
+            this._target = target;
+        }
+        IncrementValueAction.prototype._prepare = function () {
+            this._target = this._getEffectiveTarget(this._target, this.propertyPath);
+            this._property = this._getProperty(this.propertyPath);
+
+            if (typeof this._target[this._property] !== "number") {
+                console.warn("Warning: IncrementValueAction can only be used with number values");
+            }
+        };
+
+        IncrementValueAction.prototype.execute = function () {
+            this._target[this._property] += this.value;
+        };
+        return IncrementValueAction;
+    })(BABYLON.Action);
+    BABYLON.IncrementValueAction = IncrementValueAction;
+
     var PlayAnimationAction = (function (_super) {
         __extends(PlayAnimationAction, _super);
-        function PlayAnimationAction(trigger, targetType, targetName, from, to, loop, condition) {
+        function PlayAnimationAction(trigger, target, from, to, loop, condition) {
             _super.call(this, trigger, condition);
-            this.targetType = targetType;
-            this.targetName = targetName;
             this.from = from;
             this.to = to;
             this.loop = loop;
+            this._target = target;
         }
         PlayAnimationAction.prototype._prepare = function () {
-            this._target = this._getTarget(this.targetType, this.targetName);
         };
 
         PlayAnimationAction.prototype.execute = function () {
@@ -73,13 +91,11 @@ var BABYLON;
 
     var StopAnimationAction = (function (_super) {
         __extends(StopAnimationAction, _super);
-        function StopAnimationAction(trigger, targetType, targetName, condition) {
+        function StopAnimationAction(trigger, target, condition) {
             _super.call(this, trigger, condition);
-            this.targetType = targetType;
-            this.targetName = targetName;
+            this._target = target;
         }
         StopAnimationAction.prototype._prepare = function () {
-            this._target = this._getTarget(this.targetType, this.targetName);
         };
 
         StopAnimationAction.prototype.execute = function () {
@@ -90,6 +106,40 @@ var BABYLON;
     })(BABYLON.Action);
     BABYLON.StopAnimationAction = StopAnimationAction;
 
+    var DoNothingAction = (function (_super) {
+        __extends(DoNothingAction, _super);
+        function DoNothingAction(trigger, condition) {
+            if (typeof trigger === "undefined") { trigger = BABYLON.ActionManager.NoneTrigger; }
+            _super.call(this, trigger, condition);
+        }
+        DoNothingAction.prototype.execute = function () {
+        };
+        return DoNothingAction;
+    })(BABYLON.Action);
+    BABYLON.DoNothingAction = DoNothingAction;
+
+    var CombineAction = (function (_super) {
+        __extends(CombineAction, _super);
+        function CombineAction(trigger, children, condition) {
+            _super.call(this, trigger, condition);
+            this.children = children;
+        }
+        CombineAction.prototype._prepare = function () {
+            for (var index = 0; index < this.children.length; index++) {
+                this.children[index]._actionManager = this._actionManager;
+                this.children[index]._prepare();
+            }
+        };
+
+        CombineAction.prototype.execute = function () {
+            for (var index = 0; index < this.children.length; index++) {
+                this.children[index].execute();
+            }
+        };
+        return CombineAction;
+    })(BABYLON.Action);
+    BABYLON.CombineAction = CombineAction;
+
     var ExecuteCodeAction = (function (_super) {
         __extends(ExecuteCodeAction, _super);
         function ExecuteCodeAction(trigger, func, condition) {
@@ -105,16 +155,12 @@ var BABYLON;
 
     var SetParentAction = (function (_super) {
         __extends(SetParentAction, _super);
-        function SetParentAction(trigger, targetType, targetName, parentType, parentName, condition) {
+        function SetParentAction(trigger, target, parent, condition) {
             _super.call(this, trigger, condition);
-            this.targetType = targetType;
-            this.targetName = targetName;
-            this.parentType = parentType;
-            this.parentName = parentName;
+            this._target = target;
+            this._parent = parent;
         }
         SetParentAction.prototype._prepare = function () {
-            this._target = this._getTarget(this.targetType, this.targetName);
-            this._parent = this._getTarget(this.parentType, this.parentName);
         };
 
         SetParentAction.prototype.execute = function () {

+ 63 - 12
Babylon/Actions/babylon.directActions.ts

@@ -3,12 +3,12 @@
         private _target: any;
         private _property: string;
 
-        constructor(trigger: number, public targetType: number, public targetName: string, public propertyPath: string, condition?: Condition) {
+        constructor(trigger: number, target: any, public propertyPath: string, condition?: Condition) {
             super(trigger, condition);
+            this._target = target;
         }
 
         public _prepare(): void {
-            this._target = this._getTarget(this.targetType, this.targetName);
             this._target = this._getEffectiveTarget(this._target, this.propertyPath);
             this._property = this._getProperty(this.propertyPath);
         }
@@ -22,12 +22,12 @@
         private _target: any;
         private _property: string;
 
-        constructor(trigger: number, public targetType: number, public targetName: string, public propertyPath: string, public value: any, condition?: Condition) {
+        constructor(trigger: number, target: any, public propertyPath: string, public value: any, condition?: Condition) {
             super(trigger, condition);
+            this._target = target;
         }
 
         public _prepare(): void {
-            this._target = this._getTarget(this.targetType, this.targetName);
             this._target = this._getEffectiveTarget(this._target, this.propertyPath);
             this._property = this._getProperty(this.propertyPath);
         }
@@ -37,15 +37,38 @@
         }
     }
 
+    export class IncrementValueAction extends Action {
+        private _target: any;
+        private _property: string;
+
+        constructor(trigger: number, target: any, public propertyPath: string, public value: any, condition?: Condition) {
+            super(trigger, condition);
+            this._target = target;
+        }
+
+        public _prepare(): void {
+            this._target = this._getEffectiveTarget(this._target, this.propertyPath);
+            this._property = this._getProperty(this.propertyPath);
+
+            if (typeof this._target[this._property] !== "number") {
+                console.warn("Warning: IncrementValueAction can only be used with number values");
+            }
+        }
+
+        public execute(): void {
+            this._target[this._property] += this.value;
+        }
+    }
+
     export class PlayAnimationAction extends Action {
         private _target: any;
 
-        constructor(trigger: number, public targetType: number, public targetName: string, public from: number, public to: number, public loop?: boolean, condition?: Condition) {
+        constructor(trigger: number, target: any, public from: number, public to: number, public loop?: boolean, condition?: Condition) {
             super(trigger, condition);
+            this._target = target;
         }
 
         public _prepare(): void {
-            this._target = this._getTarget(this.targetType, this.targetName);
         }
 
         public execute(): void {
@@ -57,12 +80,12 @@
     export class StopAnimationAction extends Action {
         private _target: any;
 
-        constructor(trigger: number, public targetType: number, public targetName: string, condition?: Condition) {
+        constructor(trigger: number, target: any, condition?: Condition) {
             super(trigger, condition);
+            this._target = target;
         }
 
-        public _prepare(): void {
-            this._target = this._getTarget(this.targetType, this.targetName);
+        public _prepare(): void {           
         }
 
         public execute(): void {
@@ -71,6 +94,34 @@
         }
     }
 
+    export class DoNothingAction extends Action {
+        constructor(trigger: number = ActionManager.NoneTrigger, condition?: Condition) {
+            super(trigger, condition);
+        }
+
+        public execute(): void {
+        }
+    }
+
+    export class CombineAction extends Action {
+        constructor(trigger: number, public children: Action[], condition?: Condition) {
+            super(trigger, condition);
+        }
+
+        public _prepare(): void {
+            for (var index = 0; index < this.children.length; index++) {
+                this.children[index]._actionManager = this._actionManager;
+                this.children[index]._prepare();
+            }
+        }
+
+        public execute(): void {
+            for (var index = 0; index < this.children.length; index++) {
+                this.children[index].execute();
+            }
+        }
+    }
+
     export class ExecuteCodeAction extends Action {
         constructor(trigger: number, public func: () => void, condition?: Condition) {
             super(trigger, condition);
@@ -85,13 +136,13 @@
         private _parent: any;
         private _target: any;
 
-        constructor(trigger: number, public targetType: number, public targetName: string, public parentType: number, public parentName: string, condition?: Condition) {
+        constructor(trigger: number, target: any, parent: any, condition?: Condition) {
             super(trigger, condition);
+            this._target = target;
+            this._parent = parent;
         }
 
         public _prepare(): void {
-            this._target = this._getTarget(this.targetType, this.targetName);
-            this._parent = this._getTarget(this.parentType, this.parentName);
         }
 
         public execute(): void {

+ 15 - 6
Babylon/Actions/babylon.interpolateValueAction.js

@@ -8,17 +8,17 @@ var BABYLON;
 (function (BABYLON) {
     var InterpolateValueAction = (function (_super) {
         __extends(InterpolateValueAction, _super);
-        function InterpolateValueAction(trigger, targetType, targetName, propertyPath, value, duration, condition) {
+        function InterpolateValueAction(trigger, target, propertyPath, value, duration, condition, stopOtherAnimations) {
             if (typeof duration === "undefined") { duration = 1000; }
             _super.call(this, trigger, condition);
-            this.targetType = targetType;
-            this.targetName = targetName;
             this.propertyPath = propertyPath;
             this.value = value;
             this.duration = duration;
+            this.stopOtherAnimations = stopOtherAnimations;
+
+            this._target = target;
         }
         InterpolateValueAction.prototype._prepare = function () {
-            this._target = this._getTarget(this.targetType, this.targetName);
             this._target = this._getEffectiveTarget(this._target, this.propertyPath);
             this._property = this._getProperty(this.propertyPath);
         };
@@ -35,9 +35,11 @@ var BABYLON;
                 }
             ];
 
-            var dataType = BABYLON.Animation.ANIMATIONTYPE_FLOAT;
+            var dataType;
 
-            if (this.value instanceof BABYLON.Color3) {
+            if (typeof this.value === "number") {
+                dataType = BABYLON.Animation.ANIMATIONTYPE_FLOAT;
+            } else if (this.value instanceof BABYLON.Color3) {
                 dataType = BABYLON.Animation.ANIMATIONTYPE_COLOR3;
             } else if (this.value instanceof BABYLON.Vector3) {
                 dataType = BABYLON.Animation.ANIMATIONTYPE_VECTOR3;
@@ -45,12 +47,19 @@ var BABYLON;
                 dataType = BABYLON.Animation.ANIMATIONTYPE_MATRIX;
             } else if (this.value instanceof BABYLON.Quaternion) {
                 dataType = BABYLON.Animation.ANIMATIONTYPE_QUATERNION;
+            } else {
+                console.warn("InterpolateValueAction: Unsupported type (" + typeof this.value + ")");
+                return;
             }
 
             var animation = new BABYLON.Animation("InterpolateValueAction", this._property, 100 * (1000.0 / this.duration), dataType, BABYLON.Animation.ANIMATIONLOOPMODE_CONSTANT);
 
             animation.setKeys(keys);
 
+            if (this.stopOtherAnimations) {
+                scene.stopAnimation(this._target);
+            }
+
             scene.beginDirectAnimation(this._target, [animation], 0, 100);
         };
         return InterpolateValueAction;

+ 15 - 5
Babylon/Actions/babylon.interpolateValueAction.ts

@@ -3,12 +3,13 @@
         private _target: any;
         private _property: string;
 
-        constructor(trigger: number, public targetType: number, public targetName: string, public propertyPath: string, public value: any, public duration: number = 1000, condition?: Condition) {
+        constructor(trigger: number, target: any, public propertyPath: string, public value: any, public duration: number = 1000, condition?: Condition, public stopOtherAnimations?: boolean) {
             super(trigger, condition);
+
+            this._target = target;
         }
 
         public _prepare(): void {
-            this._target = this._getTarget(this.targetType, this.targetName);
             this._target = this._getEffectiveTarget(this._target, this.propertyPath);
             this._property = this._getProperty(this.propertyPath);
         }
@@ -25,9 +26,11 @@
                 }
             ];
 
-            var dataType: number = Animation.ANIMATIONTYPE_FLOAT;
+            var dataType: number;
 
-            if (this.value instanceof Color3) {
+            if (typeof this.value === "number") {
+                dataType = Animation.ANIMATIONTYPE_FLOAT;
+            } else if (this.value instanceof Color3) {
                 dataType = Animation.ANIMATIONTYPE_COLOR3;
             } else if (this.value instanceof Vector3) {
                 dataType = Animation.ANIMATIONTYPE_VECTOR3;
@@ -35,12 +38,19 @@
                 dataType = Animation.ANIMATIONTYPE_MATRIX;
             } else if (this.value instanceof Quaternion) {
                 dataType = Animation.ANIMATIONTYPE_QUATERNION;
-            } 
+            } else {
+                console.warn("InterpolateValueAction: Unsupported type (" + typeof this.value + ")");
+                return;
+            }
 
             var animation = new BABYLON.Animation("InterpolateValueAction", this._property, 100 * (1000.0 / this.duration), dataType, Animation.ANIMATIONLOOPMODE_CONSTANT);
 
             animation.setKeys(keys);
 
+            if (this.stopOtherAnimations) {
+                scene.stopAnimation(this._target);
+            }
+
             scene.beginDirectAnimation(this._target, [animation], 0, 100);
         }
     }

+ 17 - 17
Babylon/Cameras/babylon.virtualJoysticksCamera.js

@@ -11,32 +11,32 @@ var BABYLON;
         __extends(VirtualJoysticksCamera, _super);
         function VirtualJoysticksCamera(name, position, scene) {
             _super.call(this, name, position, scene);
-            this.leftjoystick = new BABYLON.VirtualJoystick(true);
-            this.leftjoystick.setAxisForUD(2 /* Z */);
-            this.leftjoystick.setAxisForLR(0 /* X */);
-            this.leftjoystick.setJoystickSensibility(0.15);
-            this.rightjoystick = new BABYLON.VirtualJoystick(false);
-            this.rightjoystick.setAxisForUD(0 /* X */);
-            this.rightjoystick.setAxisForLR(1 /* Y */);
-            this.rightjoystick.reverseUpDown = true;
-            this.rightjoystick.setJoystickSensibility(0.05);
-            this.rightjoystick.setJoystickColor("yellow");
+            this._leftjoystick = new BABYLON.VirtualJoystick(true);
+            this._leftjoystick.setAxisForUpDown(2 /* Z */);
+            this._leftjoystick.setAxisForLeftRight(0 /* X */);
+            this._leftjoystick.setJoystickSensibility(0.15);
+            this._rightjoystick = new BABYLON.VirtualJoystick(false);
+            this._rightjoystick.setAxisForUpDown(0 /* X */);
+            this._rightjoystick.setAxisForLeftRight(1 /* Y */);
+            this._rightjoystick.reverseUpDown = true;
+            this._rightjoystick.setJoystickSensibility(0.05);
+            this._rightjoystick.setJoystickColor("yellow");
         }
         VirtualJoysticksCamera.prototype._checkInputs = function () {
             var cameraTransform = BABYLON.Matrix.RotationYawPitchRoll(this.rotation.y, this.rotation.x, 0);
-            var deltaTransform = BABYLON.Vector3.TransformCoordinates(this.leftjoystick.deltaPosition, cameraTransform);
+            var deltaTransform = BABYLON.Vector3.TransformCoordinates(this._leftjoystick.deltaPosition, cameraTransform);
             this.cameraDirection = this.cameraDirection.add(deltaTransform);
-            this.cameraRotation = this.cameraRotation.add(this.rightjoystick.deltaPosition);
-            if (!this.leftjoystick.pressed) {
-                this.leftjoystick.deltaPosition = this.leftjoystick.deltaPosition.scale(0.9);
+            this.cameraRotation = this.cameraRotation.add(this._rightjoystick.deltaPosition);
+            if (!this._leftjoystick.pressed) {
+                this._leftjoystick.deltaPosition = this._leftjoystick.deltaPosition.scale(0.9);
             }
-            if (!this.rightjoystick.pressed) {
-                this.rightjoystick.deltaPosition = this.rightjoystick.deltaPosition.scale(0.9);
+            if (!this._rightjoystick.pressed) {
+                this._rightjoystick.deltaPosition = this._rightjoystick.deltaPosition.scale(0.9);
             }
         };
 
         VirtualJoysticksCamera.prototype.dispose = function () {
-            this.leftjoystick.releaseCanvas();
+            this._leftjoystick.releaseCanvas();
         };
         return VirtualJoysticksCamera;
     })(BABYLON.FreeCamera);

+ 22 - 22
Babylon/Cameras/babylon.virtualJoysticksCamera.ts

@@ -1,38 +1,38 @@
 module BABYLON {
     // We're mainly based on the logic defined into the FreeCamera code
     export class VirtualJoysticksCamera extends FreeCamera {
-        private leftjoystick: BABYLON.VirtualJoystick;
-        private rightjoystick: BABYLON.VirtualJoystick;
+        private _leftjoystick: BABYLON.VirtualJoystick;
+        private _rightjoystick: BABYLON.VirtualJoystick;
 
-        constructor(name, position, scene) {
+        constructor(name: string, position: Vector3, scene: Scene) {
             super(name, position, scene);
-            this.leftjoystick = new BABYLON.VirtualJoystick(true);
-            this.leftjoystick.setAxisForUD(BABYLON.JoystickAxis.Z);
-            this.leftjoystick.setAxisForLR(BABYLON.JoystickAxis.X);
-            this.leftjoystick.setJoystickSensibility(0.15);
-            this.rightjoystick = new BABYLON.VirtualJoystick(false);
-            this.rightjoystick.setAxisForUD(BABYLON.JoystickAxis.X);
-            this.rightjoystick.setAxisForLR(BABYLON.JoystickAxis.Y);
-            this.rightjoystick.reverseUpDown = true;
-            this.rightjoystick.setJoystickSensibility(0.05);
-            this.rightjoystick.setJoystickColor("yellow");
+            this._leftjoystick = new BABYLON.VirtualJoystick(true);
+            this._leftjoystick.setAxisForUpDown(BABYLON.JoystickAxis.Z);
+            this._leftjoystick.setAxisForLeftRight(BABYLON.JoystickAxis.X);
+            this._leftjoystick.setJoystickSensibility(0.15);
+            this._rightjoystick = new BABYLON.VirtualJoystick(false);
+            this._rightjoystick.setAxisForUpDown(BABYLON.JoystickAxis.X);
+            this._rightjoystick.setAxisForLeftRight(BABYLON.JoystickAxis.Y);
+            this._rightjoystick.reverseUpDown = true;
+            this._rightjoystick.setJoystickSensibility(0.05);
+            this._rightjoystick.setJoystickColor("yellow");
         }
 
-        public _checkInputs() {
+        public _checkInputs(): void {
             var cameraTransform = BABYLON.Matrix.RotationYawPitchRoll(this.rotation.y, this.rotation.x, 0);
-            var deltaTransform = BABYLON.Vector3.TransformCoordinates(this.leftjoystick.deltaPosition, cameraTransform);
+            var deltaTransform = BABYLON.Vector3.TransformCoordinates(this._leftjoystick.deltaPosition, cameraTransform);
             this.cameraDirection = this.cameraDirection.add(deltaTransform);
-            this.cameraRotation = this.cameraRotation.add(this.rightjoystick.deltaPosition);
-            if (!this.leftjoystick.pressed) {
-                this.leftjoystick.deltaPosition = this.leftjoystick.deltaPosition.scale(0.9);
+            this.cameraRotation = this.cameraRotation.add(this._rightjoystick.deltaPosition);
+            if (!this._leftjoystick.pressed) {
+                this._leftjoystick.deltaPosition = this._leftjoystick.deltaPosition.scale(0.9);
             }
-            if (!this.rightjoystick.pressed) {
-                this.rightjoystick.deltaPosition = this.rightjoystick.deltaPosition.scale(0.9);
+            if (!this._rightjoystick.pressed) {
+                this._rightjoystick.deltaPosition = this._rightjoystick.deltaPosition.scale(0.9);
             }
         }
 
-        public dispose() {
-            this.leftjoystick.releaseCanvas();
+        public dispose(): void {
+            this._leftjoystick.releaseCanvas();
         }
     }
 }

+ 3 - 4
Babylon/Materials/babylon.standardMaterial.js

@@ -232,11 +232,10 @@ var BABYLON;
 
                 // Legacy browser patch
                 var shaderName = "default";
+                if (!scene.getEngine().getCaps().standardDerivatives) {
+                    shaderName = "legacydefault";
+                }
 
-                //     if (!scene.getEngine().getCaps().standardDerivatives) {
-                shaderName = "legacydefault";
-
-                //   }
                 this._effect = scene.getEngine().createEffect(shaderName, attribs, [
                     "world", "view", "viewProjection", "vEyePosition", "vLightsType", "vAmbientColor", "vDiffuseColor", "vSpecularColor", "vEmissiveColor",
                     "vLightData0", "vLightDiffuse0", "vLightSpecular0", "vLightDirection0", "vLightGround0", "lightMatrix0",

+ 2 - 2
Babylon/Materials/babylon.standardMaterial.ts

@@ -235,9 +235,9 @@
 
                 // Legacy browser patch
                 var shaderName = "default";
-           //     if (!scene.getEngine().getCaps().standardDerivatives) {
+                if (!scene.getEngine().getCaps().standardDerivatives) {
                     shaderName = "legacydefault";
-             //   }
+                }
 
                 this._effect = scene.getEngine().createEffect(shaderName,
                     attribs,

+ 25 - 0
Babylon/Math/babylon.math.js

@@ -108,6 +108,31 @@
 
             return new Color3(r, g, b);
         };
+
+        Color3.Red = function () {
+            return new Color3(1, 0, 0);
+        };
+        Color3.Green = function () {
+            return new Color3(0, 1, 0);
+        };
+        Color3.Blue = function () {
+            return new Color3(0, 0, 1);
+        };
+        Color3.Black = function () {
+            return new Color3(0, 0, 0);
+        };
+        Color3.White = function () {
+            return new Color3(1, 1, 1);
+        };
+        Color3.Purple = function () {
+            return new Color3(0.5, 0, 0.5);
+        };
+        Color3.Magenta = function () {
+            return new Color3(1, 0, 1);
+        };
+        Color3.Yellow = function () {
+            return new Color3(1, 1, 0);
+        };
         return Color3;
     })();
     BABYLON.Color3 = Color3;

+ 9 - 0
Babylon/Math/babylon.math.ts

@@ -102,6 +102,15 @@
 
             return new Color3(r, g, b);
         }
+
+        public static Red(): Color3 { return new Color3(1, 0, 0); }
+        public static Green(): Color3 { return new Color3(0, 1, 0); }
+        public static Blue(): Color3 { return new Color3(0, 0, 1); }
+        public static Black(): Color3 { return new Color3(0, 0, 0); }
+        public static White(): Color3 { return new Color3(1, 1, 1); }
+        public static Purple(): Color3 { return new Color3(0.5, 0, 0.5); }
+        public static Magenta(): Color3 { return new Color3(1, 0, 1); }
+        public static Yellow(): Color3 { return new Color3(1, 1, 0); }
     }
 
     export class Color4 {

+ 5 - 4
Babylon/Tools/babylon.tools.js

@@ -320,9 +320,9 @@
             var width;
             var height;
 
-            //If a zoom value is specified
-            if (size.zoom) {
-                width = Math.round(engine.getRenderWidth() * size.zoom);
+            //If a precision value is specified
+            if (size.precision) {
+                width = Math.round(engine.getRenderWidth() * size.precision);
                 height = Math.round(width / engine.getAspectRatio(camera));
                 size = { width: width, height: height };
             } else if (size.width && size.height) {
@@ -341,8 +341,10 @@
                 width = size;
             } else {
                 console.error("Invalid 'size' parameter !");
+                return;
             }
 
+            //At this point size can be a number, or an object (according to engine.prototype.createRenderTargetTexture method)
             var texture = new BABYLON.RenderTargetTexture("screenShot", size, engine.scenes[0]);
             texture.renderList = engine.scenes[0].meshes;
 
@@ -359,7 +361,6 @@
                         var currentCell = j + i * numberOfChannelsByLine;
                         var targetLine = height - i - 1;
                         var targetCell = j + targetLine * numberOfChannelsByLine;
-                        ;
 
                         var temp = data[currentCell];
                         data[currentCell] = data[targetCell];

+ 7 - 5
Babylon/Tools/babylon.tools.ts

@@ -86,7 +86,7 @@
             };
         }
 
-        public static MakeArray(obj, allowsNullUndefined: boolean): Array<any> {
+        public static MakeArray(obj, allowsNullUndefined?: boolean): Array<any> {
             if (allowsNullUndefined !== true && (obj === undefined || obj == null))
                 return undefined;
 
@@ -341,9 +341,9 @@
             var width: number;
             var height: number;
 
-            //If a zoom value is specified
-            if (size.zoom) {
-                width = Math.round(engine.getRenderWidth() * size.zoom);
+            //If a precision value is specified
+            if (size.precision) {
+                width = Math.round(engine.getRenderWidth() * size.precision);
                 height = Math.round(width / engine.getAspectRatio(camera));
                 size = { width: width, height: height };
             }
@@ -370,8 +370,10 @@
             }
             else {
                 console.error("Invalid 'size' parameter !");
+                return;
             }
 
+            //At this point size can be a number, or an object (according to engine.prototype.createRenderTargetTexture method)
             var texture = new RenderTargetTexture("screenShot", size, engine.scenes[0]);
             texture.renderList = engine.scenes[0].meshes;
 
@@ -389,7 +391,7 @@
                     for (var j = 0; j < numberOfChannelsByLine; j++) {
                         var currentCell = j + i * numberOfChannelsByLine;
                         var targetLine = height - i - 1;
-                        var targetCell = j + targetLine * numberOfChannelsByLine;;
+                        var targetCell = j + targetLine * numberOfChannelsByLine;
 
                         var temp = data[currentCell];
                         data[currentCell] = data[targetCell];

+ 94 - 92
Babylon/Tools/babylon.virtualJoystick.js

@@ -19,7 +19,7 @@ var BABYLON;
                 this._leftJoystick = false;
             }
 
-            this.joystickIndex = VirtualJoystick._globalJoystickIndex;
+            this._joystickIndex = VirtualJoystick._globalJoystickIndex;
             VirtualJoystick._globalJoystickIndex++;
 
             // By default left & right arrow keys are moving the X
@@ -75,32 +75,32 @@ var BABYLON;
             // default joystick color
             this._joystickColor = "cyan";
 
-            this.joystickPointerID = -1;
+            this._joystickPointerID = -1;
 
             // current joystick position
-            this.joystickPointerPos = new BABYLON.Vector2(0, 0);
+            this._joystickPointerPos = new BABYLON.Vector2(0, 0);
 
             // origin joystick position
-            this.joystickPointerStartPos = new BABYLON.Vector2(0, 0);
-            this.deltaJoystickVector = new BABYLON.Vector2(0, 0);
+            this._joystickPointerStartPos = new BABYLON.Vector2(0, 0);
+            this._deltaJoystickVector = new BABYLON.Vector2(0, 0);
 
             VirtualJoystick.vjCanvas.addEventListener('pointerdown', function (evt) {
-                _this.onPointerDown(evt);
+                _this._onPointerDown(evt);
             }, false);
             VirtualJoystick.vjCanvas.addEventListener('pointermove', function (evt) {
-                _this.onPointerMove(evt);
+                _this._onPointerMove(evt);
             }, false);
             VirtualJoystick.vjCanvas.addEventListener('pointerup', function (evt) {
-                _this.onPointerUp(evt);
+                _this._onPointerUp(evt);
             }, false);
             VirtualJoystick.vjCanvas.addEventListener('pointerout', function (evt) {
-                _this.onPointerUp(evt);
+                _this._onPointerUp(evt);
             }, false);
             VirtualJoystick.vjCanvas.addEventListener("contextmenu", function (evt) {
                 evt.preventDefault(); // Disables system menu
             }, false);
             requestAnimationFrame(function () {
-                _this.drawVirtualJoystick();
+                _this._drawVirtualJoystick();
             });
         }
         VirtualJoystick.prototype.setJoystickSensibility = function (newJoystickSensibility) {
@@ -108,45 +108,46 @@ var BABYLON;
             this._inversedSensibility = 1 / (this._joystickSensibility / 1000);
         };
 
-        VirtualJoystick.prototype.onPointerDown = function (e) {
-            e.preventDefault();
-            var newPointer = { identifier: e.pointerId, x: e.clientX, y: e.clientY, type: this.givePointerType(e) };
+        VirtualJoystick.prototype._onPointerDown = function (e) {
             var positionOnScreenCondition;
+
+            e.preventDefault();
+
             if (this._leftJoystick === true) {
                 positionOnScreenCondition = (e.clientX < VirtualJoystick.halfWidth);
             } else {
                 positionOnScreenCondition = (e.clientX > VirtualJoystick.halfWidth);
             }
 
-            if (positionOnScreenCondition && this.joystickPointerID < 0) {
+            if (positionOnScreenCondition && this._joystickPointerID < 0) {
                 // First contact will be dedicated to the virtual joystick
-                this.joystickPointerID = e.pointerId;
-                this.joystickPointerStartPos.x = e.clientX;
-                this.joystickPointerStartPos.y = e.clientY;
-                this.joystickPointerPos = this.joystickPointerStartPos.clone();
-                this.deltaJoystickVector.x = 0;
-                this.deltaJoystickVector.y = 0;
+                this._joystickPointerID = e.pointerId;
+                this._joystickPointerStartPos.x = e.clientX;
+                this._joystickPointerStartPos.y = e.clientY;
+                this._joystickPointerPos = this._joystickPointerStartPos.clone();
+                this._deltaJoystickVector.x = 0;
+                this._deltaJoystickVector.y = 0;
                 this.pressed = true;
-                this._touches.add(e.pointerId.toString(), newPointer);
+                this._touches.add(e.pointerId.toString(), e);
             } else {
                 // You can only trigger the action buttons with a joystick declared
                 if (VirtualJoystick._globalJoystickIndex < 2 && this._action) {
                     this._action();
-                    this._touches.add(e.pointerId.toString(), newPointer);
+                    this._touches.add(e.pointerId.toString(), e);
                 }
             }
         };
 
-        VirtualJoystick.prototype.onPointerMove = function (e) {
+        VirtualJoystick.prototype._onPointerMove = function (e) {
             // If the current pointer is the one associated to the joystick (first touch contact)
-            if (this.joystickPointerID == e.pointerId) {
-                this.joystickPointerPos.x = e.clientX;
-                this.joystickPointerPos.y = e.clientY;
-                this.deltaJoystickVector = this.joystickPointerPos.clone();
-                this.deltaJoystickVector = this.deltaJoystickVector.subtract(this.joystickPointerStartPos);
+            if (this._joystickPointerID == e.pointerId) {
+                this._joystickPointerPos.x = e.clientX;
+                this._joystickPointerPos.y = e.clientY;
+                this._deltaJoystickVector = this._joystickPointerPos.clone();
+                this._deltaJoystickVector = this._deltaJoystickVector.subtract(this._joystickPointerStartPos);
 
                 var directionLeftRight = this.reverseLeftRight ? -1 : 1;
-                var deltaJoystickX = directionLeftRight * this.deltaJoystickVector.x / this._inversedSensibility;
+                var deltaJoystickX = directionLeftRight * this._deltaJoystickVector.x / this._inversedSensibility;
                 switch (this._axisTargetedByLeftAndRight) {
                     case 0 /* X */:
                         this.deltaPosition.x = Math.min(1, Math.max(-1, deltaJoystickX));
@@ -159,7 +160,7 @@ var BABYLON;
                         break;
                 }
                 var directionUpDown = this.reverseUpDown ? 1 : -1;
-                var deltaJoystickY = directionUpDown * this.deltaJoystickVector.y / this._inversedSensibility;
+                var deltaJoystickY = directionUpDown * this._deltaJoystickVector.y / this._inversedSensibility;
                 switch (this._axisTargetedByUpAndDown) {
                     case 0 /* X */:
                         this.deltaPosition.x = Math.min(1, Math.max(-1, deltaJoystickY));
@@ -179,17 +180,22 @@ var BABYLON;
             }
         };
 
-        VirtualJoystick.prototype.onPointerUp = function (e) {
-            if (this.joystickPointerID == e.pointerId) {
-                this.joystickPointerID = -1;
+        VirtualJoystick.prototype._onPointerUp = function (e) {
+            this._clearCanvas();
+            if (this._joystickPointerID == e.pointerId) {
+                this._joystickPointerID = -1;
                 this.pressed = false;
             }
-            this.deltaJoystickVector.x = 0;
-            this.deltaJoystickVector.y = 0;
+            this._deltaJoystickVector.x = 0;
+            this._deltaJoystickVector.y = 0;
 
             this._touches.remove(e.pointerId.toString());
         };
 
+        /**
+        * Change the color of the virtual joystick
+        * @param newColor a string that must be a CSS color value (like "red") or the hexa value (like "#FF0000")
+        */
         VirtualJoystick.prototype.setJoystickColor = function (newColor) {
             this._joystickColor = newColor;
         };
@@ -199,7 +205,7 @@ var BABYLON;
         };
 
         // Define which axis you'd like to control for left & right
-        VirtualJoystick.prototype.setAxisForLR = function (axis) {
+        VirtualJoystick.prototype.setAxisForLeftRight = function (axis) {
             switch (axis) {
                 case 0 /* X */:
                 case 1 /* Y */:
@@ -215,7 +221,7 @@ var BABYLON;
         };
 
         // Define which axis you'd like to control for up & down
-        VirtualJoystick.prototype.setAxisForUD = function (axis) {
+        VirtualJoystick.prototype.setAxisForUpDown = function (axis) {
             switch (axis) {
                 case 0 /* X */:
                 case 1 /* Y */:
@@ -228,57 +234,49 @@ var BABYLON;
             }
         };
 
-        VirtualJoystick.prototype.drawVirtualJoystick = function () {
-            var _this = this;
+        VirtualJoystick.prototype._clearCanvas = function () {
             if (this._leftJoystick) {
                 VirtualJoystick.vjCanvasContext.clearRect(0, 0, VirtualJoystick.vjCanvasWidth / 2, VirtualJoystick.vjCanvasHeight);
             } else {
                 VirtualJoystick.vjCanvasContext.clearRect(VirtualJoystick.vjCanvasWidth / 2, 0, VirtualJoystick.vjCanvasWidth, VirtualJoystick.vjCanvasHeight);
             }
-            this._touches.forEach(function (touch) {
-                if (touch.identifier === _this.joystickPointerID) {
-                    VirtualJoystick.vjCanvasContext.beginPath();
-                    VirtualJoystick.vjCanvasContext.strokeStyle = _this._joystickColor;
-                    VirtualJoystick.vjCanvasContext.lineWidth = 6;
-                    VirtualJoystick.vjCanvasContext.arc(_this.joystickPointerStartPos.x, _this.joystickPointerStartPos.y, 40, 0, Math.PI * 2, true);
-                    VirtualJoystick.vjCanvasContext.stroke();
-                    VirtualJoystick.vjCanvasContext.beginPath();
-                    VirtualJoystick.vjCanvasContext.strokeStyle = _this._joystickColor;
-                    VirtualJoystick.vjCanvasContext.lineWidth = 2;
-                    VirtualJoystick.vjCanvasContext.arc(_this.joystickPointerStartPos.x, _this.joystickPointerStartPos.y, 60, 0, Math.PI * 2, true);
-                    VirtualJoystick.vjCanvasContext.stroke();
-                    VirtualJoystick.vjCanvasContext.beginPath();
-                    VirtualJoystick.vjCanvasContext.strokeStyle = _this._joystickColor;
-                    VirtualJoystick.vjCanvasContext.arc(_this.joystickPointerPos.x, _this.joystickPointerPos.y, 40, 0, Math.PI * 2, true);
-                    VirtualJoystick.vjCanvasContext.stroke();
-                } else {
-                    VirtualJoystick.vjCanvasContext.beginPath();
-                    VirtualJoystick.vjCanvasContext.fillStyle = "white";
-                    VirtualJoystick.vjCanvasContext.beginPath();
-                    VirtualJoystick.vjCanvasContext.strokeStyle = "red";
-                    VirtualJoystick.vjCanvasContext.lineWidth = 6;
-                    VirtualJoystick.vjCanvasContext.arc(touch.x, touch.y, 40, 0, Math.PI * 2, true);
-                    VirtualJoystick.vjCanvasContext.stroke();
-                }
-                ;
-            });
-            requestAnimationFrame(function () {
-                _this.drawVirtualJoystick();
-            });
         };
 
-        VirtualJoystick.prototype.givePointerType = function (event) {
-            switch (event.pointerType) {
-                case event.POINTER_TYPE_MOUSE:
-                    return "MOUSE";
-                    break;
-                case event.POINTER_TYPE_PEN:
-                    return "PEN";
-                    break;
-                case event.POINTER_TYPE_TOUCH:
-                    return "TOUCH";
-                    break;
+        VirtualJoystick.prototype._drawVirtualJoystick = function () {
+            var _this = this;
+            if (this.pressed) {
+                this._clearCanvas();
+                this._touches.forEach(function (touch) {
+                    if (touch.pointerId === _this._joystickPointerID) {
+                        VirtualJoystick.vjCanvasContext.beginPath();
+                        VirtualJoystick.vjCanvasContext.strokeStyle = _this._joystickColor;
+                        VirtualJoystick.vjCanvasContext.lineWidth = 6;
+                        VirtualJoystick.vjCanvasContext.arc(_this._joystickPointerStartPos.x, _this._joystickPointerStartPos.y, 40, 0, Math.PI * 2, true);
+                        VirtualJoystick.vjCanvasContext.stroke();
+                        VirtualJoystick.vjCanvasContext.beginPath();
+                        VirtualJoystick.vjCanvasContext.strokeStyle = _this._joystickColor;
+                        VirtualJoystick.vjCanvasContext.lineWidth = 2;
+                        VirtualJoystick.vjCanvasContext.arc(_this._joystickPointerStartPos.x, _this._joystickPointerStartPos.y, 60, 0, Math.PI * 2, true);
+                        VirtualJoystick.vjCanvasContext.stroke();
+                        VirtualJoystick.vjCanvasContext.beginPath();
+                        VirtualJoystick.vjCanvasContext.strokeStyle = _this._joystickColor;
+                        VirtualJoystick.vjCanvasContext.arc(_this._joystickPointerPos.x, _this._joystickPointerPos.y, 40, 0, Math.PI * 2, true);
+                        VirtualJoystick.vjCanvasContext.stroke();
+                    } else {
+                        VirtualJoystick.vjCanvasContext.beginPath();
+                        VirtualJoystick.vjCanvasContext.fillStyle = "white";
+                        VirtualJoystick.vjCanvasContext.beginPath();
+                        VirtualJoystick.vjCanvasContext.strokeStyle = "red";
+                        VirtualJoystick.vjCanvasContext.lineWidth = 6;
+                        VirtualJoystick.vjCanvasContext.arc(touch.x, touch.y, 40, 0, Math.PI * 2, true);
+                        VirtualJoystick.vjCanvasContext.stroke();
+                    }
+                    ;
+                });
             }
+            requestAnimationFrame(function () {
+                _this._drawVirtualJoystick();
+            });
         };
 
         VirtualJoystick.prototype.releaseCanvas = function () {
@@ -298,34 +296,38 @@ var BABYLON;
     (function (VirtualJoystick) {
         var Collection = (function () {
             function Collection() {
-                this.count = 0;
-                this.collection = new Array();
+                this._count = 0;
+                this._collection = new Array();
             }
+            Collection.prototype.Count = function () {
+                return this._count;
+            };
+
             Collection.prototype.add = function (key, item) {
-                if (this.collection[key] != undefined) {
+                if (this._collection[key] != undefined) {
                     return undefined;
                 }
-                this.collection[key] = item;
-                return ++this.count;
+                this._collection[key] = item;
+                return ++this._count;
             };
 
             Collection.prototype.remove = function (key) {
-                if (this.collection[key] == undefined) {
+                if (this._collection[key] == undefined) {
                     return undefined;
                 }
-                delete this.collection[key];
-                return --this.count;
+                delete this._collection[key];
+                return --this._count;
             };
 
             Collection.prototype.item = function (key) {
-                return this.collection[key];
+                return this._collection[key];
             };
 
             Collection.prototype.forEach = function (block) {
                 var key;
-                for (key in this.collection) {
-                    if (this.collection.hasOwnProperty(key)) {
-                        block(this.collection[key]);
+                for (key in this._collection) {
+                    if (this._collection.hasOwnProperty(key)) {
+                        block(this._collection[key]);
                     }
                 }
             };

+ 111 - 107
Babylon/Tools/babylon.virtualJoystick.ts

@@ -10,6 +10,12 @@ module BABYLON {
     }
 
     export class VirtualJoystick {
+        public reverseLeftRight: boolean;
+        public reverseUpDown: boolean;
+        public deltaPosition: Vector3;
+        public pressed: boolean;
+
+        // Used to draw the virtual joystick inside a 2D canvas on top of the WebGL rendering canvas
         private static _globalJoystickIndex: number = 0;
         private static vjCanvas: HTMLCanvasElement;
         private static vjCanvasContext: CanvasRenderingContext2D;
@@ -18,26 +24,22 @@ module BABYLON {
         private static halfWidth: number; 
         private static halfHeight: number;
 
-        private _leftJoystick: boolean;
-        private joystickIndex: number;
-        public reverseLeftRight: boolean;
-        public reverseUpDown: boolean;
-        private _touches: BABYLON.VirtualJoystick.Collection<any>;
-        public deltaPosition: Vector3;
+        private _action: () => any;
         private _axisTargetedByLeftAndRight: JoystickAxis;
-        private _axisTargetedByUpAndDown: JoystickAxis; 
+        private _axisTargetedByUpAndDown: JoystickAxis;
         private _joystickSensibility: number;
         private _inversedSensibility: number;
         private _rotationSpeed: number;
         private _inverseRotationSpeed: number;
         private _rotateOnAxisRelativeToMesh: boolean;
-        private joystickPointerID: number;
+        private _joystickPointerID: number;
         private _joystickColor: string;
-        private joystickPointerPos: Vector2;
-        private joystickPointerStartPos: Vector2;
-        private deltaJoystickVector: Vector2;
-        public pressed: boolean;
-        private _action: () => any;
+        private _joystickPointerPos: Vector2;
+        private _joystickPointerStartPos: Vector2;
+        private _deltaJoystickVector: Vector2;
+        private _leftJoystick: boolean;
+        private _joystickIndex: number;
+        private _touches: BABYLON.VirtualJoystick.Collection<PointerEvent>;
 
         constructor(leftJoystick?: boolean) {
             if (leftJoystick) {
@@ -47,7 +49,7 @@ module BABYLON {
                 this._leftJoystick = false;
             }
 
-            this.joystickIndex = VirtualJoystick._globalJoystickIndex;
+            this._joystickIndex = VirtualJoystick._globalJoystickIndex;
             VirtualJoystick._globalJoystickIndex++;
 
             // By default left & right arrow keys are moving the X
@@ -59,7 +61,7 @@ module BABYLON {
             this.reverseUpDown = false;
 
             // collections of pointers
-            this._touches = new BABYLON.VirtualJoystick.Collection<any>();
+            this._touches = new BABYLON.VirtualJoystick.Collection<PointerEvent>();
             this.deltaPosition = BABYLON.Vector3.Zero();
 
             this._joystickSensibility = 25;
@@ -102,29 +104,29 @@ module BABYLON {
             // default joystick color
             this._joystickColor = "cyan";
 
-            this.joystickPointerID = -1;
+            this._joystickPointerID = -1;
             // current joystick position
-            this.joystickPointerPos = new BABYLON.Vector2(0, 0);
+            this._joystickPointerPos = new BABYLON.Vector2(0, 0);
             // origin joystick position
-            this.joystickPointerStartPos = new BABYLON.Vector2(0, 0);
-            this.deltaJoystickVector = new BABYLON.Vector2(0, 0);
+            this._joystickPointerStartPos = new BABYLON.Vector2(0, 0);
+            this._deltaJoystickVector = new BABYLON.Vector2(0, 0);
 
             VirtualJoystick.vjCanvas.addEventListener('pointerdown', (evt) => {
-                this.onPointerDown(evt);
+                this._onPointerDown(evt);
             }, false);
             VirtualJoystick.vjCanvas.addEventListener('pointermove', (evt) => {
-                this.onPointerMove(evt);
+                this._onPointerMove(evt);
             }, false);
             VirtualJoystick.vjCanvas.addEventListener('pointerup',  (evt) => {
-                this.onPointerUp(evt);
+                this._onPointerUp(evt);
             }, false);
             VirtualJoystick.vjCanvas.addEventListener('pointerout', (evt) => {
-                this.onPointerUp(evt);
+                this._onPointerUp(evt);
             }, false);
             VirtualJoystick.vjCanvas.addEventListener("contextmenu", (evt) => {
                 evt.preventDefault();    // Disables system menu
             }, false);
-            requestAnimationFrame(() => { this.drawVirtualJoystick(); });
+            requestAnimationFrame(() => { this._drawVirtualJoystick(); });
         }
 
         public setJoystickSensibility (newJoystickSensibility: number) {
@@ -132,10 +134,11 @@ module BABYLON {
             this._inversedSensibility = 1 / (this._joystickSensibility / 1000);
         }
 
-        private onPointerDown (e: PointerEvent) {
-            e.preventDefault();
-            var newPointer = { identifier: e.pointerId, x: e.clientX, y: e.clientY, type: this.givePointerType(e) };
+        private _onPointerDown (e: PointerEvent) {
             var positionOnScreenCondition: boolean;
+
+            e.preventDefault();
+
             if (this._leftJoystick === true) {
                 positionOnScreenCondition = (e.clientX < VirtualJoystick.halfWidth);
             }
@@ -143,36 +146,36 @@ module BABYLON {
                 positionOnScreenCondition = (e.clientX > VirtualJoystick.halfWidth);
             }
 
-            if (positionOnScreenCondition && this.joystickPointerID < 0) {
+            if (positionOnScreenCondition && this._joystickPointerID < 0) {
                 // First contact will be dedicated to the virtual joystick
-                this.joystickPointerID = e.pointerId;
-                this.joystickPointerStartPos.x = e.clientX;
-                this.joystickPointerStartPos.y = e.clientY;
-                this.joystickPointerPos = this.joystickPointerStartPos.clone();
-                this.deltaJoystickVector.x = 0;
-                this.deltaJoystickVector.y = 0;
+                this._joystickPointerID = e.pointerId;
+                this._joystickPointerStartPos.x = e.clientX;
+                this._joystickPointerStartPos.y = e.clientY;
+                this._joystickPointerPos = this._joystickPointerStartPos.clone();
+                this._deltaJoystickVector.x = 0;
+                this._deltaJoystickVector.y = 0;
                 this.pressed = true;
-                this._touches.add(e.pointerId.toString(), newPointer);
+                this._touches.add(e.pointerId.toString(), e);
             }
             else {
                 // You can only trigger the action buttons with a joystick declared
                 if (VirtualJoystick._globalJoystickIndex < 2 && this._action) {
                     this._action();
-                    this._touches.add(e.pointerId.toString(), newPointer);
+                    this._touches.add(e.pointerId.toString(), e);
                 }
             }
         }
 
-        private onPointerMove (e: PointerEvent) {
+        private _onPointerMove (e: PointerEvent) {
             // If the current pointer is the one associated to the joystick (first touch contact)
-            if (this.joystickPointerID == e.pointerId) {
-                this.joystickPointerPos.x = e.clientX;
-                this.joystickPointerPos.y = e.clientY;
-                this.deltaJoystickVector = this.joystickPointerPos.clone();
-                this.deltaJoystickVector = this.deltaJoystickVector.subtract(this.joystickPointerStartPos);
+            if (this._joystickPointerID == e.pointerId) {
+                this._joystickPointerPos.x = e.clientX;
+                this._joystickPointerPos.y = e.clientY;
+                this._deltaJoystickVector = this._joystickPointerPos.clone();
+                this._deltaJoystickVector = this._deltaJoystickVector.subtract(this._joystickPointerStartPos);
 
                 var directionLeftRight = this.reverseLeftRight ? -1 : 1;
-                var deltaJoystickX = directionLeftRight * this.deltaJoystickVector.x / this._inversedSensibility;
+                var deltaJoystickX = directionLeftRight * this._deltaJoystickVector.x / this._inversedSensibility;
                 switch (this._axisTargetedByLeftAndRight) {
                     case JoystickAxis.X:
                         this.deltaPosition.x = Math.min(1, Math.max(-1, deltaJoystickX));
@@ -185,7 +188,7 @@ module BABYLON {
                         break;
                 }
                 var directionUpDown = this.reverseUpDown ? 1 : -1;
-                var deltaJoystickY = directionUpDown * this.deltaJoystickVector.y / this._inversedSensibility;
+                var deltaJoystickY = directionUpDown * this._deltaJoystickVector.y / this._inversedSensibility;
                 switch (this._axisTargetedByUpAndDown) {
                     case JoystickAxis.X:
                         this.deltaPosition.x = Math.min(1, Math.max(-1, deltaJoystickY));
@@ -206,17 +209,22 @@ module BABYLON {
             }
         }
 
-       private onPointerUp (e: PointerEvent) {
-            if (this.joystickPointerID == e.pointerId) {
-                this.joystickPointerID = -1;
+        private _onPointerUp(e: PointerEvent) {
+            this._clearCanvas();
+            if (this._joystickPointerID == e.pointerId) {
+                this._joystickPointerID = -1;
                 this.pressed = false;
             }
-            this.deltaJoystickVector.x = 0;
-            this.deltaJoystickVector.y = 0;
+            this._deltaJoystickVector.x = 0;
+            this._deltaJoystickVector.y = 0;
 
            this._touches.remove(e.pointerId.toString());
         }
 
+        /**
+        * Change the color of the virtual joystick
+        * @param newColor a string that must be a CSS color value (like "red") or the hexa value (like "#FF0000")
+        */
         public setJoystickColor (newColor: string) {
             this._joystickColor = newColor;
         }
@@ -226,7 +234,7 @@ module BABYLON {
         }
 
         // Define which axis you'd like to control for left & right 
-        public setAxisForLR(axis: JoystickAxis) {
+        public setAxisForLeftRight(axis: JoystickAxis) {
             switch (axis) {
                 case JoystickAxis.X:
                 case JoystickAxis.Y:
@@ -242,7 +250,7 @@ module BABYLON {
         }
 
         // Define which axis you'd like to control for up & down 
-        public setAxisForUD(axis: JoystickAxis) {
+        public setAxisForUpDown(axis: JoystickAxis) {
             switch (axis) {
                 case JoystickAxis.X:
                 case JoystickAxis.Y:
@@ -255,55 +263,47 @@ module BABYLON {
             }
         }
 
-        private drawVirtualJoystick () {
+        private _clearCanvas(): void {
             if (this._leftJoystick) {
                 VirtualJoystick.vjCanvasContext.clearRect(0, 0, VirtualJoystick.vjCanvasWidth / 2, VirtualJoystick.vjCanvasHeight);
             }
             else {
                 VirtualJoystick.vjCanvasContext.clearRect(VirtualJoystick.vjCanvasWidth / 2, 0, VirtualJoystick.vjCanvasWidth, VirtualJoystick.vjCanvasHeight);
-            }
-            this._touches.forEach((touch) => {
-                if (touch.identifier === this.joystickPointerID) {
-                    VirtualJoystick.vjCanvasContext.beginPath();
-                    VirtualJoystick.vjCanvasContext.strokeStyle = this._joystickColor;
-                    VirtualJoystick.vjCanvasContext.lineWidth = 6;
-                    VirtualJoystick.vjCanvasContext.arc(this.joystickPointerStartPos.x, this.joystickPointerStartPos.y, 40, 0, Math.PI * 2, true);
-                    VirtualJoystick.vjCanvasContext.stroke();
-                    VirtualJoystick.vjCanvasContext.beginPath();
-                    VirtualJoystick.vjCanvasContext.strokeStyle = this._joystickColor;
-                    VirtualJoystick.vjCanvasContext.lineWidth = 2;
-                    VirtualJoystick.vjCanvasContext.arc(this.joystickPointerStartPos.x, this.joystickPointerStartPos.y, 60, 0, Math.PI * 2, true);
-                    VirtualJoystick.vjCanvasContext.stroke();
-                    VirtualJoystick.vjCanvasContext.beginPath();
-                    VirtualJoystick.vjCanvasContext.strokeStyle = this._joystickColor;
-                    VirtualJoystick.vjCanvasContext.arc(this.joystickPointerPos.x, this.joystickPointerPos.y, 40, 0, Math.PI * 2, true);
-                    VirtualJoystick.vjCanvasContext.stroke();
-                }
-                else {
-                    VirtualJoystick.vjCanvasContext.beginPath();
-                    VirtualJoystick.vjCanvasContext.fillStyle = "white";
-                    VirtualJoystick.vjCanvasContext.beginPath();
-                    VirtualJoystick.vjCanvasContext.strokeStyle = "red";
-                    VirtualJoystick.vjCanvasContext.lineWidth = 6;
-                    VirtualJoystick.vjCanvasContext.arc(touch.x, touch.y, 40, 0, Math.PI * 2, true);
-                    VirtualJoystick.vjCanvasContext.stroke();
-                };
-            });
-            requestAnimationFrame(() => { this.drawVirtualJoystick(); });
+            } 
         }
 
-        private givePointerType (event) {
-            switch (event.pointerType) {
-                case event.POINTER_TYPE_MOUSE:
-                    return "MOUSE";
-                    break;
-                case event.POINTER_TYPE_PEN:
-                    return "PEN";
-                    break;
-                case event.POINTER_TYPE_TOUCH:
-                    return "TOUCH";
-                    break;
+        private _drawVirtualJoystick() {
+            if (this.pressed) {
+                this._clearCanvas();
+                this._touches.forEach((touch: PointerEvent) => {
+                    if (touch.pointerId === this._joystickPointerID) {
+                        VirtualJoystick.vjCanvasContext.beginPath();
+                        VirtualJoystick.vjCanvasContext.strokeStyle = this._joystickColor;
+                        VirtualJoystick.vjCanvasContext.lineWidth = 6;
+                        VirtualJoystick.vjCanvasContext.arc(this._joystickPointerStartPos.x, this._joystickPointerStartPos.y, 40, 0, Math.PI * 2, true);
+                        VirtualJoystick.vjCanvasContext.stroke();
+                        VirtualJoystick.vjCanvasContext.beginPath();
+                        VirtualJoystick.vjCanvasContext.strokeStyle = this._joystickColor;
+                        VirtualJoystick.vjCanvasContext.lineWidth = 2;
+                        VirtualJoystick.vjCanvasContext.arc(this._joystickPointerStartPos.x, this._joystickPointerStartPos.y, 60, 0, Math.PI * 2, true);
+                        VirtualJoystick.vjCanvasContext.stroke();
+                        VirtualJoystick.vjCanvasContext.beginPath();
+                        VirtualJoystick.vjCanvasContext.strokeStyle = this._joystickColor;
+                        VirtualJoystick.vjCanvasContext.arc(this._joystickPointerPos.x, this._joystickPointerPos.y, 40, 0, Math.PI * 2, true);
+                        VirtualJoystick.vjCanvasContext.stroke();
+                    }
+                    else {
+                        VirtualJoystick.vjCanvasContext.beginPath();
+                        VirtualJoystick.vjCanvasContext.fillStyle = "white";
+                        VirtualJoystick.vjCanvasContext.beginPath();
+                        VirtualJoystick.vjCanvasContext.strokeStyle = "red";
+                        VirtualJoystick.vjCanvasContext.lineWidth = 6;
+                        VirtualJoystick.vjCanvasContext.arc(touch.x, touch.y, 40, 0, Math.PI * 2, true);
+                        VirtualJoystick.vjCanvasContext.stroke();
+                    };
+                });
             }
+            requestAnimationFrame(() => { this._drawVirtualJoystick(); });
         }
 
         public releaseCanvas () {
@@ -317,39 +317,43 @@ module BABYLON {
 
 module BABYLON.VirtualJoystick {
     export class Collection<T> {
-        private count: number;
-        private collection: Array<T>;
+        private _count: number;
+        private _collection: Array<T>;
 
         constructor() {
-            this.count = 0;
-            this.collection = new Array<T>();
+            this._count = 0;
+            this._collection = new Array<T>();
+        }
+
+        public Count(): number {
+            return this._count;
         }
 
         public add<T>(key: string, item: T): number {
-            if (this.collection[key] != undefined) {
+            if (this._collection[key] != undefined) {
                 return undefined;
             }
-            this.collection[key] = item;
-            return ++this.count;
+            this._collection[key] = item;
+            return ++this._count;
         }
 
         public remove(key: string): number {
-            if (this.collection[key] == undefined) {
+            if (this._collection[key] == undefined) {
                 return undefined;
             }
-            delete this.collection[key];
-            return --this.count;
+            delete this._collection[key];
+            return --this._count;
         }
 
         public item(key: string) {
-            return this.collection[key];
+            return this._collection[key];
         }
 
-        public forEach<T>(block: (T) => any) {
+        public forEach<T>(block: (item: T) => void) {
             var key: string;
-            for (key in this.collection) {
-                if (this.collection.hasOwnProperty(key)) {
-                    block(this.collection[key]);
+            for (key in this._collection) {
+                if (this._collection.hasOwnProperty(key)) {
+                    block(this._collection[key]);
                 }
             }
         }

+ 72 - 0
Babylon/babylon.scene.js

@@ -97,6 +97,8 @@
             this.postProcessManager = new BABYLON.PostProcessManager(this);
 
             this._boundingBoxRenderer = new BABYLON.BoundingBoxRenderer(this);
+
+            this.attachControl();
         }
         // Properties
         Scene.prototype.getBoundingBoxRenderer = function () {
@@ -156,6 +158,49 @@
             return this._renderId;
         };
 
+        // Pointers handling
+        Scene.prototype.attachControl = function () {
+            var _this = this;
+            this._onPointerMove = function (evt) {
+                var canvas = _this._engine.getRenderingCanvas();
+                var pickResult = _this.pick(evt.clientX, evt.clientY, function (mesh) {
+                    return mesh.actionManager && mesh.isPickable;
+                });
+
+                if (pickResult.hit) {
+                    _this.setPointerOverMesh(pickResult.pickedMesh);
+                    canvas.style.cursor = "pointer";
+                } else {
+                    _this.setPointerOverMesh(null);
+                    canvas.style.cursor = "";
+                }
+            };
+
+            this._onPointerDown = function (evt) {
+                var pickResult = _this.pick(evt.clientX, evt.clientY);
+
+                if (pickResult.hit) {
+                    if (pickResult.pickedMesh.actionManager) {
+                        pickResult.pickedMesh.actionManager.processTrigger(BABYLON.ActionManager.OnPickTrigger);
+                    }
+                }
+
+                if (_this.onPointerDown) {
+                    _this.onPointerDown(evt, pickResult);
+                }
+            };
+
+            var eventPrefix = BABYLON.Tools.GetPointerPrefix();
+            this._engine.getRenderingCanvas().addEventListener(eventPrefix + "move", this._onPointerMove, false);
+            this._engine.getRenderingCanvas().addEventListener(eventPrefix + "down", this._onPointerDown, false);
+        };
+
+        Scene.prototype.detachControl = function () {
+            var eventPrefix = BABYLON.Tools.GetPointerPrefix();
+            this._engine.getRenderingCanvas().removeEventListener(eventPrefix + "move", this._onPointerMove);
+            this._engine.getRenderingCanvas().removeEventListener(eventPrefix + "down", this._onPointerDown);
+        };
+
         // Ready
         Scene.prototype.isReady = function () {
             if (this._pendingData.length > 0) {
@@ -762,6 +807,11 @@
             this._totalVertices = 0;
             this._activeVertices = 0;
 
+            // Actions
+            if (this.actionManager) {
+                this.actionManager.processTrigger(BABYLON.ActionManager.OnEveryFrameTrigger);
+            }
+
             // Before render
             if (this.beforeRender) {
                 this.beforeRender();
@@ -827,6 +877,9 @@
 
             this._boundingBoxRenderer.dispose();
 
+            // Events
+            this.detachControl();
+
             // Detach cameras
             var canvas = this._engine.getRenderingCanvas();
             var index;
@@ -1031,6 +1084,25 @@
             }, predicate, fastCheck);
         };
 
+        Scene.prototype.setPointerOverMesh = function (mesh) {
+            if (this._pointerOverMesh === mesh) {
+                return;
+            }
+
+            if (this._pointerOverMesh && this._pointerOverMesh.actionManager) {
+                this._pointerOverMesh.actionManager.processTrigger(BABYLON.ActionManager.OnPointerOutTrigger);
+            }
+
+            this._pointerOverMesh = mesh;
+            if (this._pointerOverMesh && this._pointerOverMesh.actionManager) {
+                this._pointerOverMesh.actionManager.processTrigger(BABYLON.ActionManager.OnPointerOverTrigger);
+            }
+        };
+
+        Scene.prototype.getPointerOverMesh = function () {
+            return this._pointerOverMesh;
+        };
+
         // Physics
         Scene.prototype.getPhysicsEngine = function () {
             return this._physicsEngine;

+ 81 - 1
Babylon/babylon.scene.ts

@@ -31,6 +31,11 @@
         public forceWireframe = false;
         public clipPlane: Plane;
 
+        // Pointers
+        private _onPointerMove: (evt: PointerEvent) => void;
+        private _onPointerDown: (evt: PointerEvent) => void;
+        public onPointerDown: (evt: PointerEvent, pickInfo: PickingInfo) => void;
+
         // Fog
         public fogMode = BABYLON.Scene.FOGMODE_NONE;
         public fogColor = new Color3(0.2, 0.2, 0.3);
@@ -92,6 +97,9 @@
         // Database
         public database; //ANY
 
+        // Actions
+        public actionManager: ActionManager;
+
         // Private
         private _engine: Engine;
         private _totalVertices = 0;
@@ -141,6 +149,8 @@
 
         private _selectionOctree: Octree;
 
+        private _pointerOverMesh: Mesh;
+
         // Constructor
         constructor(engine: Engine) {
             this._engine = engine;
@@ -152,6 +162,8 @@
             this.postProcessManager = new PostProcessManager(this);
 
             this._boundingBoxRenderer = new BoundingBoxRenderer(this);
+
+            this.attachControl();
         }
 
         // Properties 
@@ -212,6 +224,47 @@
             return this._renderId;
         }
 
+        // Pointers handling
+        public attachControl() {
+            this._onPointerMove = (evt: PointerEvent) => {
+                var canvas = this._engine.getRenderingCanvas();
+                var pickResult = this.pick(evt.clientX, evt.clientY, mesh => mesh.actionManager && mesh.isPickable);
+
+                if (pickResult.hit) {
+                    this.setPointerOverMesh(pickResult.pickedMesh);
+                    canvas.style.cursor = "pointer";
+                } else {
+                    this.setPointerOverMesh(null);
+                    canvas.style.cursor = "";
+                }
+            };
+
+            this._onPointerDown = (evt: PointerEvent) => {
+                var pickResult = this.pick(evt.clientX, evt.clientY);
+
+                if (pickResult.hit) {
+                    if (pickResult.pickedMesh.actionManager) {
+                        pickResult.pickedMesh.actionManager.processTrigger(BABYLON.ActionManager.OnPickTrigger);
+                    }
+                }
+
+                if (this.onPointerDown) {
+                    this.onPointerDown(evt, pickResult);
+                }
+            };
+
+
+            var eventPrefix = Tools.GetPointerPrefix();
+            this._engine.getRenderingCanvas().addEventListener(eventPrefix + "move", this._onPointerMove, false);
+            this._engine.getRenderingCanvas().addEventListener(eventPrefix + "down", this._onPointerDown, false);
+        }
+
+        public detachControl() {
+            var eventPrefix = Tools.GetPointerPrefix();
+            this._engine.getRenderingCanvas().removeEventListener(eventPrefix + "move", this._onPointerMove);
+            this._engine.getRenderingCanvas().removeEventListener(eventPrefix + "down", this._onPointerDown);
+        }
+
         // Ready
         public isReady(): boolean {
             if (this._pendingData.length > 0) {
@@ -818,6 +871,11 @@
             this._totalVertices = 0;
             this._activeVertices = 0;
 
+            // Actions
+            if (this.actionManager) {
+                this.actionManager.processTrigger(ActionManager.OnEveryFrameTrigger);
+            }
+
             // Before render
             if (this.beforeRender) {
                 this.beforeRender();
@@ -885,6 +943,9 @@
 
             this._boundingBoxRenderer.dispose();
 
+            // Events
+            this.detachControl();
+
             // Detach cameras
             var canvas = this._engine.getRenderingCanvas();
             var index;
@@ -1074,7 +1135,7 @@
             return pickingInfo || new BABYLON.PickingInfo();
         }
 
-        public pick(x: number, y: number, predicate: (mesh: Mesh) => boolean, fastCheck?: boolean, camera?: Camera): PickingInfo {
+        public pick(x: number, y: number, predicate?: (mesh: Mesh) => boolean, fastCheck?: boolean, camera?: Camera): PickingInfo {
             /// <summary>Launch a ray to try to pick a mesh in the scene</summary>
             /// <param name="x">X position on screen</param>
             /// <param name="y">Y position on screen</param>
@@ -1094,6 +1155,25 @@
             }, predicate, fastCheck);
         }
 
+        public setPointerOverMesh(mesh: Mesh): void {
+            if (this._pointerOverMesh === mesh) {
+                return;
+            }
+
+            if (this._pointerOverMesh && this._pointerOverMesh.actionManager) {
+                this._pointerOverMesh.actionManager.processTrigger(ActionManager.OnPointerOutTrigger);
+            }
+
+            this._pointerOverMesh = mesh;
+            if (this._pointerOverMesh && this._pointerOverMesh.actionManager) {
+                this._pointerOverMesh.actionManager.processTrigger(ActionManager.OnPointerOverTrigger);
+            }
+        }
+
+        public getPointerOverMesh(): Mesh {
+            return this._pointerOverMesh;
+        }
+
         // Physics
         public getPhysicsEngine(): PhysicsEngine {
             return this._physicsEngine;

文件差異過大導致無法顯示
+ 2 - 2
babylon.1.12-beta.js