Simplified interactions, changed menu interactions for changing entities.
This commit is contained in:
parent
2d3855621e
commit
727977d5c6
98
package-lock.json
generated
98
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.45.1",
|
"@babylonjs/core": "^7.1.0",
|
||||||
"@babylonjs/gui": "^6.45.1",
|
"@babylonjs/gui": "^7.1.0",
|
||||||
"@babylonjs/havok": "1.3.1",
|
"@babylonjs/havok": "1.3.1",
|
||||||
"@babylonjs/inspector": "^6.45.1",
|
"@babylonjs/inspector": "^7.1.0",
|
||||||
"@babylonjs/loaders": "^6.45.1",
|
"@babylonjs/loaders": "^7.1.0",
|
||||||
"@babylonjs/materials": "^6.45.1",
|
"@babylonjs/materials": "^7.1.0",
|
||||||
"@babylonjs/procedural-textures": "^6.45.1",
|
"@babylonjs/procedural-textures": "^7.1.0",
|
||||||
"@babylonjs/serializers": "^6.45.1",
|
"@babylonjs/serializers": "^7.1.0",
|
||||||
"@picovoice/cobra-web": "^2.0.3",
|
"@picovoice/cobra-web": "^2.0.3",
|
||||||
"@picovoice/eagle-web": "^1.0.0",
|
"@picovoice/eagle-web": "^1.0.0",
|
||||||
"@picovoice/web-voice-processor": "^4.0.9",
|
"@picovoice/web-voice-processor": "^4.0.9",
|
||||||
@ -51,26 +51,26 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babylonjs/core": {
|
"node_modules/@babylonjs/core": {
|
||||||
"version": "6.45.1",
|
"version": "7.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@babylonjs/core/-/core-6.45.1.tgz",
|
"resolved": "https://registry.npmjs.org/@babylonjs/core/-/core-7.1.0.tgz",
|
||||||
"integrity": "sha512-wkORoAqpnZb10bUhrI0vinE9IiW7+gSgH4U4Zp41wO4kSeV0mtJY+Q5Ez6/n9ad9sLykD2FD7650B+Qi5tTMSw=="
|
"integrity": "sha512-nz1CmflajMPnjdnwYrj72s4D/Q8IkOW4DBbwMfUNLFSCondfFXS3sZBgHeCAHpimR5n4e27YwvJ66MkQJsSraQ=="
|
||||||
},
|
},
|
||||||
"node_modules/@babylonjs/gui": {
|
"node_modules/@babylonjs/gui": {
|
||||||
"version": "6.45.1",
|
"version": "7.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@babylonjs/gui/-/gui-6.45.1.tgz",
|
"resolved": "https://registry.npmjs.org/@babylonjs/gui/-/gui-7.1.0.tgz",
|
||||||
"integrity": "sha512-lev/3nprv4t8lu3kW1zdlH7VzlWh9dmyZ2PkzybmBI6nB48bswPm7cX2ppaFTkpY8Z904js9TOsrYQotMzsUiw==",
|
"integrity": "sha512-tY6MGtigjZwv+9rqtGTsyBZL9sHSPjgVq+JEWHUsACH0ffNkKsQxtKSDc5bryzNQpo1rzTMHqEeU+DnqNSVe1Q==",
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@babylonjs/core": "^6.0.0"
|
"@babylonjs/core": "^7.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babylonjs/gui-editor": {
|
"node_modules/@babylonjs/gui-editor": {
|
||||||
"version": "6.8.0",
|
"version": "7.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@babylonjs/gui-editor/-/gui-editor-6.8.0.tgz",
|
"resolved": "https://registry.npmjs.org/@babylonjs/gui-editor/-/gui-editor-7.1.0.tgz",
|
||||||
"integrity": "sha512-XSTYEfCdf04Th1xrTuIO/lHBSmfiG4s4fIDzpi0+OERO19bKQffzhFGh95NVzdL0XhvnQT88Fb6bkvsuAxFI/Q==",
|
"integrity": "sha512-YHPR/2HxTT1ILSdGMAKOZ+askVCRV/hnI5CQqLVmAYkoW5FlY7TdRJtHn0JGEiOuK6Z5T3lJ3ru89wM+lGLqeg==",
|
||||||
"peer": true,
|
"peer": true,
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@babylonjs/core": "^6.0.0",
|
"@babylonjs/core": "^7.0.0",
|
||||||
"@babylonjs/gui": "^6.0.0",
|
"@babylonjs/gui": "^7.0.0",
|
||||||
"@types/react": ">=16.7.3",
|
"@types/react": ">=16.7.3",
|
||||||
"@types/react-dom": ">=16.0.9"
|
"@types/react-dom": ">=16.0.9"
|
||||||
}
|
}
|
||||||
@ -84,57 +84,57 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babylonjs/inspector": {
|
"node_modules/@babylonjs/inspector": {
|
||||||
"version": "6.45.1",
|
"version": "7.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@babylonjs/inspector/-/inspector-6.45.1.tgz",
|
"resolved": "https://registry.npmjs.org/@babylonjs/inspector/-/inspector-7.1.0.tgz",
|
||||||
"integrity": "sha512-4YhJLD2FrVXUFIU+ttBanhevVaCBVLaBxhPuwrxXxKWkuBulFOQz7GkvRT/CJwA3Ad9/66qwS5+vfRT99GLM/w==",
|
"integrity": "sha512-Hs9pk1LstJMnD4xXpHFlQVqXPtH/hhUcNSPaZlz8iesFrHJEXF4Mlao+ozwbl2WzDbMzmmex5nc1lw2HEBdhww==",
|
||||||
"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",
|
||||||
"@fortawesome/free-solid-svg-icons": "^6.0.0"
|
"@fortawesome/free-solid-svg-icons": "^6.0.0"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@babylonjs/core": "^6.0.0",
|
"@babylonjs/core": "^7.0.0",
|
||||||
"@babylonjs/gui": "^6.0.0",
|
"@babylonjs/gui": "^7.0.0",
|
||||||
"@babylonjs/gui-editor": "^6.0.0",
|
"@babylonjs/gui-editor": "^7.0.0",
|
||||||
"@babylonjs/loaders": "^6.0.0",
|
"@babylonjs/loaders": "^7.0.0",
|
||||||
"@babylonjs/materials": "^6.0.0",
|
"@babylonjs/materials": "^7.0.0",
|
||||||
"@babylonjs/serializers": "^6.0.0",
|
"@babylonjs/serializers": "^7.0.0",
|
||||||
"@types/react": ">=16.7.3",
|
"@types/react": ">=16.7.3",
|
||||||
"@types/react-dom": ">=16.0.9"
|
"@types/react-dom": ">=16.0.9"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babylonjs/loaders": {
|
"node_modules/@babylonjs/loaders": {
|
||||||
"version": "6.45.1",
|
"version": "7.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@babylonjs/loaders/-/loaders-6.45.1.tgz",
|
"resolved": "https://registry.npmjs.org/@babylonjs/loaders/-/loaders-7.1.0.tgz",
|
||||||
"integrity": "sha512-a75JvRVxT3DROCrl5iigLEpI5/eR7Rh4wdsDzZNn7bv3sXB40Kbw8EL60W3jDBXPdGUqNVzqtrxJF/ec2udg/Q==",
|
"integrity": "sha512-6gLbFiUsiqsQDRWLl4TL5pMKiemSAB/E61SHpp8xkBalxZUiKroSbZt3Irxc7CHIq8SE5CYfPUPYjs6BmpTgqw==",
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@babylonjs/core": "^6.0.0",
|
"@babylonjs/core": "^7.0.0",
|
||||||
"babylonjs-gltf2interface": "^6.0.0"
|
"babylonjs-gltf2interface": "^7.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babylonjs/materials": {
|
"node_modules/@babylonjs/materials": {
|
||||||
"version": "6.45.1",
|
"version": "7.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@babylonjs/materials/-/materials-6.45.1.tgz",
|
"resolved": "https://registry.npmjs.org/@babylonjs/materials/-/materials-7.1.0.tgz",
|
||||||
"integrity": "sha512-v1jqgG0bfX+8Qezq4eDT2sSjpQYW+ocNU70dbJF0AYrhuhhgf0SpM28C7DAKi9GUOKjMvZrIBEbFmJ6AijLjcQ==",
|
"integrity": "sha512-tHzpV6xUqpAgF9rPudDXetk1tIPbhggrybfIpvoWwbKlffIPQw4URsA+IBG04U5owWsicdhvTLQWP1WEwfbMQg==",
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@babylonjs/core": "^6.0.0"
|
"@babylonjs/core": "^7.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babylonjs/procedural-textures": {
|
"node_modules/@babylonjs/procedural-textures": {
|
||||||
"version": "6.45.1",
|
"version": "7.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@babylonjs/procedural-textures/-/procedural-textures-6.45.1.tgz",
|
"resolved": "https://registry.npmjs.org/@babylonjs/procedural-textures/-/procedural-textures-7.1.0.tgz",
|
||||||
"integrity": "sha512-QpLuPknYIvylfUscSqorkuXO4QSI49atQnScWN43ZpRzr+ecXWnxEaOyAmt7bbf93htshtIkUQdJhwx8w4fqrg==",
|
"integrity": "sha512-ajjaXEQJpWNQQzWZdUJJzN4NBtI96lxbrhmBUpPdfQwAhX2LRG0tbKWKXd66QHh82f/FG+daIA2BCL7M4f2MMw==",
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@babylonjs/core": "^6.0.0"
|
"@babylonjs/core": "^7.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babylonjs/serializers": {
|
"node_modules/@babylonjs/serializers": {
|
||||||
"version": "6.45.1",
|
"version": "7.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@babylonjs/serializers/-/serializers-6.45.1.tgz",
|
"resolved": "https://registry.npmjs.org/@babylonjs/serializers/-/serializers-7.1.0.tgz",
|
||||||
"integrity": "sha512-iSPUdjZhQIbSyi21IFiFC/wm6Bj4zcH9NhsN9i+xqLTbO/Uho49cHU0ew39n0Xn+LRsGRMTJWQLTsp+TPvAvrw==",
|
"integrity": "sha512-ToYutpqvqFVic+mhFkza6rLeE31sXXpixhdpu2bE+MRP13FoxNKfPD4np/DGBP7zUWmXIi2yRm6sZ7cGs8jp1g==",
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@babylonjs/core": "^6.0.0",
|
"@babylonjs/core": "^7.0.0",
|
||||||
"babylonjs-gltf2interface": "^6.0.0"
|
"babylonjs-gltf2interface": "^7.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@esbuild/aix-ppc64": {
|
"node_modules/@esbuild/aix-ppc64": {
|
||||||
@ -1083,9 +1083,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/babylonjs-gltf2interface": {
|
"node_modules/babylonjs-gltf2interface": {
|
||||||
"version": "6.8.0",
|
"version": "7.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/babylonjs-gltf2interface/-/babylonjs-gltf2interface-6.8.0.tgz",
|
"resolved": "https://registry.npmjs.org/babylonjs-gltf2interface/-/babylonjs-gltf2interface-7.1.0.tgz",
|
||||||
"integrity": "sha512-uCehLc8CnMUvWYttqQmJCHnhUjoftb4gK6Q+GXclgNr3CWiNDXHnbiBZQynA8SBfgkgE3bRk1+u+J5PQwkOepQ==",
|
"integrity": "sha512-44UnRGFj/kp6/MxB6SU5ThxYBjm9W0aYGkDbtSoPW2ZuWd4uTCjCKe8oS3fhsqXcZ5+K+rQVsHb785hxC4zRcw==",
|
||||||
"peer": true
|
"peer": true
|
||||||
},
|
},
|
||||||
"node_modules/base64-js": {
|
"node_modules/base64-js": {
|
||||||
|
|||||||
14
package.json
14
package.json
@ -17,14 +17,14 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"axios": "^1.6.8",
|
"axios": "^1.6.8",
|
||||||
"@babylonjs/core": "^6.45.1",
|
"@babylonjs/core": "^7.1.0",
|
||||||
"@babylonjs/gui": "^6.45.1",
|
"@babylonjs/gui": "^7.1.0",
|
||||||
"@babylonjs/havok": "1.3.1",
|
"@babylonjs/havok": "1.3.1",
|
||||||
"@babylonjs/inspector": "^6.45.1",
|
"@babylonjs/inspector": "^7.1.0",
|
||||||
"@babylonjs/loaders": "^6.45.1",
|
"@babylonjs/loaders": "^7.1.0",
|
||||||
"@babylonjs/materials": "^6.45.1",
|
"@babylonjs/materials": "^7.1.0",
|
||||||
"@babylonjs/procedural-textures": "^6.45.1",
|
"@babylonjs/procedural-textures": "^7.1.0",
|
||||||
"@babylonjs/serializers": "^6.45.1",
|
"@babylonjs/serializers": "^7.1.0",
|
||||||
"events": "^3.3.0",
|
"events": "^3.3.0",
|
||||||
"@typed-mxgraph/typed-mxgraph": "^1.0.8",
|
"@typed-mxgraph/typed-mxgraph": "^1.0.8",
|
||||||
"@types/node": "^18.14.0",
|
"@types/node": "^18.14.0",
|
||||||
|
|||||||
@ -20,7 +20,9 @@ import {snapGridVal} from "../util/functions/snapGridVal";
|
|||||||
import {snapRotateVal} from "../util/functions/snapRotateVal";
|
import {snapRotateVal} from "../util/functions/snapRotateVal";
|
||||||
import {grabAndClone} from "./functions/grab";
|
import {grabAndClone} from "./functions/grab";
|
||||||
import {isDiagramEntity} from "../diagram/functions/isDiagramEntity";
|
import {isDiagramEntity} from "../diagram/functions/isDiagramEntity";
|
||||||
|
import {ClickMenu} from "../menus/clickMenu";
|
||||||
|
|
||||||
|
const CLICK_TIME = 300;
|
||||||
export class Base {
|
export class Base {
|
||||||
static stickVector = Vector3.Zero();
|
static stickVector = Vector3.Zero();
|
||||||
protected controller: WebXRInputSource;
|
protected controller: WebXRInputSource;
|
||||||
@ -32,7 +34,7 @@ export class Base {
|
|||||||
protected previousRotation: Vector3 = null;
|
protected previousRotation: Vector3 = null;
|
||||||
protected previousScaling: Vector3 = null;
|
protected previousScaling: Vector3 = null;
|
||||||
protected previousPosition: Vector3 = null;
|
protected previousPosition: Vector3 = null;
|
||||||
|
private clickStart: number = 0;
|
||||||
protected readonly xr: WebXRDefaultExperience;
|
protected readonly xr: WebXRDefaultExperience;
|
||||||
protected readonly diagramManager: DiagramManager;
|
protected readonly diagramManager: DiagramManager;
|
||||||
private logger: log.Logger;
|
private logger: log.Logger;
|
||||||
@ -45,6 +47,7 @@ export class Base {
|
|||||||
controllers: Controllers,
|
controllers: Controllers,
|
||||||
diagramManager: DiagramManager) {
|
diagramManager: DiagramManager) {
|
||||||
this.logger = log.getLogger('Base');
|
this.logger = log.getLogger('Base');
|
||||||
|
this.logger.setLevel(this.logger.levels.DEBUG);
|
||||||
this.controller = controller;
|
this.controller = controller;
|
||||||
this.controllers = controllers;
|
this.controllers = controllers;
|
||||||
this.scene = scene;
|
this.scene = scene;
|
||||||
@ -71,9 +74,14 @@ export class Base {
|
|||||||
this.diagramManager = diagramManager;
|
this.diagramManager = diagramManager;
|
||||||
|
|
||||||
this.controller.onMotionControllerInitObservable.add((init) => {
|
this.controller.onMotionControllerInitObservable.add((init) => {
|
||||||
|
this.logger.debug(init.components);
|
||||||
if (init.components['xr-standard-squeeze']) {
|
if (init.components['xr-standard-squeeze']) {
|
||||||
this.initGrip(init.components['xr-standard-squeeze'])
|
this.initGrip(init.components['xr-standard-squeeze'])
|
||||||
}
|
}
|
||||||
|
if (init.components['xr-standard-trigger']) {
|
||||||
|
this.initClicker(init.components['xr-standard-trigger']);
|
||||||
|
}
|
||||||
|
|
||||||
}, -1, false, this);
|
}, -1, false, this);
|
||||||
this.controllers.controllerObserver.add((event) => {
|
this.controllers.controllerObserver.add((event) => {
|
||||||
this.logger.debug(event);
|
this.logger.debug(event);
|
||||||
@ -108,7 +116,33 @@ export class Base {
|
|||||||
this.controller.pointer.setEnabled(true)
|
this.controller.pointer.setEnabled(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
private grab() {
|
protected initClicker(trigger: WebXRControllerComponent) {
|
||||||
|
this.logger.debug("initTrigger");
|
||||||
|
trigger.onButtonStateChangedObservable.add(() => {
|
||||||
|
if (trigger.changes.pressed) {
|
||||||
|
if (trigger.pressed) {
|
||||||
|
if (this.clickStart == 0) {
|
||||||
|
this.clickStart = Date.now();
|
||||||
|
window.setTimeout(() => {
|
||||||
|
if (this.clickStart > 0) {
|
||||||
|
this.logger.debug("grabbing and cloning");
|
||||||
|
this.grab(true);
|
||||||
|
}
|
||||||
|
}, 300, this);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const clickEnd = Date.now();
|
||||||
|
if (this.clickStart > 0 && (clickEnd - this.clickStart) < CLICK_TIME) {
|
||||||
|
this.click();
|
||||||
|
}
|
||||||
|
this.drop();
|
||||||
|
this.clickStart = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, -1, false, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private grab(cloneEntity: boolean = false) {
|
||||||
let mesh = this.xr.pointerSelection.getMeshUnderPointer(this.controller.uniqueId);
|
let mesh = this.xr.pointerSelection.getMeshUnderPointer(this.controller.uniqueId);
|
||||||
if (!mesh) {
|
if (!mesh) {
|
||||||
return;
|
return;
|
||||||
@ -116,7 +150,7 @@ export class Base {
|
|||||||
let player = false;
|
let player = false;
|
||||||
|
|
||||||
if (!isDiagramEntity(mesh)) {
|
if (!isDiagramEntity(mesh)) {
|
||||||
if (mesh?.metadata?.handle == true) {
|
if (this.handleWasGrabbed(mesh)) {
|
||||||
mesh && mesh.setParent(this.controller.motionController.rootMesh);
|
mesh && mesh.setParent(this.controller.motionController.rootMesh);
|
||||||
this.grabbedMesh = mesh;
|
this.grabbedMesh = mesh;
|
||||||
} else {
|
} else {
|
||||||
@ -132,7 +166,6 @@ export class Base {
|
|||||||
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
if (mesh?.metadata?.template == '#connection-template') {
|
if (mesh?.metadata?.template == '#connection-template') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -143,7 +176,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 (!mesh.metadata?.grabClone || player) {
|
if ((!mesh.metadata?.grabClone || player) && !cloneEntity) {
|
||||||
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);
|
||||||
@ -151,9 +184,9 @@ export class Base {
|
|||||||
} else {
|
} else {
|
||||||
mesh.setParent(this.controller.motionController.rootMesh);
|
mesh.setParent(this.controller.motionController.rootMesh);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.grabbedMesh = mesh;
|
this.grabbedMesh = mesh;
|
||||||
} else {
|
} else {
|
||||||
|
this.logger.debug("cloning " + mesh?.id);
|
||||||
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.grabClone = false;
|
||||||
clone.newMesh.metadata.tool = false;
|
clone.newMesh.metadata.tool = false;
|
||||||
@ -168,29 +201,25 @@ export class Base {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private toolboxHandleWasGrabbed(mesh: AbstractMesh): boolean {
|
private handleWasGrabbed(mesh: AbstractMesh): boolean {
|
||||||
if (isDiagramEntity(mesh)) {
|
if (isDiagramEntity(mesh)) {
|
||||||
this.grabbedMesh = null;
|
|
||||||
this.previousParentId = null;
|
|
||||||
mesh.setParent(null);
|
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
return (mesh?.metadata?.handle == true);
|
return (mesh?.metadata?.handle == true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private drop() {
|
private drop() {
|
||||||
const mesh = this.grabbedMesh;
|
const mesh = this.grabbedMesh;
|
||||||
if (!mesh) {
|
if (!mesh) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (this.toolboxHandleWasGrabbed(mesh)) {
|
if (this.handleWasGrabbed(mesh)) {
|
||||||
mesh.setParent(this.scene.getMeshByName("platform"))
|
mesh.setParent(this.scene.getMeshByName("platform"))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
reparent(mesh, this.previousParentId, this.grabbedMeshParentId);
|
reparent(mesh, this.previousParentId, this.grabbedMeshParentId);
|
||||||
this.grabbedMeshParentId = null;
|
this.grabbedMeshParentId = null;
|
||||||
|
|
||||||
if (!mesh.physicsBody) {
|
if (!mesh.physicsBody) {
|
||||||
mesh.position = snapGridVal(mesh.position, this.diagramManager._config.current.gridSnap);
|
mesh.position = snapGridVal(mesh.position, this.diagramManager._config.current.gridSnap);
|
||||||
mesh.rotation = snapRotateVal(mesh.rotation, this.diagramManager._config.current.rotateSnap);
|
mesh.rotation = snapRotateVal(mesh.rotation, this.diagramManager._config.current.rotateSnap);
|
||||||
@ -224,15 +253,32 @@ export class Base {
|
|||||||
this.diagramManager.onDiagramEventObservable.notifyObservers(event, -1);
|
this.diagramManager.onDiagramEventObservable.notifyObservers(event, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
} else {
|
||||||
|
this.logger.debug("click on nothing");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
private initGrip(grip: WebXRControllerComponent) {
|
private initGrip(grip: WebXRControllerComponent) {
|
||||||
grip.onButtonStateChangedObservable.add(() => {
|
grip.onButtonStateChangedObservable.add(() => {
|
||||||
if (grip.changes.pressed) {
|
if (grip.changes.pressed) {
|
||||||
if (grip.pressed) {
|
if (grip.pressed) {
|
||||||
this.grab();
|
this.grab();
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
this.drop();
|
this.drop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function pointable(mesh: AbstractMesh): boolean {
|
||||||
|
return (mesh && mesh.metadata?.template && !mesh.metadata?.tool && !mesh.metadata?.handle && !mesh.metadata?.grabbable && !mesh.metadata?.grabClone);
|
||||||
}
|
}
|
||||||
1
src/env.d.ts
vendored
1
src/env.d.ts
vendored
@ -3,6 +3,7 @@
|
|||||||
interface ImportMetaEnv {
|
interface ImportMetaEnv {
|
||||||
readonly VITE_SYNCDB_ENDPOINT: string,
|
readonly VITE_SYNCDB_ENDPOINT: string,
|
||||||
readonly VITE_SYNCDB_USER: string
|
readonly VITE_SYNCDB_USER: string
|
||||||
|
readonly VITE_CREATE_ENDPOINT: string
|
||||||
// more env variables...
|
// more env variables...
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -37,8 +37,6 @@ export class InputTextView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public showVirtualKeyboard() {
|
public showVirtualKeyboard() {
|
||||||
|
|
||||||
|
|
||||||
const inputMesh = MeshBuilder.CreatePlane("input", {width: 1, height: .5}, this.scene);
|
const inputMesh = MeshBuilder.CreatePlane("input", {width: 1, height: .5}, this.scene);
|
||||||
const handle = new Handle(inputMesh);
|
const handle = new Handle(inputMesh);
|
||||||
setMenuPosition(handle.mesh, this.scene, new Vector3(0, .4, 0));
|
setMenuPosition(handle.mesh, this.scene, new Vector3(0, .4, 0));
|
||||||
|
|||||||
@ -1,20 +0,0 @@
|
|||||||
import log from "loglevel";
|
|
||||||
|
|
||||||
const logger = log.getLogger('syncDoc');
|
|
||||||
export function syncDoc(info) {
|
|
||||||
logger.debug(info);
|
|
||||||
if (info.direction == 'pull') {
|
|
||||||
const docs = info.change.docs;
|
|
||||||
for (const doc of docs) {
|
|
||||||
logger.debug(doc);
|
|
||||||
if (doc._deleted) {
|
|
||||||
logger.debug('Delete', doc);
|
|
||||||
this.removeObserver.notifyObservers({id: doc._id, template: doc.template}, 1);
|
|
||||||
} else {
|
|
||||||
this.updateObserver.notifyObservers(doc, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -6,7 +6,6 @@ import {v4 as uuidv4} from 'uuid';
|
|||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import {DiagramManager} from "../diagram/diagramManager";
|
import {DiagramManager} from "../diagram/diagramManager";
|
||||||
import log, {Logger} from "loglevel";
|
import log, {Logger} from "loglevel";
|
||||||
import {syncDoc} from "./functions/syncDoc";
|
|
||||||
|
|
||||||
const logger: Logger = log.getLogger('PouchdbPersistenceManager');
|
const logger: Logger = log.getLogger('PouchdbPersistenceManager');
|
||||||
export class PouchdbPersistenceManager {
|
export class PouchdbPersistenceManager {
|
||||||
@ -166,7 +165,7 @@ export class PouchdbPersistenceManager {
|
|||||||
createSnap: 0,
|
createSnap: 0,
|
||||||
turnSnap: 0,
|
turnSnap: 0,
|
||||||
flyMode: true,
|
flyMode: true,
|
||||||
currentDiagramId: uuidv4()
|
currentDiagramId: 'public'
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
await this.setConfig(defaultConfig, true);
|
await this.setConfig(defaultConfig, true);
|
||||||
@ -217,21 +216,52 @@ export class PouchdbPersistenceManager {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async beginSync(remoteDbName: string) {
|
private syncDoc(info) {
|
||||||
|
logger.debug(info);
|
||||||
|
if (info.direction == 'pull') {
|
||||||
|
const docs = info.change.docs;
|
||||||
|
for (const doc of docs) {
|
||||||
|
logger.debug(doc);
|
||||||
|
if (doc._deleted) {
|
||||||
|
logger.debug('Delete', doc);
|
||||||
|
this.removeObserver.notifyObservers({id: doc._id, template: doc.template}, 1);
|
||||||
|
} else {
|
||||||
|
this.updateObserver.notifyObservers(doc, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private async beginSync(localName: string) {
|
||||||
try {
|
try {
|
||||||
//const remoteDbName = "db1";
|
//const remoteDbName = "db1";
|
||||||
const userHex = remoteDbName.split('-');
|
|
||||||
if (userHex.length < 2) {
|
const userHex = ascii_to_hex(localName);
|
||||||
return;
|
const remoteDbName = 'userdb-' + userHex;
|
||||||
}
|
const remoteUserName = localName;
|
||||||
const username = hex_to_ascii(userHex[1]);
|
const password = localName;
|
||||||
const remoteUserName = username;
|
|
||||||
const password = "password";
|
|
||||||
const dbs = await axios.get(import.meta.env.VITE_SYNCDB_ENDPOINT + 'list');
|
const dbs = await axios.get(import.meta.env.VITE_SYNCDB_ENDPOINT + 'list');
|
||||||
logger.debug(dbs.data);
|
logger.debug(dbs.data);
|
||||||
if (dbs.data.indexOf(remoteDbName) == -1) {
|
if (dbs.data.indexOf(remoteDbName) == -1) {
|
||||||
logger.warn('sync target missing');
|
logger.warn('sync target missing attempting to create');
|
||||||
return;
|
const newdb = await axios.post(import.meta.env.VITE_CREATE_ENDPOINT,
|
||||||
|
|
||||||
|
{
|
||||||
|
"_id": "org.couchdb.user:" + localName,
|
||||||
|
"name": localName,
|
||||||
|
"password": localName,
|
||||||
|
"roles": ["readers"],
|
||||||
|
"type": "user"
|
||||||
|
}
|
||||||
|
);
|
||||||
|
if (newdb.status == 200) {
|
||||||
|
logger.info('sync target created');
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
const userEndpoint: string = import.meta.env.VITE_USER_ENDPOINT
|
const userEndpoint: string = import.meta.env.VITE_USER_ENDPOINT
|
||||||
logger.debug(userEndpoint);
|
logger.debug(userEndpoint);
|
||||||
@ -262,9 +292,11 @@ export class PouchdbPersistenceManager {
|
|||||||
{auth: {username: remoteUserName, password: password}, skip_setup: true});
|
{auth: {username: remoteUserName, password: password}, skip_setup: true});
|
||||||
const dbInfo = await this.remote.info();
|
const dbInfo = await this.remote.info();
|
||||||
logger.debug(dbInfo);
|
logger.debug(dbInfo);
|
||||||
syncDoc.bind(this);
|
|
||||||
this.db.sync(this.remote, {live: true, retry: true})
|
this.db.sync(this.remote, {live: true, retry: true})
|
||||||
.on('change', syncDoc)
|
.on('change', (info) => {
|
||||||
|
this.syncDoc(info)
|
||||||
|
})
|
||||||
.on('active', function (info) {
|
.on('active', function (info) {
|
||||||
logger.debug('sync active', info)
|
logger.debug('sync active', info)
|
||||||
})
|
})
|
||||||
@ -272,7 +304,7 @@ export class PouchdbPersistenceManager {
|
|||||||
logger.debug('sync paused', info)
|
logger.debug('sync paused', info)
|
||||||
})
|
})
|
||||||
.on('error', function (err) {
|
.on('error', function (err) {
|
||||||
logger.debug('sync error', err)
|
logger.error('sync error', err)
|
||||||
});
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
logger.error(err);
|
logger.error(err);
|
||||||
@ -283,8 +315,17 @@ export class PouchdbPersistenceManager {
|
|||||||
function hex_to_ascii(input) {
|
function hex_to_ascii(input) {
|
||||||
var hex = input.toString();
|
var hex = input.toString();
|
||||||
let output = '';
|
let output = '';
|
||||||
for (var n = 0; n < hex.length; n += 2) {
|
for (let n = 0; n < hex.length; n += 2) {
|
||||||
output += String.fromCharCode(parseInt(hex.substr(n, 2), 16));
|
output += String.fromCharCode(parseInt(hex.substr(n, 2), 16));
|
||||||
}
|
}
|
||||||
return output;
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
function ascii_to_hex(str) {
|
||||||
|
const arr1 = [];
|
||||||
|
for (let n = 0, l = str.length; n < l; n++) {
|
||||||
|
var hex = Number(str.charCodeAt(n)).toString(16);
|
||||||
|
arr1.push(hex);
|
||||||
|
}
|
||||||
|
return arr1.join('');
|
||||||
}
|
}
|
||||||
78
src/menus/clickMenu.ts
Normal file
78
src/menus/clickMenu.ts
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
import {Button3D, GUI3DManager, PlanePanel, TextBlock} from "@babylonjs/gui";
|
||||||
|
import {AbstractMesh, TransformNode} from "@babylonjs/core";
|
||||||
|
import {DiagramEvent, DiagramEventType} from "../diagram/types/diagramEntity";
|
||||||
|
import {toDiagramEntity} from "../diagram/functions/toDiagramEntity";
|
||||||
|
import {DiagramManager} from "../diagram/diagramManager";
|
||||||
|
|
||||||
|
export class ClickMenu {
|
||||||
|
private static readonly sounds;
|
||||||
|
private readonly entity: AbstractMesh;
|
||||||
|
private readonly manager: GUI3DManager;
|
||||||
|
private readonly transform: TransformNode;
|
||||||
|
private readonly diagramManager: DiagramManager;
|
||||||
|
|
||||||
|
constructor(entity: AbstractMesh, diagramManager: DiagramManager) {
|
||||||
|
this.entity = entity;
|
||||||
|
this.diagramManager = diagramManager;
|
||||||
|
const scene = entity.getScene();
|
||||||
|
const manager = new GUI3DManager(scene);
|
||||||
|
const transform = new TransformNode("transform", scene);
|
||||||
|
|
||||||
|
transform.position = entity.absolutePosition.clone();
|
||||||
|
transform.position.y += entity.scaling.y;
|
||||||
|
|
||||||
|
const panel = new PlanePanel();
|
||||||
|
|
||||||
|
panel.orientation = PlanePanel.FACEFORWARDREVERSED_ORIENTATION;
|
||||||
|
panel.columns = 4;
|
||||||
|
|
||||||
|
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.linkToTransformNode(transform);
|
||||||
|
this.transform = transform;
|
||||||
|
this.manager = manager;
|
||||||
|
}
|
||||||
|
|
||||||
|
private 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;
|
||||||
|
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":
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}, -1, false, this, true);
|
||||||
|
return button;
|
||||||
|
}
|
||||||
|
|
||||||
|
private dispose() {
|
||||||
|
this.manager.dispose();
|
||||||
|
this.transform.dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -13,6 +13,7 @@ export class Handle {
|
|||||||
private buildHandle() {
|
private buildHandle() {
|
||||||
const scene: Scene = this.transformNode.getScene();
|
const scene: Scene = this.transformNode.getScene();
|
||||||
const handle = getHandleMesh("handle-" + this.transformNode.id + "-mesh", scene);
|
const handle = getHandleMesh("handle-" + this.transformNode.id + "-mesh", scene);
|
||||||
|
|
||||||
handle.position = Vector3.Zero();
|
handle.position = Vector3.Zero();
|
||||||
handle.metadata = {handle: true};
|
handle.metadata = {handle: true};
|
||||||
if (this.transformNode) {
|
if (this.transformNode) {
|
||||||
|
|||||||
6
src/objects/objectMetaType.ts
Normal file
6
src/objects/objectMetaType.ts
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
export type ObjectMetaType = {
|
||||||
|
id: string;
|
||||||
|
parent: string;
|
||||||
|
position: { x: number, y: number, z: number };
|
||||||
|
rotation: { x: number, y: number, z: number };
|
||||||
|
}
|
||||||
@ -1,6 +1,5 @@
|
|||||||
import {AxesViewer, Color3, Mesh, Node, Observable, Scene, TransformNode, Vector3} from "@babylonjs/core";
|
import {AbstractMesh, AxesViewer, Color3, Node, Observable, Scene, TransformNode, Vector3} from "@babylonjs/core";
|
||||||
import {GUI3DManager, StackPanel3D,} from "@babylonjs/gui";
|
import {GUI3DManager, StackPanel3D,} from "@babylonjs/gui";
|
||||||
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";
|
||||||
@ -34,20 +33,14 @@ export class Toolbox {
|
|||||||
new Handle(this.toolboxBaseNode);
|
new Handle(this.toolboxBaseNode);
|
||||||
this.toolboxBaseNode.position.y = .2;
|
this.toolboxBaseNode.position.y = .2;
|
||||||
//this.toolboxBaseNode.position.z = .05;
|
//this.toolboxBaseNode.position.z = .05;
|
||||||
/**this.axes = new AxesViewer(this.scene);
|
/*this.axes = new AxesViewer(this.scene);
|
||||||
this.axes.xAxis.parent = this.toolboxBaseNode;
|
this.axes.xAxis.parent = this.toolboxBaseNode;
|
||||||
this.axes.yAxis.parent = this.toolboxBaseNode;
|
this.axes.yAxis.parent = this.toolboxBaseNode;
|
||||||
this.axes.zAxis.parent = this.toolboxBaseNode;*/
|
this.axes.zAxis.parent = this.toolboxBaseNode; */
|
||||||
this.toolboxBaseNode.scaling = new Vector3(0.6, 0.6, 0.6);
|
this.toolboxBaseNode.scaling = new Vector3(0.6, 0.6, 0.6);
|
||||||
this.buildToolbox();
|
this.buildToolbox();
|
||||||
}
|
}
|
||||||
|
|
||||||
public toggle() {
|
|
||||||
this.toolboxBaseNode.parent.setEnabled(!this.toolboxBaseNode.parent.isEnabled(false));
|
|
||||||
setMenuPosition(this.toolboxBaseNode.parent as Mesh, this.scene,
|
|
||||||
Vector3.Zero());
|
|
||||||
}
|
|
||||||
|
|
||||||
public updateToolbox(color: string) {
|
public updateToolbox(color: string) {
|
||||||
if (color) {
|
if (color) {
|
||||||
if (this.scene.getMeshById("toolbox-color-" + color)) {
|
if (this.scene.getMeshById("toolbox-color-" + color)) {
|
||||||
@ -98,9 +91,27 @@ export class Toolbox {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
//this.toolboxBaseNode.parent.setEnabled(false);
|
//this.toolboxBaseNode.parent.setEnabled(false);
|
||||||
setMenuPosition(this.toolboxBaseNode.parent as Mesh, this.scene,
|
const offset = new Vector3(0, 1, 1);
|
||||||
Vector3.Zero());
|
if (this.toolboxBaseNode.parent) {
|
||||||
|
const platform = this.scene.getNodeById("platform");
|
||||||
|
if (platform) {
|
||||||
|
const handle = (this.toolboxBaseNode.parent as TransformNode);
|
||||||
|
handle.parent = platform;
|
||||||
|
handle.position = offset;
|
||||||
|
} else {
|
||||||
|
this.scene.onNewMeshAddedObservable.add((mesh: AbstractMesh) => {
|
||||||
|
if (mesh.id == "platform") {
|
||||||
|
const handle = (this.toolboxBaseNode.parent as TransformNode);
|
||||||
|
handle.parent = mesh;
|
||||||
|
handle.position = offset;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*setMenuPosition(this.toolboxBaseNode.parent as Mesh, this.scene,
|
||||||
|
Vector3.Zero());*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,10 +1,11 @@
|
|||||||
import {MeshBuilder, Scene, Vector3} from "@babylonjs/core";
|
import {MeshBuilder, Scene, Vector3} from "@babylonjs/core";
|
||||||
|
|
||||||
const debug = false;
|
const debug = true;
|
||||||
export function getFrontPosition(distance: number, scene: Scene): Vector3 {
|
export function getFrontPosition(distance: number, scene: Scene): Vector3 {
|
||||||
const offset = new Vector3(0, 0, distance);
|
const offset = new Vector3(0, 0, distance);
|
||||||
offset.applyRotationQuaternionInPlace(scene.activeCamera.absoluteRotation);
|
//offset.applyRotationQuaternionInPlace(scene.activeCamera.absoluteRotation);
|
||||||
const newPos = scene.activeCamera.globalPosition.add(offset);
|
const camPos = scene.activeCamera.globalPosition.clone();
|
||||||
|
const newPos = camPos.add(offset);
|
||||||
if (debug) {
|
if (debug) {
|
||||||
const mesh = MeshBuilder.CreateIcoSphere("front", {radius: .1}, scene);
|
const mesh = MeshBuilder.CreateIcoSphere("front", {radius: .1}, scene);
|
||||||
mesh.position = newPos;
|
mesh.position = newPos;
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
import {Scene, TransformNode, Vector3} from "@babylonjs/core";
|
import {Scene, TransformNode, Vector3, WebXRCamera} from "@babylonjs/core";
|
||||||
import {getFrontPosition} from "./getFrontPosition";
|
|
||||||
import log from "loglevel";
|
import log from "loglevel";
|
||||||
|
|
||||||
const logger = log.getLogger('setMenuPosition');
|
const logger = log.getLogger('setMenuPosition');
|
||||||
@ -39,34 +38,33 @@ export function setMenuPosition(node: TransformNode, scene: Scene, offset: Vecto
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
if (scene.activeCamera) {
|
if (scene.activeCamera) {
|
||||||
setPosition(node, scene, offset);
|
//setPosition(node, scene, offset);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
scene.onActiveCameraChanged.add((scene: Scene) => {
|
scene.onActiveCameraChanged.add((scene: Scene) => {
|
||||||
setPosition(node, scene, offset);
|
//setPosition(node, scene, offset);
|
||||||
});
|
});
|
||||||
logger.error("No active camera");
|
logger.error("No active camera");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const debug = true;
|
const debug = false;
|
||||||
function setPosition(node: TransformNode, scene: Scene, offset: Vector3 = Vector3.Zero()) {
|
function setPosition(node: TransformNode, scene: Scene, offset: Vector3 = Vector3.Zero()) {
|
||||||
const platform = scene.getNodeById("platform");
|
const platform = scene.getNodeById("platform");
|
||||||
switch (scene.activeCamera.getClassName()) {
|
switch (scene.activeCamera.getClassName()) {
|
||||||
case "WebXRCamera":
|
case "WebXRCamera":
|
||||||
//const oldParent = node.parent;
|
//const oldParent = node.parent;
|
||||||
|
window.setTimeout(() => {
|
||||||
node.setParent(null);
|
node.setParent(null);
|
||||||
const front = getFrontPosition(1, scene).clone();
|
const camera = scene.activeCamera as WebXRCamera;
|
||||||
const camPos = scene.activeCamera.globalPosition.clone();
|
const front = camera.getFrontPosition(.7);
|
||||||
const newPos = new Vector3(front.x + offset.x, 1.2 + offset.y, front.z + offset.z);
|
const camPos = camera.globalPosition.clone();
|
||||||
node.position = newPos;
|
const newPos = new Vector3(front.x + offset.x, front.y + offset.y - .3, front.z + offset.z);
|
||||||
node.lookAt(camPos);
|
node.position = newPos;
|
||||||
// const target = MeshBuilder.CreateIcoSphere("target", {radius: .1}, scene);
|
node.lookAt(camPos);
|
||||||
// target.position = newPos;
|
node.setParent(platform);
|
||||||
// target.setParent(platform);
|
}, 1000);
|
||||||
node.setParent(platform);
|
|
||||||
break;
|
break;
|
||||||
case "FreeCamera":
|
case "FreeCamera":
|
||||||
case "DeviceOrientationCamera":
|
case "DeviceOrientationCamera":
|
||||||
|
|||||||
@ -18,6 +18,10 @@ export default defineConfig({
|
|||||||
'^/sync/.*': {
|
'^/sync/.*': {
|
||||||
target: 'https://www.deepdiagram.com/',
|
target: 'https://www.deepdiagram.com/',
|
||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
|
},
|
||||||
|
'^/create-db': {
|
||||||
|
target: 'https://www.deepdiagram.com/',
|
||||||
|
changeOrigin: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user