Updated click menu to use Html Button. Added Scale feature.
This commit is contained in:
parent
ea5b8789c0
commit
b2c5c85d7e
14
package-lock.json
generated
14
package-lock.json
generated
@ -26,7 +26,7 @@
|
||||
"@types/react": "^18.2.72",
|
||||
"@types/react-dom": "^18.2.22",
|
||||
"axios": "^1.6.8",
|
||||
"babylon-html": "0.0.1",
|
||||
"babylon-html": "^0.0.2",
|
||||
"dom-to-image-more": "^3.3.0",
|
||||
"earcut": "^2.2.4",
|
||||
"events": "^3.3.0",
|
||||
@ -55,7 +55,8 @@
|
||||
}
|
||||
},
|
||||
"../babylon-html": {
|
||||
"version": "0.0.1",
|
||||
"version": "0.0.2",
|
||||
"extraneous": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babylonjs/core": "^7.1.0",
|
||||
@ -1107,8 +1108,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/babylon-html": {
|
||||
"resolved": "../babylon-html",
|
||||
"link": true
|
||||
"version": "0.0.2",
|
||||
"resolved": "https://registry.npmjs.org/babylon-html/-/babylon-html-0.0.2.tgz",
|
||||
"integrity": "sha512-bcdLgMmnjvLrysZq5VFzc71TkDT0b6coCv3ZoFzTxJDhXtZF96FFaRMba9rxMHp1TM3rX9u6yW8N/sJodA/qVg==",
|
||||
"dependencies": {
|
||||
"@babylonjs/core": "^7.1.0",
|
||||
"dom-to-image-more": "^3.3.0"
|
||||
}
|
||||
},
|
||||
"node_modules/babylonjs-gltf2interface": {
|
||||
"version": "7.1.0",
|
||||
|
||||
@ -34,7 +34,7 @@
|
||||
"@types/react": "^18.2.72",
|
||||
"@types/react-dom": "^18.2.22",
|
||||
"axios": "^1.6.8",
|
||||
"babylon-html": "0.0.1",
|
||||
"babylon-html": "^0.0.2",
|
||||
"dom-to-image-more": "^3.3.0",
|
||||
"earcut": "^2.2.4",
|
||||
"events": "^3.3.0",
|
||||
|
||||
@ -14,6 +14,7 @@ import {buildEntityActionManager} from "./functions/buildEntityActionManager";
|
||||
import {isDiagramEntity} from "./functions/isDiagramEntity";
|
||||
import {InputTextView} from "../information/inputTextView";
|
||||
import {DefaultScene} from "../defaultScene";
|
||||
import {ScaleMenu} from "../menus/scaleMenu";
|
||||
|
||||
|
||||
export class DiagramManager {
|
||||
@ -21,7 +22,7 @@ export class DiagramManager {
|
||||
private readonly _controllers: Controllers;
|
||||
private readonly diagramEntityActionManager: ActionManager;
|
||||
private readonly inputTextView: InputTextView;
|
||||
|
||||
public readonly scaleMenu: ScaleMenu;
|
||||
public readonly onDiagramEventObservable: Observable<DiagramEvent> = new Observable();
|
||||
private readonly logger = log.getLogger('DiagramManager');
|
||||
private readonly toolbox: Toolbox;
|
||||
@ -48,6 +49,17 @@ export class DiagramManager {
|
||||
});
|
||||
|
||||
this.toolbox = new Toolbox();
|
||||
this.scaleMenu = new ScaleMenu();
|
||||
this.scaleMenu.onScaleChangeObservable.add((mesh: AbstractMesh) => {
|
||||
this.onDiagramEventObservable.notifyObservers({
|
||||
type: DiagramEventType.MODIFY,
|
||||
entity: toDiagramEntity(mesh),
|
||||
}, -1);
|
||||
|
||||
const position = mesh.absolutePosition.clone();
|
||||
position.y = mesh.getBoundingInfo().boundingBox.maximumWorld.y + .1;
|
||||
this.scaleMenu.changePosition(position);
|
||||
});
|
||||
//this.presentationManager = new PresentationManager(this._scene);
|
||||
this.diagramEntityActionManager = buildEntityActionManager(this._controllers);
|
||||
|
||||
|
||||
@ -1,55 +1,76 @@
|
||||
import {GUI3DManager, PlanePanel} from "@babylonjs/gui";
|
||||
import {AbstractMesh, Tools, TransformNode, Vector3} from "@babylonjs/core";
|
||||
import {AbstractMesh, Scene, TransformNode, Vector3} 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";
|
||||
import {makeButton} from "./functions/makeButton";
|
||||
import {HtmlButton} from "babylon-html";
|
||||
|
||||
export class ClickMenu {
|
||||
private static readonly sounds;
|
||||
private readonly entity: AbstractMesh;
|
||||
private readonly manager: GUI3DManager;
|
||||
private readonly _mesh: AbstractMesh;
|
||||
private readonly transform: TransformNode;
|
||||
private readonly diagramManager: DiagramManager;
|
||||
private utilityPosition: Vector3;
|
||||
|
||||
private connection: DiagramConnection = null;
|
||||
|
||||
constructor(entity: AbstractMesh, diagramManager: DiagramManager, grip: TransformNode) {
|
||||
this.entity = entity;
|
||||
constructor(mesh: AbstractMesh, diagramManager: DiagramManager, grip: TransformNode) {
|
||||
this._mesh = mesh;
|
||||
this.diagramManager = diagramManager;
|
||||
const scene = entity.getScene();
|
||||
const manager = new GUI3DManager(scene);
|
||||
manager.onPickingObservable.add((mesh) => {
|
||||
if (mesh) {
|
||||
this.utilityPosition = mesh.getAbsolutePosition();
|
||||
const scene = mesh.getScene();
|
||||
this.transform = new TransformNode("transform", scene);
|
||||
let x = -.54 / 2;
|
||||
|
||||
const removeButton: HtmlButton = this.makeNewButton("Remove", "remove", scene, x += .11);
|
||||
removeButton.onPointerObservable.add((eventData) => {
|
||||
if (eventData.sourceEvent.type == "pointerup") {
|
||||
const event: DiagramEvent = {
|
||||
type: DiagramEventType.REMOVE,
|
||||
entity:
|
||||
toDiagramEntity(this._mesh)
|
||||
}
|
||||
this.diagramManager.onDiagramEventObservable.notifyObservers(event, -1);
|
||||
this.dispose();
|
||||
}
|
||||
});
|
||||
const transform = new TransformNode("transform", scene);
|
||||
const panel = new PlanePanel();
|
||||
}, -1, false, this, false);
|
||||
|
||||
panel.orientation = PlanePanel.FACEFORWARD_ORIENTATION;
|
||||
panel.columns = 4;
|
||||
panel.margin = .1;
|
||||
manager.addControl(panel);
|
||||
panel.linkToTransformNode(transform);
|
||||
const labelButton: HtmlButton = this.makeNewButton("Label", "label", scene, x += .11);
|
||||
labelButton.onPointerObservable.add((eventData) => {
|
||||
if (eventData.sourceEvent.type == "pointerup") {
|
||||
this.diagramManager.editText(this._mesh);
|
||||
this.dispose();
|
||||
}
|
||||
}, -1, false, this, false);
|
||||
|
||||
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));
|
||||
const connectButton: HtmlButton = this.makeNewButton("Connect", "connect", scene, x += .11);
|
||||
connectButton.onPointerObservable.add((eventData) => {
|
||||
if (eventData.sourceEvent.type == "pointerup") {
|
||||
this.createMeshConnection(this._mesh, grip, eventData.additionalData.pickedPoint.clone());
|
||||
}
|
||||
}, -1, false, this, false);
|
||||
|
||||
manager.controlScaling = .1;
|
||||
panel.updateLayout();
|
||||
this.transform = transform;
|
||||
this.manager = manager;
|
||||
Tools.SetImmediate(() => {
|
||||
transform.position = entity.absolutePosition.clone();
|
||||
transform.position.y = entity.getBoundingInfo().boundingBox.maximumWorld.y + .1;
|
||||
transform.billboardMode = TransformNode.BILLBOARDMODE_Y;
|
||||
});
|
||||
const closeButton: HtmlButton = this.makeNewButton("Close", "close", scene, x += .11);
|
||||
closeButton.onPointerObservable.add((eventData) => {
|
||||
eventData.sourceEvent.type == "pointerup" && this.dispose();
|
||||
}, -1, false, this, false);
|
||||
|
||||
const sizeButton: HtmlButton = this.makeNewButton("Size", "size", scene, x += .11);
|
||||
sizeButton.onPointerObservable.add((eventData) => {
|
||||
if (eventData.sourceEvent.type == "pointerup") {
|
||||
this.diagramManager.scaleMenu.show(this._mesh);
|
||||
}
|
||||
}, -1, false, this, false);
|
||||
|
||||
|
||||
this.transform.position = mesh.absolutePosition.clone();
|
||||
this.transform.position.y = mesh.getBoundingInfo().boundingBox.maximumWorld.y + .1;
|
||||
this.transform.billboardMode = TransformNode.BILLBOARDMODE_Y;
|
||||
}
|
||||
|
||||
private makeNewButton(name: string, id: string, scene: Scene, x: number): HtmlButton {
|
||||
const button = new HtmlButton(name, id, scene, null, {html: null, image: {width: 268, height: 268}});
|
||||
button.transform.parent = this.transform;
|
||||
button.transform.rotation.y = Math.PI;
|
||||
button.transform.position.x = x;
|
||||
return button;
|
||||
}
|
||||
|
||||
public get isConnecting() {
|
||||
@ -74,40 +95,12 @@ export class ClickMenu {
|
||||
}
|
||||
}
|
||||
|
||||
private makeButton(name: string, id: string, grip: TransformNode) {
|
||||
const button = makeButton(id, name);
|
||||
button.onPointerClickObservable.add(() => {
|
||||
switch (id) {
|
||||
case "close":
|
||||
this.dispose();
|
||||
break;
|
||||
case "remove":
|
||||
const event: DiagramEvent = {
|
||||
type: DiagramEventType.REMOVE,
|
||||
entity:
|
||||
toDiagramEntity(this.entity)
|
||||
}
|
||||
this.diagramManager.onDiagramEventObservable.notifyObservers(event, -1);
|
||||
this.dispose();
|
||||
break;
|
||||
case "label":
|
||||
this.diagramManager.editText(this.entity);
|
||||
this.dispose();
|
||||
break;
|
||||
case "connect":
|
||||
this.createMeshConnection(this.entity, grip);
|
||||
}
|
||||
}, -1, false, this, true);
|
||||
return button;
|
||||
}
|
||||
|
||||
private createMeshConnection(mesh: AbstractMesh, grip: TransformNode) {
|
||||
this.connection = new DiagramConnection(mesh.id, null, null, this.transform.getScene(), grip, this.utilityPosition);
|
||||
private createMeshConnection(mesh: AbstractMesh, grip: TransformNode, utilityPosition: Vector3) {
|
||||
this.connection = new DiagramConnection(mesh.id, null, null, this.transform.getScene(), grip, utilityPosition);
|
||||
}
|
||||
|
||||
private dispose() {
|
||||
this.manager.onPickingObservable.clear();
|
||||
this.manager.dispose();
|
||||
this.transform.dispose();
|
||||
this.diagramManager.scaleMenu.hide();
|
||||
this.transform.dispose(false, true);
|
||||
}
|
||||
}
|
||||
@ -1,103 +1,131 @@
|
||||
import {AbstractMesh, TransformNode, Vector3, WebXRDefaultExperience} from "@babylonjs/core";
|
||||
import {DefaultScene} from "../defaultScene";
|
||||
import {HtmlButton, HtmlMeshBuilder} from "babylon-html";
|
||||
import {AbstractMesh, Observable, TransformNode, Vector3} from "@babylonjs/core";
|
||||
|
||||
import {Controllers} from "../controllers/controllers";
|
||||
import {DiaSounds} from "../util/diaSounds";
|
||||
import {AbstractMenu} from "./abstractMenu";
|
||||
|
||||
import {GUI3DManager, Slider3D} from "@babylonjs/gui";
|
||||
|
||||
export class ScaleMenu extends AbstractMenu {
|
||||
private sounds: DiaSounds;
|
||||
private mesh: AbstractMesh;
|
||||
private xSlider: Slider3D;
|
||||
private ySlider: Slider3D;
|
||||
private zSlider: Slider3D;
|
||||
private transformNode: TransformNode;
|
||||
private xTransformNode: TransformNode;
|
||||
private yTransformNode: TransformNode;
|
||||
private zTransformNode: TransformNode;
|
||||
|
||||
constructor(xr: WebXRDefaultExperience, controllers: Controllers) {
|
||||
super(xr, controllers);
|
||||
this.transformNode = new TransformNode("scaleMenu", this.scene);
|
||||
this.xTransformNode = new TransformNode("xTransformNode", this.scene);
|
||||
this.xTransformNode.parent = this.transformNode;
|
||||
this.yTransformNode = new TransformNode("yTransformNode", this.scene);
|
||||
this.yTransformNode.parent = this.transformNode;
|
||||
this.zTransformNode = new TransformNode("zTransformNode", this.scene);
|
||||
this.zTransformNode.parent = this.transformNode;
|
||||
//super.createHandle(this.transformNode);
|
||||
this.transformNode.position.y = 0;
|
||||
this.transformNode.position.z = 0;
|
||||
this.transformNode.position.x = 0;
|
||||
|
||||
this.buildMenu();
|
||||
|
||||
//this.transformNode.position.y = 2;
|
||||
export class ScaleMenu {
|
||||
private static Sizes = [
|
||||
.025, .05, .1, .25, .5, 1.0, 2.0, 3.0, 4.0, 5.0
|
||||
]
|
||||
public readonly onScaleChangeObservable: Observable<AbstractMesh> = new Observable<AbstractMesh>();
|
||||
private readonly transform;
|
||||
private _mesh: AbstractMesh;
|
||||
|
||||
constructor() {
|
||||
this.transform = new TransformNode("scaleMenu", DefaultScene.Scene);
|
||||
this.transform.scaling = new Vector3(.5, .5, .5);
|
||||
this.build();
|
||||
}
|
||||
|
||||
public changeMesh(mesh: AbstractMesh) {
|
||||
this.mesh = mesh;
|
||||
this.xSlider.value = mesh.scaling.x;
|
||||
this.ySlider.value = mesh.scaling.y;
|
||||
this.zSlider.value = mesh.scaling.z;
|
||||
|
||||
const two = new Vector3(2, 2, 2);
|
||||
this.transformNode.position = this.mesh.absolutePosition.clone();
|
||||
this.transformNode.rotation = this.mesh.absoluteRotationQuaternion.toEulerAngles();
|
||||
|
||||
public changePosition(position: Vector3) {
|
||||
this.transform.position = position.clone();
|
||||
}
|
||||
|
||||
private buildMenu() {
|
||||
const manager = new GUI3DManager(this.scene);
|
||||
//manager.rootContainer.position.y = 2;
|
||||
//manager.rootContainer.node.position.y = 2;
|
||||
this.xSlider = new Slider3D("xslider");
|
||||
this.ySlider = new Slider3D("yslider");
|
||||
this.zSlider = new Slider3D("zslider");
|
||||
|
||||
manager.addControl(this.xSlider);
|
||||
manager.addControl(this.ySlider);
|
||||
manager.addControl(this.zSlider);
|
||||
this.xSlider.linkToTransformNode(this.xTransformNode);
|
||||
this.ySlider.linkToTransformNode(this.yTransformNode);
|
||||
this.zSlider.linkToTransformNode(this.zTransformNode);
|
||||
|
||||
this.xTransformNode.position = new Vector3(0, 0, .6);
|
||||
this.xTransformNode.rotation.y = Math.PI;
|
||||
this.yTransformNode.position = new Vector3(.6, .6, .6);
|
||||
this.yTransformNode.rotation.z = Math.PI / 2;
|
||||
this.zTransformNode.position = new Vector3(.6, .6, 0);
|
||||
this.zTransformNode.rotation.y = Math.PI / 2;
|
||||
setValues(this.xSlider);
|
||||
setValues(this.ySlider);
|
||||
setValues(this.zSlider);
|
||||
this.xSlider.onValueChangedObservable.add((value) => {
|
||||
if (this.mesh) {
|
||||
this.mesh.scaling.x = value;
|
||||
}
|
||||
});
|
||||
this.ySlider.onValueChangedObservable.add((value) => {
|
||||
if (this.mesh) {
|
||||
this.mesh.scaling.y = value;
|
||||
}
|
||||
});
|
||||
this.zSlider.onValueChangedObservable.add((value) => {
|
||||
if (this.mesh) {
|
||||
this.mesh.scaling.z = value;
|
||||
}
|
||||
});
|
||||
this.transformNode.scaling.x = .5;
|
||||
this.transformNode.scaling.y = .5;
|
||||
this.transformNode.scaling.z = .5;
|
||||
public show(mesh: AbstractMesh) {
|
||||
this.transform.position = mesh.absolutePosition.clone();
|
||||
this.transform.position.y = mesh.getBoundingInfo().boundingBox.maximumWorld.y + .1;
|
||||
//this.transform.billboardMode = TransformNode.BILLBOARDMODE_Y;
|
||||
this.transform.setEnabled(true);
|
||||
this._mesh = mesh;
|
||||
}
|
||||
|
||||
public hide() {
|
||||
this.transform.setEnabled(false);
|
||||
this._mesh = null;
|
||||
}
|
||||
|
||||
private async build() {
|
||||
let x = .12;
|
||||
const xParent = new TransformNode("xParent", DefaultScene.Scene);
|
||||
xParent.parent = this.transform;
|
||||
const yParent = new TransformNode("yParent", DefaultScene.Scene);
|
||||
yParent.parent = this.transform;
|
||||
const zParent = new TransformNode("zParent", DefaultScene.Scene);
|
||||
zParent.parent = this.transform;
|
||||
xParent.rotation.x = Math.PI / 2;
|
||||
yParent.rotation.z = Math.PI / 2;
|
||||
yParent.billboardMode = TransformNode.BILLBOARDMODE_Y;
|
||||
zParent.rotation.y = Math.PI / 2;
|
||||
zParent.rotation.x = Math.PI / 2;
|
||||
for (const size of ScaleMenu.Sizes) {
|
||||
const xbutton = this.makeButton(size.toString(), x, 0, xParent);
|
||||
xbutton.onPointerObservable.add((eventData) => {
|
||||
if (eventData.sourceEvent.type == "pointerup") {
|
||||
this.scaleX(size)
|
||||
}
|
||||
}, -1, false, this, false);
|
||||
|
||||
const ybutton = this.makeButton(size.toString(), x, Math.PI / 2, yParent);
|
||||
ybutton.onPointerObservable.add((eventData) => {
|
||||
if (eventData.sourceEvent.type == "pointerup") {
|
||||
this.scaleY(size)
|
||||
}
|
||||
}, -1, false, this, false);
|
||||
|
||||
const zbutton = this.makeButton(size.toString(), x, -Math.PI / 2, zParent);
|
||||
zbutton.onPointerObservable.add((eventData) => {
|
||||
if (eventData.sourceEvent.type == "pointerup") {
|
||||
this.scaleZ(size)
|
||||
}
|
||||
}, -1, false, this, false);
|
||||
x += .11;
|
||||
}
|
||||
// const labelX = await this.createLabel('X Size', .3);
|
||||
// const labelY = await this.createLabel('Y Size', .2);
|
||||
// const labelZ = await this.createLabel('Z Size', .1);
|
||||
this.transform.position.y = 1;
|
||||
this.transform.rotation.y = Math.PI;
|
||||
this.transform.setEnabled(false);
|
||||
}
|
||||
|
||||
private makeButton(name: string, x: number, y: number, parent: TransformNode = null) {
|
||||
const button = new HtmlButton(name, name, DefaultScene.Scene);
|
||||
button.transform.parent = parent;
|
||||
button.transform.position.x = x;
|
||||
//button.transform.position.y = y;
|
||||
button.transform.rotation.z = y;
|
||||
button.transform.rotation.y = Math.PI;
|
||||
return button;
|
||||
}
|
||||
|
||||
private scaleX(size: number) {
|
||||
if (this._mesh) {
|
||||
this._mesh.scaling.x = size;
|
||||
this.scaleChanged();
|
||||
}
|
||||
}
|
||||
|
||||
private scaleY(size: number) {
|
||||
if (this._mesh) {
|
||||
this._mesh.scaling.y = size;
|
||||
this.scaleChanged();
|
||||
}
|
||||
}
|
||||
|
||||
private scaleZ(size: number) {
|
||||
if (this._mesh) {
|
||||
this._mesh.scaling.z = size;
|
||||
this.scaleChanged();
|
||||
}
|
||||
}
|
||||
|
||||
private scaleChanged() {
|
||||
if (this._mesh) {
|
||||
this.onScaleChangeObservable.notifyObservers(this._mesh);
|
||||
}
|
||||
}
|
||||
|
||||
private async createLabel(name: string, y: number) {
|
||||
const label = await HtmlMeshBuilder.CreatePlane(`${name}-label`,
|
||||
{
|
||||
html: `<div style='margin: 0; padding-top: 40px; font-size: 32px; text-align: center; color:#ffffff; background: #000000; width: 128px; height: 128px'>${name}</div>`,
|
||||
height: .1, image: {width: 128, height: 128}
|
||||
},
|
||||
DefaultScene.Scene);
|
||||
|
||||
label.parent = this.transform;
|
||||
label.position.y = y;
|
||||
label.position.x = -.42;
|
||||
return label;
|
||||
}
|
||||
}
|
||||
|
||||
function setValues(slider: Slider3D) {
|
||||
slider.minimum = .1;
|
||||
slider.maximum = 1;
|
||||
slider.step = .1;
|
||||
slider.value = .1;
|
||||
}
|
||||
@ -52,7 +52,6 @@ export class VrApp {
|
||||
|
||||
*/
|
||||
addSceneInspector();
|
||||
//const mainMenu = new MainMenu(scene);
|
||||
const el = document.querySelector('#download');
|
||||
if (el) {
|
||||
el.addEventListener('click', () => {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user