import { LineSegments, Mesh, Vector3, Box3, ColorRepresentation, Sphere } from 'three/webgpu'; import { BoundingBox } from '../../engine/boundingbox/BoundingBox.ts'; import { DIVEComponent } from '../../engine/component/Component.ts'; import { DIVENode } from '../../engine/node/Node.ts'; /** * Keeps a {@link BoundingBox} around the node it is attached to, and can draw it. * * The measurement itself is `BoundingBox`, which knows nothing about nodes. What * this adds is the node: it always encloses its owner, and it watches that owner * so the numbers are never behind the scene. * * Watched, and therefore free: * * - a child node or a contributed object arriving or leaving (`childadded` / * `childremoved`), which is how a finished asset load reaches this -- the * loader contributes the file's roots to the node * - a component arriving or leaving (`componentadded` / `componentremoved`) * - the node moving, turning or scaling (`object-transform`), whatever moved it * * Not watched, because nothing announces it: geometry swapped in place on a mesh * that is already there. Call {@link refresh} after that. * * An event only marks the box stale; the measurement happens when someone reads * it. That matters because a glTF with fifty root nodes arrives as fifty * `childadded` events, and re-measuring per event would traverse the subtree * fifty times for one load. * * @module */ export declare class BoundingBoxComponent extends DIVEComponent { readonly isBoundingBoxComponent: true; private _boundingBox; private _oriented; private _stale; private _boxHelper; private _sphereHelper; private _invalidate; constructor(); /** The measurement, current as of this read. */ get boundingBox(): BoundingBox; /** The box itself, in the frame it was measured in. */ get box(): Box3; /** Width, height and depth, in the frame the box was measured in. */ get size(): Vector3; /** The centre of the box, in world space. */ get center(): Vector3; /** The sphere around the box, in world space. */ get sphere(): Sphere; /** The radius of that sphere. */ get radius(): number; /** Whether the box is aligned to its owner rather than to the world axes. */ get oriented(): boolean; /** * The wireframe box, for anyone that wants to style or inspect it. * * Measures first, like every other read: a helper handed out unplaced would * be a matrix from before whatever last changed the node. */ get boxHelper(): LineSegments; /** The wireframe sphere, placed the same way. */ get sphereHelper(): Mesh; /** * Chooses between a world-aligned and an owner-aligned box. * * @param oriented - Whether to align the box to the owner. */ setOriented(oriented: boolean): this; /** * Marks the box stale, so the next read measures again. * * Only needed for changes nothing announces -- a geometry swapped in place on * a mesh that is already in the node. Everything that goes through the node's * own API arrives here as an event. */ refresh(): this; /** * @param visible - Whether the box wireframe is drawn. */ setBoxHelperVisible(visible: boolean): void; /** * @param visible - Whether the sphere wireframe is drawn. */ setSphereHelperVisible(visible: boolean): void; /** * @param color - The helper colour. */ setHelperColor(color: ColorRepresentation): void; /** Keeps a drawn box glued to the node while anything moves it. */ tick(): void; protected onAttach(owner: DIVENode): void; protected onDetach(previousOwner: DIVENode): void; /** Re-encloses the owner if anything has happened since the last read. */ private _measure; /** Puts the helpers where the measurement says they belong. */ private _place; /** Ticks only while there is something drawn to keep up to date. */ private _refreshTick; copy(source: this): this; dispose(): void; }