Simplified interactions, changed menu interactions for changing entities.

This commit is contained in:
Michael Mainguy 2024-04-12 13:33:52 -05:00
parent cabc38ce09
commit 159e687c19
8 changed files with 111 additions and 45 deletions

View File

@ -41,6 +41,7 @@ export class Base {
private logger: log.Logger;
private lastPosition: Vector3 = null;
protected controllers: Controllers;
private clickMenu: ClickMenu;
constructor(controller: WebXRInputSource,
scene: Scene,
@ -262,9 +263,18 @@ export class Base {
private click() {
let mesh = this.xr.pointerSelection.getMeshUnderPointer(this.controller.uniqueId);
if (pointable(mesh)) {
this.logger.debug("click on " + mesh.id);
const menu = new ClickMenu(mesh, this.diagramManager);
if (this.clickMenu && !this.clickMenu.isDisposed) {
if (this.clickMenu.isConnecting) {
this.clickMenu.connect(mesh);
this.clickMenu = null;
}
} else {
this.clickMenu = new ClickMenu(mesh, this.diagramManager, this.controller.grip);
}
} else {
this.logger.debug("click on nothing");
}

View File

@ -1,4 +1,4 @@
import {AbstractMesh, MeshBuilder, PointerInfo, Scene, TransformNode, Vector3} from "@babylonjs/core";
import {AbstractMesh, MeshBuilder, Scene, TransformNode, Vector3} from "@babylonjs/core";
import {v4 as uuidv4} from 'uuid';
import log, {Logger} from "loglevel";
import {buildStandardMaterial} from "../materials/functions/buildStandardMaterial";
@ -8,7 +8,7 @@ export class DiagramConnection {
private logger: Logger = log.getLogger('DiagramConnection');
private readonly id: string;
constructor(from: string, to: string, id: string, scene?: Scene, pointerInfo?: PointerInfo) {
constructor(from: string, to: string, id: string, scene?: Scene, gripTransform?: TransformNode) {
this.logger.debug('buildConnection constructor');
if (id) {
this.id = id;
@ -34,8 +34,8 @@ export class DiagramConnection {
to.ignoreNonUniformScaling = true;
to.id = this.id + "_to";
to.position = fromMesh.absolutePosition.clone();
if (pointerInfo) {
to.setParent(pointerInfo.pickInfo.gripTransform);
if (gripTransform) {
to.setParent(gripTransform);
}
this.toAnchor = to;
@ -105,7 +105,7 @@ export class DiagramConnection {
private buildConnection() {
this.logger.debug(`buildConnection from ${this._from} to ${this._to}`);
this._mesh = MeshBuilder.CreateCylinder(this.id + "_connection", {diameter: .02, height: 1}, this.scene);
this._mesh.material = buildStandardMaterial(this.id + "_material", this.scene, "#000000");
this._mesh.material = buildStandardMaterial(this.id + "_material", this.scene, "#FFFFFF");
this.transformNode = new TransformNode(this.id + "_transform", this.scene);
this.transformNode.metadata = {exportable: true};
this._mesh.setParent(this.transformNode);

View File

@ -66,6 +66,7 @@ export function diagramEventHandler(event: DiagramEvent,
if (physicsEnabled) {
applyPhysics(sounds, mesh, scene);
}
updateTextNode(mesh, entity.text);
break;
case DiagramEventType.REMOVE:
if (mesh) {

View File

@ -20,6 +20,7 @@ export class InputTextView {
private readonly handle: Handle;
private inputText: InputText;
private diagramMesh: AbstractMesh;
private keyboard: VirtualKeyboard;
constructor(scene: Scene, controllers: Controllers) {
this.controllers = controllers;
@ -31,41 +32,49 @@ export class InputTextView {
}
public show(mesh: AbstractMesh) {
this.inputText.text = mesh.metadata?.label || "";
this.handle.mesh.setEnabled(true);
if (mesh.metadata?.label) {
this.inputText.text = mesh.metadata?.label;
}
this.diagramMesh = mesh;
this.keyboard.isVisible = true;
this.inputText.focus();
console.log(mesh.metadata);
}
public createKeyboard() {
const platform = this.scene.getMeshById('platform');
let position = new Vector3(0, 1.66, .5);
let rotation = new Vector3(0, .9, 0);
const position = new Vector3(0, 1.66, .5);
const rotation = new Vector3(.9, 0, 0);
const handle = this.handle;
if (handle.mesh.position.x != 0 && handle.mesh.position.y != 0 && handle.mesh.position.z != 0) {
/*if (handle.mesh.position.x != 0 && handle.mesh.position.y != 0 && handle.mesh.position.z != 0) {
position = handle.mesh.position;
}
if (handle.mesh.rotation.x != 0 && handle.mesh.rotation.y != 0 && handle.mesh.rotation.z != 0) {
rotation = handle.mesh.rotation;
}
}*/
if (!platform) {
this.scene.onNewMeshAddedObservable.add((mesh) => {
if (mesh.id == 'platform') {
this.logger.debug("platform added");
handle.mesh.setParent(platform);
handle.mesh.position = position;
handle.mesh.rotation = rotation;
handle.mesh.parent = mesh;
if (!handle.idStored) {
handle.mesh.position = position;
handle.mesh.rotation = rotation;
}
}
});
}, -1, false, this, false);
} else {
handle.mesh.parent = platform;
handle.mesh.position = position;
handle.mesh.rotation = rotation;
handle.mesh.setParent(platform);
if (!handle.idStored) {
handle.mesh.position = position;
handle.mesh.rotation = rotation;
}
}
//setMenuPosition(handle.mesh, this.scene, new Vector3(0, .4, 0));
const advancedTexture = AdvancedDynamicTexture.CreateForMesh(this.inputMesh, 2048, 1024, false);
const input = new InputText();
input.width = 0.5;
input.maxWidth = 0.5;
@ -110,11 +119,17 @@ export class InputTextView {
});
keyboard.onKeyPressObservable.add((key) => {
if (key === '↵') {
this.logger.error(this.inputText.text);
this.onTextObservable.notifyObservers({id: this.diagramMesh.id, text: this.inputText.text});
if (this.inputText.text && this.inputText.text.length > 0) {
this.logger.error(this.inputText.text);
this.onTextObservable.notifyObservers({id: this.diagramMesh.id, text: this.inputText.text});
} else {
this.onTextObservable.notifyObservers({id: this.diagramMesh.id, text: null});
}
this.hide();
}
}, -1, false, this, false);
this.keyboard = keyboard;
this.handle.mesh.setEnabled(false);
}

View File

@ -3,6 +3,8 @@ import {AbstractMesh, TransformNode} from "@babylonjs/core";
import {DiagramEvent, DiagramEventType} from "../diagram/types/diagramEntity";
import {toDiagramEntity} from "../diagram/functions/toDiagramEntity";
import {DiagramManager} from "../diagram/diagramManager";
import {DiagramConnection} from "../diagram/diagramConnection";
import {isDiagramEntity} from "../diagram/functions/isDiagramEntity";
export class ClickMenu {
private static readonly sounds;
@ -11,7 +13,10 @@ export class ClickMenu {
private readonly transform: TransformNode;
private readonly diagramManager: DiagramManager;
constructor(entity: AbstractMesh, diagramManager: DiagramManager) {
private connection: DiagramConnection = null;
constructor(entity: AbstractMesh, diagramManager: DiagramManager, grip: TransformNode) {
this.entity = entity;
this.diagramManager = diagramManager;
const scene = entity.getScene();
@ -29,17 +34,39 @@ export class ClickMenu {
manager.controlScaling = .1;
manager.addControl(panel);
panel.addControl(this.makeButton("Remove", "remove"));
panel.addControl(this.makeButton("Label", "label"));
panel.addControl(this.makeButton("Connect", "connect"));
panel.addControl(this.makeButton("Close", "close"));
panel.addControl(this.makeButton("Remove", "remove", grip));
panel.addControl(this.makeButton("Label", "label", grip));
panel.addControl(this.makeButton("Connect", "connect", grip));
panel.addControl(this.makeButton("Close", "close", grip));
panel.linkToTransformNode(transform);
this.transform = transform;
this.manager = manager;
}
private makeButton(name: string, id: string) {
public get isConnecting() {
return this.connection != null;
}
public get isDisposed(): boolean {
return this.transform.isDisposed();
}
public connect(mesh: AbstractMesh) {
if (this.connection) {
if (mesh && isDiagramEntity(mesh)) {
this.connection.to = mesh.id;
this.diagramManager.onDiagramEventObservable.notifyObservers({
type: DiagramEventType.ADD,
entity: toDiagramEntity(this.connection.mesh)
}, -1);
this.connection = null;
this.dispose();
}
}
}
private makeButton(name: string, id: string, grip: TransformNode) {
const button = new Button3D(name);
//button.scaling = new Vector3(.1, .1, .1);
button.name = id;
@ -66,7 +93,8 @@ export class ClickMenu {
this.diagramManager.editText(this.entity);
this.dispose();
break;
case "connect":
this.createMeshConnection(this.entity, grip);
}
@ -74,8 +102,13 @@ export class ClickMenu {
return button;
}
private createMeshConnection(mesh: AbstractMesh, grip: TransformNode) {
this.connection = new DiagramConnection(mesh.id, null, null, this.transform.getScene(), grip);
}
private dispose() {
this.manager.dispose();
this.transform.dispose();
}
}

View File

@ -147,7 +147,7 @@ export class EditMenu extends AbstractMenu {
}, -1);
this.connection = null;
} else {
this.connection = new DiagramConnection(mesh.id, null, null, this.scene, pointerInfo);
this.connection = new DiagramConnection(mesh.id, null, null, this.scene, pointerInfo.pickInfo.gripTransform);
}
}

View File

@ -4,12 +4,16 @@ import {buildStandardMaterial} from "../materials/functions/buildStandardMateria
export class Handle {
public mesh: AbstractMesh;
private readonly transformNode: TransformNode;
private _isStored: boolean = false;
constructor(mesh: TransformNode) {
this.transformNode = mesh;
this.buildHandle();
}
public get idStored() {
return this._isStored;
}
private buildHandle() {
const scene: Scene = this.transformNode.getScene();
const handle = getHandleMesh("handle-" + this.transformNode.id + "-mesh", scene);
@ -22,6 +26,7 @@ export class Handle {
const locationdata = JSON.parse(stored);
handle.position = new Vector3(locationdata.position.x, locationdata.position.y, locationdata.position.z);
handle.rotation = new Vector3(locationdata.rotation.x, locationdata.rotation.y, locationdata.rotation.z);
this._isStored = true;
} catch (e) {
console.error(e);
handle.position = Vector3.Zero();

View File

@ -93,38 +93,40 @@ export class Toolbox {
}
}
//this.toolboxBaseNode.parent.setEnabled(false);
let offset = new Vector3(-.50, 1.6, .38);
let rotation = new Vector3(.5, -.6, .18);
const offset = new Vector3(-.50, 1.6, .38);
const rotation = new Vector3(.5, -.6, .18);
if (this.toolboxBaseNode.parent) {
const platform = this.scene.getNodeById("platform");
if (platform) {
const handle = this.handle;
if (handle.mesh.position.x != 0 && handle.mesh.position.y != 0 && handle.mesh.position.z != 0) {
handle.mesh.parent = platform;
/*if (handle.mesh.position.x != 0 && handle.mesh.position.y != 0 && handle.mesh.position.z != 0) {
offset = handle.mesh.position;
}
if (handle.mesh.rotation.x != 0 && handle.mesh.rotation.y != 0 && handle.mesh.rotation.z != 0) {
rotation = handle.mesh.rotation;
}*/
//handle.mesh.parent = platform;
if (!handle.idStored) {
handle.mesh.position = offset;
handle.mesh.rotation = rotation;
}
handle.mesh.parent = platform;
handle.mesh.position = offset;
handle.mesh.rotation = rotation;
} else {
this.scene.onNewMeshAddedObservable.add((mesh: AbstractMesh) => {
if (mesh.id == "platform") {
if (mesh && mesh.id == "platform") {
const handle = this.handle;
if (handle.mesh.position.x != 0 && handle.mesh.position.y != 0 && handle.mesh.position.z != 0) {
offset = handle.mesh.position;
}
if (handle.mesh.rotation.x != 0 && handle.mesh.rotation.y != 0 && handle.mesh.rotation.z != 0) {
rotation = handle.mesh.rotation;
}
handle.mesh.parent = mesh;
handle.mesh.position = offset;
handle.mesh.rotation = rotation;
if (!handle.idStored) {
handle.mesh.position = offset;
handle.mesh.rotation = rotation;
}
//handle.mesh.parent = mesh;
}
});
}, -1, false, this, false);
}
}