import {AbstractMesh, MeshBuilder, Scene} from "@babylonjs/core"; import {Rigplatform} from "./rigplatform"; import {ControllerEventType, Controllers} from "./controllers"; import {DiagramManager} from "../diagram/diagramManager"; import {GridMaterial} from "@babylonjs/materials"; import {wheelHandler} from "./functions/wheelHandler"; import log, {Logger} from "loglevel"; import {isDiagramEntity} from "../diagram/functions/isDiagramEntity"; import {DiagramEventType} from "../diagram/types/diagramEntity"; import {toDiagramEntity} from "../diagram/functions/toDiagramEntity"; export class WebController { private readonly scene: Scene; private readonly logger: Logger = log.getLogger('WebController'); private speed: number = 1; private readonly referencePlane: AbstractMesh; private pickedMesh: AbstractMesh; private rig: Rigplatform; private diagramManager: DiagramManager; private mouseDown: boolean = false; private readonly controllers: Controllers; private upDownWheel: boolean = false; private fowardBackWheel: boolean = false; constructor(scene: Scene, rig: Rigplatform, diagramManager: DiagramManager, controllers: Controllers) { this.scene = scene; this.rig = rig; this.diagramManager = diagramManager; this.controllers = controllers; this.referencePlane = MeshBuilder.CreatePlane('referencePlane', {size: 10}, this.scene); this.referencePlane.setEnabled(false); this.referencePlane.visibility = 0.5; const material = new GridMaterial('grid', this.scene); material.gridRatio = 1; material.backFaceCulling = false; material.antialias = true; this.referencePlane.material = material; this.scene.onKeyboardObservable.add((kbInfo) => { this.logger.debug(kbInfo); if (kbInfo.type == 1) { switch (kbInfo.event.key) { case "ArrowUp": this.rig.forwardback(-this.speed); break; case "ArrowDown": this.rig.forwardback(this.speed); break; case "ArrowLeft": this.rig.leftright(-this.speed); break; case "ArrowRight": this.rig.leftright(this.speed); break; case "]": this.speed *= 1.5; break; case "[": this.speed *= .5; break; case " ": if (kbInfo.event.ctrlKey) { if (this.controllers) { this.controllers.controllerObserver.notifyObservers( {type: ControllerEventType.X_BUTTON, value: 1} ) } } break; default: this.logger.debug(kbInfo.event); } } else { this.rig.leftright(0); this.rig.forwardback(0); } if (kbInfo.event.key == "Shift") { if (kbInfo.type == 1) { //this.referencePlane.setEnabled(true); } else { this.referencePlane.setEnabled(false); if (this.pickedMesh) { this.pickedMesh.showBoundingBox = false; this.pickedMesh = null; } } } }); this.scene.onPointerUp = () => { this.mouseDown = false; this.rig.turn(0); }; window.addEventListener('wheel', (evt) => { switch (evt.buttons) { case 0: if (this.fowardBackWheel == false) { this.fowardBackWheel = true; const reset = wheelHandler.bind(this); setTimeout(reset, 500); } if (Math.sign(evt.deltaY) != 0) { this.rig.forwardback(evt.deltaY / 100); } break; case 1: if (this.upDownWheel == false) { this.upDownWheel = true; const reset = wheelHandler.bind(this); setTimeout(reset, 500); } if (Math.sign(evt.deltaY) != 0) { this.rig.updown(evt.deltaY / 100); } break; } }); this.scene.onPointerDown = (evt, state) => { if (evt.pointerType == "mouse") { if (evt.shiftKey) { //setMenuPosition(this.referencePlane, this.scene, new Vector3(0, 0, 5)); //this.referencePlane.rotation = scene.activeCamera.absoluteRotation.toEulerAngles(); this.pickedMesh = state.pickedMesh; if (this.pickedMesh) { this.referencePlane.position = this.pickedMesh.position; this.referencePlane.rotation = scene.activeCamera.absoluteRotation.toEulerAngles(); } this.pickedMesh.rotation = scene.activeCamera.absoluteRotation.toEulerAngles(); this.referencePlane.setEnabled(true); } else { this.mouseDown = true; } } }; this.scene.onPointerMove = (evt) => { if (evt.pointerType != "mouse") { return; } if (this.mouseDown) { this.rig.turn(evt.movementX); } const meshPickInfo = scene.pick(this.scene.pointerX, this.scene.pointerY, (mesh) => { return isDiagramEntity(mesh); }); const planePickInfo = scene.pick(this.scene.pointerX, this.scene.pointerY, (mesh) => { return mesh.id == this.referencePlane.id; }); if (meshPickInfo.hit) { if (!this._mesh) { this.mesh = meshPickInfo.pickedMesh; } else { if (this._mesh.id != meshPickInfo.pickedMesh.id) { this.mesh = meshPickInfo.pickedMesh; } } } else { if (this.mesh) { this.diagramManager.onDiagramEventObservable.notifyObservers({ type: DiagramEventType.MODIFY, entity: toDiagramEntity(this.mesh) }, -1); } this.mesh = null; } if (this.pickedMesh && planePickInfo.hit) { this.pickedMesh.position = planePickInfo.pickedPoint; } } } _mesh: AbstractMesh; get mesh(): AbstractMesh { return this._mesh; } set mesh(mesh: AbstractMesh) { if (mesh) { mesh.showBoundingBox = true; mesh.outlineWidth = 0.08; } else { if (this._mesh) { this._mesh.showBoundingBox = false; } } this._mesh = mesh; } }