Added copy capability.
This commit is contained in:
parent
397c87eeba
commit
afba69042c
@ -40,7 +40,8 @@ export class App {
|
||||
|
||||
constructor() {
|
||||
const config = AppConfig.config;
|
||||
log.setLevel('debug');
|
||||
log.setLevel('info');
|
||||
log.getLogger('App').setLevel('debug');
|
||||
const canvas = document.createElement("canvas");
|
||||
canvas.style.width = "100%";
|
||||
canvas.style.height = "100%";
|
||||
@ -73,6 +74,8 @@ export class App {
|
||||
|
||||
const havokPlugin = new HavokPlugin(true, havokInstance);
|
||||
scene.enablePhysics(new Vector3(0, -9.8, 0), havokPlugin);
|
||||
scene.collisionsEnabled = true;
|
||||
|
||||
const camera: ArcRotateCamera = new ArcRotateCamera("Camera", Math.PI / 2, Math.PI / 2, 2,
|
||||
new Vector3(0, 1.6, 0), scene);
|
||||
camera.radius = 0;
|
||||
@ -102,8 +105,6 @@ export class App {
|
||||
this.xr.baseExperience.onStateChangedObservable.add((state) => {
|
||||
if (state == WebXRState.IN_XR) {
|
||||
this.scene.audioEnabled = true;
|
||||
|
||||
|
||||
this.xr.baseExperience.camera.position = new Vector3(0, 1.6, 0);
|
||||
window.addEventListener(('pa-button-state-change'), (event: any) => {
|
||||
if (event.detail) {
|
||||
|
||||
@ -14,6 +14,7 @@ import {DiagramManager} from "../diagram/diagramManager";
|
||||
import {DiagramEvent, DiagramEventType} from "../diagram/diagramEntity";
|
||||
import log from "loglevel";
|
||||
import {Controllers} from "./controllers";
|
||||
import {DiagramShapePhysics} from "../diagram/diagramShapePhysics";
|
||||
|
||||
|
||||
export class Base {
|
||||
@ -74,7 +75,11 @@ export class Base {
|
||||
|
||||
});
|
||||
}
|
||||
this.initGrip(init.components['xr-standard-squeeze']);
|
||||
|
||||
if (init.components['xr-standard-squeeze']) {
|
||||
this.initGrip(init.components['xr-standard-squeeze'])
|
||||
}
|
||||
;
|
||||
});
|
||||
Controllers.controllerObserver.add((event) => {
|
||||
if (event.type == 'pulse') {
|
||||
@ -153,7 +158,7 @@ export class Base {
|
||||
}
|
||||
transformNode.setParent(this.controller.motionController.rootMesh);
|
||||
this.grabbedMeshParentId = transformNode.id;
|
||||
MeshConverter
|
||||
DiagramShapePhysics
|
||||
.applyPhysics(newMesh, this.scene)
|
||||
.setMotionType(PhysicsMotionType.ANIMATED);
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import {Color3, Vector3} from "@babylonjs/core";
|
||||
import {BmenuState} from "../menus/MenuState";
|
||||
import {EditMenuState} from "../menus/MenuState";
|
||||
|
||||
export enum DiagramEventType {
|
||||
ADD,
|
||||
@ -8,7 +8,8 @@ export enum DiagramEventType {
|
||||
DROP,
|
||||
DROPPED,
|
||||
CLEAR,
|
||||
CHANGECOLOR
|
||||
CHANGECOLOR,
|
||||
COPY
|
||||
|
||||
|
||||
}
|
||||
@ -16,7 +17,7 @@ export enum DiagramEventType {
|
||||
|
||||
export type DiagramEvent = {
|
||||
type: DiagramEventType;
|
||||
menustate?: BmenuState;
|
||||
menustate?: EditMenuState;
|
||||
entity?: DiagramEntity;
|
||||
oldColor?: Color3;
|
||||
newColor?: Color3;
|
||||
|
||||
@ -18,6 +18,8 @@ import log from "loglevel";
|
||||
import {Controllers} from "../controllers/controllers";
|
||||
import {DiaSounds} from "../util/diaSounds";
|
||||
import {AppConfig} from "../util/appConfig";
|
||||
import {DiagramShapePhysics} from "./diagramShapePhysics";
|
||||
import {TextLabel} from "./textLabel";
|
||||
|
||||
export class DiagramManager {
|
||||
public readonly onDiagramEventObservable: Observable<DiagramEvent> = new Observable();
|
||||
@ -63,7 +65,7 @@ export class DiagramManager {
|
||||
this.logger.debug("DiagramManager constructed");
|
||||
}
|
||||
|
||||
public createCopy(mesh: AbstractMesh): AbstractMesh {
|
||||
public createCopy(mesh: AbstractMesh, copy: boolean = false): AbstractMesh {
|
||||
let newMesh;
|
||||
if (!mesh.isAnInstance) {
|
||||
newMesh = new InstancedMesh("new", (mesh as Mesh));
|
||||
@ -77,10 +79,13 @@ export class DiagramManager {
|
||||
} else {
|
||||
this.logger.error("no rotation quaternion");
|
||||
}
|
||||
newMesh.scaling = AppConfig.config.createSnapVal;
|
||||
if (copy) {
|
||||
newMesh.scaling = mesh.scaling.clone();
|
||||
} else {
|
||||
newMesh.scaling = AppConfig.config.createSnapVal;
|
||||
}
|
||||
newMesh.material = mesh.material;
|
||||
newMesh.metadata = mesh.metadata;
|
||||
|
||||
return newMesh;
|
||||
}
|
||||
|
||||
@ -99,7 +104,7 @@ export class DiagramManager {
|
||||
if (event.parent) {
|
||||
mesh.parent = this.scene.getMeshById(event.parent);
|
||||
}
|
||||
MeshConverter.applyPhysics(mesh, this.scene)
|
||||
DiagramShapePhysics.applyPhysics(mesh, this.scene)
|
||||
.setMotionType(PhysicsMotionType.DYNAMIC);
|
||||
|
||||
}
|
||||
@ -111,8 +116,6 @@ export class DiagramManager {
|
||||
if (entity) {
|
||||
mesh = this.scene.getMeshById(entity.id);
|
||||
}
|
||||
//const body = mesh?.physicsBody;
|
||||
|
||||
switch (event.type) {
|
||||
case DiagramEventType.CLEAR:
|
||||
break;
|
||||
@ -120,12 +123,10 @@ export class DiagramManager {
|
||||
break;
|
||||
case DiagramEventType.DROP:
|
||||
this.getPersistenceManager()?.modify(mesh);
|
||||
MeshConverter.updateTextNode(mesh, entity.text);
|
||||
|
||||
TextLabel.updateTextNode(mesh, entity.text);
|
||||
break;
|
||||
case DiagramEventType.ADD:
|
||||
this.getPersistenceManager()?.add(mesh);
|
||||
|
||||
break;
|
||||
case DiagramEventType.MODIFY:
|
||||
this.getPersistenceManager()?.modify(mesh);
|
||||
|
||||
50
src/diagram/diagramShapePhysics.ts
Normal file
50
src/diagram/diagramShapePhysics.ts
Normal file
@ -0,0 +1,50 @@
|
||||
import {AbstractMesh, PhysicsAggregate, PhysicsBody, PhysicsMotionType, PhysicsShapeType, Scene} from "@babylonjs/core";
|
||||
import {DiaSounds} from "../util/diaSounds";
|
||||
import log from "loglevel";
|
||||
|
||||
export class DiagramShapePhysics {
|
||||
private static logger: log.Logger = log.getLogger('DiagramShapePhysics');
|
||||
|
||||
public static applyPhysics(mesh: AbstractMesh, scene: Scene): PhysicsBody {
|
||||
if (!mesh?.metadata?.template) {
|
||||
this.logger.error("applyPhysics: mesh.metadata.template is null", mesh);
|
||||
return null;
|
||||
}
|
||||
if (!scene) {
|
||||
this.logger.error("applyPhysics: mesh or scene is null");
|
||||
return null;
|
||||
}
|
||||
if (mesh.physicsBody) {
|
||||
mesh.physicsBody.dispose();
|
||||
}
|
||||
let shapeType = PhysicsShapeType.BOX;
|
||||
switch (mesh.metadata.template) {
|
||||
case "#sphere-template":
|
||||
shapeType = PhysicsShapeType.SPHERE;
|
||||
break;
|
||||
case "#cylinder-template":
|
||||
shapeType = PhysicsShapeType.CYLINDER;
|
||||
break;
|
||||
case "#cone-template":
|
||||
shapeType = PhysicsShapeType.CONVEX_HULL;
|
||||
break;
|
||||
|
||||
}
|
||||
const aggregate = new PhysicsAggregate(mesh,
|
||||
shapeType, {mass: 20, restitution: .02, friction: .9}, scene);
|
||||
aggregate.body.setCollisionCallbackEnabled(true);
|
||||
aggregate.body.getCollisionObservable().add((event, state) => {
|
||||
if (event.distance > .001 && !DiaSounds.instance.low.isPlaying) {
|
||||
this.logger.debug(event, state);
|
||||
DiaSounds.instance.low.play();
|
||||
}
|
||||
|
||||
}, -1, false, this);
|
||||
const body = aggregate.body;
|
||||
body.setMotionType(PhysicsMotionType.ANIMATED);
|
||||
body.setLinearDamping(.95);
|
||||
body.setAngularDamping(.99);
|
||||
body.setGravityFactor(0);
|
||||
return aggregate.body;
|
||||
}
|
||||
}
|
||||
@ -1,22 +1,8 @@
|
||||
import {DiagramEntity} from "./diagramEntity";
|
||||
import {
|
||||
AbstractMesh,
|
||||
Color3,
|
||||
DynamicTexture,
|
||||
InstancedMesh,
|
||||
Mesh,
|
||||
MeshBuilder,
|
||||
PhysicsAggregate,
|
||||
PhysicsBody,
|
||||
PhysicsMotionType,
|
||||
PhysicsShapeType,
|
||||
Quaternion,
|
||||
Scene,
|
||||
StandardMaterial
|
||||
} from "@babylonjs/core";
|
||||
import {AbstractMesh, Color3, InstancedMesh, Mesh, Quaternion, Scene, StandardMaterial} from "@babylonjs/core";
|
||||
import {v4 as uuidv4} from 'uuid';
|
||||
import log from "loglevel";
|
||||
|
||||
import {TextLabel} from "./textLabel";
|
||||
|
||||
export class MeshConverter {
|
||||
private static logger = log.getLogger('MeshConverter');
|
||||
@ -44,7 +30,6 @@ export class MeshConverter {
|
||||
}
|
||||
return entity;
|
||||
}
|
||||
|
||||
public static fromDiagramEntity(entity: DiagramEntity, scene: Scene): AbstractMesh {
|
||||
if (!entity) {
|
||||
this.logger.error("fromDiagramEntity: entity is null");
|
||||
@ -63,22 +48,15 @@ export class MeshConverter {
|
||||
log.debug('error: mesh is an instance');
|
||||
} else {
|
||||
mesh = new InstancedMesh(entity.id, (mesh as Mesh));
|
||||
|
||||
}
|
||||
} else {
|
||||
log.debug('no mesh found for ' + entity.template + "-" + entity.color);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (mesh) {
|
||||
mesh.metadata = {template: entity.template};
|
||||
|
||||
if (entity.position) {
|
||||
|
||||
mesh.position = entity.position;
|
||||
|
||||
|
||||
}
|
||||
if (entity.rotation) {
|
||||
if (mesh.rotationQuaternion) {
|
||||
@ -86,7 +64,6 @@ export class MeshConverter {
|
||||
} else {
|
||||
mesh.rotation = entity.rotation;
|
||||
}
|
||||
|
||||
}
|
||||
if (entity.parent) {
|
||||
mesh.parent = scene.getNodeById(entity.parent);
|
||||
@ -101,111 +78,11 @@ export class MeshConverter {
|
||||
}
|
||||
if (entity.text) {
|
||||
mesh.metadata.text = entity.text;
|
||||
this.updateTextNode(mesh, entity.text);
|
||||
TextLabel.updateTextNode(mesh, entity.text);
|
||||
}
|
||||
/*
|
||||
const sphereAggregate = new PhysicsAggregate(mesh, PhysicsShapeType.BOX, {
|
||||
|
||||
mass: 10,
|
||||
restitution: 0.1,
|
||||
startAsleep: false
|
||||
}, scene);
|
||||
|
||||
*/
|
||||
} else {
|
||||
this.logger.error("fromDiagramEntity: mesh is null after it should have been created");
|
||||
}
|
||||
|
||||
return mesh;
|
||||
|
||||
}
|
||||
|
||||
public static applyPhysics(mesh: AbstractMesh, scene: Scene): PhysicsBody {
|
||||
if (!mesh?.metadata?.template || !scene) {
|
||||
this.logger.error("applyPhysics: mesh or scene is null");
|
||||
return null;
|
||||
}
|
||||
if (mesh.physicsBody) {
|
||||
mesh.physicsBody.dispose();
|
||||
}
|
||||
let shapeType = PhysicsShapeType.BOX;
|
||||
switch (mesh.metadata.template) {
|
||||
case "#sphere-template":
|
||||
shapeType = PhysicsShapeType.SPHERE;
|
||||
break;
|
||||
case "#cylinder-template":
|
||||
shapeType = PhysicsShapeType.CYLINDER;
|
||||
break;
|
||||
case "#cone-template":
|
||||
shapeType = PhysicsShapeType.CONVEX_HULL;
|
||||
break;
|
||||
|
||||
}
|
||||
const aggregate = new PhysicsAggregate(mesh,
|
||||
shapeType, {mass: 20, restitution: .2, friction: .9}, scene);
|
||||
const body = aggregate.body;
|
||||
body.setMotionType(PhysicsMotionType.ANIMATED);
|
||||
body.setLinearDamping(.9);
|
||||
body.setAngularDamping(.5);
|
||||
body.setGravityFactor(0);
|
||||
return aggregate.body;
|
||||
|
||||
}
|
||||
|
||||
public static updateTextNode(mesh: AbstractMesh, text: string) {
|
||||
if (!mesh) {
|
||||
this.logger.error("updateTextNode: mesh is null");
|
||||
return null;
|
||||
}
|
||||
let textNode = (mesh.getChildren((node) => {
|
||||
return node.name == 'text'
|
||||
})[0] as Mesh);
|
||||
if (textNode) {
|
||||
textNode.dispose(false, true);
|
||||
}
|
||||
if (!text) {
|
||||
return null;
|
||||
}
|
||||
|
||||
//Set font
|
||||
const height = 0.125;
|
||||
const font_size = 24;
|
||||
const font = "bold " + font_size + "px Arial";
|
||||
//Set height for dynamic texture
|
||||
const DTHeight = 1.5 * font_size; //or set as wished
|
||||
//Calc Ratio
|
||||
const ratio = height / DTHeight;
|
||||
|
||||
//Use a temporary dynamic texture to calculate the length of the text on the dynamic texture canvas
|
||||
const temp = new DynamicTexture("DynamicTexture", 32, mesh.getScene());
|
||||
const tmpctx = temp.getContext();
|
||||
tmpctx.font = font;
|
||||
const DTWidth = tmpctx.measureText(text).width + 8;
|
||||
|
||||
//Calculate width the plane has to be
|
||||
const planeWidth = DTWidth * ratio;
|
||||
|
||||
//Create dynamic texture and write the text
|
||||
const dynamicTexture = new DynamicTexture("DynamicTexture", {
|
||||
width: DTWidth,
|
||||
height: DTHeight
|
||||
}, mesh.getScene(), false);
|
||||
const mat = new StandardMaterial("mat", mesh.getScene());
|
||||
mat.diffuseTexture = dynamicTexture;
|
||||
dynamicTexture.drawText(text, null, null, font, "#000000", "#ffffff", true);
|
||||
|
||||
//Create plane and set dynamic texture as material
|
||||
const plane = MeshBuilder.CreatePlane("text", {width: planeWidth, height: height}, mesh.getScene());
|
||||
plane.material = mat;
|
||||
plane.billboardMode = Mesh.BILLBOARDMODE_ALL;
|
||||
|
||||
|
||||
const yOffset = mesh.getBoundingInfo().boundingSphere.radius;
|
||||
plane.parent = mesh;
|
||||
plane.position.y = yOffset;
|
||||
plane.scaling.y = 1 / mesh.scaling.y;
|
||||
plane.scaling.x = 1 / mesh.scaling.x;
|
||||
plane.scaling.z = 1 / mesh.scaling.z;
|
||||
return plane;
|
||||
}
|
||||
}
|
||||
63
src/diagram/textLabel.ts
Normal file
63
src/diagram/textLabel.ts
Normal file
@ -0,0 +1,63 @@
|
||||
import {AbstractMesh, DynamicTexture, Mesh, MeshBuilder, StandardMaterial} from "@babylonjs/core";
|
||||
import log from "loglevel";
|
||||
|
||||
export class TextLabel {
|
||||
private static logger: log.Logger = log.getLogger('TextLabel');
|
||||
|
||||
public static updateTextNode(mesh: AbstractMesh, text: string): AbstractMesh {
|
||||
if (!mesh) {
|
||||
this.logger.error("updateTextNode: mesh is null");
|
||||
return null;
|
||||
}
|
||||
let textNode = (mesh.getChildren((node) => {
|
||||
return node.name == 'text'
|
||||
})[0] as Mesh);
|
||||
if (textNode) {
|
||||
textNode.dispose(false, true);
|
||||
}
|
||||
if (!text) {
|
||||
return null;
|
||||
}
|
||||
|
||||
//Set font
|
||||
const height = 0.125;
|
||||
const font_size = 24;
|
||||
const font = "bold " + font_size + "px Arial";
|
||||
//Set height for dynamic texture
|
||||
const DTHeight = 1.5 * font_size; //or set as wished
|
||||
//Calc Ratio
|
||||
const ratio = height / DTHeight;
|
||||
|
||||
//Use a temporary dynamic texture to calculate the length of the text on the dynamic texture canvas
|
||||
const temp = new DynamicTexture("DynamicTexture", 32, mesh.getScene());
|
||||
const tmpctx = temp.getContext();
|
||||
tmpctx.font = font;
|
||||
const DTWidth = tmpctx.measureText(text).width + 8;
|
||||
|
||||
//Calculate width the plane has to be
|
||||
const planeWidth = DTWidth * ratio;
|
||||
|
||||
//Create dynamic texture and write the text
|
||||
const dynamicTexture = new DynamicTexture("DynamicTexture", {
|
||||
width: DTWidth,
|
||||
height: DTHeight
|
||||
}, mesh.getScene(), false);
|
||||
const mat = new StandardMaterial("mat", mesh.getScene());
|
||||
mat.diffuseTexture = dynamicTexture;
|
||||
dynamicTexture.drawText(text, null, null, font, "#000000", "#ffffff", true);
|
||||
|
||||
//Create plane and set dynamic texture as material
|
||||
const plane = MeshBuilder.CreatePlane("text", {width: planeWidth, height: height}, mesh.getScene());
|
||||
plane.material = mat;
|
||||
plane.billboardMode = Mesh.BILLBOARDMODE_ALL;
|
||||
|
||||
|
||||
const yOffset = mesh.getBoundingInfo().boundingSphere.radius;
|
||||
plane.parent = mesh;
|
||||
plane.position.y = yOffset;
|
||||
plane.scaling.y = 1 / mesh.scaling.y;
|
||||
plane.scaling.x = 1 / mesh.scaling.x;
|
||||
plane.scaling.z = 1 / mesh.scaling.z;
|
||||
return plane;
|
||||
}
|
||||
}
|
||||
@ -1,7 +1,8 @@
|
||||
export enum BmenuState {
|
||||
export enum EditMenuState {
|
||||
NONE,
|
||||
LABELING,
|
||||
MODIFYING, // Editing an entity
|
||||
REMOVING, // Removing an entity
|
||||
REMOVING,
|
||||
COPYING // Removing an entity
|
||||
|
||||
}
|
||||
@ -9,20 +9,23 @@ import {
|
||||
} from "@babylonjs/core";
|
||||
import {Button3D, GUI3DManager, StackPanel3D, TextBlock} from "@babylonjs/gui";
|
||||
import {DiagramManager} from "../diagram/diagramManager";
|
||||
import {BmenuState} from "./MenuState";
|
||||
import {EditMenuState} from "./MenuState";
|
||||
import {DiagramEvent, DiagramEventType} from "../diagram/diagramEntity";
|
||||
import {MeshConverter} from "../diagram/meshConverter";
|
||||
import log from "loglevel";
|
||||
import {InputTextView} from "../information/inputTextView";
|
||||
import {DiaSounds} from "../util/diaSounds";
|
||||
import {CameraHelper} from "../util/cameraHelper";
|
||||
import {TextLabel} from "../diagram/textLabel";
|
||||
import {DiagramShapePhysics} from "../diagram/diagramShapePhysics";
|
||||
|
||||
export class EditMenu {
|
||||
private state: BmenuState = BmenuState.NONE;
|
||||
private state: EditMenuState = EditMenuState.NONE;
|
||||
private manager: GUI3DManager;
|
||||
private readonly scene: Scene;
|
||||
private textView: InputTextView;
|
||||
private textInput: HTMLElement;
|
||||
private readonly logger: log.Logger = log.getLogger('EditMenu');
|
||||
private gizmoManager: GizmoManager;
|
||||
private readonly xr: WebXRExperienceHelper;
|
||||
private readonly diagramManager: DiagramManager;
|
||||
@ -44,10 +47,10 @@ export class EditMenu {
|
||||
case PointerEventTypes.POINTERPICK:
|
||||
if (pointerInfo.pickInfo?.pickedMesh?.metadata?.template &&
|
||||
pointerInfo.pickInfo?.pickedMesh?.parent?.parent?.id != "toolbox") {
|
||||
this.handleEventStateAction(pointerInfo).then(() => {
|
||||
log.getLogger("bmenu").debug("handled");
|
||||
this.diagramEntityPicked(pointerInfo).then(() => {
|
||||
this.logger.debug("handled");
|
||||
}).catch((e) => {
|
||||
log.getLogger("bmenu").error(e);
|
||||
this.logger.error(e);
|
||||
});
|
||||
break;
|
||||
}
|
||||
@ -68,6 +71,8 @@ export class EditMenu {
|
||||
panel.addControl(this.makeButton("Modify", "modify"));
|
||||
panel.addControl(this.makeButton("Remove", "remove"));
|
||||
panel.addControl(this.makeButton("Add Label", "label"));
|
||||
panel.addControl(this.makeButton("Copy", "copy"));
|
||||
|
||||
//panel.addControl(this.makeButton("Add Ring Cameras", "addRingCameras"));
|
||||
this.manager.controlScaling = .5;
|
||||
CameraHelper.setMenuPosition(panel.node, this.scene);
|
||||
@ -78,7 +83,7 @@ export class EditMenu {
|
||||
if (mesh.metadata) {
|
||||
mesh.metadata.text = text;
|
||||
} else {
|
||||
log.getLogger('bmenu').error("mesh has no metadata");
|
||||
this.logger.error("mesh has no metadata");
|
||||
}
|
||||
this.diagramManager.onDiagramEventObservable.notifyObservers({
|
||||
type: DiagramEventType.MODIFY,
|
||||
@ -98,27 +103,30 @@ export class EditMenu {
|
||||
return button;
|
||||
}
|
||||
|
||||
private async handleEventStateAction(pointerInfo: PointerInfo) {
|
||||
private async diagramEntityPicked(pointerInfo: PointerInfo) {
|
||||
const mesh = pointerInfo.pickInfo.pickedMesh;
|
||||
if (!mesh) {
|
||||
log.warn("no mesh");
|
||||
this.logger.warn("no mesh");
|
||||
return;
|
||||
}
|
||||
switch (this.state) {
|
||||
case BmenuState.REMOVING:
|
||||
case EditMenuState.REMOVING:
|
||||
this.remove(mesh);
|
||||
break;
|
||||
case BmenuState.MODIFYING:
|
||||
case EditMenuState.MODIFYING:
|
||||
this.setModify(mesh);
|
||||
break;
|
||||
case BmenuState.LABELING:
|
||||
case EditMenuState.LABELING:
|
||||
this.setLabeling(mesh);
|
||||
break;
|
||||
case EditMenuState.COPYING:
|
||||
this.setCopying(mesh);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private remove(mesh: AbstractMesh) {
|
||||
log.debug("removing " + mesh?.id);
|
||||
this.logger.debug("removing " + mesh?.id);
|
||||
const event: DiagramEvent = {
|
||||
type: DiagramEventType.REMOVE,
|
||||
entity:
|
||||
@ -140,14 +148,24 @@ export class EditMenu {
|
||||
entity: MeshConverter.toDiagramEntity(mesh),
|
||||
}
|
||||
)
|
||||
log.debug(mesh.scaling);
|
||||
this.logger.debug(mesh.scaling);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private setCopying(mesh: AbstractMesh) {
|
||||
if (mesh) {
|
||||
const newMesh = this.diagramManager.createCopy(mesh);
|
||||
DiagramShapePhysics.applyPhysics(newMesh, this.scene);
|
||||
newMesh.parent = null;
|
||||
}
|
||||
this.logger.warn('copying not implemented', mesh);
|
||||
//@todo implement
|
||||
}
|
||||
|
||||
private setLabeling(mesh: AbstractMesh) {
|
||||
log.debug("labeling " + mesh.id);
|
||||
this.logger.debug("labeling " + mesh.id);
|
||||
let text = "";
|
||||
if (mesh?.metadata?.text) {
|
||||
text = mesh.metadata.text;
|
||||
@ -156,7 +174,7 @@ export class EditMenu {
|
||||
textInput.show();
|
||||
textInput.onTextObservable.addOnce((value) => {
|
||||
this.persist(mesh, value.text);
|
||||
MeshConverter.updateTextNode(mesh, value.text);
|
||||
TextLabel.updateTextNode(mesh, value.text);
|
||||
});
|
||||
|
||||
}
|
||||
@ -164,16 +182,19 @@ export class EditMenu {
|
||||
private handleClick(_info, state) {
|
||||
switch (state.currentTarget.name) {
|
||||
case "modify":
|
||||
this.state = BmenuState.MODIFYING;
|
||||
this.state = EditMenuState.MODIFYING;
|
||||
break;
|
||||
case "remove":
|
||||
this.state = BmenuState.REMOVING;
|
||||
this.state = EditMenuState.REMOVING;
|
||||
break;
|
||||
case "label":
|
||||
this.state = BmenuState.LABELING;
|
||||
this.state = EditMenuState.LABELING;
|
||||
break;
|
||||
case "copy":
|
||||
this.state = EditMenuState.COPYING;
|
||||
break;
|
||||
default:
|
||||
log.error("Unknown button");
|
||||
this.logger.error("Unknown button");
|
||||
return;
|
||||
}
|
||||
this.manager.dispose();
|
||||
|
||||
@ -6,6 +6,7 @@ export class DiaSounds {
|
||||
private readonly scene: Scene;
|
||||
|
||||
constructor(scene: Scene) {
|
||||
|
||||
this.scene = scene;
|
||||
this._enter = new Sound("enter", "./sounds.mp3", this.scene, null, {
|
||||
autoplay: false,
|
||||
@ -28,7 +29,7 @@ export class DiaSounds {
|
||||
this._low = new Sound("low", "./sounds.mp3", this.scene, null, {
|
||||
autoplay: false,
|
||||
loop: false,
|
||||
offset: 2,
|
||||
offset: 3,
|
||||
length: 1.0
|
||||
});
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user