瀏覽代碼

add gamepad to arcrotatecamera and fix potential memory leak through gamepad events

gleborgne 9 年之前
父節點
當前提交
d9223aa97b

+ 1 - 0
Tools/Gulp/config.json

@@ -54,6 +54,7 @@
       "../../src/cameras/inputs/babylon.arcrotatecamera.input.keyboard.js",
       "../../src/cameras/inputs/babylon.arcrotatecamera.input.mousewheel.js",
       "../../src/cameras/inputs/babylon.arcrotatecamera.input.pointers.js",
+      "../../src/cameras/inputs/babylon.arcrotatecamera.input.gamepad.js",
       "../../src/Cameras/babylon.targetCamera.js",
       "../../src/Cameras/babylon.freeCamera.js",
       "../../src/Cameras/babylon.freeCameraInputsManager.js",

文件差異過大導致無法顯示
+ 28 - 27
dist/preview release/babylon.js


+ 77 - 5
dist/preview release/babylon.max.js

@@ -11642,6 +11642,7 @@ var BABYLON;
             this.camera = camera;
         };
         FreeCameraGamepadInput.prototype.detach = function () {
+            this._gamepads.dispose();
         };
         FreeCameraGamepadInput.prototype.checkInputs = function () {
             if (this.gamepad) {
@@ -12099,6 +12100,65 @@ var BABYLON;
     BABYLON.CameraInputTypes["ArcRotateCameraPointersInput"] = ArcRotateCameraPointersInput;
 })(BABYLON || (BABYLON = {}));
 
+var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
+    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
+    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
+    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
+    return c > 3 && r && Object.defineProperty(target, key, r), r;
+};
+var BABYLON;
+(function (BABYLON) {
+    var ArcRotateCameraGamepadInput = (function () {
+        function ArcRotateCameraGamepadInput() {
+            var _this = this;
+            this.gamepadRotationSensibility = 80;
+            this._gamepads = new BABYLON.Gamepads(function (gamepad) { _this._onNewGameConnected(gamepad); });
+        }
+        ArcRotateCameraGamepadInput.prototype.attachCamera = function (camera) {
+            this.camera = camera;
+        };
+        ArcRotateCameraGamepadInput.prototype.detach = function () {
+            this._gamepads.dispose();
+        };
+        ArcRotateCameraGamepadInput.prototype.checkInputs = function () {
+            if (this.gamepad) {
+                var camera = this.camera;
+                var LSValues = this.gamepad.leftStick;
+                if (LSValues.x != 0) {
+                    var normalizedLX = LSValues.x / this.gamepadRotationSensibility;
+                    if (normalizedLX != 0 && Math.abs(normalizedLX) > 0.005) {
+                        camera.inertialAlphaOffset += normalizedLX;
+                    }
+                }
+                if (LSValues.y != 0) {
+                    var normalizedLY = LSValues.y / this.gamepadRotationSensibility;
+                    if (normalizedLY != 0 && Math.abs(normalizedLY) > 0.005) {
+                        camera.inertialBetaOffset += normalizedLY;
+                    }
+                }
+            }
+        };
+        ArcRotateCameraGamepadInput.prototype._onNewGameConnected = function (gamepad) {
+            // Only the first gamepad can control the camera
+            if (gamepad.index === 0) {
+                this.gamepad = gamepad;
+            }
+        };
+        ArcRotateCameraGamepadInput.prototype.getTypeName = function () {
+            return "ArcRotateCameraGamepadInput";
+        };
+        ArcRotateCameraGamepadInput.prototype.getSimpleName = function () {
+            return "gamepad";
+        };
+        __decorate([
+            BABYLON.serialize()
+        ], ArcRotateCameraGamepadInput.prototype, "gamepadRotationSensibility", void 0);
+        return ArcRotateCameraGamepadInput;
+    }());
+    BABYLON.ArcRotateCameraGamepadInput = ArcRotateCameraGamepadInput;
+    BABYLON.CameraInputTypes["ArcRotateCameraGamepadInput"] = ArcRotateCameraGamepadInput;
+})(BABYLON || (BABYLON = {}));
+
 
 var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
     var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
@@ -12874,7 +12934,7 @@ var BABYLON;
             this.radius = radius;
             this.getViewMatrix();
             this.inputs = new BABYLON.ArcRotateCameraInputsManager(this);
-            this.inputs.addKeyboard().addMouseWheel().addPointers();
+            this.inputs.addKeyboard().addMouseWheel().addPointers().addGamepad();
         }
         Object.defineProperty(ArcRotateCamera.prototype, "angularSensibility", {
             //-- 2016-03-08 properties for backward compatibility for inputs
@@ -13414,6 +13474,10 @@ var BABYLON;
             this.add(new BABYLON.ArcRotateCameraKeyboardMoveInput());
             return this;
         };
+        ArcRotateCameraInputsManager.prototype.addGamepad = function () {
+            this.add(new BABYLON.ArcRotateCameraGamepadInput());
+            return this;
+        };
         return ArcRotateCameraInputsManager;
     }(BABYLON.CameraInputsManager));
     BABYLON.ArcRotateCameraInputsManager = ArcRotateCameraInputsManager;
@@ -37113,12 +37177,14 @@ var BABYLON;
             if (this.gamepadSupportAvailable) {
                 // Checking if the gamepad connected event is supported (like in Firefox)
                 if (this.gamepadEventSupported) {
-                    window.addEventListener('gamepadconnected', function (evt) {
+                    this._onGamepadConnectedEvent = function (evt) {
                         _this._onGamepadConnected(evt);
-                    }, false);
-                    window.addEventListener('gamepaddisconnected', function (evt) {
+                    };
+                    this._onGamepadDisonnectedEvent = function (evt) {
                         _this._onGamepadDisconnected(evt);
-                    }, false);
+                    };
+                    window.addEventListener('gamepadconnected', this._onGamepadConnectedEvent, false);
+                    window.addEventListener('gamepaddisconnected', this._onGamepadDisonnectedEvent, false);
                 }
                 else {
                     this._startMonitoringGamepads();
@@ -37129,6 +37195,12 @@ var BABYLON;
             if (Gamepads.gamepadDOMInfo) {
                 document.body.removeChild(Gamepads.gamepadDOMInfo);
             }
+            if (this._onGamepadConnectedEvent) {
+                window.removeEventListener('gamepadconnected', this._onGamepadConnectedEvent, false);
+                window.removeEventListener('gamepaddisconnected', this._onGamepadDisonnectedEvent, false);
+                this._onGamepadConnectedEvent = null;
+                this._onGamepadDisonnectedEvent = null;
+            }
         };
         Gamepads.prototype._onGamepadConnected = function (evt) {
             var newGamepad = this._addNewGamepad(evt.gamepad);

+ 58 - 0
src/Cameras/Inputs/babylon.arcrotatecamera.input.gamepad.js

@@ -0,0 +1,58 @@
+var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
+    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
+    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
+    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
+    return c > 3 && r && Object.defineProperty(target, key, r), r;
+};
+var BABYLON;
+(function (BABYLON) {
+    var ArcRotateCameraGamepadInput = (function () {
+        function ArcRotateCameraGamepadInput() {
+            var _this = this;
+            this.gamepadRotationSensibility = 80;
+            this._gamepads = new BABYLON.Gamepads(function (gamepad) { _this._onNewGameConnected(gamepad); });
+        }
+        ArcRotateCameraGamepadInput.prototype.attachCamera = function (camera) {
+            this.camera = camera;
+        };
+        ArcRotateCameraGamepadInput.prototype.detach = function () {
+            this._gamepads.dispose();
+        };
+        ArcRotateCameraGamepadInput.prototype.checkInputs = function () {
+            if (this.gamepad) {
+                var camera = this.camera;
+                var LSValues = this.gamepad.leftStick;
+                if (LSValues.x != 0) {
+                    var normalizedLX = LSValues.x / this.gamepadRotationSensibility;
+                    if (normalizedLX != 0 && Math.abs(normalizedLX) > 0.005) {
+                        camera.inertialAlphaOffset += normalizedLX;
+                    }
+                }
+                if (LSValues.y != 0) {
+                    var normalizedLY = LSValues.y / this.gamepadRotationSensibility;
+                    if (normalizedLY != 0 && Math.abs(normalizedLY) > 0.005) {
+                        camera.inertialBetaOffset += normalizedLY;
+                    }
+                }
+            }
+        };
+        ArcRotateCameraGamepadInput.prototype._onNewGameConnected = function (gamepad) {
+            // Only the first gamepad can control the camera
+            if (gamepad.index === 0) {
+                this.gamepad = gamepad;
+            }
+        };
+        ArcRotateCameraGamepadInput.prototype.getTypeName = function () {
+            return "ArcRotateCameraGamepadInput";
+        };
+        ArcRotateCameraGamepadInput.prototype.getSimpleName = function () {
+            return "gamepad";
+        };
+        __decorate([
+            BABYLON.serialize()
+        ], ArcRotateCameraGamepadInput.prototype, "gamepadRotationSensibility", void 0);
+        return ArcRotateCameraGamepadInput;
+    }());
+    BABYLON.ArcRotateCameraGamepadInput = ArcRotateCameraGamepadInput;
+    BABYLON.CameraInputTypes["ArcRotateCameraGamepadInput"] = ArcRotateCameraGamepadInput;
+})(BABYLON || (BABYLON = {}));

+ 61 - 0
src/Cameras/Inputs/babylon.arcrotatecamera.input.gamepad.ts

@@ -0,0 +1,61 @@
+module BABYLON {       
+    export class ArcRotateCameraGamepadInput implements ICameraInput<ArcRotateCamera> {
+        camera : ArcRotateCamera;
+        
+        public gamepad: Gamepad;
+        private _gamepads: Gamepads;        
+
+        @serialize()
+        public gamepadRotationSensibility = 80;
+        
+        constructor(){
+            this._gamepads = new Gamepads((gamepad: Gamepad) => { this._onNewGameConnected(gamepad); });
+        }
+        
+        attachCamera(camera : ArcRotateCamera){
+            this.camera = camera;
+        }
+        
+        detach(){
+            this._gamepads.dispose();
+        }
+        
+        checkInputs(){
+            if (this.gamepad) {
+                var camera = this.camera;
+                var LSValues = this.gamepad.leftStick;
+                
+                if (LSValues.x != 0){
+                    var normalizedLX = LSValues.x / this.gamepadRotationSensibility;                
+                    if (normalizedLX != 0 && Math.abs(normalizedLX) > 0.005) {
+                        camera.inertialAlphaOffset += normalizedLX;
+                    }
+                }
+                
+                if (LSValues.y != 0){
+                    var normalizedLY = LSValues.y / this.gamepadRotationSensibility;
+                    if (normalizedLY != 0 && Math.abs(normalizedLY) > 0.005) {
+                        camera.inertialBetaOffset += normalizedLY;
+                    }
+                }
+            }
+        }
+        
+        private _onNewGameConnected(gamepad: Gamepad) {
+            // Only the first gamepad can control the camera
+            if (gamepad.index === 0) {
+                this.gamepad = gamepad;
+            }
+        }
+        
+        getTypeName(): string{
+            return "ArcRotateCameraGamepadInput";
+        }
+        
+        getSimpleName(){
+            return "gamepad";
+        }
+    }
+    
+    CameraInputTypes["ArcRotateCameraGamepadInput"] = ArcRotateCameraGamepadInput;
+}

+ 1 - 0
src/Cameras/Inputs/babylon.freecamera.input.gamepad.js

@@ -17,6 +17,7 @@ var BABYLON;
             this.camera = camera;
         };
         FreeCameraGamepadInput.prototype.detach = function () {
+            this._gamepads.dispose();
         };
         FreeCameraGamepadInput.prototype.checkInputs = function () {
             if (this.gamepad) {

+ 1 - 1
src/Cameras/Inputs/babylon.freecamera.input.gamepad.ts

@@ -20,7 +20,7 @@ module BABYLON {
         }
         
         detach(){
-            
+            this._gamepads.dispose();
         }
         
         checkInputs(){

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

@@ -87,7 +87,7 @@ var BABYLON;
             this.radius = radius;
             this.getViewMatrix();
             this.inputs = new BABYLON.ArcRotateCameraInputsManager(this);
-            this.inputs.addKeyboard().addMouseWheel().addPointers();
+            this.inputs.addKeyboard().addMouseWheel().addPointers().addGamepad();
         }
         Object.defineProperty(ArcRotateCamera.prototype, "angularSensibility", {
             //-- 2016-03-08 properties for backward compatibility for inputs

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

@@ -266,7 +266,7 @@
 
             this.getViewMatrix();
             this.inputs = new ArcRotateCameraInputsManager(this);
-            this.inputs.addKeyboard().addMouseWheel().addPointers();
+            this.inputs.addKeyboard().addMouseWheel().addPointers().addGamepad();
         }
 
         // Cache

+ 4 - 0
src/Cameras/babylon.arcRotateCameraInputsManager.js

@@ -28,6 +28,10 @@ var BABYLON;
             this.add(new BABYLON.ArcRotateCameraKeyboardMoveInput());
             return this;
         };
+        ArcRotateCameraInputsManager.prototype.addGamepad = function () {
+            this.add(new BABYLON.ArcRotateCameraGamepadInput());
+            return this;
+        };
         return ArcRotateCameraInputsManager;
     }(BABYLON.CameraInputsManager));
     BABYLON.ArcRotateCameraInputsManager = ArcRotateCameraInputsManager;

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

@@ -25,5 +25,10 @@ module BABYLON {
             this.add(new ArcRotateCameraKeyboardMoveInput());
             return this;
         }
+        
+        public addGamepad(){
+            this.add(new ArcRotateCameraGamepadInput());
+            return this;
+        }
     }
 }

+ 12 - 4
src/Tools/babylon.gamepads.js

@@ -18,12 +18,14 @@ var BABYLON;
             if (this.gamepadSupportAvailable) {
                 // Checking if the gamepad connected event is supported (like in Firefox)
                 if (this.gamepadEventSupported) {
-                    window.addEventListener('gamepadconnected', function (evt) {
+                    this._onGamepadConnectedEvent = function (evt) {
                         _this._onGamepadConnected(evt);
-                    }, false);
-                    window.addEventListener('gamepaddisconnected', function (evt) {
+                    };
+                    this._onGamepadDisonnectedEvent = function (evt) {
                         _this._onGamepadDisconnected(evt);
-                    }, false);
+                    };
+                    window.addEventListener('gamepadconnected', this._onGamepadConnectedEvent, false);
+                    window.addEventListener('gamepaddisconnected', this._onGamepadDisonnectedEvent, false);
                 }
                 else {
                     this._startMonitoringGamepads();
@@ -34,6 +36,12 @@ var BABYLON;
             if (Gamepads.gamepadDOMInfo) {
                 document.body.removeChild(Gamepads.gamepadDOMInfo);
             }
+            if (this._onGamepadConnectedEvent) {
+                window.removeEventListener('gamepadconnected', this._onGamepadConnectedEvent, false);
+                window.removeEventListener('gamepaddisconnected', this._onGamepadDisonnectedEvent, false);
+                this._onGamepadConnectedEvent = null;
+                this._onGamepadDisonnectedEvent = null;
+            }
         };
         Gamepads.prototype._onGamepadConnected = function (evt) {
             var newGamepad = this._addNewGamepad(evt.gamepad);

+ 19 - 6
src/Tools/babylon.gamepads.ts

@@ -10,20 +10,26 @@
 
         private _callbackGamepadConnected: (gamepad: Gamepad) => void;
 
+        private _onGamepadConnectedEvent: (evt: Event) => void;
+        private _onGamepadDisonnectedEvent: (evt: Event) => void;
+
         private static gamepadDOMInfo: HTMLElement;
 
+
         constructor(ongamedpadconnected: (gamepad: Gamepad) => void) {
             this._callbackGamepadConnected = ongamedpadconnected;
             if (this.gamepadSupportAvailable) {
+
                 // Checking if the gamepad connected event is supported (like in Firefox)
                 if (this.gamepadEventSupported) {
-                    window.addEventListener('gamepadconnected', (evt) => {
+                    this._onGamepadConnectedEvent = (evt) => {
                         this._onGamepadConnected(evt);
-                    }, false);
-                    window.addEventListener('gamepaddisconnected',
-                        (evt) => {
-                            this._onGamepadDisconnected(evt);
-                        }, false);
+                    };
+                    this._onGamepadDisonnectedEvent = (evt) => {
+                        this._onGamepadDisconnected(evt);
+                    };
+                    window.addEventListener('gamepadconnected', this._onGamepadConnectedEvent, false);
+                    window.addEventListener('gamepaddisconnected', this._onGamepadDisonnectedEvent, false);
                 }
                 else {
                     this._startMonitoringGamepads();
@@ -35,6 +41,13 @@
             if (Gamepads.gamepadDOMInfo) {
                 document.body.removeChild(Gamepads.gamepadDOMInfo);
             }
+            
+            if (this._onGamepadConnectedEvent){
+                window.removeEventListener('gamepadconnected', this._onGamepadConnectedEvent, false);
+                window.removeEventListener('gamepaddisconnected', this._onGamepadDisonnectedEvent, false);
+                this._onGamepadConnectedEvent = null;
+                this._onGamepadDisonnectedEvent = null;
+            }
         }
 
         private _onGamepadConnected(evt) {