Refactored diagram manager and loggers.
This commit is contained in:
parent
fc588c5dbe
commit
d87d8bace4
23
src/app.ts
23
src/app.ts
@ -25,7 +25,8 @@ import {DiagramManager} from "./diagram/diagramManager";
|
|||||||
import {Toolbox} from "./toolbox/toolbox";
|
import {Toolbox} from "./toolbox/toolbox";
|
||||||
import {DualshockEventMapper} from "./util/dualshockEventMapper";
|
import {DualshockEventMapper} from "./util/dualshockEventMapper";
|
||||||
import log from "loglevel";
|
import log from "loglevel";
|
||||||
|
import {AppConfig} from "./util/appConfig";
|
||||||
|
import {IndexdbPersistenceManager} from "./diagram/indexdbPersistenceManager";
|
||||||
|
|
||||||
export class App {
|
export class App {
|
||||||
//preTasks = [havokModule];
|
//preTasks = [havokModule];
|
||||||
@ -35,6 +36,8 @@ export class App {
|
|||||||
private rig: Rigplatform;
|
private rig: Rigplatform;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
|
const config = AppConfig.config;
|
||||||
|
|
||||||
log.setLevel('debug');
|
log.setLevel('debug');
|
||||||
const canvas = document.createElement("canvas");
|
const canvas = document.createElement("canvas");
|
||||||
canvas.style.width = "100%";
|
canvas.style.width = "100%";
|
||||||
@ -56,10 +59,6 @@ export class App {
|
|||||||
this.scene.dispose();
|
this.scene.dispose();
|
||||||
this.scene = null;
|
this.scene = null;
|
||||||
}
|
}
|
||||||
if (DiagramManager.onDiagramEventObservable) {
|
|
||||||
DiagramManager.onDiagramEventObservable.clear();
|
|
||||||
DiagramManager.onDiagramEventObservable = null;
|
|
||||||
}
|
|
||||||
const engine = new Engine(canvas, true);
|
const engine = new Engine(canvas, true);
|
||||||
const scene = new Scene(engine);
|
const scene = new Scene(engine);
|
||||||
|
|
||||||
@ -106,10 +105,14 @@ export class App {
|
|||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
const persistenceManager = new IndexdbPersistenceManager("diagram");
|
||||||
const diagramManager = new DiagramManager(this.scene, this.xr.baseExperience);
|
const diagramManager = new DiagramManager(this.scene, this.xr.baseExperience);
|
||||||
this.rig = new Rigplatform(this.scene, this.xr);
|
diagramManager.setPersistenceManager(persistenceManager);
|
||||||
const toolbox = new Toolbox(scene, this.xr.baseExperience);
|
AppConfig.config.setPersistenceManager(persistenceManager);
|
||||||
|
|
||||||
|
|
||||||
|
this.rig = new Rigplatform(this.scene, this.xr, diagramManager);
|
||||||
|
const toolbox = new Toolbox(scene, this.xr.baseExperience, diagramManager);
|
||||||
|
|
||||||
this.scene.gamepadManager.onGamepadConnectedObservable.add((gamepad) => {
|
this.scene.gamepadManager.onGamepadConnectedObservable.add((gamepad) => {
|
||||||
try {
|
try {
|
||||||
@ -119,7 +122,7 @@ export class App {
|
|||||||
const buttonEvent = DualshockEventMapper.mapButtonEvent(button, 1);
|
const buttonEvent = DualshockEventMapper.mapButtonEvent(button, 1);
|
||||||
if (buttonEvent.objectName) {
|
if (buttonEvent.objectName) {
|
||||||
window.dispatchEvent(new CustomEvent('pa-button-state-change', {
|
window.dispatchEvent(new CustomEvent('pa-button-state-change', {
|
||||||
detail: buttonEvent
|
detail: buttonEvent
|
||||||
}
|
}
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@ -187,7 +190,7 @@ export class App {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
log.info('App', 'keydown event listener added, use Ctrl+Shift+Alt+I to toggle debug layer');
|
log.info('App', 'keydown event listener added, use Ctrl+Shift+Alt+I to toggle debug layer');
|
||||||
|
persistenceManager.initialize();
|
||||||
engine.runRenderLoop(() => {
|
engine.runRenderLoop(() => {
|
||||||
scene.render();
|
scene.render();
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
import {
|
import {
|
||||||
AbstractMesh,
|
AbstractMesh,
|
||||||
Angle,
|
|
||||||
InstancedMesh,
|
InstancedMesh,
|
||||||
Mesh,
|
Mesh,
|
||||||
Scene,
|
Scene,
|
||||||
@ -14,7 +13,6 @@ import {DiagramManager} from "../diagram/diagramManager";
|
|||||||
import {DiagramEvent, DiagramEventType} from "../diagram/diagramEntity";
|
import {DiagramEvent, DiagramEventType} from "../diagram/diagramEntity";
|
||||||
import log from "loglevel";
|
import log from "loglevel";
|
||||||
import {AppConfig} from "../util/appConfig";
|
import {AppConfig} from "../util/appConfig";
|
||||||
import round from "round";
|
|
||||||
|
|
||||||
|
|
||||||
export class Base {
|
export class Base {
|
||||||
@ -29,12 +27,16 @@ export class Base {
|
|||||||
protected previousPosition: Vector3 = null;
|
protected previousPosition: Vector3 = null;
|
||||||
|
|
||||||
protected readonly xr: WebXRDefaultExperience;
|
protected readonly xr: WebXRDefaultExperience;
|
||||||
|
protected readonly diagramManager: DiagramManager;
|
||||||
|
|
||||||
constructor(controller: WebXRInputSource, scene: Scene, xr: WebXRDefaultExperience) {
|
constructor(controller: WebXRInputSource,
|
||||||
|
scene: Scene,
|
||||||
|
xr: WebXRDefaultExperience,
|
||||||
|
diagramManager: DiagramManager) {
|
||||||
this.controller = controller;
|
this.controller = controller;
|
||||||
this.scene = scene;
|
this.scene = scene;
|
||||||
this.xr = xr;
|
this.xr = xr;
|
||||||
|
this.diagramManager = diagramManager;
|
||||||
this.controller.onMotionControllerInitObservable.add((init) => {
|
this.controller.onMotionControllerInitObservable.add((init) => {
|
||||||
if (init.components['xr-standard-trigger']) {
|
if (init.components['xr-standard-trigger']) {
|
||||||
init.components['xr-standard-trigger']
|
init.components['xr-standard-trigger']
|
||||||
@ -66,35 +68,6 @@ export class Base {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static snapRotation(rotation): Vector3 {
|
|
||||||
const config = AppConfig.config;
|
|
||||||
if (config.rotateSnap == 0) {
|
|
||||||
return rotation;
|
|
||||||
}
|
|
||||||
rotation.x = this.CalcToSnap(rotation.x, config.rotateSnap);
|
|
||||||
rotation.y = this.CalcToSnap(rotation.y, config.rotateSnap);
|
|
||||||
rotation.z = this.CalcToSnap(rotation.z, config.rotateSnap);
|
|
||||||
return rotation;
|
|
||||||
}
|
|
||||||
|
|
||||||
static snapPosition(position): Vector3 {
|
|
||||||
const config = AppConfig.config;
|
|
||||||
if (config.gridSnap == 0) {
|
|
||||||
return position;
|
|
||||||
}
|
|
||||||
position.x = round(position.x, config.gridSnap);
|
|
||||||
position.y = round(position.y, config.gridSnap);
|
|
||||||
position.z = round(position.z, config.gridSnap);
|
|
||||||
return position;
|
|
||||||
}
|
|
||||||
|
|
||||||
static CalcToSnap(val, snap) {
|
|
||||||
const deg = Angle.FromRadians(val).degrees();
|
|
||||||
const snappedDegrees = round(deg, snap);
|
|
||||||
log.getLogger('Base').debug("deg", val, deg, snappedDegrees, snap);
|
|
||||||
return Angle.FromDegrees(snappedDegrees).radians();
|
|
||||||
}
|
|
||||||
|
|
||||||
private initGrip(grip: WebXRControllerComponent) {
|
private initGrip(grip: WebXRControllerComponent) {
|
||||||
grip.onButtonStateChangedObservable.add(() => {
|
grip.onButtonStateChangedObservable.add(() => {
|
||||||
if (grip.changes.pressed) {
|
if (grip.changes.pressed) {
|
||||||
@ -124,10 +97,11 @@ export class Base {
|
|||||||
mesh && mesh.setParent(this.controller.motionController.rootMesh);
|
mesh && mesh.setParent(this.controller.motionController.rootMesh);
|
||||||
this.grabbedMesh = mesh;
|
this.grabbedMesh = mesh;
|
||||||
} else {
|
} else {
|
||||||
|
const config = AppConfig.config;
|
||||||
const newMesh = this.createCopy(mesh);
|
const newMesh = this.createCopy(mesh);
|
||||||
newMesh.position = mesh.absolutePosition.clone();
|
newMesh.position = mesh.absolutePosition.clone();
|
||||||
newMesh.rotation = mesh.absoluteRotationQuaternion.toEulerAngles().clone();
|
newMesh.rotation = mesh.absoluteRotationQuaternion.toEulerAngles().clone();
|
||||||
newMesh.scaling = mesh.absoluteScaling.clone();
|
newMesh.scaling = config.createSnapVal;
|
||||||
newMesh.material = mesh.material;
|
newMesh.material = mesh.material;
|
||||||
newMesh.metadata = mesh.metadata;
|
newMesh.metadata = mesh.metadata;
|
||||||
newMesh && newMesh.setParent(this.controller.motionController.rootMesh);
|
newMesh && newMesh.setParent(this.controller.motionController.rootMesh);
|
||||||
@ -156,15 +130,19 @@ export class Base {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const snappedRotation = Base.snapRotation(mesh.absoluteRotationQuaternion.toEulerAngles().clone());
|
const config = AppConfig.config;
|
||||||
const snappedPosition = Base.snapPosition(mesh.absolutePosition.clone());
|
const snappedRotation = config.snapRotateVal(mesh.absoluteRotationQuaternion.toEulerAngles().clone());
|
||||||
|
const snappedPosition = config.snapGridVal(mesh.absolutePosition.clone());
|
||||||
if (this.previousParent) {
|
if (this.previousParent) {
|
||||||
const p = this.scene.getMeshById(this.previousParent);
|
const p = this.scene.getMeshById(this.previousParent);
|
||||||
if (p) {
|
if (p) {
|
||||||
mesh && mesh.setParent(this.scene.getMeshById(this.previousParent));
|
mesh && mesh.setParent(this.scene.getMeshById(this.previousParent));
|
||||||
|
log.getLogger("Base").warn("Base", "Have not implemented snapping to parent yet");
|
||||||
|
//@note: this is not implemented yet
|
||||||
} else {
|
} else {
|
||||||
mesh && mesh.setParent(null);
|
mesh && mesh.setParent(null);
|
||||||
|
mesh.rotation = snappedRotation;
|
||||||
|
mesh.position = snappedPosition;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
mesh && mesh.setParent(null);
|
mesh && mesh.setParent(null);
|
||||||
@ -180,7 +158,7 @@ export class Base {
|
|||||||
this.previousScaling = null;
|
this.previousScaling = null;
|
||||||
this.previousRotation = null;
|
this.previousRotation = null;
|
||||||
this.previousPosition = null;
|
this.previousPosition = null;
|
||||||
DiagramManager.onDiagramEventObservable.notifyObservers(event);
|
this.diagramManager.onDiagramEventObservable.notifyObservers(event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,7 +1,8 @@
|
|||||||
import {AbstractMesh, Observable, TransformNode} from "@babylonjs/core";
|
import {AbstractMesh, Observable, TransformNode} from "@babylonjs/core";
|
||||||
|
|
||||||
export type ControllerEventType = {
|
export type ControllerEventType = {
|
||||||
type: string
|
type: string,
|
||||||
|
value?: number
|
||||||
}
|
}
|
||||||
export class Controllers {
|
export class Controllers {
|
||||||
public static movable: TransformNode | AbstractMesh;
|
public static movable: TransformNode | AbstractMesh;
|
||||||
|
|||||||
@ -3,15 +3,17 @@ import {Base} from "./base";
|
|||||||
import {Controllers} from "./controllers";
|
import {Controllers} from "./controllers";
|
||||||
import log from "loglevel";
|
import log from "loglevel";
|
||||||
import {ConfigMenu} from "../menus/configMenu";
|
import {ConfigMenu} from "../menus/configMenu";
|
||||||
|
import {DiagramManager} from "../diagram/diagramManager";
|
||||||
|
|
||||||
|
|
||||||
export class Left extends Base {
|
export class Left extends Base {
|
||||||
public static instance: Left;
|
public static instance: Left;
|
||||||
public configMenu: ConfigMenu;
|
public configMenu: ConfigMenu;
|
||||||
constructor(controller:
|
|
||||||
WebXRInputSource, scene: Scene, xr: WebXRDefaultExperience) {
|
|
||||||
|
|
||||||
super(controller, scene, xr);
|
constructor(controller:
|
||||||
|
WebXRInputSource, scene: Scene, xr: WebXRDefaultExperience, diagramManager: DiagramManager) {
|
||||||
|
|
||||||
|
super(controller, scene, xr, diagramManager);
|
||||||
this.configMenu = new ConfigMenu(this.scene, xr.baseExperience);
|
this.configMenu = new ConfigMenu(this.scene, xr.baseExperience);
|
||||||
Left.instance = this;
|
Left.instance = this;
|
||||||
this.controller.onMotionControllerInitObservable.add((init) => {
|
this.controller.onMotionControllerInitObservable.add((init) => {
|
||||||
|
|||||||
@ -2,13 +2,15 @@ import {Base} from "./base";
|
|||||||
import {Scene, Vector3, WebXRControllerComponent, WebXRDefaultExperience, WebXRInputSource} from "@babylonjs/core";
|
import {Scene, Vector3, WebXRControllerComponent, WebXRDefaultExperience, WebXRInputSource} from "@babylonjs/core";
|
||||||
import {Controllers} from "./controllers";
|
import {Controllers} from "./controllers";
|
||||||
import log from "loglevel";
|
import log from "loglevel";
|
||||||
|
import {DiagramManager} from "../diagram/diagramManager";
|
||||||
|
|
||||||
export class Right extends Base {
|
export class Right extends Base {
|
||||||
public static instance: Right;
|
public static instance: Right;
|
||||||
|
|
||||||
constructor(controller:
|
constructor(controller:
|
||||||
WebXRInputSource, scene: Scene, xr: WebXRDefaultExperience) {
|
WebXRInputSource, scene: Scene, xr: WebXRDefaultExperience, diagramManager: DiagramManager
|
||||||
super(controller, scene, xr);
|
) {
|
||||||
|
super(controller, scene, xr, diagramManager);
|
||||||
Right.instance = this;
|
Right.instance = this;
|
||||||
this.controller.onMotionControllerInitObservable.add((init) => {
|
this.controller.onMotionControllerInitObservable.add((init) => {
|
||||||
this.initTrigger(init.components['xr-standard-trigger']);
|
this.initTrigger(init.components['xr-standard-trigger']);
|
||||||
|
|||||||
@ -19,6 +19,7 @@ import {Left} from "./left";
|
|||||||
import {EditMenu} from "../menus/editMenu";
|
import {EditMenu} from "../menus/editMenu";
|
||||||
import {Controllers} from "./controllers";
|
import {Controllers} from "./controllers";
|
||||||
import log from "loglevel";
|
import log from "loglevel";
|
||||||
|
import {DiagramManager} from "../diagram/diagramManager";
|
||||||
|
|
||||||
|
|
||||||
export class Rigplatform {
|
export class Rigplatform {
|
||||||
@ -34,13 +35,15 @@ export class Rigplatform {
|
|||||||
private camera: Camera;
|
private camera: Camera;
|
||||||
private turning: boolean = false;
|
private turning: boolean = false;
|
||||||
private velocity: Vector3 = Vector3.Zero();
|
private velocity: Vector3 = Vector3.Zero();
|
||||||
|
private readonly diagramManager: DiagramManager;
|
||||||
|
|
||||||
constructor(scene: Scene, xr: WebXRDefaultExperience) {
|
constructor(scene: Scene, xr: WebXRDefaultExperience, diagramManager: DiagramManager) {
|
||||||
|
|
||||||
this.scene = scene;
|
this.scene = scene;
|
||||||
|
this.diagramManager = diagramManager;
|
||||||
Rigplatform.xr = xr;
|
Rigplatform.xr = xr;
|
||||||
Rigplatform.instance = this;
|
Rigplatform.instance = this;
|
||||||
this.bMenu = new EditMenu(scene, xr.baseExperience);
|
this.bMenu = new EditMenu(scene, xr.baseExperience, this.diagramManager);
|
||||||
this.camera = scene.activeCamera;
|
this.camera = scene.activeCamera;
|
||||||
|
|
||||||
this.rigMesh = MeshBuilder.CreateBox("platform", {width: 2, height: .02, depth: 2}, scene);
|
this.rigMesh = MeshBuilder.CreateBox("platform", {width: 2, height: .02, depth: 2}, scene);
|
||||||
@ -111,11 +114,11 @@ export class Rigplatform {
|
|||||||
let controller;
|
let controller;
|
||||||
switch (source.inputSource.handedness) {
|
switch (source.inputSource.handedness) {
|
||||||
case "right":
|
case "right":
|
||||||
Right.instance = new Right(source, this.scene, Rigplatform.xr);
|
Right.instance = new Right(source, this.scene, Rigplatform.xr, this.diagramManager);
|
||||||
Controllers.controllerObserver.add((event: { type: string, value: number }) => {
|
Controllers.controllerObserver.add((event: { type: string, value: number }) => {
|
||||||
switch (event.type) {
|
switch (event.type) {
|
||||||
case "increaseVelocity":
|
case "increaseVelocity":
|
||||||
if (this.velocityIndex < this.velocityArray.length -1) {
|
if (this.velocityIndex < this.velocityArray.length - 1) {
|
||||||
this.velocityIndex++;
|
this.velocityIndex++;
|
||||||
} else {
|
} else {
|
||||||
this.velocityIndex = 0;
|
this.velocityIndex = 0;
|
||||||
@ -150,7 +153,7 @@ export class Rigplatform {
|
|||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
case "left":
|
case "left":
|
||||||
Left.instance = new Left(source, this.scene, Rigplatform.xr);
|
Left.instance = new Left(source, this.scene, Rigplatform.xr, this.diagramManager);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,41 +1,42 @@
|
|||||||
import {Observable, Scene, WebXRExperienceHelper} from "@babylonjs/core";
|
import {Observable, Scene, WebXRExperienceHelper} from "@babylonjs/core";
|
||||||
|
|
||||||
import {DiagramEntity, DiagramEvent, DiagramEventType} from "./diagramEntity";
|
import {DiagramEntity, DiagramEvent, DiagramEventType} from "./diagramEntity";
|
||||||
import {IPersistenceManager} from "./persistenceManager";
|
import {IPersistenceManager} from "./persistenceManager";
|
||||||
import {IndexdbPersistenceManager} from "./indexdbPersistenceManager";
|
|
||||||
import {MeshConverter} from "./meshConverter";
|
import {MeshConverter} from "./meshConverter";
|
||||||
import log from "loglevel";
|
import log from "loglevel";
|
||||||
|
|
||||||
export class DiagramManager {
|
export class DiagramManager {
|
||||||
private persistenceManager: IPersistenceManager = new IndexdbPersistenceManager("diagram");
|
public readonly onDiagramEventObservable: Observable<DiagramEvent> = new Observable();
|
||||||
static onDiagramEventObservable: Observable<DiagramEvent> = new Observable();
|
private readonly logger = log.getLogger('DiagramManager');
|
||||||
|
private persistenceManager: IPersistenceManager = null;
|
||||||
private readonly scene: Scene;
|
private readonly scene: Scene;
|
||||||
private xr: WebXRExperienceHelper;
|
private xr: WebXRExperienceHelper;
|
||||||
|
|
||||||
constructor(scene: Scene, xr: WebXRExperienceHelper) {
|
constructor(scene: Scene, xr: WebXRExperienceHelper) {
|
||||||
this.scene = scene;
|
this.scene = scene;
|
||||||
this.xr = xr;
|
this.xr = xr;
|
||||||
this.persistenceManager.updateObserver.add(this.onRemoteEvent, -1, true, this);
|
if (this.onDiagramEventObservable.hasObservers()) {
|
||||||
log.getLogger('DiagramManager').debug( "remote event observer added");
|
this.logger.warn("onDiagramEventObservable already has Observers, you should be careful");
|
||||||
this.persistenceManager.initialize();
|
|
||||||
|
|
||||||
if (!DiagramManager.onDiagramEventObservable) {
|
|
||||||
log.getLogger('DiagramManager').debug( "onDiagramEventObservable missing, recreated");
|
|
||||||
DiagramManager.onDiagramEventObservable = new Observable();
|
|
||||||
}
|
}
|
||||||
if (DiagramManager.onDiagramEventObservable.hasObservers()) {
|
this.onDiagramEventObservable.add(this.onDiagramEvent, -1, true, this);
|
||||||
log.getLogger('DiagramManager').debug("onDiagramEventObservable already has Observers, this shouldn't happen");
|
this.logger.debug("DiagramManager constructed");
|
||||||
} else {
|
|
||||||
DiagramManager.onDiagramEventObservable.add(this.onDiagramEvent, -1, true, this);
|
|
||||||
log.getLogger('DiagramManager').debug( "onDiagramEventObservable Observer added");
|
|
||||||
}
|
|
||||||
log.getLogger('DiagramManager').debug( "DiagramManager constructed");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public setPersistenceManager(persistenceManager: IPersistenceManager) {
|
||||||
|
this.persistenceManager = persistenceManager;
|
||||||
|
this.persistenceManager.updateObserver.add(this.onRemoteEvent, -1, true, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private getPersistenceManager(): IPersistenceManager {
|
||||||
|
if (!this.persistenceManager) {
|
||||||
|
this.logger.warn("persistenceManager not set");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return this.persistenceManager;
|
||||||
|
}
|
||||||
|
|
||||||
private onRemoteEvent(event: DiagramEntity) {
|
private onRemoteEvent(event: DiagramEntity) {
|
||||||
//const mesh = Toolbox.instance.newMesh(ToolType[Object.entries(ToolType).find(e => e[1] == event.template)[0]], event.id);
|
//const mesh = Toolbox.instance.newMesh(ToolType[Object.entries(ToolType).find(e => e[1] == event.template)[0]], event.id);
|
||||||
log.getLogger('DiagramManager').debug(event);
|
this.logger.debug(event);
|
||||||
const mesh = MeshConverter.fromDiagramEntity(event, this.scene);
|
const mesh = MeshConverter.fromDiagramEntity(event, this.scene);
|
||||||
if (event.parent) {
|
if (event.parent) {
|
||||||
mesh.parent = this.scene.getMeshById(event.parent);
|
mesh.parent = this.scene.getMeshById(event.parent);
|
||||||
@ -43,7 +44,7 @@ export class DiagramManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private onDiagramEvent(event: DiagramEvent) {
|
private onDiagramEvent(event: DiagramEvent) {
|
||||||
log.getLogger("DiagramManager").debug(event);
|
this.logger.debug(event.type);
|
||||||
const entity = event.entity;
|
const entity = event.entity;
|
||||||
let mesh;
|
let mesh;
|
||||||
if (entity) {
|
if (entity) {
|
||||||
@ -55,19 +56,19 @@ export class DiagramManager {
|
|||||||
case DiagramEventType.DROPPED:
|
case DiagramEventType.DROPPED:
|
||||||
break;
|
break;
|
||||||
case DiagramEventType.DROP:
|
case DiagramEventType.DROP:
|
||||||
this.persistenceManager.add(mesh);
|
this.getPersistenceManager()?.add(mesh)
|
||||||
break;
|
break;
|
||||||
case DiagramEventType.ADD:
|
case DiagramEventType.ADD:
|
||||||
break;
|
break;
|
||||||
case DiagramEventType.MODIFY:
|
case DiagramEventType.MODIFY:
|
||||||
this.persistenceManager.modify(mesh);
|
this.getPersistenceManager()?.modify(mesh)
|
||||||
break;
|
break;
|
||||||
case DiagramEventType.CHANGECOLOR:
|
case DiagramEventType.CHANGECOLOR:
|
||||||
this.persistenceManager.changeColor(event.oldColor, event.newColor);
|
this.getPersistenceManager()?.changeColor(event.oldColor, event.newColor);
|
||||||
break;
|
break;
|
||||||
case DiagramEventType.REMOVE:
|
case DiagramEventType.REMOVE:
|
||||||
if (mesh) {
|
if (mesh) {
|
||||||
this.persistenceManager.remove(mesh);
|
this.getPersistenceManager()?.remove(mesh)
|
||||||
mesh.dispose();
|
mesh.dispose();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|||||||
@ -6,16 +6,18 @@ import {MeshConverter} from "./meshConverter";
|
|||||||
import log from "loglevel";
|
import log from "loglevel";
|
||||||
|
|
||||||
export class IndexdbPersistenceManager implements IPersistenceManager {
|
export class IndexdbPersistenceManager implements IPersistenceManager {
|
||||||
|
private readonly logger = log.getLogger('IndexdbPersistenceManager');
|
||||||
public updateObserver: Observable<DiagramEntity> = new Observable<DiagramEntity>();
|
public updateObserver: Observable<DiagramEntity> = new Observable<DiagramEntity>();
|
||||||
private db: Dexie;
|
private db: Dexie;
|
||||||
constructor(name: string) {
|
constructor(name: string) {
|
||||||
this.db = new Dexie(name);
|
this.db = new Dexie(name);
|
||||||
this.db.version(1).stores({entities: "id,position,rotation,last_seen,template,text,scale,color"});
|
this.db.version(1).stores({entities: "id,position,rotation,last_seen,template,text,scale,color"});
|
||||||
log.debug('IndexdbPersistenceManager', "IndexdbPersistenceManager constructed");
|
this.logger.debug("IndexdbPersistenceManager constructed");
|
||||||
|
|
||||||
}
|
}
|
||||||
public add(mesh: AbstractMesh) {
|
public add(mesh: AbstractMesh) {
|
||||||
if (!mesh) {
|
if (!mesh) {
|
||||||
log.warn('IndexdbPersistenceManager', "Adding null mesh");
|
this.logger.error("Adding null mesh, early return");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const entity = <any>MeshConverter.toDiagramEntity(mesh);
|
const entity = <any>MeshConverter.toDiagramEntity(mesh);
|
||||||
@ -24,36 +26,54 @@ export class IndexdbPersistenceManager implements IPersistenceManager {
|
|||||||
entity.scale = this.vectoxys(mesh.scaling);
|
entity.scale = this.vectoxys(mesh.scaling);
|
||||||
|
|
||||||
this.db["entities"].add(entity);
|
this.db["entities"].add(entity);
|
||||||
}
|
this.logger.debug('add', mesh, entity);
|
||||||
private vectoxys(v: Vector3): {x, y ,z} {
|
|
||||||
return {x: v.x, y: v.y, z: v.z};
|
|
||||||
}
|
|
||||||
private xyztovec(xyz: {x, y, z}): Vector3 {
|
|
||||||
return new Vector3(xyz.x, xyz.y, xyz.z);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public remove(mesh: AbstractMesh) {
|
public remove(mesh: AbstractMesh) {
|
||||||
this.db["entities"].delete(mesh.id);
|
this.db["entities"].delete(mesh.id);
|
||||||
}
|
}
|
||||||
public modify(mesh) {
|
|
||||||
|
public getConfig(): any {
|
||||||
|
this.logger.warn('getConfig not implemented');
|
||||||
|
//@todo implement
|
||||||
|
}
|
||||||
|
|
||||||
|
public setConfig(config: any) {
|
||||||
|
this.logger.warn('setConfig not implemented, value not persisted', config);
|
||||||
|
//@todo implement
|
||||||
|
}
|
||||||
|
|
||||||
|
public modify(mesh) {
|
||||||
const entity = <any>MeshConverter.toDiagramEntity(mesh);
|
const entity = <any>MeshConverter.toDiagramEntity(mesh);
|
||||||
entity.position = this.vectoxys(mesh.position);
|
entity.position = this.vectoxys(mesh.position);
|
||||||
entity.rotation = this.vectoxys(mesh.rotation);
|
entity.rotation = this.vectoxys(mesh.rotation);
|
||||||
entity.scale = this.vectoxys(mesh.scaling);
|
entity.scale = this.vectoxys(mesh.scaling);
|
||||||
this.db["entities"].update(mesh.id, entity);
|
this.db["entities"].update(mesh.id, entity);
|
||||||
|
this.logger.debug('modify', mesh, entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
public initialize() {
|
public initialize() {
|
||||||
|
this.logger.info('initialize', this.db['entities'].length);
|
||||||
this.db['entities'].each((e) => {
|
this.db['entities'].each((e) => {
|
||||||
e.position = this.xyztovec(e.position);
|
e.position = this.xyztovec(e.position);
|
||||||
e.rotation = this.xyztovec(e.rotation);
|
e.rotation = this.xyztovec(e.rotation);
|
||||||
e.scale = this.xyztovec(e.scale);
|
e.scale = this.xyztovec(e.scale);
|
||||||
log.debug('IndexdbPersistenceManager', 'adding', e);
|
this.logger.debug('adding', e);
|
||||||
this.updateObserver.notifyObservers(e);
|
this.updateObserver.notifyObservers(e);
|
||||||
});
|
});
|
||||||
log.warn('IndexdbPersistenceManager', "initialize finished");
|
this.logger.info("initialize finished");
|
||||||
}
|
}
|
||||||
|
|
||||||
public changeColor(oldColor, newColor) {
|
public changeColor(oldColor, newColor) {
|
||||||
log.debug('IndexdbPersistenceManager', `changeColor ${oldColor.toHexString()} to ${newColor.toHexString()}`);
|
this.logger.debug(`changeColor ${oldColor.toHexString()} to ${newColor.toHexString()}`);
|
||||||
this.db['entities'].where('color').equals(oldColor.toHexString()).modify({color: newColor.toHexString()});
|
this.db['entities'].where('color').equals(oldColor.toHexString()).modify({color: newColor.toHexString()});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private vectoxys(v: Vector3): { x, y, z } {
|
||||||
|
return {x: v.x, y: v.y, z: v.z};
|
||||||
|
}
|
||||||
|
|
||||||
|
private xyztovec(xyz: { x, y, z }): Vector3 {
|
||||||
|
return new Vector3(xyz.x, xyz.y, xyz.z);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -1,12 +1,22 @@
|
|||||||
import {AbstractMesh, Color3, Observable} from "@babylonjs/core";
|
import {AbstractMesh, Color3, Observable} from "@babylonjs/core";
|
||||||
import {DiagramEntity} from "./diagramEntity";
|
import {DiagramEntity} from "./diagramEntity";
|
||||||
|
import {AppConfigType} from "../util/appConfig";
|
||||||
|
|
||||||
export interface IPersistenceManager {
|
export interface IPersistenceManager {
|
||||||
add(mesh: AbstractMesh);
|
add(mesh: AbstractMesh);
|
||||||
|
|
||||||
remove(mesh: AbstractMesh);
|
remove(mesh: AbstractMesh);
|
||||||
|
|
||||||
modify(mesh: AbstractMesh);
|
modify(mesh: AbstractMesh);
|
||||||
|
|
||||||
initialize();
|
initialize();
|
||||||
|
|
||||||
|
getConfig(): AppConfigType;
|
||||||
|
|
||||||
|
setConfig(config: AppConfigType);
|
||||||
|
|
||||||
changeColor(oldColor: Color3, newColor: Color3)
|
changeColor(oldColor: Color3, newColor: Color3)
|
||||||
|
|
||||||
updateObserver: Observable<DiagramEntity>;
|
updateObserver: Observable<DiagramEntity>;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import {AdvancedDynamicTexture, InputText} from "@babylonjs/gui";
|
|||||||
|
|
||||||
export class InputTextView {
|
export class InputTextView {
|
||||||
private mesh: AbstractMesh;
|
private mesh: AbstractMesh;
|
||||||
private scene: Scene;
|
private readonly scene: Scene;
|
||||||
private xr: WebXRExperienceHelper;
|
private xr: WebXRExperienceHelper;
|
||||||
private inputPlane: AbstractMesh;
|
private inputPlane: AbstractMesh;
|
||||||
private inputText: InputText;
|
private inputText: InputText;
|
||||||
|
|||||||
@ -38,30 +38,52 @@ export class ConfigMenu {
|
|||||||
selectionPanel.fontSize = "24px";
|
selectionPanel.fontSize = "24px";
|
||||||
selectionPanel.height = "100%";
|
selectionPanel.height = "100%";
|
||||||
configTexture.addControl(selectionPanel)
|
configTexture.addControl(selectionPanel)
|
||||||
const radio1 = new RadioGroup("Rotation Snap");
|
selectionPanel.addGroup(this.buildGridSizeControl());
|
||||||
radio1.addRadio("Off", this.rotateVal);
|
selectionPanel.addGroup(this.buildRotationSnapControl());
|
||||||
radio1.addRadio("22.5 degrees", this.rotateVal);
|
selectionPanel.addGroup(this.buildCreateScaleControl());
|
||||||
radio1.addRadio("45 degrees", this.rotateVal);
|
|
||||||
radio1.addRadio("90 degrees", this.rotateVal);
|
|
||||||
selectionPanel.addGroup(radio1);
|
|
||||||
const radio2 = new RadioGroup("Grid Snap");
|
|
||||||
radio2.addRadio("Off", this.gridVal);
|
|
||||||
radio2.addRadio("1 cm", this.gridVal);
|
|
||||||
radio2.addRadio("10 cm", this.gridVal);
|
|
||||||
radio2.addRadio("25 cm", this.gridVal);
|
|
||||||
selectionPanel.addGroup(radio1);
|
|
||||||
selectionPanel.addGroup(radio2);
|
|
||||||
this.configPlane.position = CameraHelper.getFrontPosition(2, this.scene);
|
this.configPlane.position = CameraHelper.getFrontPosition(2, this.scene);
|
||||||
this.configPlane.rotation.y = Angle.FromDegrees(180).radians();
|
this.configPlane.rotation.y = Angle.FromDegrees(180).radians();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private createVal(value) {
|
||||||
|
AppConfig.config.currentCreateSnapIndex = value;
|
||||||
|
log.debug("configMenu", "create Snap", value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private buildCreateScaleControl(): RadioGroup {
|
||||||
|
const radio = new RadioGroup("Create Scale");
|
||||||
|
for (const [index, snap] of AppConfig.config.createSnaps().entries()) {
|
||||||
|
const selected = AppConfig.config.currentCreateSnapIndex == index;
|
||||||
|
radio.addRadio(snap.label, this.createVal, selected);
|
||||||
|
}
|
||||||
|
return radio;
|
||||||
|
}
|
||||||
|
|
||||||
|
private buildRotationSnapControl(): RadioGroup {
|
||||||
|
const radio = new RadioGroup("Rotation Snap");
|
||||||
|
for (const [index, snap] of AppConfig.config.rotateSnaps().entries()) {
|
||||||
|
const selected = AppConfig.config.currentRotateSnapIndex == index;
|
||||||
|
radio.addRadio(snap.label, this.rotateVal, selected);
|
||||||
|
}
|
||||||
|
return radio;
|
||||||
|
}
|
||||||
|
|
||||||
|
private buildGridSizeControl(): RadioGroup {
|
||||||
|
const radio = new RadioGroup("Grid Snap");
|
||||||
|
for (const [index, snap] of AppConfig.config.gridSnaps().entries()) {
|
||||||
|
const selected = AppConfig.config.currentGridSnapIndex == index;
|
||||||
|
radio.addRadio(snap.label, this.gridVal, selected);
|
||||||
|
}
|
||||||
|
return radio;
|
||||||
|
}
|
||||||
|
|
||||||
private rotateVal(value) {
|
private rotateVal(value) {
|
||||||
AppConfig.config.rotateSnap = AppConfig.config.rotateSnapArray[value];
|
AppConfig.config.currentRotateSnapIndex = value;
|
||||||
log.debug("configMenu", "rotate Snap", value);
|
log.debug("configMenu", "rotate Snap", value);
|
||||||
}
|
}
|
||||||
|
|
||||||
private gridVal(value) {
|
private gridVal(value) {
|
||||||
AppConfig.config.gridSnap = AppConfig.config.gridSnapArray[value];
|
AppConfig.config.currentGridSnapIndex = value;
|
||||||
log.debug("configMenu", "grid Snap", value);
|
log.debug("configMenu", "grid Snap", value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -24,12 +24,13 @@ export class EditMenu {
|
|||||||
private textView: InputTextView;
|
private textView: InputTextView;
|
||||||
private textInput: HTMLElement;
|
private textInput: HTMLElement;
|
||||||
private gizmoManager: GizmoManager;
|
private gizmoManager: GizmoManager;
|
||||||
private xr: WebXRExperienceHelper;
|
private readonly xr: WebXRExperienceHelper;
|
||||||
|
private readonly diagramManager: DiagramManager;
|
||||||
constructor(scene: Scene, xr: WebXRExperienceHelper) {
|
|
||||||
|
|
||||||
|
constructor(scene: Scene, xr: WebXRExperienceHelper, diagramManager: DiagramManager) {
|
||||||
this.scene = scene;
|
this.scene = scene;
|
||||||
this.xr = xr;
|
this.xr = xr;
|
||||||
|
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;
|
||||||
@ -71,7 +72,7 @@ export class EditMenu {
|
|||||||
entity:
|
entity:
|
||||||
MeshConverter.toDiagramEntity(pointerInfo.pickInfo.pickedMesh)
|
MeshConverter.toDiagramEntity(pointerInfo.pickInfo.pickedMesh)
|
||||||
}
|
}
|
||||||
DiagramManager.onDiagramEventObservable.notifyObservers(event);
|
this.diagramManager.onDiagramEventObservable.notifyObservers(event);
|
||||||
break;
|
break;
|
||||||
case BmenuState.MODIFYING:
|
case BmenuState.MODIFYING:
|
||||||
if (pointerInfo.pickInfo.pickedMesh.metadata?.template &&
|
if (pointerInfo.pickInfo.pickedMesh.metadata?.template &&
|
||||||
@ -83,7 +84,7 @@ export class EditMenu {
|
|||||||
this.gizmoManager.attachToMesh(mesh);
|
this.gizmoManager.attachToMesh(mesh);
|
||||||
|
|
||||||
this.gizmoManager.gizmos.boundingBoxGizmo.onScaleBoxDragObservable.add(() => {
|
this.gizmoManager.gizmos.boundingBoxGizmo.onScaleBoxDragObservable.add(() => {
|
||||||
DiagramManager.onDiagramEventObservable.notifyObservers({
|
this.diagramManager.onDiagramEventObservable.notifyObservers({
|
||||||
type: DiagramEventType.MODIFY,
|
type: DiagramEventType.MODIFY,
|
||||||
entity: MeshConverter.toDiagramEntity(mesh),
|
entity: MeshConverter.toDiagramEntity(mesh),
|
||||||
}
|
}
|
||||||
@ -158,7 +159,7 @@ export class EditMenu {
|
|||||||
} else {
|
} else {
|
||||||
log.getLogger('bmenu').error("mesh has no metadata");
|
log.getLogger('bmenu').error("mesh has no metadata");
|
||||||
}
|
}
|
||||||
DiagramManager.onDiagramEventObservable.notifyObservers({
|
this.diagramManager.onDiagramEventObservable.notifyObservers({
|
||||||
type: DiagramEventType.MODIFY,
|
type: DiagramEventType.MODIFY,
|
||||||
entity: MeshConverter.toDiagramEntity(mesh),
|
entity: MeshConverter.toDiagramEntity(mesh),
|
||||||
});
|
});
|
||||||
|
|||||||
@ -27,27 +27,30 @@ export enum ToolType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class Toolbox {
|
export class Toolbox {
|
||||||
public static getToolTypeFromString(type: string): ToolType {
|
|
||||||
return ToolType[Object.keys(ToolType).find(() => type)]
|
|
||||||
}
|
|
||||||
|
|
||||||
private index = 0;
|
private index = 0;
|
||||||
public static instance: Toolbox;
|
public static instance: Toolbox;
|
||||||
private readonly scene: Scene;
|
private readonly scene: Scene;
|
||||||
private readonly xr: WebXRExperienceHelper;
|
private readonly xr: WebXRExperienceHelper;
|
||||||
public readonly node : TransformNode;
|
public readonly node: TransformNode;
|
||||||
|
private readonly diagramManager: DiagramManager;
|
||||||
private readonly manager: GUI3DManager;
|
private readonly manager: GUI3DManager;
|
||||||
private readonly gridsize = 5;
|
private readonly gridsize = 5;
|
||||||
private readonly addPanel: StackPanel3D;
|
private readonly addPanel: StackPanel3D;
|
||||||
constructor (scene:Scene, xr: WebXRExperienceHelper) {
|
|
||||||
|
constructor(scene: Scene, xr: WebXRExperienceHelper, diagramManager: DiagramManager) {
|
||||||
this.scene = scene;
|
this.scene = scene;
|
||||||
|
this.diagramManager = diagramManager;
|
||||||
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.node = new TransformNode("toolbox", this.scene);
|
||||||
const handle = MeshBuilder.CreateCapsule("handle", { radius: .01 , orientation: Vector3.Right(), height: .3}, this.scene);
|
const handle = MeshBuilder.CreateCapsule("handle", {
|
||||||
|
radius: .01,
|
||||||
|
orientation: Vector3.Right(),
|
||||||
|
height: .3
|
||||||
|
}, this.scene);
|
||||||
handle.id = "handle";
|
handle.id = "handle";
|
||||||
const handleMaterial = new StandardMaterial("handle-material", this.scene);
|
const handleMaterial = new StandardMaterial("handle-material", this.scene);
|
||||||
handleMaterial.diffuseColor = Color3.FromHexString("#EEEEFF");
|
handleMaterial.diffuseColor = Color3.FromHexString("#EEEEFF");
|
||||||
handle.material = handleMaterial;
|
handle.material = handleMaterial;
|
||||||
handle.position = CameraHelper.getFrontPosition(2, this.scene);
|
handle.position = CameraHelper.getFrontPosition(2, this.scene);
|
||||||
@ -129,7 +132,7 @@ export class Toolbox {
|
|||||||
material.name = "material-" + value.toHexString();
|
material.name = "material-" + value.toHexString();
|
||||||
mesh.id = "toolbox-color-" + value.toHexString();
|
mesh.id = "toolbox-color-" + value.toHexString();
|
||||||
mesh.name = "toolbox-color-" + value.toHexString();
|
mesh.name = "toolbox-color-" + value.toHexString();
|
||||||
DiagramManager.onDiagramEventObservable.notifyObservers(
|
this.diagramManager.onDiagramEventObservable.notifyObservers(
|
||||||
{
|
{
|
||||||
type: DiagramEventType.CHANGECOLOR,
|
type: DiagramEventType.CHANGECOLOR,
|
||||||
oldColor: oldColor,
|
oldColor: oldColor,
|
||||||
@ -206,9 +209,6 @@ export class Toolbox {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public show() {
|
|
||||||
this.buildToolbox();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
function enumKeys<O extends object, K extends keyof O = keyof O>(obj: O): K[] {
|
function enumKeys<O extends object, K extends keyof O = keyof O>(obj: O): K[] {
|
||||||
return Object.keys(obj).filter(k => Number.isNaN(+k)) as K[];
|
return Object.keys(obj).filter(k => Number.isNaN(+k)) as K[];
|
||||||
|
|||||||
@ -1,10 +1,45 @@
|
|||||||
|
import {Angle, Vector3} from "@babylonjs/core";
|
||||||
|
import round from "round";
|
||||||
|
import log from "loglevel";
|
||||||
|
import {IPersistenceManager} from "../diagram/persistenceManager";
|
||||||
|
|
||||||
|
export type SnapValue = {
|
||||||
|
value: number,
|
||||||
|
label: string
|
||||||
|
}
|
||||||
|
export type AppConfigType = {
|
||||||
|
gridSnap: number,
|
||||||
|
rotateSnap: number,
|
||||||
|
createSnap: number
|
||||||
|
}
|
||||||
|
|
||||||
export class AppConfig {
|
export class AppConfig {
|
||||||
public gridSnap = 0;
|
private gridSnap = 0;
|
||||||
public rotateSnap = 0;
|
private rotateSnap = 0;
|
||||||
public gridSnapArray =
|
private createSnap = 0;
|
||||||
[0, 0.1, 0.5, 1];
|
private readonly defaultGridSnapIndex = 1;
|
||||||
public rotateSnapArray =
|
private persistenceManager: IPersistenceManager = null;
|
||||||
[0, 22.5, 45, 90]
|
private gridSnapArray: SnapValue[] =
|
||||||
|
[{value: 0, label: "Off"},
|
||||||
|
{value: 0.05, label: "(Default)"},
|
||||||
|
{value: 0.01, label: "1 cm"},
|
||||||
|
{value: 0.1, label: "10 cm"},
|
||||||
|
{value: 0.25, label: "25 cm"},
|
||||||
|
{value: .5, label: ".5 m"}]
|
||||||
|
private createSnapArray: SnapValue[] =
|
||||||
|
[{value: .1, label: "Default (10 cm)"},
|
||||||
|
{value: 0.2, label: "20 cm"},
|
||||||
|
{value: 0.5, label: ".5 m"},
|
||||||
|
{value: 1, label: "1 m"}];
|
||||||
|
private rotateSnapArray: SnapValue[] =
|
||||||
|
[{value: 0, label: "Off"},
|
||||||
|
{value: 22.5, label: "22.5 Degrees"},
|
||||||
|
{value: 45, label: "45 Degrees"},
|
||||||
|
{value: 90, label: "90 Degrees"}];
|
||||||
|
|
||||||
|
public get currentGridSnap(): SnapValue {
|
||||||
|
return this.gridSnapArray[this.gridSnap];
|
||||||
|
}
|
||||||
|
|
||||||
private static _config: AppConfig;
|
private static _config: AppConfig;
|
||||||
|
|
||||||
@ -13,7 +48,116 @@ export class AppConfig {
|
|||||||
AppConfig._config = new AppConfig();
|
AppConfig._config = new AppConfig();
|
||||||
}
|
}
|
||||||
return AppConfig._config;
|
return AppConfig._config;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public get currentRotateSnap(): SnapValue {
|
||||||
|
return this.rotateSnapArray[this.rotateSnap];
|
||||||
|
}
|
||||||
|
|
||||||
|
public get currentCreateSnap(): SnapValue {
|
||||||
|
return this.createSnapArray[this.createSnap];
|
||||||
|
}
|
||||||
|
|
||||||
|
public get currentGridSnapIndex(): number {
|
||||||
|
return this.gridSnap;
|
||||||
|
}
|
||||||
|
|
||||||
|
public set currentGridSnapIndex(val: number) {
|
||||||
|
this.gridSnap = val;
|
||||||
|
this.save();
|
||||||
|
}
|
||||||
|
|
||||||
|
public get currentCreateSnapIndex(): number {
|
||||||
|
return this.createSnap;
|
||||||
|
}
|
||||||
|
|
||||||
|
public set currentCreateSnapIndex(val: number) {
|
||||||
|
this.createSnap = val;
|
||||||
|
if (this.currentGridSnapIndex == this.defaultGridSnapIndex) {
|
||||||
|
this.currentGridSnap.value = this.currentCreateSnap.value / 2;
|
||||||
|
log.getLogger('AppConfig').debug("Set grid snap to " + this.currentGridSnap.value);
|
||||||
|
}
|
||||||
|
this.save();
|
||||||
|
}
|
||||||
|
|
||||||
|
public get currentRotateSnapIndex(): number {
|
||||||
|
return this.rotateSnap;
|
||||||
|
}
|
||||||
|
|
||||||
|
public set currentRotateSnapIndex(val: number) {
|
||||||
|
this.rotateSnap = val;
|
||||||
|
this.save();
|
||||||
|
}
|
||||||
|
|
||||||
|
public get createSnapVal(): Vector3 {
|
||||||
|
return new Vector3(this.currentCreateSnap.value, this.currentCreateSnap.value, this.currentCreateSnap.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public setPersistenceManager(persistenceManager: IPersistenceManager) {
|
||||||
|
this.persistenceManager = persistenceManager;
|
||||||
|
this.load();
|
||||||
|
}
|
||||||
|
|
||||||
|
public gridSnaps(): SnapValue[] {
|
||||||
|
return this.gridSnapArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
public createSnaps(): SnapValue[] {
|
||||||
|
return this.createSnapArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
public rotateSnaps(): SnapValue[] {
|
||||||
|
return this.rotateSnapArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
public snapGridVal(value: Vector3): Vector3 {
|
||||||
|
if (this.currentGridSnapIndex == 0) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
const position = value.clone();
|
||||||
|
position.x = round(position.x, this.currentGridSnap.value);
|
||||||
|
position.y = round(position.y, this.currentGridSnap.value);
|
||||||
|
position.z = round(position.z, this.currentGridSnap.value);
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
public snapRotateVal(value: Vector3): Vector3 {
|
||||||
|
if (this.currentRotateSnapIndex == 0) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
const rotation = new Vector3();
|
||||||
|
rotation.x = this.snapAngle(value.x);
|
||||||
|
rotation.y = this.snapAngle(value.y);
|
||||||
|
rotation.z = this.snapAngle(value.z);
|
||||||
|
return rotation;
|
||||||
|
}
|
||||||
|
|
||||||
|
private save() {
|
||||||
|
this.persistenceManager.setConfig(
|
||||||
|
{
|
||||||
|
gridSnap: this.currentGridSnap.value,
|
||||||
|
rotateSnap: this.currentRotateSnap.value,
|
||||||
|
createSnap: this.currentCreateSnap.value
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private load() {
|
||||||
|
const config = this.persistenceManager.getConfig();
|
||||||
|
if (config) {
|
||||||
|
this.rotateSnap = this.rotateSnapArray.findIndex((snap) => snap.value == config.rotateSnap);
|
||||||
|
this.createSnap = this.createSnapArray.findIndex((snap) => snap.value == config.createSnap);
|
||||||
|
const gridSnap = this.gridSnapArray.findIndex((snap) => snap.value == config.gridSnap);
|
||||||
|
if (gridSnap == -1) {
|
||||||
|
this.gridSnap = this.defaultGridSnapIndex;
|
||||||
|
this.currentGridSnap.value = config.gridSnap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private snapAngle(val: number): number {
|
||||||
|
const deg = Angle.FromRadians(val).degrees();
|
||||||
|
const snappedDegrees = round(deg, this.currentRotateSnap.value);
|
||||||
|
log.getLogger('AppConfig').debug("deg", val, deg, snappedDegrees, this.currentRotateSnap.value);
|
||||||
|
return Angle.FromDegrees(snappedDegrees).radians();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue
Block a user