From 2515f80461fa00c44c3188d40f65e3bf33f5709e Mon Sep 17 00:00:00 2001 From: Michael Mainguy Date: Wed, 26 Jul 2023 09:51:54 -0500 Subject: [PATCH] Added Dualshock mapping for desktop. started textedit option. --- src/app.ts | 131 +++++++++++++++++++++++++++++-- src/controllers/controllers.ts | 1 - src/controllers/rigplatform.ts | 9 ++- src/menus/MenuState.ts | 3 +- src/menus/bmenu.ts | 62 ++++++++++++--- src/util/DualshockEventMapper.ts | 78 ++++++++++++++++++ 6 files changed, 259 insertions(+), 25 deletions(-) create mode 100644 src/util/DualshockEventMapper.ts diff --git a/src/app.ts b/src/app.ts index bfa913d..2a74cd5 100644 --- a/src/app.ts +++ b/src/app.ts @@ -3,10 +3,12 @@ import "@babylonjs/inspector"; import { ArcRotateCamera, + DualShockButton, + DualShockPad, Engine, HavokPlugin, HemisphericLight, - MeshBuilder, + MeshBuilder, OculusTouchController, PBRMetallicRoughnessMaterial, PhotoDome, PhysicsAggregate, @@ -22,7 +24,7 @@ import HavokPhysics from "@babylonjs/havok"; import {Rigplatform} from "./controllers/rigplatform"; import {DiagramManager} from "./diagram/diagramManager"; import {Toolbox} from "./toolbox/toolbox"; - +import {DualshockEventMapper} from "./util/DualshockEventMapper"; export class App { @@ -31,13 +33,15 @@ export class App { public static scene: Scene; public static xr: WebXRDefaultExperience; public static rig: Rigplatform; + public static gamepad: Gamepad; + constructor() { const canvas = document.createElement("canvas"); canvas.style.width = "100%"; canvas.style.height = "100%"; canvas.id = "gameCanvas"; document.body.appendChild(canvas); - this.initialize(canvas).then(()=>{ + this.initialize(canvas).then(() => { console.log('Scene Initialized'); }); } @@ -45,7 +49,7 @@ export class App { async initialize(canvas) { if (App.xr) { App.xr.dispose(); - App.xr=null; + App.xr = null; } if (App.scene) { App.scene.dispose(); @@ -61,7 +65,6 @@ export class App { App.scene = scene; - const havokInstance = await HavokPhysics(); const havokPlugin = new HavokPlugin(true, havokInstance); @@ -92,17 +95,129 @@ export class App { }); App.xr.baseExperience.onStateChangedObservable.add((state) => { - if (state == WebXRState.IN_XR) { + if (state == WebXRState.IN_XR) { App.xr.baseExperience.camera.position = new Vector3(0, 1.6, 0); + window.addEventListener(('pa-button-state-change'), (event: any) => { + if (event.detail) { + console.log(event.detail); + } + }); + } }); - - const diagramManager = new DiagramManager(App.scene, App.xr.baseExperience); App.rig = new Rigplatform(App.scene, App.xr); const toolbox = new Toolbox(scene, App.xr.baseExperience); + App.scene.gamepadManager.onGamepadConnectedObservable.add((gamepad) => { + const dualshock = (gamepad as DualShockPad); + + dualshock.onButtonDownObservable.add((button: any) => { + const buttonEvent = DualshockEventMapper.mapButtonEvent(button, 1); + if (buttonEvent.objectName) { + window.dispatchEvent(new CustomEvent('pa-button-state-change', { + detail: buttonEvent + } + )); + } + }); + dualshock.onButtonUpObservable.add((button: any) => { + const buttonEvent = DualshockEventMapper.mapButtonEvent(button, 0); + if (buttonEvent.objectName) { + window.dispatchEvent(new CustomEvent('pa-button-state-change', { + detail: buttonEvent + } + )); + } + }); + + const buttonMap = [ + {buttonIndex: 3, objectName: "right-controller"}, + {buttonIndex: 3, objectName: "right-Controller"}, + {buttonIndex: 4, objectName: "right-Controller"}, + {buttonIndex: 4, objectName: "right-Controller"}, + + ]; + + /* + gamepad.onButtonDownObservable.add((button, state) => { + + console.log(buttonIndex); + console.log(buttonMap); + + if (buttonIndex < 4) { + window.dispatchEvent(new CustomEvent('pa-button-state-change', { + detail: { + objectName: buttonMap[buttonIndex].objectName, + pressed: true, + touched: false, + buttonIndex: buttonMap[buttonIndex].buttonIndex, + value: 1 + } + } + )); + } + }); + + + gamepad.onButtonUpObservable.add((buttonIndex, state) => { + console.log(buttonIndex); + console.log(state); + if (buttonIndex < 4) { + window.dispatchEvent( new CustomEvent('pa-button-state-change', { + detail: { + objectName: buttonMap[buttonIndex].objectName, + pressed: false, + touched: false, + buttonIndex: buttonMap[buttonIndex].buttonIndex, + value: 0 + } + } + )); + } + }); + + */ + + gamepad.onleftstickchanged((values) => { + window.dispatchEvent( + new CustomEvent('pa-analog-value-change', { + detail: { + objectName: "left-controller", + value: values.x, + axisIndex: 0 + } + })); + window.dispatchEvent( + new CustomEvent('pa-analog-value-change', { + detail: { + objectName: "left-controller", + value: values.y, + axisIndex: 1 + } + })); + }); + gamepad.onrightstickchanged((values) => { + window.dispatchEvent( + new CustomEvent('pa-analog-value-change', { + detail: { + objectName: "right-controller", + value: values.x, + axisIndex: 0 + } + })); + window.dispatchEvent( + new CustomEvent('pa-analog-value-change', { + detail: { + objectName: "right-controller", + value: values.y, + axisIndex: 1 + } + })); + }); + }); + //camera.parent = App.rig.rigMesh; window.addEventListener("keydown", (ev) => { // Shift+Ctrl+Alt+I diff --git a/src/controllers/controllers.ts b/src/controllers/controllers.ts index c8ecfb4..c1d3cf4 100644 --- a/src/controllers/controllers.ts +++ b/src/controllers/controllers.ts @@ -28,5 +28,4 @@ export class Controllers { this.movementMode = ControllerMovementMode.ROTATE; } } - } \ No newline at end of file diff --git a/src/controllers/rigplatform.ts b/src/controllers/rigplatform.ts index 54aea41..992b7b4 100644 --- a/src/controllers/rigplatform.ts +++ b/src/controllers/rigplatform.ts @@ -83,12 +83,17 @@ export class Rigplatform { const ray = this.camera.getForwardRay(); this.body.setLinearVelocity(ray.direction.scale(val * -1)); } - + public forwardbackleftright(x: number, y: number) { + const ray = this.camera.getForwardRay(); + const direction = ray.direction.applyRotationQuaternion(Rigplatform.x90).scale(x); + direction.z = y; + this.body.setLinearVelocity(direction); + } public leftright(val: number) { const ray = this.camera.getForwardRay(); const direction = ray.direction.applyRotationQuaternion(Rigplatform.x90).scale(val); this.body.setLinearVelocity(direction); - //console.log(val); + } public stop() { diff --git a/src/menus/MenuState.ts b/src/menus/MenuState.ts index 0a3f4d8..ec3e427 100644 --- a/src/menus/MenuState.ts +++ b/src/menus/MenuState.ts @@ -1,7 +1,6 @@ export enum BmenuState { NONE, - ADDING, // Adding a new entity - DROPPING, // Dropping an entity + LABELING, MODIFYING, // Editing an entity REMOVING, // Removing an entity diff --git a/src/menus/bmenu.ts b/src/menus/bmenu.ts index d9c4f74..109e609 100644 --- a/src/menus/bmenu.ts +++ b/src/menus/bmenu.ts @@ -1,11 +1,13 @@ +import {GizmoManager, MeshBuilder, PointerEventTypes, Scene, Vector3, WebXRExperienceHelper} from "@babylonjs/core"; import { - GizmoManager, - PointerEventTypes, - Scene, - Vector3, - WebXRExperienceHelper -} from "@babylonjs/core"; -import {Button3D, GUI3DManager, InputText, StackPanel3D, TextBlock} from "@babylonjs/gui"; + AdvancedDynamicTexture, + Button3D, + ColorPicker, + GUI3DManager, + InputText, + StackPanel3D, + TextBlock +} from "@babylonjs/gui"; import {DiagramManager} from "../diagram/diagramManager"; import {BmenuState} from "./MenuState"; import {DiagramEvent, DiagramEventType} from "../diagram/diagramEntity"; @@ -26,6 +28,12 @@ export class Bmenu { this.scene = scene; this.xr = xr; this.gizmoManager = new GizmoManager(scene); + this.gizmoManager.boundingBoxGizmoEnabled = true; + this.gizmoManager.gizmos.boundingBoxGizmo.scaleBoxSize = .020; + this.gizmoManager.gizmos.boundingBoxGizmo.rotationSphereSize = .020; + this.gizmoManager.gizmos.boundingBoxGizmo.scaleDragSpeed = 2; + this.gizmoManager.clearGizmoOnEmptyPointerEvent = true; + this.gizmoManager.usePointerToAttachGizmos = false; this.scene.onPointerObservable.add((pointerInfo) => { switch (pointerInfo.type) { @@ -42,6 +50,37 @@ export class Bmenu { } DiagramManager.onDiagramEventObservable.notifyObservers(event); break; + case BmenuState.MODIFYING: + if (pointerInfo.pickInfo.pickedMesh.metadata?.template && + pointerInfo.pickInfo.pickedMesh.parent?.parent?.id != "toolbox") { + if (this.gizmoManager.gizmos.boundingBoxGizmo.attachedMesh?.id == pointerInfo.pickInfo?.pickedMesh?.id) { + this.gizmoManager.gizmos.boundingBoxGizmo.attachedMesh = null; + } else { + this.gizmoManager.attachToMesh(pointerInfo.pickInfo.pickedMesh); + } + + } + + break; + case BmenuState.LABELING: + const mesh = pointerInfo.pickInfo.pickedMesh; + console.log("labeling " + mesh.id); + const myPlane = MeshBuilder.CreatePlane("myPlane", {width: .1, height: .1}, this.scene); + myPlane.parent=mesh; + myPlane.position= new Vector3(1,1,1); + + const advancedTexture2 = AdvancedDynamicTexture.CreateForMesh(myPlane, 1024, 1024); + const inputText = new InputText("input"); + advancedTexture2.addControl(inputText); + inputText.scaleY = 5; + inputText.scaleX = 5; + + inputText.focus(); + inputText.onTextChangedObservable.add((text) => { + console.log(text); + }); + break; + } break; } @@ -80,6 +119,7 @@ export class Bmenu { this.manager.addControl(panel); panel.addControl(this.makeButton("Modify", "modify")); panel.addControl(this.makeButton("Remove", "remove")); + panel.addControl(this.makeButton("Add Label", "label")); this.manager.controlScaling = .5; const offset = new Vector3(0, -.2, 3); offset.applyRotationQuaternionInPlace(this.scene.activeCamera.absoluteRotation); @@ -94,15 +134,13 @@ export class Bmenu { switch (state.currentTarget.name) { case "modify": this.state = BmenuState.MODIFYING; - this.gizmoManager.boundingBoxGizmoEnabled = true; - this.gizmoManager.gizmos.boundingBoxGizmo.scaleBoxSize = .01; - this.gizmoManager.gizmos.boundingBoxGizmo.rotationSphereSize = .01; - this.gizmoManager.gizmos.boundingBoxGizmo.scaleDragSpeed = 1; - this.gizmoManager.usePointerToAttachGizmos = false; break; case "remove": this.state = BmenuState.REMOVING; break; + case "label": + this.state = BmenuState.LABELING; + break; default: console.log("Unknown button"); return; diff --git a/src/util/DualshockEventMapper.ts b/src/util/DualshockEventMapper.ts new file mode 100644 index 0000000..00c8b87 --- /dev/null +++ b/src/util/DualshockEventMapper.ts @@ -0,0 +1,78 @@ +import {DualShockButton} from "@babylonjs/core"; +type ButtonEvent = { + objectName?: string, + pressed: boolean, + touched: boolean, + value: number, + buttonIndex?: number +} +export class DualshockEventMapper { + public static mapButtonEvent(buttonid: any, value: number): ButtonEvent { + const buttonEvent = { + objectName: null, + pressed: value == 1, + touched: false, + value: value, + buttonIndex: null + }; + switch (buttonid) { + case DualShockButton.Circle: + console.log('circle'); + break; + case DualShockButton.Cross: + console.log('cross'); + buttonEvent.objectName = "right-controller"; + buttonEvent.buttonIndex = 3; + break; + case DualShockButton.Triangle: + console.log('triangle'); + break; + case DualShockButton.Square: + console.log('square'); + buttonEvent.objectName = "right-controller"; + buttonEvent.buttonIndex = 4; + break; + case DualShockButton.L1: + console.log('L1'); + buttonEvent.objectName = "left-controller"; + buttonEvent.buttonIndex = 2; + break; + case DualShockButton.R1: + console.log('R1'); + buttonEvent.objectName = "right-controller"; + buttonEvent.buttonIndex = 2; + break; + case 6: + console.log('L2'); + buttonEvent.objectName = "left-controller"; + buttonEvent.buttonIndex = 1; + break; + case 7: + console.log('R2'); + buttonEvent.objectName = "right-controller"; + buttonEvent.buttonIndex = 1; + break; + case 12: + console.log('D-Pad Up'); + break; + case 13: + console.log('D-Pad Down'); + buttonEvent.objectName = "left-controller"; + buttonEvent.buttonIndex = 3; + break; + case 14: + console.log('D-Pad Left'); + buttonEvent.objectName = "left-controller"; + buttonEvent.buttonIndex = 4; + break; + case 15: + console.log('D-Pad Right'); + break; + + default: + console.log(buttonid); + + } + return buttonEvent; + } +} \ No newline at end of file