Updated menu system to be more consistent. Change toolbox to fixed colors;
This commit is contained in:
parent
1413a0bda9
commit
73a850613d
64
package-lock.json
generated
64
package-lock.json
generated
@ -8,14 +8,14 @@
|
|||||||
"name": "immersive",
|
"name": "immersive",
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babylonjs/core": "^6.21.3",
|
"@babylonjs/core": "^6.45.1",
|
||||||
"@babylonjs/gui": "^6.21.3",
|
"@babylonjs/gui": "^6.45.1",
|
||||||
"@babylonjs/havok": "1.1.4",
|
"@babylonjs/havok": "1.3.1",
|
||||||
"@babylonjs/inspector": "^6.21.3",
|
"@babylonjs/inspector": "^6.45.1",
|
||||||
"@babylonjs/loaders": "^6.21.3",
|
"@babylonjs/loaders": "^6.45.1",
|
||||||
"@babylonjs/materials": "^6.21.3",
|
"@babylonjs/materials": "^6.45.1",
|
||||||
"@babylonjs/procedural-textures": "^6.21.3",
|
"@babylonjs/procedural-textures": "^6.45.1",
|
||||||
"@babylonjs/serializers": "^6.21.3",
|
"@babylonjs/serializers": "^6.45.1",
|
||||||
"@cloudflare/workers-types": "^4.20230821.0",
|
"@cloudflare/workers-types": "^4.20230821.0",
|
||||||
"@netlify/functions": "^2.3.0",
|
"@netlify/functions": "^2.3.0",
|
||||||
"@typed-mxgraph/typed-mxgraph": "^1.0.8",
|
"@typed-mxgraph/typed-mxgraph": "^1.0.8",
|
||||||
@ -49,14 +49,14 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babylonjs/core": {
|
"node_modules/@babylonjs/core": {
|
||||||
"version": "6.21.3",
|
"version": "6.45.1",
|
||||||
"resolved": "https://registry.npmjs.org/@babylonjs/core/-/core-6.21.3.tgz",
|
"resolved": "https://registry.npmjs.org/@babylonjs/core/-/core-6.45.1.tgz",
|
||||||
"integrity": "sha512-j+UnhCSz3HldEWVHnxRHKGLqhWafju/WGqKaLXncbgo/Fkz48OoFbrec651jv1cBiNx82zdVa59c8VIK6FNSOw=="
|
"integrity": "sha512-wkORoAqpnZb10bUhrI0vinE9IiW7+gSgH4U4Zp41wO4kSeV0mtJY+Q5Ez6/n9ad9sLykD2FD7650B+Qi5tTMSw=="
|
||||||
},
|
},
|
||||||
"node_modules/@babylonjs/gui": {
|
"node_modules/@babylonjs/gui": {
|
||||||
"version": "6.21.3",
|
"version": "6.45.1",
|
||||||
"resolved": "https://registry.npmjs.org/@babylonjs/gui/-/gui-6.21.3.tgz",
|
"resolved": "https://registry.npmjs.org/@babylonjs/gui/-/gui-6.45.1.tgz",
|
||||||
"integrity": "sha512-bsh6GT/tvWIDua1vSg2n3GeMGWnkuW7j9Dpi6+NVRjaXYEKdtbsSuWwND8JVClSoYa23qosIeeNPCqRPB8pq3g==",
|
"integrity": "sha512-lev/3nprv4t8lu3kW1zdlH7VzlWh9dmyZ2PkzybmBI6nB48bswPm7cX2ppaFTkpY8Z904js9TOsrYQotMzsUiw==",
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@babylonjs/core": "^6.0.0"
|
"@babylonjs/core": "^6.0.0"
|
||||||
}
|
}
|
||||||
@ -74,17 +74,17 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babylonjs/havok": {
|
"node_modules/@babylonjs/havok": {
|
||||||
"version": "1.1.4",
|
"version": "1.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/@babylonjs/havok/-/havok-1.1.4.tgz",
|
"resolved": "https://registry.npmjs.org/@babylonjs/havok/-/havok-1.3.1.tgz",
|
||||||
"integrity": "sha512-mK/sgqv4LaI4BjoQgWYGxOBX45hVauZ8PopPkIUIB42DiVPgWkiCZbBQ9pL7r1tbLhThvV1RTokj4z5bVGBayw==",
|
"integrity": "sha512-ctaAQ2RN7hzE2vukGiA27//08YE4RNqH4RN26fCd8q0q7Qn+pXg4P61ZgakWYox/YS4VqHrB3ovZUDtPt2Scxg==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/emscripten": "^1.39.6"
|
"@types/emscripten": "^1.39.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babylonjs/inspector": {
|
"node_modules/@babylonjs/inspector": {
|
||||||
"version": "6.21.3",
|
"version": "6.45.1",
|
||||||
"resolved": "https://registry.npmjs.org/@babylonjs/inspector/-/inspector-6.21.3.tgz",
|
"resolved": "https://registry.npmjs.org/@babylonjs/inspector/-/inspector-6.45.1.tgz",
|
||||||
"integrity": "sha512-XJfqYVilSWEDLRy7IaSxkGNAs5U+SHsWBi9+eS49bFsP06fGjcbJjF2ZK1qY7DbMEThbwzwD6VypJtjKaoF9kw==",
|
"integrity": "sha512-4YhJLD2FrVXUFIU+ttBanhevVaCBVLaBxhPuwrxXxKWkuBulFOQz7GkvRT/CJwA3Ad9/66qwS5+vfRT99GLM/w==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fortawesome/fontawesome-svg-core": "^6.1.0",
|
"@fortawesome/fontawesome-svg-core": "^6.1.0",
|
||||||
"@fortawesome/free-regular-svg-icons": "^6.0.0",
|
"@fortawesome/free-regular-svg-icons": "^6.0.0",
|
||||||
@ -102,34 +102,34 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babylonjs/loaders": {
|
"node_modules/@babylonjs/loaders": {
|
||||||
"version": "6.21.3",
|
"version": "6.45.1",
|
||||||
"resolved": "https://registry.npmjs.org/@babylonjs/loaders/-/loaders-6.21.3.tgz",
|
"resolved": "https://registry.npmjs.org/@babylonjs/loaders/-/loaders-6.45.1.tgz",
|
||||||
"integrity": "sha512-2GpMOEQFuih8O/l6IIyGd0i0gCYo6x8LPjD10FBFBVX2dSkazhWDaAQSS8HCZNY2Uennmy83ePzuTf5RvaKDaw==",
|
"integrity": "sha512-a75JvRVxT3DROCrl5iigLEpI5/eR7Rh4wdsDzZNn7bv3sXB40Kbw8EL60W3jDBXPdGUqNVzqtrxJF/ec2udg/Q==",
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@babylonjs/core": "^6.0.0",
|
"@babylonjs/core": "^6.0.0",
|
||||||
"babylonjs-gltf2interface": "^6.0.0"
|
"babylonjs-gltf2interface": "^6.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babylonjs/materials": {
|
"node_modules/@babylonjs/materials": {
|
||||||
"version": "6.21.3",
|
"version": "6.45.1",
|
||||||
"resolved": "https://registry.npmjs.org/@babylonjs/materials/-/materials-6.21.3.tgz",
|
"resolved": "https://registry.npmjs.org/@babylonjs/materials/-/materials-6.45.1.tgz",
|
||||||
"integrity": "sha512-oH/ZmiYKTJnvWzaZVNDPSjvekKK9C/eQZaiMcYiPTb39LHJw+bnIJS8NyvWjDLLn4cJ9XfEict69WqMb1XItVA==",
|
"integrity": "sha512-v1jqgG0bfX+8Qezq4eDT2sSjpQYW+ocNU70dbJF0AYrhuhhgf0SpM28C7DAKi9GUOKjMvZrIBEbFmJ6AijLjcQ==",
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@babylonjs/core": "^6.0.0"
|
"@babylonjs/core": "^6.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babylonjs/procedural-textures": {
|
"node_modules/@babylonjs/procedural-textures": {
|
||||||
"version": "6.21.3",
|
"version": "6.45.1",
|
||||||
"resolved": "https://registry.npmjs.org/@babylonjs/procedural-textures/-/procedural-textures-6.21.3.tgz",
|
"resolved": "https://registry.npmjs.org/@babylonjs/procedural-textures/-/procedural-textures-6.45.1.tgz",
|
||||||
"integrity": "sha512-S1KIMrrVubk06mxuVeLGH8YngUj1W0zhdYjp2tHP2a7gueARG8a2OhqLW4e0MwFxi7XnP9DuFyzmkK95XZMaKw==",
|
"integrity": "sha512-QpLuPknYIvylfUscSqorkuXO4QSI49atQnScWN43ZpRzr+ecXWnxEaOyAmt7bbf93htshtIkUQdJhwx8w4fqrg==",
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@babylonjs/core": "^6.0.0"
|
"@babylonjs/core": "^6.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babylonjs/serializers": {
|
"node_modules/@babylonjs/serializers": {
|
||||||
"version": "6.21.3",
|
"version": "6.45.1",
|
||||||
"resolved": "https://registry.npmjs.org/@babylonjs/serializers/-/serializers-6.21.3.tgz",
|
"resolved": "https://registry.npmjs.org/@babylonjs/serializers/-/serializers-6.45.1.tgz",
|
||||||
"integrity": "sha512-E8jerSLDrDkwkNc8D9a9vmvPlNJiaXUl5m6cIUQ317oUk0/pT06NiM/N//HbyjM8ccnkaPUBkNBq4dxtPW/XSw==",
|
"integrity": "sha512-iSPUdjZhQIbSyi21IFiFC/wm6Bj4zcH9NhsN9i+xqLTbO/Uho49cHU0ew39n0Xn+LRsGRMTJWQLTsp+TPvAvrw==",
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@babylonjs/core": "^6.0.0",
|
"@babylonjs/core": "^6.0.0",
|
||||||
"babylonjs-gltf2interface": "^6.0.0"
|
"babylonjs-gltf2interface": "^6.0.0"
|
||||||
|
|||||||
16
package.json
16
package.json
@ -16,14 +16,14 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"axios": "^0.24.0",
|
"axios": "^0.24.0",
|
||||||
"@babylonjs/core": "^6.21.3",
|
"@babylonjs/core": "^6.45.1",
|
||||||
"@babylonjs/gui": "^6.21.3",
|
"@babylonjs/gui": "^6.45.1",
|
||||||
"@babylonjs/havok": "1.1.4",
|
"@babylonjs/havok": "1.3.1",
|
||||||
"@babylonjs/inspector": "^6.21.3",
|
"@babylonjs/inspector": "^6.45.1",
|
||||||
"@babylonjs/loaders": "^6.21.3",
|
"@babylonjs/loaders": "^6.45.1",
|
||||||
"@babylonjs/materials": "^6.21.3",
|
"@babylonjs/materials": "^6.45.1",
|
||||||
"@babylonjs/procedural-textures": "^6.21.3",
|
"@babylonjs/procedural-textures": "^6.45.1",
|
||||||
"@babylonjs/serializers": "^6.21.3",
|
"@babylonjs/serializers": "^6.45.1",
|
||||||
"@cloudflare/workers-types": "^4.20230821.0",
|
"@cloudflare/workers-types": "^4.20230821.0",
|
||||||
"@netlify/functions": "^2.3.0",
|
"@netlify/functions": "^2.3.0",
|
||||||
"events": "^3.3.0",
|
"events": "^3.3.0",
|
||||||
|
|||||||
@ -143,7 +143,7 @@ export class Base {
|
|||||||
this.previousScaling = mesh?.scaling.clone();
|
this.previousScaling = mesh?.scaling.clone();
|
||||||
this.previousPosition = mesh?.position.clone();
|
this.previousPosition = mesh?.position.clone();
|
||||||
|
|
||||||
if (("toolbox" != mesh?.parent?.parent?.id) || player) {
|
if (!mesh.metadata?.grabClone || player) {
|
||||||
if (mesh.physicsBody) {
|
if (mesh.physicsBody) {
|
||||||
const transformNode = setupTransformNode(mesh, this.controller.motionController.rootMesh);
|
const transformNode = setupTransformNode(mesh, this.controller.motionController.rootMesh);
|
||||||
mesh.physicsBody.setMotionType(PhysicsMotionType.ANIMATED);
|
mesh.physicsBody.setMotionType(PhysicsMotionType.ANIMATED);
|
||||||
@ -155,6 +155,8 @@ export class Base {
|
|||||||
this.grabbedMesh = mesh;
|
this.grabbedMesh = mesh;
|
||||||
} else {
|
} else {
|
||||||
const clone = grabAndClone(this.diagramManager, mesh, this.controller.motionController.rootMesh);
|
const clone = grabAndClone(this.diagramManager, mesh, this.controller.motionController.rootMesh);
|
||||||
|
clone.newMesh.metadata.grabClone = false;
|
||||||
|
clone.newMesh.metadata.tool = false;
|
||||||
this.grabbedMeshParentId = clone.transformNode.id;
|
this.grabbedMeshParentId = clone.transformNode.id;
|
||||||
this.grabbedMesh = clone.newMesh;
|
this.grabbedMesh = clone.newMesh;
|
||||||
this.previousParentId = null;
|
this.previousParentId = null;
|
||||||
|
|||||||
@ -51,9 +51,16 @@ export class WebController {
|
|||||||
}
|
}
|
||||||
if (kbInfo.type == KeyboardEventTypes.KEYUP) {
|
if (kbInfo.type == KeyboardEventTypes.KEYUP) {
|
||||||
this.rig.turn(0);
|
this.rig.turn(0);
|
||||||
|
this.rig.updown(0);
|
||||||
}
|
}
|
||||||
if (kbInfo.type == 1) {
|
if (kbInfo.type == 1) {
|
||||||
switch (kbInfo.event.key) {
|
switch (kbInfo.event.key) {
|
||||||
|
case "W":
|
||||||
|
this.rig.updown(-this.speed);
|
||||||
|
break;
|
||||||
|
case "S":
|
||||||
|
this.rig.updown(this.speed);
|
||||||
|
break;
|
||||||
case "ArrowUp":
|
case "ArrowUp":
|
||||||
case "w":
|
case "w":
|
||||||
this.rig.forwardback(-this.speed);
|
this.rig.forwardback(-this.speed);
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import {MeshBuilder, Observable, Scene, Vector3, WebXRDefaultExperience} from "@babylonjs/core";
|
import {MeshBuilder, Observable, Scene, TransformNode, Vector3, WebXRDefaultExperience} from "@babylonjs/core";
|
||||||
import log, {Logger} from "loglevel";
|
import log, {Logger} from "loglevel";
|
||||||
import {AdvancedDynamicTexture, Control, InputText, VirtualKeyboard} from "@babylonjs/gui";
|
import {AdvancedDynamicTexture, Control, InputText, VirtualKeyboard} from "@babylonjs/gui";
|
||||||
import {ControllerEventType, Controllers} from "../controllers/controllers";
|
import {ControllerEventType, Controllers} from "../controllers/controllers";
|
||||||
@ -37,8 +37,10 @@ export class InputTextView {
|
|||||||
|
|
||||||
public showVirtualKeyboard() {
|
public showVirtualKeyboard() {
|
||||||
|
|
||||||
|
const inputBaseNode = new TransformNode("inputBase", this.scene);
|
||||||
const inputMesh = MeshBuilder.CreatePlane("input", {width: 1, height: .5}, this.scene);
|
const inputMesh = MeshBuilder.CreatePlane("input", {width: 1, height: .5}, this.scene);
|
||||||
|
inputMesh.parent = inputBaseNode;
|
||||||
|
inputMesh.rotation.y = Math.PI;
|
||||||
const advancedTexture = AdvancedDynamicTexture.CreateForMesh(inputMesh, 2048, 1024, false);
|
const advancedTexture = AdvancedDynamicTexture.CreateForMesh(inputMesh, 2048, 1024, false);
|
||||||
|
|
||||||
const input = new InputText();
|
const input = new InputText();
|
||||||
@ -96,7 +98,7 @@ export class InputTextView {
|
|||||||
this.sounds.exit.play();
|
this.sounds.exit.play();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
setMenuPosition(inputMesh, this.scene, new Vector3(0, .4, 0));
|
setMenuPosition(inputBaseNode, this.scene, new Vector3(0, .4, 0));
|
||||||
this.sounds.enter.play();
|
this.sounds.enter.play();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import {AdvancedDynamicTexture, CheckboxGroup, RadioGroup, SelectionPanel, StackPanel} from "@babylonjs/gui";
|
import {AdvancedDynamicTexture, CheckboxGroup, RadioGroup, SelectionPanel, StackPanel} from "@babylonjs/gui";
|
||||||
import {MeshBuilder, Scene, Vector3, WebXRDefaultExperience} from "@babylonjs/core";
|
import {MeshBuilder, Scene, TransformNode, Vector3, WebXRDefaultExperience} from "@babylonjs/core";
|
||||||
import {AppConfig} from "../util/appConfig";
|
import {AppConfig} from "../util/appConfig";
|
||||||
import {ControllerEventType, Controllers} from "../controllers/controllers";
|
import {ControllerEventType, Controllers} from "../controllers/controllers";
|
||||||
import {DiaSounds} from "../util/diaSounds";
|
import {DiaSounds} from "../util/diaSounds";
|
||||||
@ -9,6 +9,7 @@ import {setMenuPosition} from "../util/functions/setMenuPosition";
|
|||||||
export class ConfigMenu extends AbstractMenu {
|
export class ConfigMenu extends AbstractMenu {
|
||||||
private sounds: DiaSounds;
|
private sounds: DiaSounds;
|
||||||
private config: AppConfig;
|
private config: AppConfig;
|
||||||
|
private readonly baseTransform: TransformNode;
|
||||||
private gridSnaps: Array<{ label: string, value: number }> = [
|
private gridSnaps: Array<{ label: string, value: number }> = [
|
||||||
{label: "Off", value: 0},
|
{label: "Off", value: 0},
|
||||||
{label: "0.01", value: 0.01},
|
{label: "0.01", value: 0.01},
|
||||||
@ -22,11 +23,11 @@ export class ConfigMenu extends AbstractMenu {
|
|||||||
{label: "22.5", value: 22.5},
|
{label: "22.5", value: 22.5},
|
||||||
{label: "45", value: 45},
|
{label: "45", value: 45},
|
||||||
{label: "90", value: 90},
|
{label: "90", value: 90},
|
||||||
|
|
||||||
]
|
]
|
||||||
|
|
||||||
constructor(scene: Scene, xr: WebXRDefaultExperience, controllers: Controllers, config: AppConfig) {
|
constructor(scene: Scene, xr: WebXRDefaultExperience, controllers: Controllers, config: AppConfig) {
|
||||||
super(scene, xr, controllers);
|
super(scene, xr, controllers);
|
||||||
|
this.baseTransform = new TransformNode("configMenuBase", scene);
|
||||||
this.config = config;
|
this.config = config;
|
||||||
this.sounds = new DiaSounds(scene);
|
this.sounds = new DiaSounds(scene);
|
||||||
|
|
||||||
@ -35,56 +36,72 @@ export class ConfigMenu extends AbstractMenu {
|
|||||||
this.toggle();
|
this.toggle();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
this.buildMenu();
|
||||||
|
}
|
||||||
|
|
||||||
|
public toggle() {
|
||||||
|
|
||||||
|
if (this.baseTransform.parent.isEnabled()) {
|
||||||
|
this.sounds.exit.play();
|
||||||
|
this.baseTransform.parent.setEnabled(false);
|
||||||
|
} else {
|
||||||
|
this.sounds.enter.play();
|
||||||
|
this.baseTransform.parent.setEnabled(true);
|
||||||
|
}
|
||||||
|
setMenuPosition(this.handle.mesh, this.scene, new Vector3(.6, .1, 0));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private buildMenu() {
|
||||||
public toggle() {
|
|
||||||
if (this.handle) {
|
|
||||||
this.handle.mesh.dispose(false, true);
|
|
||||||
this.sounds.exit.play();
|
|
||||||
this.handle = null;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.sounds.enter.play();
|
|
||||||
const configPlane = MeshBuilder
|
const configPlane = MeshBuilder
|
||||||
.CreatePlane("gridSizePlane",
|
.CreatePlane("configMenuPlane",
|
||||||
{
|
{
|
||||||
width: .6,
|
width: .6,
|
||||||
height: .3
|
height: .3
|
||||||
}, this.scene);
|
}, this.scene);
|
||||||
this.createHandle(configPlane);
|
configPlane.rotation.y = Math.PI;
|
||||||
|
configPlane.setParent(this.baseTransform);
|
||||||
|
this.createHandle(this.baseTransform);
|
||||||
|
this.baseTransform.position.set(0, .2, 0);
|
||||||
const configTexture = AdvancedDynamicTexture.CreateForMesh(configPlane, 2048, 1024);
|
const configTexture = AdvancedDynamicTexture.CreateForMesh(configPlane, 2048, 1024);
|
||||||
|
//configTexture.background = "#00ffff";
|
||||||
configTexture.background = "white";
|
|
||||||
const columnPanel = new StackPanel('columns');
|
const columnPanel = new StackPanel('columns');
|
||||||
columnPanel.fontSize = "48px";
|
|
||||||
columnPanel.isVertical = false;
|
columnPanel.isVertical = false;
|
||||||
|
|
||||||
|
//columnPanel.width = 1;
|
||||||
|
columnPanel.fontSize = "48px";
|
||||||
|
//columnPanel.background = "#ff0000";
|
||||||
|
//
|
||||||
configTexture.addControl(columnPanel);
|
configTexture.addControl(columnPanel);
|
||||||
const selectionPanel1 = new SelectionPanel("selectionPanel1");
|
const selectionPanel1 = new SelectionPanel("selectionPanel1");
|
||||||
selectionPanel1.width = .3;
|
selectionPanel1.width = "500px";
|
||||||
|
//selectionPanel1.width = .3;
|
||||||
columnPanel.addControl(selectionPanel1);
|
columnPanel.addControl(selectionPanel1);
|
||||||
this.buildGridSizeControl(selectionPanel1);
|
this.buildGridSizeControl(selectionPanel1);
|
||||||
this.buildCreateScaleControl(selectionPanel1);
|
this.buildCreateScaleControl(selectionPanel1);
|
||||||
|
|
||||||
const selectionPanel2 = new SelectionPanel("selectionPanel2");
|
const selectionPanel2 = new SelectionPanel("selectionPanel2");
|
||||||
selectionPanel2.width = .3;
|
selectionPanel2.width = "500px";
|
||||||
|
|
||||||
columnPanel.addControl(selectionPanel2);
|
columnPanel.addControl(selectionPanel2);
|
||||||
this.buildRotationSnapControl(selectionPanel2);
|
this.buildRotationSnapControl(selectionPanel2);
|
||||||
this.buildTurnSnapControl(selectionPanel2);
|
this.buildTurnSnapControl(selectionPanel2);
|
||||||
|
|
||||||
const selectionPanel3 = new SelectionPanel("selectionPanel3");
|
const selectionPanel3 = new SelectionPanel("selectionPanel3");
|
||||||
selectionPanel3.width = .3;
|
selectionPanel3.width = "768px";
|
||||||
columnPanel.addControl(selectionPanel3);
|
columnPanel.addControl(selectionPanel3);
|
||||||
|
|
||||||
this.buildFlyModeControl(selectionPanel3);
|
this.buildFlyModeControl(selectionPanel3);
|
||||||
|
|
||||||
configPlane.position.set(0, .2, 0);
|
setMenuPosition(this.handle.mesh, this.scene, new Vector3(.6, .1, 0));
|
||||||
setMenuPosition(this.handle.mesh, this.scene, new Vector3(.6, .4, 0));
|
this.baseTransform.parent.setEnabled(false);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private adjustRadio(radio: RadioGroup | CheckboxGroup) {
|
private adjustRadio(radio: RadioGroup | CheckboxGroup) {
|
||||||
radio.groupPanel.height = "512px";
|
radio.groupPanel.height = "512px";
|
||||||
|
radio.groupPanel.background = "#cccccc";
|
||||||
|
radio.groupPanel.color = "#000000";
|
||||||
radio.groupPanel.fontSize = "64px";
|
radio.groupPanel.fontSize = "64px";
|
||||||
radio.groupPanel.children[0].height = "70px";
|
radio.groupPanel.children[0].height = "70px";
|
||||||
radio.groupPanel.paddingLeft = "16px";
|
radio.groupPanel.paddingLeft = "16px";
|
||||||
@ -100,16 +117,15 @@ export class ConfigMenu extends AbstractMenu {
|
|||||||
|
|
||||||
private buildCreateScaleControl(selectionPanel: SelectionPanel): RadioGroup {
|
private buildCreateScaleControl(selectionPanel: SelectionPanel): RadioGroup {
|
||||||
const radio = new RadioGroup("Create Scale");
|
const radio = new RadioGroup("Create Scale");
|
||||||
|
|
||||||
selectionPanel.addGroup(radio);
|
selectionPanel.addGroup(radio);
|
||||||
for (const [index, snap] of this.gridSnaps.entries()) {
|
for (const [index, snap] of this.gridSnaps.entries()) {
|
||||||
const selected = (this.config.current.createSnap == snap.value);
|
const selected = (this.config.current.createSnap == snap.value);
|
||||||
|
console.log(selected);
|
||||||
radio.addRadio(snap.label, this.createVal.bind(this), selected);
|
radio.addRadio(snap.label, this.createVal.bind(this), selected);
|
||||||
}
|
}
|
||||||
this.adjustRadio(radio);
|
this.adjustRadio(radio);
|
||||||
return radio;
|
return radio;
|
||||||
}
|
}
|
||||||
|
|
||||||
private buildFlyModeControl(selectionPanel: SelectionPanel): CheckboxGroup {
|
private buildFlyModeControl(selectionPanel: SelectionPanel): CheckboxGroup {
|
||||||
const checkbox = new CheckboxGroup("Fly Mode");
|
const checkbox = new CheckboxGroup("Fly Mode");
|
||||||
selectionPanel.addGroup(checkbox);
|
selectionPanel.addGroup(checkbox);
|
||||||
@ -117,7 +133,6 @@ export class ConfigMenu extends AbstractMenu {
|
|||||||
this.adjustRadio(checkbox);
|
this.adjustRadio(checkbox);
|
||||||
return checkbox;
|
return checkbox;
|
||||||
}
|
}
|
||||||
|
|
||||||
private buildRotationSnapControl(selectionPanel: SelectionPanel): RadioGroup {
|
private buildRotationSnapControl(selectionPanel: SelectionPanel): RadioGroup {
|
||||||
const radio = new RadioGroup("Rotation Snap");
|
const radio = new RadioGroup("Rotation Snap");
|
||||||
selectionPanel.addGroup(radio);
|
selectionPanel.addGroup(radio);
|
||||||
@ -128,15 +143,11 @@ export class ConfigMenu extends AbstractMenu {
|
|||||||
this.adjustRadio(radio);
|
this.adjustRadio(radio);
|
||||||
return radio;
|
return radio;
|
||||||
}
|
}
|
||||||
|
|
||||||
private buildGridSizeControl(selectionPanel: SelectionPanel): RadioGroup {
|
private buildGridSizeControl(selectionPanel: SelectionPanel): RadioGroup {
|
||||||
const radio = new RadioGroup("Grid Snap");
|
const radio = new RadioGroup("Grid Snap");
|
||||||
|
|
||||||
selectionPanel.addGroup(radio);
|
selectionPanel.addGroup(radio);
|
||||||
|
|
||||||
for (const [index, snap] of this.gridSnaps.entries()) {
|
for (const [index, snap] of this.gridSnaps.entries()) {
|
||||||
const selected = (this.config.current.gridSnap == snap.value);
|
const selected = (this.config.current.gridSnap == snap.value);
|
||||||
|
|
||||||
radio.addRadio(snap.label, this.gridVal.bind(this), selected);
|
radio.addRadio(snap.label, this.gridVal.bind(this), selected);
|
||||||
}
|
}
|
||||||
this.adjustRadio(radio);
|
this.adjustRadio(radio);
|
||||||
|
|||||||
@ -168,20 +168,21 @@ export class EditMenu extends AbstractMenu {
|
|||||||
//this.scaleMenu = new ScaleMenu(this.scene, this.xr, this.controllers);
|
//this.scaleMenu = new ScaleMenu(this.scene, this.xr, this.controllers);
|
||||||
this.sounds = new DiaSounds(scene);
|
this.sounds = new DiaSounds(scene);
|
||||||
this.diagramManager = diagramManager;
|
this.diagramManager = diagramManager;
|
||||||
this.gizmoManager = new GizmoManager(scene);
|
/*this.gizmoManager = new GizmoManager(scene);
|
||||||
this.gizmoManager.boundingBoxGizmoEnabled = true;
|
this.gizmoManager.boundingBoxGizmoEnabled = true;
|
||||||
this.gizmoManager.gizmos.boundingBoxGizmo.scaleBoxSize = .020;
|
this.gizmoManager.gizmos.boundingBoxGizmo.scaleBoxSize = .020;
|
||||||
this.gizmoManager.gizmos.boundingBoxGizmo.rotationSphereSize = .020;
|
this.gizmoManager.gizmos.boundingBoxGizmo.rotationSphereSize = .020;
|
||||||
this.gizmoManager.gizmos.boundingBoxGizmo.scaleDragSpeed = 2;
|
this.gizmoManager.gizmos.boundingBoxGizmo.scaleDragSpeed = 2;
|
||||||
this.gizmoManager.clearGizmoOnEmptyPointerEvent = true;
|
this.gizmoManager.clearGizmoOnEmptyPointerEvent = true;
|
||||||
this.gizmoManager.usePointerToAttachGizmos = false;
|
this.gizmoManager.usePointerToAttachGizmos = false;*/
|
||||||
this.manager = new GUI3DManager(this.scene);
|
this.manager = new GUI3DManager(this.scene);
|
||||||
const panel = new PlanePanel();
|
|
||||||
|
|
||||||
|
const panel = new PlanePanel();
|
||||||
|
panel.orientation = PlanePanel.FACEFORWARDREVERSED_ORIENTATION;
|
||||||
panel.columns = 4;
|
panel.columns = 4;
|
||||||
this.manager.addControl(panel);
|
this.manager.addControl(panel);
|
||||||
//panel.addControl(this.makeButton("Cameras", "camera"));
|
//panel.addControl(this.makeButton("Cameras", "camera"));
|
||||||
panel.addControl(this.makeButton("Modify", "modify"));
|
//panel.addControl(this.makeButton("Modify", "modify"));
|
||||||
panel.addControl(this.makeButton("Remove", "remove"));
|
panel.addControl(this.makeButton("Remove", "remove"));
|
||||||
panel.addControl(this.makeButton("Label", "label"));
|
panel.addControl(this.makeButton("Label", "label"));
|
||||||
panel.addControl(this.makeButton("Copy", "copy"));
|
panel.addControl(this.makeButton("Copy", "copy"));
|
||||||
@ -218,7 +219,7 @@ export class EditMenu extends AbstractMenu {
|
|||||||
});
|
});
|
||||||
this.panel = panel;
|
this.panel = panel;
|
||||||
this.createHandle(this.manager.rootContainer.children[0].node);
|
this.createHandle(this.manager.rootContainer.children[0].node);
|
||||||
this.manager.rootContainer.children[0].node.position.y = .2;
|
this.manager.rootContainer.children[0].node.position.y = .15;
|
||||||
this.isVisible = false;
|
this.isVisible = false;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,6 +17,7 @@ export class Handle {
|
|||||||
handle.metadata = {handle: true};
|
handle.metadata = {handle: true};
|
||||||
if (this.transformNode) {
|
if (this.transformNode) {
|
||||||
this.transformNode.setParent(handle);
|
this.transformNode.setParent(handle);
|
||||||
|
//this.transformNode.rotation.y = Math.PI;
|
||||||
}
|
}
|
||||||
this.mesh = handle;
|
this.mesh = handle;
|
||||||
}
|
}
|
||||||
@ -30,9 +31,9 @@ function getHandleMesh(name: string, scene: Scene): InstancedMesh {
|
|||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
const handle = MeshBuilder.CreateCapsule("base-handle-mesh", {
|
const handle = MeshBuilder.CreateCapsule("base-handle-mesh", {
|
||||||
radius: .05,
|
radius: .04,
|
||||||
orientation: Vector3.Right(),
|
orientation: Vector3.Right(),
|
||||||
height: .4
|
height: .3
|
||||||
}, scene);
|
}, scene);
|
||||||
handle.setEnabled(false);
|
handle.setEnabled(false);
|
||||||
handle.material = buildStandardMaterial('base-handle-material', scene, "#CCCCDD");
|
handle.material = buildStandardMaterial('base-handle-material', scene, "#CCCCDD");
|
||||||
|
|||||||
@ -57,8 +57,9 @@ function DiagramList({display, onClick}) {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const listDb = async () => {
|
const listDb = async () => {
|
||||||
const data = await indexedDB.databases();
|
const data = await indexedDB.databases();
|
||||||
|
let i = 0;
|
||||||
setDbList(data.filter((item) => item.name.indexOf('_pouch_') > -1).map((item) => {
|
setDbList(data.filter((item) => item.name.indexOf('_pouch_') > -1).map((item) => {
|
||||||
return {name: item.name.replace('_pouch_', '')}
|
return {key: i++, name: item.name.replace('_pouch_', '')}
|
||||||
}));
|
}));
|
||||||
};
|
};
|
||||||
listDb();
|
listDb();
|
||||||
@ -71,7 +72,7 @@ function DiagramList({display, onClick}) {
|
|||||||
<div id="startCreate"><a href="#" id="startCreateLink" onClick={onClick}>New</a></div>
|
<div id="startCreate"><a href="#" id="startCreateLink" onClick={onClick}>New</a></div>
|
||||||
<div id="diagramListContent">
|
<div id="diagramListContent">
|
||||||
<ul>
|
<ul>
|
||||||
{dbList.map((item) => <li><a href={`/db/${item.name}`}>{item.name}</a></li>)}
|
{dbList.map((item) => <li key={item.key}><a href={`/db/${item.name}`}>{item.name}</a></li>)}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,75 +1,50 @@
|
|||||||
import {Color3, MeshBuilder, Observable, Scene, StandardMaterial, TransformNode, Vector3} from "@babylonjs/core";
|
import {Color3, MeshBuilder, Node, Scene, StandardMaterial, TransformNode, Vector3} from "@babylonjs/core";
|
||||||
import {enumKeys} from "../../util/functions/enumKeys";
|
import {enumKeys} from "../../util/functions/enumKeys";
|
||||||
import {ToolType} from "../types/toolType";
|
import {ToolType} from "../types/toolType";
|
||||||
import {buildTool} from "./buildTool";
|
import {buildTool} from "./buildTool";
|
||||||
import {AdvancedDynamicTexture, ColorPicker} from "@babylonjs/gui";
|
|
||||||
|
|
||||||
export function buildColor(color: Color3, scene: Scene, parent: TransformNode, index: number,
|
export function buildColor(color: Color3, scene: Scene, parent: TransformNode, index: number): Node {
|
||||||
colorChangeObservable: Observable<{ oldColor: string, newColor: string }>) {
|
const width = .1;
|
||||||
const width = 1;
|
const depth = .1;
|
||||||
const depth = .2;
|
const height = .01;
|
||||||
//const material = new PBRMaterial("material-" + color.toHexString(), scene);
|
|
||||||
const material = new StandardMaterial("material-" + color.toHexString(), scene);
|
const material = new StandardMaterial("material-" + color.toHexString(), scene);
|
||||||
material.diffuseColor = color;
|
material.diffuseColor = color;
|
||||||
material.roughness = 1;
|
material.ambientColor = color;
|
||||||
material.specularPower = 1;
|
|
||||||
//material.emissiveColor = color;
|
|
||||||
|
|
||||||
//const material = new StandardMaterial("material-" + color.toHexString(), scene);
|
//material.emissiveColor = new Color3(.1,.1,.1);
|
||||||
//material.albedoColor = color;
|
//material.roughness = 1;
|
||||||
//material.metallic = 1;
|
//material.specularPower = .0001;
|
||||||
//material.bumpTexture = new MarbleProceduralTexture("marble", 1024, scene);
|
|
||||||
//material.bumpTexture.level = 5;
|
const colorBoxMesh = MeshBuilder.CreateBox("toolbox-color-" + color.toHexString(), {
|
||||||
const mesh = MeshBuilder.CreateBox("toolbox-color-" + color.toHexString(), {
|
|
||||||
width: width,
|
width: width,
|
||||||
height: .01,
|
height: height,
|
||||||
depth: depth
|
depth: depth
|
||||||
}, scene);
|
}, scene);
|
||||||
mesh.material = material;
|
colorBoxMesh.rotation.x = Math.PI / 2;
|
||||||
mesh.position.z = index / 4;
|
colorBoxMesh.material = material;
|
||||||
mesh.parent = parent;
|
const rowLength = 8;
|
||||||
mesh.metadata = {tool: 'color'};
|
colorBoxMesh.position.x = -.45 + ((index % rowLength) / rowLength);
|
||||||
|
colorBoxMesh.position.y = -Math.floor(index / rowLength) * .1;
|
||||||
|
|
||||||
|
colorBoxMesh.parent = parent;
|
||||||
|
colorBoxMesh.metadata = {tool: 'color'};
|
||||||
|
|
||||||
let i = 0;
|
let i = 0;
|
||||||
|
const tools = [];
|
||||||
for (const tool of enumKeys(ToolType)) {
|
for (const tool of enumKeys(ToolType)) {
|
||||||
const newItem = buildTool(ToolType[tool], mesh);
|
const newItem = buildTool(ToolType[tool], colorBoxMesh, material);
|
||||||
if (newItem) {
|
if (newItem) {
|
||||||
|
//buildColorPicker(scene, color, newItem, material, i, colorChangeObservable);
|
||||||
newItem.position = new Vector3(calculatePosition(++i), .1, 0);
|
newItem.position = new Vector3(calculatePosition(++i), .1, 0);
|
||||||
|
tools.push(newItem.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const colorPickerPlane = MeshBuilder
|
colorBoxMesh.metadata.tools = tools;
|
||||||
.CreatePlane("colorPickerPlane",
|
return colorBoxMesh;
|
||||||
{
|
|
||||||
width: .1,
|
|
||||||
height: .1
|
|
||||||
}, scene);
|
|
||||||
const colorPickerTexture = AdvancedDynamicTexture.CreateForMesh(colorPickerPlane, 1024, 1024);
|
|
||||||
colorPickerPlane.parent = mesh;
|
|
||||||
colorPickerPlane.position = new Vector3(calculatePosition(++i), .1, 0);
|
|
||||||
|
|
||||||
|
|
||||||
const colorPicker = new ColorPicker("color-picker");
|
|
||||||
colorPicker.scaleY = 5;
|
|
||||||
colorPicker.scaleX = 5;
|
|
||||||
colorPicker.value = color;
|
|
||||||
colorPicker.onValueChangedObservable.add((value) => {
|
|
||||||
const oldColor = material.diffuseColor.clone();
|
|
||||||
const newColor = value.clone();
|
|
||||||
material.diffuseColor = newColor;
|
|
||||||
const newColorHex = newColor.toHexString();
|
|
||||||
material.id = "material-" + newColorHex;
|
|
||||||
material.name = "material-" + newColorHex;
|
|
||||||
mesh.id = "toolbox-color-" + newColorHex;
|
|
||||||
mesh.name = "toolbox-color-" + newColorHex;
|
|
||||||
colorChangeObservable.notifyObservers({
|
|
||||||
oldColor: oldColor.toHexString(),
|
|
||||||
newColor: newColor.toHexString()
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
colorPickerTexture.addControl(colorPicker);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const GRID_SIZE = 5;
|
const GRID_SIZE = 5;
|
||||||
|
|
||||||
function calculatePosition(i: number) {
|
function calculatePosition(i: number) {
|
||||||
|
|||||||
@ -7,11 +7,16 @@ export function buildMesh(type: ToolType, toolname: string, scene: Scene): Mesh
|
|||||||
return MeshBuilder.CreateBox(toolname, {width: 1, height: 1, depth: 1}, scene);
|
return MeshBuilder.CreateBox(toolname, {width: 1, height: 1, depth: 1}, scene);
|
||||||
|
|
||||||
case ToolType.SPHERE:
|
case ToolType.SPHERE:
|
||||||
return MeshBuilder.CreateIcoSphere(toolname, {subdivisions: 5, radius: .5}, scene);
|
return MeshBuilder.CreateIcoSphere(toolname, {subdivisions: 6, radius: .5, flat: false}, scene);
|
||||||
//return MeshBuilder.CreateSphere(toolname, {diameter: 1}, scene);
|
//return MeshBuilder.CreateSphere(toolname, {diameter: 1}, scene);
|
||||||
|
|
||||||
case ToolType.CYLINDER:
|
case ToolType.CYLINDER:
|
||||||
return MeshBuilder.CreateCylinder(toolname, {height: 1, diameter: 1, subdivisions: 1, tessellation: 12}, scene);
|
return MeshBuilder.CreateCylinder(toolname, {
|
||||||
|
height: 1,
|
||||||
|
diameter: 1,
|
||||||
|
subdivisions: 1,
|
||||||
|
tessellation: 24
|
||||||
|
}, scene);
|
||||||
|
|
||||||
case ToolType.CONE:
|
case ToolType.CONE:
|
||||||
return MeshBuilder.CreateCylinder(toolname, {
|
return MeshBuilder.CreateCylinder(toolname, {
|
||||||
@ -19,7 +24,7 @@ export function buildMesh(type: ToolType, toolname: string, scene: Scene): Mesh
|
|||||||
subdivisions: 1,
|
subdivisions: 1,
|
||||||
height: 1,
|
height: 1,
|
||||||
diameterBottom: 1,
|
diameterBottom: 1,
|
||||||
tessellation: 12
|
tessellation: 24
|
||||||
}, scene);
|
}, scene);
|
||||||
|
|
||||||
case ToolType.PLANE:
|
case ToolType.PLANE:
|
||||||
|
|||||||
@ -1,44 +1,48 @@
|
|||||||
import {AbstractMesh, Color3, InstancedMesh, PBRMaterial, StandardMaterial, Vector3} from "@babylonjs/core";
|
import {AbstractMesh, Color3, InstancedMesh, Material, PBRMaterial, StandardMaterial, Vector3} from "@babylonjs/core";
|
||||||
import {ToolType} from "../types/toolType";
|
import {ToolType} from "../types/toolType";
|
||||||
import {buildMesh} from "./buildMesh";
|
import {buildMesh} from "./buildMesh";
|
||||||
|
|
||||||
const WIDGET_SIZE = .1;
|
const WIDGET_SIZE = .1;
|
||||||
|
|
||||||
export function buildTool(tool: ToolType, parent: AbstractMesh) {
|
export function buildTool(tool: ToolType, colorParent: AbstractMesh, material: Material) {
|
||||||
let id = "ID";
|
let id = "ID";
|
||||||
switch (parent.material.getClassName()) {
|
switch (material.getClassName()) {
|
||||||
|
|
||||||
case "StandardMaterial":
|
case "StandardMaterial":
|
||||||
id = toolId(tool, (parent.material as StandardMaterial).diffuseColor);
|
id = toolId(tool, (material as StandardMaterial).diffuseColor);
|
||||||
break;
|
break;
|
||||||
case "PBRMaterial":
|
case "PBRMaterial":
|
||||||
id = toolId(tool, (parent.material as PBRMaterial).albedoColor);
|
id = toolId(tool, (material as PBRMaterial).albedoColor);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
this.logger.warn("buildTool: parent.material is null");
|
this.logger.warn("buildTool: parent.material is null");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const newItem = buildMesh(tool, `tool-${id}`, parent.getScene());
|
const newItem = buildMesh(tool, `tool-${id}`, colorParent.getScene());
|
||||||
if (!newItem) {
|
if (!newItem) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
newItem.material = parent.material;
|
newItem.material = material;
|
||||||
if (tool === ToolType.PLANE) {
|
if (tool === ToolType.PLANE) {
|
||||||
newItem.material.backFaceCulling = false;
|
newItem.material.backFaceCulling = false;
|
||||||
}
|
}
|
||||||
newItem.scaling = new Vector3(WIDGET_SIZE,
|
newItem.scaling = new Vector3(WIDGET_SIZE,
|
||||||
WIDGET_SIZE,
|
WIDGET_SIZE,
|
||||||
WIDGET_SIZE);
|
WIDGET_SIZE);
|
||||||
newItem.parent = parent;
|
newItem.parent = colorParent.parent;
|
||||||
newItem.metadata = {template: tool, tool: true};
|
newItem.metadata = {template: tool, tool: true, grabClone: true};
|
||||||
const instance = new InstancedMesh("instance-" + id, newItem);
|
const instance = new InstancedMesh("instance-" + id, newItem);
|
||||||
instance.metadata = {template: tool, tool: true};
|
instance.metadata = {template: tool, tool: true, grabClone: true};
|
||||||
instance.parent = parent;
|
instance.parent = colorParent.parent;
|
||||||
|
instance.setEnabled(false);
|
||||||
newItem.setEnabled(false);
|
newItem.setEnabled(false);
|
||||||
|
/*
|
||||||
newItem.onEnabledStateChangedObservable.add(() => {
|
newItem.onEnabledStateChangedObservable.add(() => {
|
||||||
|
|
||||||
instance.setEnabled(false);
|
instance.setEnabled(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
*/
|
||||||
return instance;
|
return instance;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,20 +0,0 @@
|
|||||||
import {Color3, Scene, StandardMaterial, TransformNode} from "@babylonjs/core";
|
|
||||||
import {enumKeys} from "../util/functions/enumKeys";
|
|
||||||
import {ToolType} from "./types/toolType";
|
|
||||||
import {buildMesh} from "./functions/buildMesh";
|
|
||||||
|
|
||||||
export class SimpleToolbox {
|
|
||||||
private scene: Scene;
|
|
||||||
private transformNode: TransformNode;
|
|
||||||
|
|
||||||
constructor(scene: Scene) {
|
|
||||||
this.scene = scene;
|
|
||||||
this.transformNode = new TransformNode("SimpleToolbox", this.scene);
|
|
||||||
}
|
|
||||||
|
|
||||||
private buildBaseShapes(color: Color3) {
|
|
||||||
for (const tool of enumKeys(ToolType)) {
|
|
||||||
const mesh = buildMesh(ToolType[tool], id = toolId(tool, (parent.material as StandardMaterial).diffuseColor), this.transformNode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,49 +1,52 @@
|
|||||||
import {AssetContainer, Color3, Mesh, Observable, Scene, TransformNode, Vector3} from "@babylonjs/core";
|
import {AxesViewer, Color3, Mesh, Node, Observable, Scene, TransformNode, Vector3} from "@babylonjs/core";
|
||||||
|
import {GUI3DManager, StackPanel3D,} from "@babylonjs/gui";
|
||||||
import {Button3D, GUI3DManager, StackPanel3D, TextBlock} from "@babylonjs/gui";
|
|
||||||
import {ControllerEventType, Controllers} from "../controllers/controllers";
|
|
||||||
import {setMenuPosition} from "../util/functions/setMenuPosition";
|
import {setMenuPosition} from "../util/functions/setMenuPosition";
|
||||||
import {buildColor} from "./functions/buildColor";
|
import {buildColor} from "./functions/buildColor";
|
||||||
|
|
||||||
import log from "loglevel";
|
import log from "loglevel";
|
||||||
import {Handle} from "../objects/handle";
|
import {Handle} from "../objects/handle";
|
||||||
|
|
||||||
|
const colors: string[] = [
|
||||||
|
"#222222", "#8b4513", "#006400", "#778899",
|
||||||
|
"#4b0082", "#ff0000", "#ffa500", "#ffff00",
|
||||||
|
"#00ff00", "#00ffff", "#0000ff", "#ff00ff",
|
||||||
|
"#1e90ff", "#98fb98", "#ffe4b5", "#ff69b4"
|
||||||
|
]
|
||||||
|
|
||||||
export class Toolbox {
|
export class Toolbox {
|
||||||
private readonly logger = log.getLogger('Toolbox');
|
private readonly logger = log.getLogger('Toolbox');
|
||||||
private index = 0;
|
private index = 0;
|
||||||
|
public readonly toolboxBaseNode: TransformNode;
|
||||||
private readonly scene: Scene;
|
private readonly scene: Scene;
|
||||||
public readonly node: TransformNode;
|
private colorPicker: TransformNode;
|
||||||
|
private changing = false;
|
||||||
private readonly manager: GUI3DManager;
|
private readonly manager: GUI3DManager;
|
||||||
private readonly addPanel: StackPanel3D;
|
private readonly addPanel: StackPanel3D;
|
||||||
private readonly controllers: Controllers;
|
|
||||||
private readonly xObserver;
|
|
||||||
public readonly colorChangeObservable: Observable<{ oldColor: string, newColor: string }> =
|
public readonly colorChangeObservable: Observable<{ oldColor: string, newColor: string }> =
|
||||||
new Observable<{ oldColor: string; newColor: string }>()
|
new Observable<{ oldColor: string; newColor: string }>()
|
||||||
private handle: Handle;
|
private handle: Handle;
|
||||||
constructor(scene: Scene, controllers: Controllers) {
|
private axes: AxesViewer;
|
||||||
|
|
||||||
|
constructor(scene: Scene) {
|
||||||
this.scene = scene;
|
this.scene = scene;
|
||||||
this.controllers = controllers;
|
|
||||||
this.addPanel = new StackPanel3D();
|
this.addPanel = new StackPanel3D();
|
||||||
this.manager = new GUI3DManager(scene);
|
this.manager = new GUI3DManager(scene);
|
||||||
this.manager.addControl(this.addPanel);
|
this.manager.addControl(this.addPanel);
|
||||||
this.node = new TransformNode("toolbox", this.scene);
|
this.toolboxBaseNode = new TransformNode("toolbox", this.scene);
|
||||||
this.handle = new Handle(this.node);
|
this.handle = new Handle(this.toolboxBaseNode);
|
||||||
this.node.position.y = .1;
|
this.toolboxBaseNode.position.y = .2;
|
||||||
this.node.position.z = .2;
|
//this.toolboxBaseNode.position.z = .05;
|
||||||
this.node.scaling = new Vector3(0.6, 0.6, 0.6);
|
/**this.axes = new AxesViewer(this.scene);
|
||||||
|
this.axes.xAxis.parent = this.toolboxBaseNode;
|
||||||
|
this.axes.yAxis.parent = this.toolboxBaseNode;
|
||||||
|
this.axes.zAxis.parent = this.toolboxBaseNode;*/
|
||||||
|
this.toolboxBaseNode.scaling = new Vector3(0.6, 0.6, 0.6);
|
||||||
this.buildToolbox();
|
this.buildToolbox();
|
||||||
|
}
|
||||||
|
|
||||||
if (!this.xObserver) {
|
public toggle() {
|
||||||
this.xObserver = this.controllers.controllerObserver.add((evt) => {
|
this.toolboxBaseNode.parent.setEnabled(!this.toolboxBaseNode.parent.isEnabled(false));
|
||||||
if (evt.type == ControllerEventType.X_BUTTON) {
|
setMenuPosition(this.toolboxBaseNode.parent as Mesh, this.scene,
|
||||||
if (evt.value == 1) {
|
Vector3.Zero());
|
||||||
this.node.parent.setEnabled(!this.node.parent.isEnabled(false));
|
|
||||||
setMenuPosition(this.node.parent as Mesh, this.scene,
|
|
||||||
Vector3.Zero());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public updateToolbox(color: string) {
|
public updateToolbox(color: string) {
|
||||||
@ -51,7 +54,7 @@ export class Toolbox {
|
|||||||
if (this.scene.getMeshById("toolbox-color-" + color)) {
|
if (this.scene.getMeshById("toolbox-color-" + color)) {
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
buildColor(Color3.FromHexString(color), this.scene, this.node, this.index++, this.colorChangeObservable);
|
buildColor(Color3.FromHexString(color), this.scene, this.toolboxBaseNode, this.index++);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.logger.warn("updateToolbox called with no color");
|
this.logger.warn("updateToolbox called with no color");
|
||||||
@ -59,38 +62,48 @@ export class Toolbox {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly objectObservable: Observable<AssetContainer> = new Observable();
|
private nodePredicate = (node: Node) => {
|
||||||
|
return node.getClassName() == "InstancedMesh" &&
|
||||||
|
node.isEnabled(false) == true
|
||||||
|
};
|
||||||
|
|
||||||
private buildToolbox() {
|
private buildToolbox() {
|
||||||
|
this.scene.onPointerObservable.add((pointerInfo) => {
|
||||||
|
if (pointerInfo.type == 1 && pointerInfo.pickInfo.pickedMesh?.metadata?.tool == 'color') {
|
||||||
|
if (this.changing) {
|
||||||
|
console.log('changing');
|
||||||
|
this.colorPicker.setEnabled(true);
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
const active = pointerInfo.pickInfo.pickedMesh?.parent.getChildren(this.nodePredicate, true);
|
||||||
|
for (const node of active) {
|
||||||
|
node.setEnabled(false);
|
||||||
|
}
|
||||||
|
const nodes = pointerInfo.pickInfo.pickedMesh?.metadata?.tools;
|
||||||
|
if (nodes) {
|
||||||
|
for (const node of nodes) {
|
||||||
|
this.scene.getNodeById(node)?.setEnabled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const color = "#7777FF";
|
}
|
||||||
buildColor(Color3.FromHexString(color), this.scene, this.node, this.index++, this.colorChangeObservable);
|
|
||||||
const addButton = createButton();
|
|
||||||
|
|
||||||
this.addPanel.node.parent = this.node.parent;
|
|
||||||
this.addPanel.addControl(addButton);
|
|
||||||
this.addPanel.node.scaling = new Vector3(.1, .1, .1);
|
|
||||||
this.addPanel.position = new Vector3(-.25, 0, 0);
|
|
||||||
//@TODO: move this somewhere else, just to prototype loading objects.
|
|
||||||
|
|
||||||
|
|
||||||
addButton.onPointerClickObservable.add(() => {
|
|
||||||
buildColor(Color3.Random(), this.scene, this.node, this.index++, this.colorChangeObservable);
|
|
||||||
});
|
});
|
||||||
//this.node.parent
|
let initial = true;
|
||||||
this.node.parent.setEnabled(false);
|
for (const c of colors) {
|
||||||
setMenuPosition(this.node.parent as Mesh, this.scene,
|
const cnode = buildColor(Color3.FromHexString(c), this.scene, this.toolboxBaseNode, this.index++);
|
||||||
|
if (initial) {
|
||||||
|
initial = false;
|
||||||
|
for (const id of cnode.metadata.tools) {
|
||||||
|
this.scene.getNodeById(id)?.setEnabled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.toolboxBaseNode.parent.setEnabled(false);
|
||||||
|
setMenuPosition(this.toolboxBaseNode.parent as Mesh, this.scene,
|
||||||
Vector3.Zero());
|
Vector3.Zero());
|
||||||
//
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function createButton(): Button3D {
|
|
||||||
const addButton = new Button3D("add-button");
|
|
||||||
const text = new TextBlock("add-button-text", "Add Color");
|
|
||||||
text.color = "white";
|
|
||||||
text.fontSize = "48px";
|
|
||||||
text.text = "Add Color";
|
|
||||||
addButton.content = text;
|
|
||||||
return addButton;
|
|
||||||
}
|
|
||||||
@ -33,9 +33,10 @@ export class CustomEnvironment {
|
|||||||
if (loading) {
|
if (loading) {
|
||||||
loading.remove();
|
loading.remove();
|
||||||
}
|
}
|
||||||
const light = new HemisphericLight("light1", new Vector3(.1, 1, 0), scene);
|
const light = new HemisphericLight("light1", new Vector3(1, 2, 1), scene);
|
||||||
light.groundColor = new Color3(.1, .1, .1)
|
light.groundColor = new Color3(.1, .1, .1)
|
||||||
light.intensity = .6;
|
light.diffuse = new Color3(1, 1, 1);
|
||||||
|
light.intensity = .8;
|
||||||
|
|
||||||
const physics = new CustomPhysics(this.scene, config);
|
const physics = new CustomPhysics(this.scene, config);
|
||||||
physics
|
physics
|
||||||
|
|||||||
@ -36,30 +36,44 @@ export function setMenuPosition(node: TransformNode, scene: Scene, offset: Vecto
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
if (scene.activeCamera) {
|
if (scene.activeCamera) {
|
||||||
switch (scene.activeCamera.getClassName()) {
|
setPosition(node, scene, offset);
|
||||||
case "WebXRCamera":
|
|
||||||
node.parent = null;
|
|
||||||
const front = getFrontPosition(.8, scene);
|
|
||||||
//front.y = scene.activeCamera.globalPosition.y;
|
|
||||||
node.position = front;
|
|
||||||
node.position.addInPlace(offset);
|
|
||||||
node.position.y -= .5;
|
|
||||||
|
|
||||||
node.lookAt(scene.activeCamera.globalPosition);
|
|
||||||
node.rotation.y = node.rotation.y + Math.PI;
|
|
||||||
break;
|
|
||||||
case "FreeCamera":
|
|
||||||
case "DeviceOrientationCamera":
|
|
||||||
case "ArcRotateCamera":
|
|
||||||
case "UniversalCamera":
|
|
||||||
node.parent = scene.activeCamera;
|
|
||||||
const width = scene.getEngine().getRenderWidth();
|
|
||||||
const height = scene.getEngine().getRenderHeight();
|
|
||||||
node.position.z = 2;
|
|
||||||
node.position.y = -.8;
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
} else {
|
||||||
|
scene.onActiveCameraChanged.add((scene: Scene) => {
|
||||||
|
setPosition(node, scene, offset);
|
||||||
|
});
|
||||||
|
console.error("No active camera");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setPosition(node: TransformNode, scene: Scene, offset: Vector3 = Vector3.Zero()) {
|
||||||
|
const platform = scene.getMeshByName("platform");
|
||||||
|
switch (scene.activeCamera.getClassName()) {
|
||||||
|
case "WebXRCamera":
|
||||||
|
//const oldParent = node.parent;
|
||||||
|
//console.log(oldParent.name);
|
||||||
|
node.setParent(null);
|
||||||
|
const front = getFrontPosition(1, scene);
|
||||||
|
const camPos = scene.activeCamera.globalPosition.clone();
|
||||||
|
node.position.x = front.x + offset.x;
|
||||||
|
node.position.z = front.z + offset.z;
|
||||||
|
node.position.y = 1.2 + offset.y;
|
||||||
|
node.lookAt(camPos);
|
||||||
|
node.setParent(platform);
|
||||||
|
break;
|
||||||
|
case "FreeCamera":
|
||||||
|
case "DeviceOrientationCamera":
|
||||||
|
case "ArcRotateCamera":
|
||||||
|
case "UniversalCamera":
|
||||||
|
node.parent = scene.activeCamera;
|
||||||
|
const width = scene.getEngine().getRenderWidth();
|
||||||
|
const height = scene.getEngine().getRenderHeight();
|
||||||
|
node.position.z = 2;
|
||||||
|
node.position.y = -.8 + offset.y;
|
||||||
|
node.position.x = offset.x;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
console.log('menu position set');
|
||||||
|
|
||||||
|
}
|
||||||
16
src/vrApp.ts
16
src/vrApp.ts
@ -1,4 +1,4 @@
|
|||||||
import {Engine, FreeCamera, Scene, Vector3} from "@babylonjs/core";
|
import {Color3, Engine, FreeCamera, Scene, Vector3} from "@babylonjs/core";
|
||||||
import '@babylonjs/loaders';
|
import '@babylonjs/loaders';
|
||||||
import {DiagramManager} from "./diagram/diagramManager";
|
import {DiagramManager} from "./diagram/diagramManager";
|
||||||
import {Toolbox} from "./toolbox/toolbox";
|
import {Toolbox} from "./toolbox/toolbox";
|
||||||
@ -6,7 +6,7 @@ import log, {Logger} from "loglevel";
|
|||||||
import {AppConfig} from "./util/appConfig";
|
import {AppConfig} from "./util/appConfig";
|
||||||
import {GamepadManager} from "./controllers/gamepadManager";
|
import {GamepadManager} from "./controllers/gamepadManager";
|
||||||
import {CustomEnvironment} from "./util/customEnvironment";
|
import {CustomEnvironment} from "./util/customEnvironment";
|
||||||
import {Controllers} from "./controllers/controllers";
|
import {ControllerEventType, Controllers} from "./controllers/controllers";
|
||||||
import {Spinner} from "./util/spinner";
|
import {Spinner} from "./util/spinner";
|
||||||
import {PouchdbPersistenceManager} from "./integration/pouchdbPersistenceManager";
|
import {PouchdbPersistenceManager} from "./integration/pouchdbPersistenceManager";
|
||||||
import {addSceneInspector} from "./util/functions/sceneInspctor";
|
import {addSceneInspector} from "./util/functions/sceneInspctor";
|
||||||
@ -38,13 +38,21 @@ export class VrApp {
|
|||||||
}
|
}
|
||||||
const scene = new Scene(this.engine);
|
const scene = new Scene(this.engine);
|
||||||
this.scene = scene;
|
this.scene = scene;
|
||||||
|
this.scene.ambientColor = new Color3(.1, .1, .1);
|
||||||
|
|
||||||
const spinner = new Spinner(scene);
|
const spinner = new Spinner(scene);
|
||||||
spinner.show();
|
spinner.show();
|
||||||
const config = new AppConfig();
|
const config = new AppConfig();
|
||||||
const controllers = new Controllers();
|
const controllers = new Controllers();
|
||||||
const toolbox = new Toolbox(scene, controllers);
|
const toolbox = new Toolbox(scene);
|
||||||
|
controllers.controllerObserver.add((evt) => {
|
||||||
|
if (evt.type == ControllerEventType.X_BUTTON) {
|
||||||
|
if (evt.value == 1) {
|
||||||
|
toolbox.toggle();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
const diagramManager = new DiagramManager(scene, controllers, toolbox, config);
|
const diagramManager = new DiagramManager(scene, controllers, toolbox, config);
|
||||||
|
|
||||||
const db = new PouchdbPersistenceManager();
|
const db = new PouchdbPersistenceManager();
|
||||||
db.setDiagramManager(diagramManager);
|
db.setDiagramManager(diagramManager);
|
||||||
db.configObserver.add((newConfig) => {
|
db.configObserver.add((newConfig) => {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user