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; }