immersive2/src/menus/bmenu.ts

138 lines
3.9 KiB
TypeScript

import {
AbstractMesh,
Angle,
Color3,
Scene,
StandardMaterial,
TransformNode,
Vector3,
WebXRExperienceHelper,
WebXRInputSource
} from "@babylonjs/core";
import {GUI3DManager, HolographicButton, PlanePanel} from "@babylonjs/gui";
import {DiagramEntity, DiagramEvent, DiagramEventType, DiagramManager} from "../diagram/diagramManager";
export enum BmenuState {
NONE,
ADDING, // Adding a new entity
DROPPING, // Dropping an entity
}
export class Bmenu {
private scene;
private state: BmenuState = BmenuState.NONE;
private xr;
private manager;
private panel;
private rightController: AbstractMesh;
constructor(scene: Scene, xr: WebXRExperienceHelper) {
this.scene = scene;
this.manager = new GUI3DManager(scene);
this.xr = xr;
DiagramManager.onDiagramEventObservable.add((event: DiagramEvent) => {
if (event.type === DiagramEventType.DROPPED) {
this.state = BmenuState.ADDING;
}
});
}
setController(controller: WebXRInputSource) {
this.rightController = controller.grip;
}
makeButton(name: string, id: string) {
const button = new HolographicButton(name);
button.text = name;
button.name = id;
button.onPointerClickObservable.add(this.#clickhandler, -1, false, this);
return button;
}
public getState() {
return this.state;
}
public setState(state: BmenuState) {
this.state = state;
}
toggle() {
if (this.panel) {
this.panel.dispose();
this.panel = null;
} else {
const anchor = new TransformNode("bMenuAnchor");
anchor.rotation.y = Angle.FromDegrees(180).radians();
const cam = this.xr.camera.getFrontPosition(2);
anchor.position = cam;
const panel = new PlanePanel();
panel.margin = .6;
//panel.scaling.y=.5;
//panel.orientation = Container3D.FACEFORWARDREVERSED_ORIENTATION;
panel.columns = 5;
this.manager.addControl(panel);
panel.linkToTransformNode(anchor);
//panel.position.z = 2;
//panel.position.y = 4;
panel.addControl(this.makeButton("Add Box", "addBox"));
panel.addControl(this.makeButton("Add Sphere", "addSphere"));
panel.addControl(this.makeButton("Add Cylinder", "addCylinder"));
this.panel = panel;
}
}
#clickhandler(_info, state) {
console.log(state.currentTarget.name);
let entity: DiagramEntity = {
template: null,
position: new Vector3(0, -.040, .13),
rotation: new Vector3(),
scale: new Vector3(.1, .1, .1),
color: "#CEE",
text: "test",
last_seen: new Date(),
parent: this.rightController.id
};
switch (state.currentTarget.name) {
case "addBox":
entity.template = "#box-template";
break;
case "addSphere":
entity.template = "#sphere-template";
break;
case "addCylinder":
entity.template = "#cylinder-template";
break;
case "doneAdding":
this.state=BmenuState.NONE;
break;
default:
console.log("Unknown button");
return;
}
const event: DiagramEvent = {
type: DiagramEventType.ADD,
entity: entity
}
this.state = BmenuState.ADDING;
DiagramManager.onDiagramEventObservable.notifyObservers(event);
}
#createDefaultMaterial() {
const myMaterial = new StandardMaterial("myMaterial", this.scene);
myMaterial.diffuseColor = Color3.FromHexString("#CEE");
return myMaterial;
}
}