diff --git a/package-lock.json b/package-lock.json index 7d0026c..9332270 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1098,9 +1098,9 @@ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, "node_modules/axios": { - "version": "1.6.8", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.8.tgz", - "integrity": "sha512-v/ZHtJDU39mDpyBoFVkETcd/uNdxrWRrg3bKpOKzXFA6Bvqopts6ALSMU3y6ijYxbw2B+wPrIv46egTzJXCLGQ==", + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.5.tgz", + "integrity": "sha512-fZu86yCo+svH3uqJ/yTdQ0QHpQu5oL+/QE+QPSv6BZSkDAoky9vytxp7u5qk83OJFS3kEBcesWni9WTZAv3tSw==", "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.0", @@ -1133,12 +1133,12 @@ ] }, "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, "dependencies": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" }, "engines": { "node": ">=8" @@ -1614,9 +1614,9 @@ } }, "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, "dependencies": { "to-regex-range": "^5.0.1" @@ -2172,12 +2172,12 @@ } }, "node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, "dependencies": { - "braces": "^3.0.2", + "braces": "^3.0.3", "picomatch": "^2.3.1" }, "engines": { diff --git a/src/controllers/abstractController.ts b/src/controllers/abstractController.ts index df8548e..6de54b6 100644 --- a/src/controllers/abstractController.ts +++ b/src/controllers/abstractController.ts @@ -7,22 +7,22 @@ import { WebXRInputSource } from "@babylonjs/core"; import {DiagramManager} from "../diagram/diagramManager"; -import {DiagramEvent, DiagramEventType} from "../diagram/types/diagramEntity"; import log from "loglevel"; import {grabAndClone} from "./functions/grabAndClone"; import {ClickMenu} from "../menus/clickMenu"; -import {motionControllerObserver} from "./functions/motionControllerObserver"; +import {motionControllerInitObserver} from "./functions/motionControllerInitObserver"; import {DefaultScene} from "../defaultScene"; -import {DiagramEventObserverMask} from "../diagram/types/diagramEventObserverMask"; + import {DiagramObject} from "../diagram/diagramObject"; -import {snapAll} from "./functions/snapAll"; import {MeshTypeEnum} from "../diagram/types/meshTypeEnum"; import {getMeshType} from "./functions/getMeshType"; import {viewOnly} from "../util/functions/getPath"; import {ControllerEventType} from "./types/controllerEventType"; import {controllerObservable} from "./controllers"; +import {grabMesh} from "../diagram/functions/grabMesh"; +import {dropMesh} from "../diagram/functions/dropMesh"; const CLICK_TIME = 300; @@ -34,12 +34,13 @@ export abstract class AbstractController { protected readonly diagramManager: DiagramManager; protected xrInputSource: WebXRInputSource; protected speedFactor = 4; + protected grabbedObject: DiagramObject = null; protected grabbedMesh: AbstractMesh = null; protected grabbedMeshType: MeshTypeEnum = null; - private readonly _logger = log.getLogger('Base'); + private readonly _logger = log.getLogger('AbstractController'); private _clickStart: number = 0; private _clickMenu: ClickMenu; private _pickPoint: Vector3 = new Vector3(); @@ -67,7 +68,7 @@ export abstract class AbstractController { this.diagramManager = diagramManager; //@TODO THis works, but it uses initGrip, not sure if this is the best idea - this.xrInputSource.onMotionControllerInitObservable.add(motionControllerObserver, -1, false, this); + this.xrInputSource.onMotionControllerInitObservable.add(motionControllerInitObserver, -1, false, this); controllerObservable.add((event) => { this._logger.debug(event); switch (event.type) { @@ -143,91 +144,26 @@ export abstract class AbstractController { }, -1, false, this); } - - private grab() { - let mesh = this._meshUnderPointer - if (!mesh || viewOnly()) { - return; - } - this.grabbedMesh = mesh; - this.grabbedMeshType = getMeshType(mesh, this.diagramManager); - - //displayDebug(mesh); - this._logger.debug("grabbing " + mesh.id + " type " + this.grabbedMeshType); - switch (this.grabbedMeshType) { - case MeshTypeEnum.ENTITY: - const diagramObject = this.diagramManager.getDiagramObject(mesh.id); - if (diagramObject.isGrabbable) { - diagramObject.baseTransform.setParent(this.xrInputSource.motionController.rootMesh); - diagramObject.grabbed = true; - this.grabbedObject = diagramObject; - } - break; - case MeshTypeEnum.HANDLE: - this.grabbedMesh.setParent(this.xrInputSource.motionController.rootMesh); - break; - case MeshTypeEnum.TOOL: - const clone = grabAndClone(this.diagramManager, mesh, this.xrInputSource.motionController.rootMesh); - this.grabbedObject = clone; - this.grabbedMesh = clone.mesh; - clone.grabbed = true; - + protected notifyObserver(value: number, controllerEventType: ControllerEventType): number { + if (Math.abs(value) > .1) { + controllerObservable.notifyObservers({ + type: controllerEventType, + value: value * this.speedFactor + }); + return 1; + } else { + return 0; } } - private drop() { - const mesh = this.grabbedMesh; - if (!mesh) { - return; - } - const diagramObject = this.grabbedObject; - switch (this.grabbedMeshType) { - case MeshTypeEnum.ENTITY: - if (diagramObject) { - diagramObject.baseTransform.setParent(null); - snapAll(this.grabbedObject.baseTransform, this.diagramManager.config, this._pickPoint); - diagramObject.mesh.computeWorldMatrix(true); - const event: DiagramEvent = - { - type: DiagramEventType.DROP, - entity: diagramObject.diagramEntity - } - this.diagramManager.onDiagramEventObservable.notifyObservers(event, DiagramEventObserverMask.ALL); - diagramObject.mesh.computeWorldMatrix(false); - diagramObject.grabbed = false; + protected initButton(button: WebXRControllerComponent, type: ControllerEventType) { + if (button) { + button.onButtonStateChangedObservable.add((value) => { + if (value.pressed) { + this._logger.debug(button.type, button.id, 'pressed'); + controllerObservable.notifyObservers({type: type}); } - - this.grabbedObject = null; - this.grabbedMesh = null; - this.grabbedMeshType = null; - break; - case MeshTypeEnum.TOOL: - this.grabbedObject.baseTransform.setParent(null); - snapAll(this.grabbedObject.baseTransform, this.diagramManager.config, this._pickPoint); - diagramObject.mesh.computeWorldMatrix(true); - const event: DiagramEvent = - { - type: DiagramEventType.DROP, - entity: diagramObject.diagramEntity - } - this.diagramManager.onDiagramEventObservable.notifyObservers(event, DiagramEventObserverMask.ALL); - diagramObject.mesh.computeWorldMatrix(false); - this.grabbedObject.grabbed = false; - this.grabbedObject = null; - this.grabbedMesh = null; - this.grabbedMeshType = null; - break; - case MeshTypeEnum.HANDLE: - mesh.setParent(this.scene.getMeshByName("platform")); - const location = { - position: {x: mesh.position.x, y: mesh.position.y, z: mesh.position.z}, - rotation: {x: mesh.rotation.x, y: mesh.rotation.y, z: mesh.rotation.z} - } - localStorage.setItem(mesh.id, JSON.stringify(location)); - this.grabbedMesh = null; - this.grabbedMeshType = null; - this.grabbedObject = null; - break; + }); } } @@ -260,4 +196,27 @@ export abstract class AbstractController { } }); } + + private grab() { + if (viewOnly() || this._meshUnderPointer == null) { + return; + } + const { + grabbedMesh, + grabbedObject, + grabbedMeshType + } = grabMesh(this._meshUnderPointer, this.diagramManager, this.xrInputSource.motionController.rootMesh); + this.grabbedMesh = grabbedMesh; + this.grabbedObject = grabbedObject; + this.grabbedMeshType = grabbedMeshType; + } + + private drop() { + const dropped = dropMesh(this.grabbedMesh, this.grabbedObject, this._pickPoint, this.grabbedMeshType, this.diagramManager); + if (dropped) { + this.grabbedMesh = null; + this.grabbedObject = null; + this.grabbedMeshType = null; + } + } } \ No newline at end of file diff --git a/src/controllers/functions/motionControllerObserver.ts b/src/controllers/functions/motionControllerInitObserver.ts similarity index 87% rename from src/controllers/functions/motionControllerObserver.ts rename to src/controllers/functions/motionControllerInitObserver.ts index 38c4bec..b578017 100644 --- a/src/controllers/functions/motionControllerObserver.ts +++ b/src/controllers/functions/motionControllerInitObserver.ts @@ -1,7 +1,7 @@ import log from "loglevel"; -export function motionControllerObserver(init) { +export function motionControllerInitObserver(init) { const logger = log.getLogger('motionControllerObserver'); logger.debug(init.components); if (init.components['xr-standard-squeeze']) { diff --git a/src/controllers/leftController.ts b/src/controllers/leftController.ts index c0f6f9e..c0ba2b1 100644 --- a/src/controllers/leftController.ts +++ b/src/controllers/leftController.ts @@ -2,7 +2,6 @@ import {Vector3, WebXRControllerComponent, WebXRDefaultExperience, WebXRInputSou import {AbstractController} from "./abstractController"; import log from "loglevel"; import {DiagramManager} from "../diagram/diagramManager"; -import {DefaultScene} from "../defaultScene"; import {ControllerEventType} from "./types/controllerEventType"; import {controllerObservable, movable} from "./controllers"; @@ -12,7 +11,6 @@ export class LeftController extends AbstractController { constructor(controller: WebXRInputSource, xr: WebXRDefaultExperience, diagramManager: DiagramManager) { super(controller, xr, diagramManager); - const scene = DefaultScene.Scene; this.xrInputSource.onMotionControllerInitObservable.add((init) => { if (init.components['xr-standard-thumbstick']) { init.components['xr-standard-thumbstick'] @@ -98,30 +96,11 @@ export class LeftController extends AbstractController { } private moveRig(value: { x: number, y: number }) { - if (Math.abs(value.x) > .1) { - controllerObservable.notifyObservers({ - type: ControllerEventType.LEFT_RIGHT, - value: value.x * this.speedFactor - }); - AbstractController.stickVector.x = 1; - } else { - AbstractController.stickVector.x = 0; - } - if (Math.abs(value.y) > .1) { - controllerObservable.notifyObservers({ - type: ControllerEventType.FORWARD_BACK, - value: value.y * this.speedFactor - }); - AbstractController.stickVector.y = 1; - } else { - AbstractController.stickVector.y = 0; - } - + AbstractController.stickVector.x = this.notifyObserver(value.x, ControllerEventType.LEFT_RIGHT); + AbstractController.stickVector.y = this.notifyObserver(value.y, ControllerEventType.FORWARD_BACK); if (AbstractController.stickVector.equals(Vector3.Zero())) { controllerObservable.notifyObservers({type: ControllerEventType.LEFT_RIGHT, value: 0}); controllerObservable.notifyObservers({type: ControllerEventType.FORWARD_BACK, value: 0}); - } else { - } } -} \ No newline at end of file +} diff --git a/src/controllers/rightController.ts b/src/controllers/rightController.ts index 81cfba8..1762e31 100644 --- a/src/controllers/rightController.ts +++ b/src/controllers/rightController.ts @@ -10,19 +10,7 @@ import {controllerObservable} from "./controllers"; export class RightController extends AbstractController { private rightLogger = log.getLogger("Right"); - private initBButton(bbutton: WebXRControllerComponent) { - if (bbutton) { - bbutton.onButtonStateChangedObservable.add((button) => { - if (button.pressed) { - this.rightLogger.debug('B Button Pressed'); - controllerObservable.notifyObservers({ - type: ControllerEventType.B_BUTTON, - value: button.value - }); - } - }); - } - } + constructor(controller: WebXRInputSource, xr: WebXRDefaultExperience, diagramManager: DiagramManager @@ -31,8 +19,8 @@ export class RightController extends AbstractController { super(controller, xr, diagramManager); this.xrInputSource.onMotionControllerInitObservable.add((init) => { this.initTrigger(init.components['xr-standard-trigger']); - this.initBButton(init.components['b-button']); - this.initAButton(init.components['a-button']); + this.initButton(init.components['b-button'], ControllerEventType.B_BUTTON); + this.initButton(init.components['a-button'], ControllerEventType.MENU); this.initThumbstick(init.components['xr-standard-thumbstick']); }); } @@ -52,17 +40,6 @@ export class RightController extends AbstractController { } } - private initAButton(abutton: WebXRControllerComponent) { - if (abutton) { - abutton.onButtonStateChangedObservable.add((value) => { - if (value.pressed) { - this.rightLogger.debug('A button pressed'); - controllerObservable.notifyObservers({type: ControllerEventType.MENU}); - } - }); - } - } - private initThumbstick(thumbstick: WebXRControllerComponent) { if (thumbstick) { thumbstick.onAxisValueChangedObservable.add((value) => { @@ -87,16 +64,8 @@ export class RightController extends AbstractController { } else { controllerObservable.notifyObservers({type: ControllerEventType.TURN, value: 0}); } - if (Math.abs(value.y) > .1) { - controllerObservable.notifyObservers({ - type: ControllerEventType.UP_DOWN, - value: value.y * this.speedFactor - }); - AbstractController.stickVector.z = 1; - } else { - controllerObservable.notifyObservers({type: ControllerEventType.UP_DOWN, value: 0}); - AbstractController.stickVector.z = 0; - } + AbstractController.stickVector.z = this.notifyObserver(value.y, ControllerEventType.UP_DOWN); + if (AbstractController.stickVector.equals(Vector3.Zero())) { controllerObservable.notifyObservers({type: ControllerEventType.UP_DOWN, value: 0}); } diff --git a/src/diagram/functions/dropMesh.ts b/src/diagram/functions/dropMesh.ts new file mode 100644 index 0000000..50a1443 --- /dev/null +++ b/src/diagram/functions/dropMesh.ts @@ -0,0 +1,61 @@ +import {AbstractMesh, Vector3} from "@babylonjs/core"; +import {DiagramManager} from "../diagramManager"; +import {DiagramObject} from "../diagramObject"; +import {MeshTypeEnum} from "../types/meshTypeEnum"; +import {snapAll} from "../../controllers/functions/snapAll"; +import {DiagramEvent, DiagramEventType} from "../types/diagramEntity"; +import {DiagramEventObserverMask} from "../types/diagramEventObserverMask"; + +export function dropMesh(mesh: AbstractMesh, + grabbedObject: DiagramObject, + pickPoint: Vector3, + grabbedMeshType: MeshTypeEnum, + diagramManager: DiagramManager): boolean { + if (!mesh) { + return false; + } + let dropped = false; + const diagramObject = grabbedObject; + switch (grabbedMeshType) { + case MeshTypeEnum.ENTITY: + if (diagramObject) { + diagramObject.baseTransform.setParent(null); + snapAll(grabbedObject.baseTransform, diagramManager.config, pickPoint); + diagramObject.mesh.computeWorldMatrix(true); + const event: DiagramEvent = + { + type: DiagramEventType.DROP, + entity: diagramObject.diagramEntity + } + diagramManager.onDiagramEventObservable.notifyObservers(event, DiagramEventObserverMask.ALL); + diagramObject.mesh.computeWorldMatrix(false); + diagramObject.grabbed = false; + dropped = true; + } + break; + case MeshTypeEnum.TOOL: + grabbedObject.baseTransform.setParent(null); + snapAll(grabbedObject.baseTransform, diagramManager.config, pickPoint); + diagramObject.mesh.computeWorldMatrix(true); + const event: DiagramEvent = + { + type: DiagramEventType.DROP, + entity: diagramObject.diagramEntity + } + diagramManager.onDiagramEventObservable.notifyObservers(event, DiagramEventObserverMask.ALL); + diagramObject.mesh.computeWorldMatrix(false); + grabbedObject.grabbed = false; + dropped = true; + break; + case MeshTypeEnum.HANDLE: + mesh.setParent(this.scene.getMeshByName("platform")); + const location = { + position: {x: mesh.position.x, y: mesh.position.y, z: mesh.position.z}, + rotation: {x: mesh.rotation.x, y: mesh.rotation.y, z: mesh.rotation.z} + } + localStorage.setItem(mesh.id, JSON.stringify(location)); + dropped = true; + break; + } + return dropped; +} \ No newline at end of file diff --git a/src/diagram/functions/grabMesh.ts b/src/diagram/functions/grabMesh.ts new file mode 100644 index 0000000..007904a --- /dev/null +++ b/src/diagram/functions/grabMesh.ts @@ -0,0 +1,40 @@ +import {viewOnly} from "../../util/functions/getPath"; +import {getMeshType} from "../../controllers/functions/getMeshType"; +import {MeshTypeEnum} from "../types/meshTypeEnum"; +import {grabAndClone} from "../../controllers/functions/grabAndClone"; +import {AbstractMesh} from "@babylonjs/core"; +import log from "loglevel"; +import {DiagramManager} from "../diagramManager"; +import {DiagramObject} from "../diagramObject"; + +export function grabMesh(mesh: AbstractMesh, diagramManager: DiagramManager, controllerMesh: AbstractMesh): + { grabbedMesh: AbstractMesh | null, grabbedObject: DiagramObject | null, grabbedMeshType: MeshTypeEnum | null } { + const logger = log.getLogger('grabMesh'); + if (!mesh || viewOnly()) { + return {grabbedMesh: null, grabbedObject: null, grabbedMeshType: null}; + } + let grabbedMesh = mesh; + let grabbedObject: DiagramObject | null = null; + let grabbedMeshType = getMeshType(mesh, diagramManager); + //displayDebug(mesh); + logger.debug("grabbing " + mesh.id + " type " + grabbedMeshType); + switch (grabbedMeshType) { + case MeshTypeEnum.ENTITY: + const diagramObject = diagramManager.getDiagramObject(mesh.id); + if (diagramObject.isGrabbable) { + diagramObject.baseTransform.setParent(controllerMesh); + diagramObject.grabbed = true; + grabbedObject = diagramObject; + } + break; + case MeshTypeEnum.HANDLE: + grabbedMesh.setParent(controllerMesh); + break; + case MeshTypeEnum.TOOL: + const clone = grabAndClone(diagramManager, mesh, controllerMesh); + grabbedObject = clone; + grabbedMesh = clone.mesh; + clone.grabbed = true; + } + return {grabbedMesh, grabbedObject, grabbedMeshType}; +} \ No newline at end of file diff --git a/src/integration/database/pouchdbPersistenceManager.ts b/src/integration/database/pouchdbPersistenceManager.ts index 2063292..889b8af 100644 --- a/src/integration/database/pouchdbPersistenceManager.ts +++ b/src/integration/database/pouchdbPersistenceManager.ts @@ -132,6 +132,7 @@ export class PouchdbPersistenceManager { this._logger.error('no image data', entity); return; } + if (this._encKey && !this._encryption.ready) { await this._encryption.setPassword(this._encKey); }