David Catuhe преди 6 години
родител
ревизия
560c129cc6
променени са 4 файла, в които са добавени 441 реда и са изтрити 4 реда
  1. 1 0
      dist/preview release/what's new.md
  2. 431 0
      src/Gamepads/dualShockGamepad.ts
  3. 7 3
      src/Gamepads/gamepadManager.ts
  4. 2 1
      src/Gamepads/index.ts

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

@@ -15,6 +15,7 @@
 ## Updates
 ## Updates
 
 
 ### General
 ### General
+- Added support for dual shock gamepads ([Deltakosh](https://github.com/deltakosh/))
 - Support Vive Focus 3Dof controller ([TrevorDev](https://github.com/TrevorDev))
 - Support Vive Focus 3Dof controller ([TrevorDev](https://github.com/TrevorDev))
 - Planar positioning support for GizmoManager ([Balupg](https://github.com/balupg))
 - Planar positioning support for GizmoManager ([Balupg](https://github.com/balupg))
 - Individual gizmos can now be enabled/disabled ([Balupg](https://github.com/balupg))
 - Individual gizmos can now be enabled/disabled ([Balupg](https://github.com/balupg))

+ 431 - 0
src/Gamepads/dualShockGamepad.ts

@@ -0,0 +1,431 @@
+import { Observable } from "../Misc/observable";
+import { Gamepad } from "./gamepad";
+import { _TimeToken } from "../Instrumentation/timeToken";
+import { _DepthCullingState, _StencilState, _AlphaState } from "../States/index";
+
+/**
+ * Defines supported buttons for DualShock compatible gamepads
+ */
+export enum DualShockButton {
+    /** Cross */
+    Cross,
+    /** Circle */
+    Circle,
+    /** Square */
+    Square,
+    /** Triangle */
+    Triangle,
+    /** Options */
+    Options,
+    /** Share */
+    Share,
+    /** L1 */
+    L1,
+    /** R1 */
+    R1,
+    /** Left stick */
+    LeftStick,
+    /** Right stick */
+    RightStick
+}
+
+/** Defines values for DualShock DPad  */
+export enum DualShockDpad {
+    /** Up */
+    Up,
+    /** Down */
+    Down,
+    /** Left */
+    Left,
+    /** Right */
+    Right
+}
+
+/**
+ * Defines a DualShock gamepad
+ */
+export class DualShockPad extends Gamepad {
+    private _leftTrigger: number = 0;
+    private _rightTrigger: number = 0;
+
+    private _onlefttriggerchanged: (value: number) => void;
+    private _onrighttriggerchanged: (value: number) => void;
+
+    private _onbuttondown: (buttonPressed: DualShockButton) => void;
+    private _onbuttonup: (buttonReleased: DualShockButton) => void;
+    private _ondpaddown: (dPadPressed: DualShockDpad) => void;
+    private _ondpadup: (dPadReleased: DualShockDpad) => void;
+
+    /** Observable raised when a button is pressed */
+    public onButtonDownObservable = new Observable<DualShockButton>();
+    /** Observable raised when a button is released */
+    public onButtonUpObservable = new Observable<DualShockButton>();
+    /** Observable raised when a pad is pressed */
+    public onPadDownObservable = new Observable<DualShockDpad>();
+    /** Observable raised when a pad is released */
+    public onPadUpObservable = new Observable<DualShockDpad>();
+
+    private _buttonCross: number = 0;
+    private _buttonCircle: number = 0;
+    private _buttonSquare: number = 0;
+    private _buttonTriangle: number = 0;
+    private _buttonShare: number = 0;
+    private _buttonOptions: number = 0;
+    private _buttonL1: number = 0;
+    private _buttonR1: number = 0;
+
+    private _buttonLeftStick: number = 0;
+    private _buttonRightStick: number = 0;
+    private _dPadUp: number = 0;
+    private _dPadDown: number = 0;
+    private _dPadLeft: number = 0;
+    private _dPadRight: number = 0;
+
+    /**
+     * Creates a new DualShock gamepad object
+     * @param id defines the id of this gamepad
+     * @param index defines its index
+     * @param gamepad defines the internal HTML gamepad object
+     */
+    constructor(id: string, index: number, gamepad: any) {
+        super(id.replace("STANDARD GAMEPAD", "SONY PLAYSTATION DUALSHOCK"), index, gamepad, 0, 1, 2, 3);
+        this.type = Gamepad.XBOX;
+    }
+
+    /**
+     * Defines the callback to call when left trigger is pressed
+     * @param callback defines the callback to use
+     */
+    public onlefttriggerchanged(callback: (value: number) => void) {
+        this._onlefttriggerchanged = callback;
+    }
+
+    /**
+     * Defines the callback to call when right trigger is pressed
+     * @param callback defines the callback to use
+     */
+    public onrighttriggerchanged(callback: (value: number) => void) {
+        this._onrighttriggerchanged = callback;
+    }
+
+    /**
+     * Gets the left trigger value
+     */
+    public get leftTrigger(): number {
+        return this._leftTrigger;
+    }
+    /**
+     * Sets the left trigger value
+     */
+    public set leftTrigger(newValue: number) {
+        if (this._onlefttriggerchanged && this._leftTrigger !== newValue) {
+            this._onlefttriggerchanged(newValue);
+        }
+        this._leftTrigger = newValue;
+    }
+
+    /**
+     * Gets the right trigger value
+     */
+    public get rightTrigger(): number {
+        return this._rightTrigger;
+    }
+    /**
+     * Sets the right trigger value
+     */
+    public set rightTrigger(newValue: number) {
+        if (this._onrighttriggerchanged && this._rightTrigger !== newValue) {
+            this._onrighttriggerchanged(newValue);
+        }
+        this._rightTrigger = newValue;
+    }
+
+    /**
+     * Defines the callback to call when a button is pressed
+     * @param callback defines the callback to use
+     */
+    public onbuttondown(callback: (buttonPressed: DualShockButton) => void) {
+        this._onbuttondown = callback;
+    }
+
+    /**
+     * Defines the callback to call when a button is released
+     * @param callback defines the callback to use
+     */
+    public onbuttonup(callback: (buttonReleased: DualShockButton) => void) {
+        this._onbuttonup = callback;
+    }
+
+    /**
+     * Defines the callback to call when a pad is pressed
+     * @param callback defines the callback to use
+     */
+    public ondpaddown(callback: (dPadPressed: DualShockDpad) => void) {
+        this._ondpaddown = callback;
+    }
+
+    /**
+     * Defines the callback to call when a pad is released
+     * @param callback defines the callback to use
+     */
+    public ondpadup(callback: (dPadReleased: DualShockDpad) => void) {
+        this._ondpadup = callback;
+    }
+
+    private _setButtonValue(newValue: number, currentValue: number, buttonType: DualShockButton): number {
+        if (newValue !== currentValue) {
+            if (newValue === 1) {
+                if (this._onbuttondown) {
+                    this._onbuttondown(buttonType);
+                }
+
+                this.onButtonDownObservable.notifyObservers(buttonType);
+            }
+            if (newValue === 0) {
+
+                if (this._onbuttonup) {
+                    this._onbuttonup(buttonType);
+                }
+
+                this.onButtonUpObservable.notifyObservers(buttonType);
+            }
+        }
+        return newValue;
+    }
+
+    private _setDPadValue(newValue: number, currentValue: number, buttonType: DualShockDpad): number {
+        if (newValue !== currentValue) {
+            if (newValue === 1) {
+                if (this._ondpaddown) {
+                    this._ondpaddown(buttonType);
+                }
+
+                this.onPadDownObservable.notifyObservers(buttonType);
+            }
+            if (newValue === 0) {
+                if (this._ondpadup) {
+                    this._ondpadup(buttonType);
+                }
+
+                this.onPadUpObservable.notifyObservers(buttonType);
+            }
+        }
+        return newValue;
+    }
+
+    /**
+     * Gets the value of the `Cross` button
+     */
+    public get buttonCross(): number {
+        return this._buttonCross;
+    }
+    /**
+     * Sets the value of the `Cross` button
+     */
+    public set buttonCross(value) {
+        this._buttonCross = this._setButtonValue(value, this._buttonCross, DualShockButton.Cross);
+    }
+
+    /**
+     * Gets the value of the `Circle` button
+     */
+    public get buttonCircle(): number {
+        return this._buttonCircle;
+    }
+    /**
+     * Sets the value of the `Circle` button
+     */
+    public set buttonCircle(value) {
+        this._buttonCircle = this._setButtonValue(value, this._buttonCircle, DualShockButton.Circle);
+    }
+
+    /**
+     * Gets the value of the `Square` button
+     */
+    public get buttonSquare(): number {
+        return this._buttonSquare;
+    }
+    /**
+     * Sets the value of the `Square` button
+     */
+    public set buttonSquare(value) {
+        this._buttonSquare = this._setButtonValue(value, this._buttonSquare, DualShockButton.Square);
+    }
+
+    /**
+     * Gets the value of the `Triangle` button
+     */
+    public get buttonTriangle(): number {
+        return this._buttonTriangle;
+    }
+    /**
+     * Sets the value of the `Triangle` button
+     */
+    public set buttonTriangle(value) {
+        this._buttonTriangle = this._setButtonValue(value, this._buttonTriangle, DualShockButton.Triangle);
+    }
+
+    /**
+     * Gets the value of the `Options` button
+     */
+    public get buttonOptions(): number {
+        return this._buttonOptions;
+    }
+    /**
+     * Sets the value of the `Options` button
+     */
+    public set buttonOptions(value) {
+        this._buttonOptions = this._setButtonValue(value, this._buttonOptions, DualShockButton.Options);
+    }
+
+    /**
+     * Gets the value of the `Share` button
+     */
+    public get buttonShare(): number {
+        return this._buttonShare;
+    }
+    /**
+     * Sets the value of the `Share` button
+     */
+    public set buttonShare(value) {
+        this._buttonShare = this._setButtonValue(value, this._buttonShare, DualShockButton.Share);
+    }
+
+    /**
+     * Gets the value of the `L1` button
+     */
+    public get buttonL1(): number {
+        return this._buttonL1;
+    }
+    /**
+     * Sets the value of the `L1` button
+     */
+    public set buttonL1(value) {
+        this._buttonL1 = this._setButtonValue(value, this._buttonL1, DualShockButton.L1);
+    }
+
+    /**
+     * Gets the value of the `R1` button
+     */
+    public get buttonR1(): number {
+        return this._buttonR1;
+    }
+    /**
+     * Sets the value of the `R1` button
+     */
+    public set buttonR1(value) {
+        this._buttonR1 = this._setButtonValue(value, this._buttonR1, DualShockButton.R1);
+    }
+
+    /**
+     * Gets the value of the Left joystick
+     */
+    public get buttonLeftStick(): number {
+        return this._buttonLeftStick;
+    }
+    /**
+     * Sets the value of the Left joystick
+     */
+    public set buttonLeftStick(value) {
+        this._buttonLeftStick = this._setButtonValue(value, this._buttonLeftStick, DualShockButton.LeftStick);
+    }
+
+    /**
+     * Gets the value of the Right joystick
+     */
+    public get buttonRightStick(): number {
+        return this._buttonRightStick;
+    }
+    /**
+     * Sets the value of the Right joystick
+     */
+    public set buttonRightStick(value) {
+        this._buttonRightStick = this._setButtonValue(value, this._buttonRightStick, DualShockButton.RightStick);
+    }
+
+    /**
+     * Gets the value of D-pad up
+     */
+    public get dPadUp(): number {
+        return this._dPadUp;
+    }
+    /**
+     * Sets the value of D-pad up
+     */
+    public set dPadUp(value) {
+        this._dPadUp = this._setDPadValue(value, this._dPadUp, DualShockDpad.Up);
+    }
+
+    /**
+     * Gets the value of D-pad down
+     */
+    public get dPadDown(): number {
+        return this._dPadDown;
+    }
+    /**
+     * Sets the value of D-pad down
+     */
+    public set dPadDown(value) {
+        this._dPadDown = this._setDPadValue(value, this._dPadDown, DualShockDpad.Down);
+    }
+
+    /**
+     * Gets the value of D-pad left
+     */
+    public get dPadLeft(): number {
+        return this._dPadLeft;
+    }
+    /**
+     * Sets the value of D-pad left
+     */
+    public set dPadLeft(value) {
+        this._dPadLeft = this._setDPadValue(value, this._dPadLeft, DualShockDpad.Left);
+    }
+
+    /**
+     * Gets the value of D-pad right
+     */
+    public get dPadRight(): number {
+        return this._dPadRight;
+    }
+    /**
+     * Sets the value of D-pad right
+     */
+    public set dPadRight(value) {
+        this._dPadRight = this._setDPadValue(value, this._dPadRight, DualShockDpad.Right);
+    }
+
+    /**
+     * Force the gamepad to synchronize with device values
+     */
+    public update() {
+        super.update();
+        this.buttonCross = this.browserGamepad.buttons[0].value;
+        this.buttonCircle = this.browserGamepad.buttons[1].value;
+        this.buttonSquare = this.browserGamepad.buttons[2].value;
+        this.buttonTriangle = this.browserGamepad.buttons[3].value;
+        this.buttonL1 = this.browserGamepad.buttons[4].value;
+        this.buttonR1 = this.browserGamepad.buttons[5].value;
+        this.leftTrigger = this.browserGamepad.buttons[6].value;
+        this.rightTrigger = this.browserGamepad.buttons[7].value;
+        this.buttonShare = this.browserGamepad.buttons[8].value;
+        this.buttonOptions = this.browserGamepad.buttons[9].value;
+        this.buttonLeftStick = this.browserGamepad.buttons[10].value;
+        this.buttonRightStick = this.browserGamepad.buttons[11].value;
+        this.dPadUp = this.browserGamepad.buttons[12].value;
+        this.dPadDown = this.browserGamepad.buttons[13].value;
+        this.dPadLeft = this.browserGamepad.buttons[14].value;
+        this.dPadRight = this.browserGamepad.buttons[15].value;
+    }
+
+    /**
+     * Disposes the gamepad
+     */
+    public dispose() {
+        super.dispose();
+        this.onButtonDownObservable.clear();
+        this.onButtonUpObservable.clear();
+        this.onPadDownObservable.clear();
+        this.onPadUpObservable.clear();
+    }
+}

+ 7 - 3
src/Gamepads/gamepadManager.ts

@@ -9,6 +9,7 @@ import { PoseEnabledControllerHelper } from "../Gamepads/Controllers/poseEnabled
 import { Xbox360Pad } from "./xboxGamepad";
 import { Xbox360Pad } from "./xboxGamepad";
 import { Gamepad, GenericPad } from "./gamepad";
 import { Gamepad, GenericPad } from "./gamepad";
 import { Engine } from '../Engines/engine';
 import { Engine } from '../Engines/engine';
+import { DualShockPad } from './dualShockGamepad';
 /**
 /**
  * Manager for handling gamepads
  * Manager for handling gamepads
  */
  */
@@ -102,7 +103,7 @@ export class GamepadManager {
             }
             }
             // Checking if the gamepad connected event is supported (like in Firefox)
             // Checking if the gamepad connected event is supported (like in Firefox)
             if (this._gamepadEventSupported) {
             if (this._gamepadEventSupported) {
-                let hostWindow = this._scene!.getEngine().getHostWindow();
+                let hostWindow = this._scene ? this._scene.getEngine().getHostWindow() : window;
 
 
                 hostWindow.addEventListener('gamepadconnected', this._onGamepadConnectedEvent, false);
                 hostWindow.addEventListener('gamepadconnected', this._onGamepadConnectedEvent, false);
                 hostWindow.addEventListener('gamepaddisconnected', this._onGamepadDisconnectedEvent, false);
                 hostWindow.addEventListener('gamepaddisconnected', this._onGamepadDisconnectedEvent, false);
@@ -174,8 +175,11 @@ export class GamepadManager {
         if (xboxOne || (<string>gamepad.id).search("Xbox 360") !== -1 || (<string>gamepad.id).search("xinput") !== -1) {
         if (xboxOne || (<string>gamepad.id).search("Xbox 360") !== -1 || (<string>gamepad.id).search("xinput") !== -1) {
             newGamepad = new Xbox360Pad(gamepad.id, gamepad.index, gamepad, xboxOne);
             newGamepad = new Xbox360Pad(gamepad.id, gamepad.index, gamepad, xboxOne);
         }
         }
-        // if pose is supported, use the (WebVR) pose enabled controller, ignore DualShock (ps4) as they have a pose but should not be used for webVR
-        else if (gamepad.pose && !dualShock) {
+        else if (dualShock) {
+            newGamepad = new DualShockPad(gamepad.id, gamepad.index, gamepad);
+        }
+        // if pose is supported, use the (WebVR) pose enabled controller
+        else if (gamepad.pose) {
             newGamepad = PoseEnabledControllerHelper.InitiateController(gamepad);
             newGamepad = PoseEnabledControllerHelper.InitiateController(gamepad);
         }
         }
         else {
         else {

+ 2 - 1
src/Gamepads/index.ts

@@ -2,4 +2,5 @@ export * from "./Controllers/index";
 export * from "./gamepad";
 export * from "./gamepad";
 export * from "./gamepadManager";
 export * from "./gamepadManager";
 export * from "./gamepadSceneComponent";
 export * from "./gamepadSceneComponent";
-export * from "./xboxGamepad";
+export * from "./xboxGamepad";
+export * from "./dualShockGamepad";