UNPKG

@shopware-ag/dive

Version:

Shopware Spatial Framework

93 lines (74 loc) 2.82 kB
import { type Object3D } from 'three'; import { type DIVEScene } from '../../scene/Scene.ts'; import DIVETransformTool from '../transform/TransformTool.ts'; import { findInterface } from '../../helper/findInterface/findInterface.ts'; import type DIVEOrbitControls from '../../controls/OrbitControls.ts'; import { type DIVESelectable } from '../../interface/Selectable.ts'; import { type DIVEMovable } from '../../interface/Movable.ts'; import { type DIVEBaseTool } from '../BaseTool.ts'; export const isSelectTool = (tool: DIVEBaseTool): tool is DIVESelectTool => { return (tool as DIVESelectTool).isSelectTool !== undefined; }; export interface DIVEObjectEventMap { select: object; } /** * A Tool to select and move objects in the scene. * * Objects have to implement the DIVESelectable interface to be selectable and DIVEMovable to be movable. * * @module */ export class DIVESelectTool extends DIVETransformTool { readonly isSelectTool: boolean = true; constructor(scene: DIVEScene, controller: DIVEOrbitControls) { super(scene, controller); this.name = 'SelectTool'; } public Activate(): void {} public Select(selectable: DIVESelectable): void { this.AttachGizmo(selectable); if (selectable.onSelect) selectable.onSelect(); } public Deselect(selectable: DIVESelectable): void { this.DetachGizmo(); if (selectable.onDeselect) selectable.onDeselect(); } public AttachGizmo(selectable: DIVESelectable): void { if ('isMovable' in selectable) { const movable = selectable as Object3D & DIVESelectable & DIVEMovable; this._gizmo.attach(movable); this.SetGizmoVisibility(movable.visible); } } public DetachGizmo(): void { this._gizmo.detach(); } public onClick(e: PointerEvent): void { super.onClick(e); const first = this._raycaster .intersectObjects(this._scene.Root.children, true) .filter((intersect) => intersect.object.visible)[0]; const selectable = findInterface<DIVESelectable>( first?.object, 'isSelectable', ); // if nothing is hit if (!first || !selectable) { if (this._gizmo.object) { this.Deselect(this._gizmo.object as Object3D & DIVESelectable); } return; } if (this._gizmo.object) { // do not reselect if the same object was clicked if (this._gizmo.object.uuid === selectable.uuid) return; // deselect previous object this.Deselect(this._gizmo.object as Object3D & DIVESelectable); } // select clicked object this.Select(selectable); } }