Dave Solares %!s(int64=5) %!d(string=hai) anos
pai
achega
eecd7be935

+ 30 - 0
src/DeviceInput/Profile/deviceSourceManager.ts

@@ -0,0 +1,30 @@
+//import { IDeviceInputSystem } from '../deviceInputSystem';
+//import { WebDeviceInputSystem } from '../../DeviceInput/Systems/webDeviceInputSystem';
+import { Scene } from '../../scene';
+import { Engine } from '../../Engines/engine';
+
+/**
+ * DeviceSourceManager
+ * Initializes Input System and keeps track of devices
+ */
+export class DeviceSourceManager
+{
+    //private _deviceInputSystem : IDeviceInputSystem;
+
+    /**
+     * Constructor
+     * @param scene - Needed to get engine
+     */
+    constructor(scene : Scene)
+    {
+        var engine = scene.getEngine();
+        // Check if DOM is available
+        if (engine instanceof Engine)
+        {
+            console.log("test");
+            //console.log(scene.getEngine() instanceof Engine);
+            //console.log(scene.getEngine() instanceof ThinEngine);
+            //this._deviceInputSystem = new WebDeviceInputSystem(canvas);
+        }
+    }
+}

+ 242 - 0
src/DeviceInput/Systems/webDeviceInputSystem.ts

@@ -0,0 +1,242 @@
+import { Engine } from '../../Engines/engine';
+import { Nullable } from '../../types';
+import { IDeviceInputSystem } from '../deviceInputSystem';
+
+/**
+ * WebDeviceInputSystem
+ * This class acts as an absraction layer for all inputs used in Babylon
+ */
+export class WebDeviceInputSystem implements IDeviceInputSystem
+{
+    private _inputs : Map<string, Array<number>> = new Map();
+    private _onDeviceConnected : (deviceName : string) => void = () => {};
+    private _onDeviceDisconnected : (deviceName : string) => void = () => {};
+    private _keyboardActive : boolean = false;
+    private _mouseActive : boolean = false;
+    private _elementToAttachTo: Nullable<HTMLElement>;
+
+    /**
+     * Default Constructor
+     * @param elementToAttachTo - element to attach events to (usually canvas)
+     */
+    constructor(elementToAttachTo: Nullable<HTMLElement>)
+    {
+        this._elementToAttachTo = elementToAttachTo;
+        this.handleKeyActions();
+        this.handleMouseActions();
+        this.handleGamepadActions();
+        this.updateDevices();
+    }
+
+    // Public functions
+    /**
+     * pollInput: Checks for current device input value, given an id and input index
+     * @param deviceName Id of connected device
+     * @param inputIndex Index of device input
+     *
+     * @returns Current value of input
+     */
+    public pollInput(deviceName : string, inputIndex : number) : number
+    {
+        if (this._inputs.has(deviceName))
+        {
+            var device = this._inputs.get(deviceName);
+
+            if (device![inputIndex] != undefined)
+            {
+                return device![inputIndex];
+            }
+            else
+            {
+                throw `Unable to find input ${inputIndex} on device ${deviceName}`;
+            }
+        }
+        else
+        {
+            throw `Unable to find device ${deviceName}`;
+        }
+    }
+
+    /**
+     * onDeviceConnected: When a device is connected, perform user specified function
+     * @param callback Callback function to use when a device is connected
+     */
+    public onDeviceConnected(callback : (deviceName : string) => void) : void
+    {
+        this._onDeviceConnected = callback;
+    }
+
+    /**
+     * onDeviceDisconnected: When a device is disconnected, perform user specified function
+     * @param callback Callback function to use when a device is disconnected
+     */
+    public onDeviceDisconnected(callback : (deviceName : string) => void) : void
+    {
+        this._onDeviceDisconnected = callback;
+    }
+
+    // Private functions
+    /**
+     * registerDevice: Add device and inputs to device map
+     * @param deviceName Assigned name of device (may be SN)
+     * @param numberOfInputs Number of input entries to create for given device
+     */
+    private registerDevice(deviceName : string, numberOfInputs : number)
+    {
+        if (!this._inputs.has(deviceName))
+        {
+            var device : Array<number> = [];
+            for (var i = 0; i < numberOfInputs; i++)
+            {
+                device.push(0);
+            }
+
+            this._inputs.set(deviceName, device);
+        }
+    }
+
+    /**
+     * deregisterDevice: Given a specific device name, remove that device from the device map
+     * @param deviceName Name of device to be removed
+     */
+    private deregisterDevice(deviceName : string)
+    {
+        this._inputs.delete(deviceName);
+    }
+
+    /**
+     * handleKeyActions: Handle all actions that come from keyboard interaction
+     */
+    private handleKeyActions()
+    {
+        window.addEventListener("keydown", (evt) => {
+            if (!this._keyboardActive)
+            {
+                this._keyboardActive = true;
+                this.registerDevice("Keyboard", 222);
+                this._onDeviceConnected("Keyboard");
+            }
+
+            let kbKey = this._inputs.get("Keyboard");
+            if (kbKey)
+            {
+                kbKey[evt.keyCode] = 1;
+            }
+        });
+
+        window.addEventListener("keyup", (evt) => {
+            let kbKey = this._inputs.get("Keyboard");
+            if (kbKey)
+            {
+                kbKey[evt.keyCode] = 0;
+            }
+        });
+    }
+
+    /**
+     * handleMouseActions: Handle all actions that come from mouse interaction
+     */
+    private handleMouseActions()
+    {
+        this._elementToAttachTo?.addEventListener("pointermove", (evt) => {
+            if (!this._mouseActive)
+            {
+                this._mouseActive = true;
+                this.registerDevice("Mouse", 5);
+                this._onDeviceConnected("Mouse");
+            }
+
+            let mouseX = this._inputs.get("Mouse");
+            if (mouseX)
+            {
+                mouseX[0] = evt.clientX;
+            }
+
+            let mouseY = this._inputs.get("Mouse");
+            if (mouseY)
+            {
+                mouseY[1] = evt.clientY;
+            }
+        });
+
+        this._elementToAttachTo?.addEventListener("pointerdown", (evt) => {
+            let mouseButton = this._inputs.get("Mouse");
+            if (mouseButton)
+            {
+                mouseButton[evt.which + 1] = 1;
+            }
+        });
+
+        this._elementToAttachTo?.addEventListener("pointerup", (evt) => {
+            let mouseButton = this._inputs.get("Mouse");
+            if (mouseButton)
+            {
+                mouseButton[evt.which + 1] = 0;
+            }
+        });
+    }
+
+    /**
+     * handleGamepadActions: Handle all actions that come from gamepad interaction
+     */
+    private handleGamepadActions()
+    {
+        window.addEventListener("gamepadconnected", (evt : any) => {
+            var deviceName = `${evt.gamepad.id}-${evt.gamepad.index}`;
+            this.registerDevice(deviceName, evt.gamepad.buttons.length + evt.gamepad.axes.length);
+            this._onDeviceConnected(deviceName);
+        });
+
+        window.addEventListener("gamepaddisconnected", (evt : any) => {
+            var deviceName = `${evt.gamepad.id}-${evt.gamepad.index}`;
+            this.deregisterDevice(deviceName);
+            this._onDeviceDisconnected(deviceName);
+        });
+    }
+
+    /**
+     * updateDevices: Update all non-event based devices with each frame
+     */
+    private updateDevices()
+    {
+        // Gamepads
+        var gamepads = this.getGamePads();
+
+        for (var j = 0; j < gamepads.length; j++)
+        {
+            let gp = gamepads[j];
+
+            if (gp)
+            {
+                for (var i = 0; i < gp.buttons.length; i++)
+                {
+                    let button = this._inputs.get(`${gp.id}-${gp.index}`);
+                    if (button)
+                    {
+                        button[i] = gp.buttons[i].value;
+                    }
+                }
+
+                for (var i = 0; i < gp.axes.length; i++)
+                {
+                    let axis = this._inputs.get(`${gp.id}-${gp.index}`);
+                    if (axis)
+                    {
+                        axis[i + gp.buttons.length] = gp.axes[i].valueOf();
+                    }
+                }
+            }
+        }
+
+        Engine.QueueNewFrame(() => { this.updateDevices(); });
+    }
+
+    /**
+     * getGamePads: returns all gamepads
+     * @returns array with active gamepads
+     */
+    private getGamePads() : (Gamepad | null) []
+    {
+        return navigator.getGamepads();
+    }
+}

+ 24 - 0
src/DeviceInput/deviceInputSystem.ts

@@ -0,0 +1,24 @@
+/**
+ * IDeviceInputSystem
+ * Interface for input systems
+ */
+export interface IDeviceInputSystem
+{
+    /**
+     * pollInput - Get value from input
+     * @param deviceName - name of device
+     * @param inputIndex - index of specific input
+     * @returns value of input
+     */
+    pollInput(deviceName : string, inputIndex : number) : number;
+    /**
+     * onDeviceConnected - Set callback for when a device is connected
+     * @param callback - function to perform when a device is connected
+     */
+    onDeviceConnected(callback : (deviceName : string) => void) : void;
+    /**
+     * onDeviceDisconnected - Set callback for when a device is disconnected
+     * @param callback - function to perform when a device is disconnected
+     */
+    onDeviceDisconnected(callback : (deviceName : string) => void) : void;
+}

+ 3 - 0
src/DeviceInput/index.ts

@@ -0,0 +1,3 @@
+export * from "./Profile/deviceSourceManager";
+export * from "./Systems/webDeviceInputSystem";
+export * from "./deviceInputSystem";

+ 1 - 0
src/index.ts

@@ -9,6 +9,7 @@ export * from "./Cameras/index";
 export * from "./Collisions/index";
 export * from "./Culling/index";
 export * from "./Debug/index";
+export * from "./DeviceInput/index";
 export * from "./Engines/index";
 export * from "./Events/index";
 export * from "./Gamepads/index";