From 18adccc77e7e509051364dfa03dc3db9c97535cd Mon Sep 17 00:00:00 2001 From: Michael Mainguy Date: Tue, 19 Sep 2023 10:00:33 -0500 Subject: [PATCH] Refactored and added soccer menu. --- src/app.ts | 5 +-- src/menus/abstractMenu.ts | 18 ++++++++- src/menus/editMenu.ts | 14 +------ src/soccer/field.ts | 25 +------------ src/soccer/soccerMenu.ts | 78 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 100 insertions(+), 40 deletions(-) create mode 100644 src/soccer/soccerMenu.ts diff --git a/src/app.ts b/src/app.ts index 1a5f531..7f99f7a 100644 --- a/src/app.ts +++ b/src/app.ts @@ -20,7 +20,7 @@ import workerUrl from "./worker?worker&url"; import {DiagramEventType} from "./diagram/diagramEntity"; import {PeerjsNetworkConnection} from "./integration/peerjsNetworkConnection"; import {DiagramExporter} from "./util/diagramExporter"; -import {Field} from "./soccer/field"; +import {SoccerMenu} from "./soccer/soccerMenu"; export class App { @@ -156,8 +156,7 @@ export class App { import('./controllers/rigplatform').then((rigmodule) => { const rig = new rigmodule.Rigplatform(scene, xr, diagramManager, controllers); setTimeout(() => { - const field = new Field(scene); - field.addControllers(controllers); + const soccerMenu = new SoccerMenu(scene, xr, controllers); }, 5000); }); }); diff --git a/src/menus/abstractMenu.ts b/src/menus/abstractMenu.ts index 883ba37..7b9ba01 100644 --- a/src/menus/abstractMenu.ts +++ b/src/menus/abstractMenu.ts @@ -1,8 +1,9 @@ -import {Scene, TransformNode, WebXRDefaultExperience} from "@babylonjs/core"; +import {Scene, TransformNode, Vector3, WebXRDefaultExperience} from "@babylonjs/core"; import {Controllers} from "../controllers/controllers"; import {MenuHandle} from "./menuHandle"; +import {Button3D, TextBlock} from "@babylonjs/gui"; -export class AbstractMenu { +export abstract class AbstractMenu { protected handle: MenuHandle; protected scene: Scene; protected xr: WebXRDefaultExperience; @@ -14,6 +15,18 @@ export class AbstractMenu { this.controllers = controllers; } + protected makeButton(name: string, id: string) { + const button = new Button3D(name); + button.scaling = new Vector3(.1, .1, .1); + button.name = id; + const text = new TextBlock(name, name); + text.fontSize = "48px"; + text.color = "#ffffff"; + text.alpha = 1; + button.content = text; + return button; + } + protected createHandle(mesh: TransformNode) { this.handle = new MenuHandle(mesh); } @@ -22,4 +35,5 @@ export class AbstractMenu { throw new Error("AbstractMenu.toggle() not implemented"); } + } \ No newline at end of file diff --git a/src/menus/editMenu.ts b/src/menus/editMenu.ts index 7789a08..02d6052 100644 --- a/src/menus/editMenu.ts +++ b/src/menus/editMenu.ts @@ -11,7 +11,7 @@ import { Vector3, WebXRDefaultExperience, } from "@babylonjs/core"; -import {Button3D, GUI3DManager, PlanePanel, TextBlock} from "@babylonjs/gui"; +import {GUI3DManager, PlanePanel} from "@babylonjs/gui"; import {DiagramManager} from "../diagram/diagramManager"; import {EditMenuState} from "./editMenuState"; import {DiagramEvent, DiagramEventType} from "../diagram/diagramEntity"; @@ -36,7 +36,6 @@ export class EditMenu extends AbstractMenu { private readonly diagramManager: DiagramManager; private connection: DiagramConnection = null; private panel: PlanePanel; - private buttonMaterial: StandardMaterial; private sounds: DiaSounds; private get isVisible(): boolean { @@ -60,8 +59,6 @@ export class EditMenu extends AbstractMenu { panel.columns = 4; this.manager.addControl(panel); - this.buttonMaterial = new StandardMaterial("buttonMaterial", this.scene); - this.buttonMaterial.diffuseColor = Color3.FromHexString("#000000"); panel.addControl(this.makeButton("Modify", "modify")); panel.addControl(this.makeButton("Remove", "remove")); panel.addControl(this.makeButton("Add Label", "label")); @@ -141,14 +138,7 @@ export class EditMenu extends AbstractMenu { } makeButton(name: string, id: string) { - const button = new Button3D(name); - button.scaling = new Vector3(.1, .1, .1); - button.name = id; - const text = new TextBlock(name, name); - text.fontSize = "48px"; - text.color = "#ffffff"; - text.alpha = 1; - button.content = text; + const button = super.makeButton(name, id); button.onPointerClickObservable.add(this.handleClick, -1, false, this); return button; } diff --git a/src/soccer/field.ts b/src/soccer/field.ts index b7821b8..712f67c 100644 --- a/src/soccer/field.ts +++ b/src/soccer/field.ts @@ -10,18 +10,16 @@ import { } from "@babylonjs/core"; import {Ball} from "./ball"; import {Team} from "./team"; -import {ControllerEventType, Controllers} from "../controllers/controllers"; export class Field { private readonly scene: Scene; - private ball: Ball; - private controllers: Controllers; + public ball: Ball; private goalMesh: Mesh; private material: StandardMaterial; private team1: Team; private readonly fieldCenter: TransformNode; private team2: Team; - private gazePoint: Vector3; + public gazePoint: Vector3; constructor(scene: Scene) { this.scene = scene; @@ -39,25 +37,6 @@ export class Field { this.buildField(); } - public addControllers(controllers: Controllers) { - this.controllers = controllers; - this.controllers.controllerObserver.add((event) => { - switch (event.type) { - case ControllerEventType.MOTION: - this.ball.kick(event.startPosition.clone().subtract(event.endPosition).normalize(), event.duration / 100); - break; - case ControllerEventType.GAZEPOINT: - if (event.endPosition) { - this.gazePoint = event.endPosition.clone(); - } - break; - - } - - }); - - - } private buildField() { const width = .08; diff --git a/src/soccer/soccerMenu.ts b/src/soccer/soccerMenu.ts new file mode 100644 index 0000000..95bfcce --- /dev/null +++ b/src/soccer/soccerMenu.ts @@ -0,0 +1,78 @@ +import {Scene, WebXRDefaultExperience} from "@babylonjs/core"; +import {AbstractMenu} from "../menus/abstractMenu"; +import {ControllerEventType, Controllers} from "../controllers/controllers"; +import {GUI3DManager, PlanePanel} from "@babylonjs/gui"; +import log, {Logger} from "loglevel"; +import {Field} from "./field"; + +enum SoccerMenuState { + PLAY, + PLAN, + TRAIN, + NONE + +} + +export class SoccerMenu extends AbstractMenu { + private manager: GUI3DManager; + private state: SoccerMenuState = SoccerMenuState.NONE; + private readonly field: Field; + private logger: Logger = log.getLogger('SoccerMenu') + + constructor(scene: Scene, xr: WebXRDefaultExperience, controllers: Controllers) { + super(scene, xr, controllers); + this.field = new Field(this.scene); + this.manager = new GUI3DManager(this.scene); + + this.controllers.controllerObserver.add((event) => { + switch (event.type) { + case ControllerEventType.MOTION: + this.field.ball.kick(event.startPosition.clone().subtract(event.endPosition).normalize(), event.duration / 100); + break; + case ControllerEventType.GAZEPOINT: + if (event.endPosition) { + this.field.gazePoint = event.endPosition.clone(); + } + break; + + } + + }); + this.buildMenu(); + } + + makeButton(name: string, id: string) { + const button = super.makeButton(name, id); + button.onPointerClickObservable.add(this.handleClick, -1, false, this); + return button; + } + + private buildMenu() { + const panel = new PlanePanel(); + panel.columns = 4; + this.manager.addControl(panel); + panel.addControl(this.makeButton("Play", "play")); + panel.addControl(this.makeButton("Plan", "plan")); + panel.addControl(this.makeButton("Train", "Train")); + panel.addControl(this.makeButton("Modify", "modify")); + this.manager.rootContainer.children[0].node.position.y = .2; + this.createHandle(this.manager.rootContainer.children[0].node); + } + + private handleClick(_info, state) { + this.logger.debug("clicked " + state.currentTarget.name); + switch (state.currentTarget.name) { + case "play": + this.state = SoccerMenuState.PLAY; + break; + case "plan": + this.state = SoccerMenuState.PLAN; + break; + case "train": + this.state = SoccerMenuState.TRAIN; + break; + } + + } + +} \ No newline at end of file