immersive2/src/toolbox/toolbox.ts

125 lines
4.2 KiB
TypeScript

import {AbstractMesh, Color3, InstancedMesh, Node, Scene, TransformNode, Vector3} from "@babylonjs/core";
import {buildColor} from "./functions/buildColor";
import log from "loglevel";
import {Handle} from "../objects/handle";
import {DefaultScene} from "../defaultScene";
const colors: string[] = [
"#222222", "#8b4513", "#006400", "#778899",
"#4b0082", "#ff0000", "#ffa500", "#ffff00",
"#00ff00", "#00ffff", "#0000ff", "#ff00ff",
"#1e90ff", "#98fb98", "#ffe4b5", "#ff69b4"
]
export class Toolbox {
public readonly _toolboxBaseNode: TransformNode;
private readonly _tools: Map<string, InstancedMesh> = new Map<string, InstancedMesh>();
private readonly _logger = log.getLogger('Toolbox');
private readonly _handle: Handle;
private readonly _scene: Scene;
constructor() {
this._scene = DefaultScene.Scene;
this._toolboxBaseNode = new TransformNode("toolbox", this._scene);
this._handle = new Handle(this._toolboxBaseNode, 'Toolbox');
this._toolboxBaseNode.position.y = .2;
this._toolboxBaseNode.scaling = new Vector3(0.6, 0.6, 0.6);
this.buildToolbox();
Toolbox._instance = this;
}
private index = 0;
private colorPicker: TransformNode;
private changing = false;
public static _instance: Toolbox;
public static get instance() {
return Toolbox._instance;
}
public get handleMesh(): AbstractMesh {
return this._handle.mesh;
}
public isTool(mesh: AbstractMesh) {
return this._tools.has(mesh.id);
}
private buildToolbox() {
this.setupPointerObservable();
this.buildColorPicker();
if (this._toolboxBaseNode.parent) {
const platform = this._scene.getMeshById("platform");
if (platform) {
this.assignHandleParentAndStore(platform);
} else {
const observer = this._scene.onNewMeshAddedObservable.add((mesh: AbstractMesh) => {
if (mesh && mesh.id == "platform") {
this.assignHandleParentAndStore(mesh);
this._scene.onNewMeshAddedObservable.remove(observer);
}
}, -1, false, this, false);
}
}
}
private setupPointerObservable() {
this._scene.onPointerObservable.add((pointerInfo) => {
const pickedMesh = pointerInfo?.pickInfo?.pickedMesh;
if (pointerInfo.type == 1 &&
pickedMesh?.metadata?.tool == 'color') {
if (this.changing) {
this._logger.debug('changing');
this.colorPicker.setEnabled(true);
return;
} else {
const active = pickedMesh?.parent.getChildren(this.nodePredicate, true);
for (const node of active) {
node.setEnabled(false);
}
const nodes = pickedMesh?.metadata?.tools;
if (nodes) {
for (const node of nodes) {
this._scene.getNodeById(node)?.setEnabled(true);
}
}
}
}
});
}
private nodePredicate = (node: Node) => {
return node.getClassName() == "InstancedMesh" &&
node.isEnabled(false) == true
};
private buildColorPicker() {
let initial = true;
for (const c of colors) {
const cnode = buildColor(Color3.FromHexString(c), this._scene, this._toolboxBaseNode, this.index++, this._tools);
if (initial) {
initial = false;
for (const id of cnode.metadata.tools) {
this._scene.getNodeById(id)?.setEnabled(true);
}
}
}
}
private assignHandleParentAndStore(mesh: TransformNode) {
const offset = new Vector3(-.50, 1.6, .38);
const rotation = new Vector3(.5, -.6, .18);
const handle = this._handle;
handle.mesh.parent = mesh;
if (!handle.idStored) {
handle.mesh.position = offset;
handle.mesh.rotation = rotation;
}
}
}