From feb595cb555b5807cde0b83d4560983e57f8657b Mon Sep 17 00:00:00 2001 From: Tony Garnock-Jones Date: Tue, 10 Jan 2023 15:14:01 +0100 Subject: [PATCH] Repair gamepad input state tracking --- src/engine.ts | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/src/engine.ts b/src/engine.ts index 50a35be..bfd7b8d 100644 --- a/src/engine.ts +++ b/src/engine.ts @@ -12,6 +12,8 @@ import { WebXRSessionManager, } from '@babylonjs/core/Legacy/legacy'; +import { log } from './log.js'; + if ((navigator as any).oscpu?.startsWith('Linux')) { // ^ oscpu is undefined on chrome on Android, at least... @@ -91,7 +93,7 @@ export class RunningEngine { leanBase: { position: Vector3 } | null = null; recenterBase: { rotation: Quaternion } | null = null; - padStates: Map = new Map(); + padStates: Map = new Map(); static async start( interactivity: Interactivity, @@ -154,20 +156,30 @@ export class RunningEngine { } this.engine.runRenderLoop(() => { - Array.from(navigator.getGamepads()).forEach(gp => { - if (gp !== null) this.checkGamepadInput(gp); - }); - this.scene.render(); + try { + Array.from(navigator.getGamepads()).forEach(gp => { + if (gp !== null) this.checkGamepadInput(gp); + }); + this.scene.render(); + } catch (e) { + console.error('Error in render loop', e); + throw e; + } }); window.addEventListener("resize", () => this.engine.resize()); } padStateFor(gp: Gamepad): GamepadState { - const state = this.padStates.get(gp); - if (state) return state; + const state = this.padStates.get(gp.index); + if (state) { + // Apparently reusing Gamepad instances across frames doesn't work, + // so we update (!) the stored instance here: + state.gp = gp; + return state; + } const newState = new GamepadState(gp); - this.padStates.set(gp, newState); + this.padStates.set(gp.index, newState); return newState; }