Added Ability to recolor instances.

This commit is contained in:
Michael Mainguy 2023-08-08 09:22:55 -05:00
parent 750e981c8e
commit 9c97b81727
5 changed files with 73 additions and 21 deletions

View File

@ -24,7 +24,7 @@ export class App {
constructor() {
const config = AppConfig.config;
const logger = log.getLogger('App');
log.disableAll();
log.setDefaultLevel('info');
log.getLogger('App').setLevel('info');
@ -33,6 +33,7 @@ export class App {
//log.getLogger('DiagramConnection').setLevel('debug');
log.getLogger('DrawioManager').setLevel('debug');
log.getLogger('EditMenu').setLevel('debug');
const canvas = document.createElement("canvas");
canvas.style.width = "100%";
canvas.style.height = "100%";

View File

@ -136,7 +136,7 @@ export class DiagramManager {
if (entity) {
mesh = this.scene.getMeshById(entity.id);
}
if (!mesh) {
if (!mesh && event?.entity?.template) {
const toolMesh = this.scene.getMeshById("tool-" + event.entity.template + "-" + event.entity.color);
if (!toolMesh) {
log.debug('no mesh found for ' + event.entity.template + "-" + event.entity.color, 'adding it');
@ -145,13 +145,16 @@ export class DiagramManager {
entity: event.entity
});
}
mesh = MeshConverter.fromDiagramEntity(event.entity, this.scene);
mesh.actionManager = this.actionManager;
DiagramShapePhysics.applyPhysics(mesh, this.scene, PhysicsMotionType.DYNAMIC);
if (mesh) {
mesh.actionManager = this.actionManager;
DiagramShapePhysics.applyPhysics(mesh, this.scene, PhysicsMotionType.DYNAMIC);
}
}
switch (event.type) {
case DiagramEventType.CLEAR:
break;
case DiagramEventType.DROPPED:
break;

View File

@ -4,6 +4,8 @@ export enum EditMenuState {
MODIFYING, // Editing an entity
REMOVING,
COPYING, // Removing an entity
CONNECTING
CONNECTING,
RECOLORING
}

View File

@ -1,9 +1,13 @@
import {
AbstractMesh,
Color3,
GizmoManager,
InstancedMesh,
Mesh,
PointerEventTypes,
PointerInfo,
Scene,
StandardMaterial,
Vector3,
WebXRExperienceHelper
} from "@babylonjs/core";
@ -24,6 +28,7 @@ export class EditMenu {
private state: EditMenuState = EditMenuState.NONE;
private manager: GUI3DManager;
private readonly scene: Scene;
private paintColor: string = null;
private readonly logger: log.Logger = log.getLogger('EditMenu');
private gizmoManager: GizmoManager;
private readonly xr: WebXRExperienceHelper;
@ -55,6 +60,13 @@ export class EditMenu {
});
break;
} else {
const tool = pickedMesh?.metadata?.tool;
if (tool) {
this.logger.debug("tool type", tool);
this.paintColor = (pickedMesh.material as StandardMaterial).diffuseColor.toHexString();
this.logger.debug((pickedMesh.material as StandardMaterial).diffuseColor.toHexString());
this.logger.debug(pickedMesh.id);
}
}
}
@ -77,6 +89,7 @@ export class EditMenu {
panel.addControl(this.makeButton("Copy", "copy"));
panel.addControl(this.makeButton("Connect", "connect"));
panel.addControl(this.makeButton("Export", "export"));
panel.addControl(this.makeButton("Recolor", "recolor"));
//panel.addControl(this.makeButton("Add Ring Cameras", "addRingCameras"));
this.manager.controlScaling = .5;
@ -84,6 +97,11 @@ export class EditMenu {
}
}
private getTool(template: string, color: Color3): Mesh {
const baseMeshId = 'tool-' + template + '-' + color.toHexString();
return (this.scene.getMeshById(baseMeshId) as Mesh);
}
private persist(mesh: AbstractMesh, text: string) {
if (mesh.metadata) {
mesh.metadata.text = text;
@ -116,24 +134,43 @@ export class EditMenu {
}
switch (this.state) {
case EditMenuState.REMOVING:
this.remove(mesh);
this.removeMesh(mesh);
break;
case EditMenuState.MODIFYING:
this.setModify(mesh);
this.modifyMesh(mesh);
break;
case EditMenuState.LABELING:
this.setLabeling(mesh);
this.labelMesh(mesh);
break;
case EditMenuState.COPYING:
this.setCopying(mesh);
this.copyMesh(mesh);
break;
case EditMenuState.CONNECTING:
this.setConnecting(mesh, pointerInfo);
this.createMeshConnection(mesh, pointerInfo);
break;
case EditMenuState.RECOLORING:
if (this.paintColor) {
const template = mesh.metadata.template;
const newBase = this.getTool(template,
Color3.FromHexString(this.paintColor));
const newMesh = (mesh as InstancedMesh).clone(mesh.name, mesh.parent, false, newBase);
newMesh.id = mesh.id;
newMesh.physicsBody = mesh.physicsBody;
newMesh.metadata = mesh.metadata;
mesh.physicsBody = null;
mesh.dispose();
this.diagramManager.onDiagramEventObservable.notifyObservers({
type: DiagramEventType.MODIFY,
entity: MeshConverter.toDiagramEntity(newMesh)
});
} else {
this.logger.error("no paint color selectced");
}
}
}
private setConnecting(mesh: AbstractMesh, pointerInfo) {
private createMeshConnection(mesh: AbstractMesh, pointerInfo) {
if (this.connection) {
this.connection.to = mesh.id;
this.diagramManager.onDiagramEventObservable.notifyObservers({
@ -146,7 +183,7 @@ export class EditMenu {
}
}
private remove(mesh: AbstractMesh) {
private removeMesh(mesh: AbstractMesh) {
this.logger.debug("removing " + mesh?.id);
const event: DiagramEvent = {
type: DiagramEventType.REMOVE,
@ -156,7 +193,7 @@ export class EditMenu {
this.diagramManager.onDiagramEventObservable.notifyObservers(event);
}
private setModify(mesh: AbstractMesh) {
private modifyMesh(mesh: AbstractMesh) {
if (mesh.metadata?.template &&
mesh.parent?.parent?.id != "toolbox") {
if (this.gizmoManager.gizmos.boundingBoxGizmo.attachedMesh?.id == mesh.id) {
@ -165,8 +202,8 @@ export class EditMenu {
this.gizmoManager.attachToMesh(mesh);
this.gizmoManager.gizmos.boundingBoxGizmo.onScaleBoxDragObservable.add(() => {
this.diagramManager.onDiagramEventObservable.notifyObservers({
type: DiagramEventType.MODIFY,
entity: MeshConverter.toDiagramEntity(mesh),
type: DiagramEventType.MODIFY,
entity: MeshConverter.toDiagramEntity(mesh),
}
)
this.logger.debug(mesh.scaling);
@ -175,16 +212,16 @@ export class EditMenu {
}
}
private setCopying(mesh: AbstractMesh) {
private copyMesh(mesh: AbstractMesh) {
if (mesh) {
const newMesh = this.diagramManager.createCopy(mesh, true);
newMesh.setParent(null);
newMesh.setParent(mesh.parent);
}
this.logger.warn('copying not implemented', mesh);
//@todo implement
}
private setLabeling(mesh: AbstractMesh) {
private labelMesh(mesh: AbstractMesh) {
this.logger.debug("labeling " + mesh.id);
let text = "";
if (mesh?.metadata?.text) {
@ -216,6 +253,9 @@ export class EditMenu {
case "connect":
this.state = EditMenuState.CONNECTING;
break;
case "recolor":
this.state = EditMenuState.RECOLORING;
break;
case "export":
GLTF2Export.GLTFAsync(this.scene, 'diagram.gltf', {
shouldExportNode: function (node) {

View File

@ -84,7 +84,7 @@ export class Toolbox {
public buildTool(tool: ToolType, parent: AbstractMesh) {
let newItem: Mesh;
const id = tool + "-" + (parent.material as StandardMaterial).diffuseColor.toHexString();
const id = this.toolId(tool, (parent.material as StandardMaterial).diffuseColor);
const material = parent.material;
const toolname = "tool-" + id;
switch (tool) {
@ -108,7 +108,7 @@ export class Toolbox {
}
if (newItem) {
newItem.material = material;
newItem.id = "tool-" + id;
newItem.id = toolname
if (tool === ToolType.PLANE) {
newItem.material.backFaceCulling = false;
}
@ -120,6 +120,7 @@ export class Toolbox {
if (!newItem.material) {
newItem.material = parent.material;
}
if (newItem.metadata) {
newItem.metadata.template = tool;
} else {
@ -141,6 +142,10 @@ export class Toolbox {
return null;
}
}
private toolId(tool: ToolType, color: Color3) {
return tool + "-" + color.toHexString();
}
private calculatePosition(i: number) {
return (i/this.gridsize)-.5-(1/this.gridsize/2);
}
@ -186,6 +191,7 @@ export class Toolbox {
mesh.material = material;
mesh.position.z = this.index++/4;
mesh.parent = this.node;
mesh.metadata = {tool: 'color'};
let i = 0;
for (const tool of enumKeys(ToolType)) {
const newItem = this.buildTool(ToolType[tool], mesh);