diff --git a/docs/astro.config.mjs b/docs/astro.config.mjs index d7d51d1ad..64fb83630 100644 --- a/docs/astro.config.mjs +++ b/docs/astro.config.mjs @@ -44,6 +44,7 @@ export default defineConfig({ items: [ { label: '', link: '/plugins/debug/' }, { label: '', link: '/plugins/draw-service/' }, + { label: '', link: '/plugins/gizmos/' }, { label: '', link: '/plugins/measure-tool/' }, { label: '', link: '/plugins/selection/' }, { label: '', link: '/plugins/skybox/' }, diff --git a/docs/src/content/docs/plugins/gizmos.mdx b/docs/src/content/docs/plugins/gizmos.mdx new file mode 100644 index 000000000..ddf101453 --- /dev/null +++ b/docs/src/content/docs/plugins/gizmos.mdx @@ -0,0 +1,161 @@ +--- +title: +description: Add a toolset for placing editable reference geometry, lines, arrows, and normals inside a motion-tools visualizer. +--- + +import { Aside } from '@astrojs/starlight/components' + +`` adds a "Gizmos" dashboard toggle with a popover of tools for placing editable scene aids: a coordinate system, reference planes, reference geometries (box / sphere / capsule), polylines with optional measurement, arrows, and vertex or surface normals. + +Each tool places a Koota entity in the world, selects it, and renders a custom Details panel for editing its parameters in place. Switching the visualizer's interaction mode back to `navigate`, `measure`, or `select` exits gizmo mode automatically. + +## Usage + +```svelte + + +
+ + + +
+``` + +A new toggle appears in the top dashboard with the `shapes` icon. Clicking it opens a popover that lets you pick which gizmo to place; selecting one switches the visualizer into `'gizmo'` interaction mode and arms the chosen tool. Click in the scene to place the gizmo. The placed entity is auto-selected so its Details panel opens for further editing. + +`` takes no props. + +## Available gizmos + +| Gizmo | Mode key | Behavior | +| ------------------ | -------------------- | ------------------------------------------------------------------------------------------------------------- | +| Coordinate system | `coordinate-system` | Place a labeled XYZ triad at a clicked surface point. | +| Reference plane | `reference-plane` | Place a `yz` / `xz` / `xy` plane either at a clicked point ("free") or at a numeric offset from world origin. | +| Reference geometry | `reference-geometry` | Drop a `box`, `sphere`, or `capsule` (solid or wireframe) at world origin or at a clicked point. | +| Polyline | `polyline` | Click to build a multi-segment line in world or screen space. Optional segment / total measurement labels. | +| Arrow | `arrow` | Place an arrow oriented to a chosen world axis or to the clicked surface normal. | +| Vertex normals | `vertex-normals` | Render the per-vertex normals of a clicked mesh. | +| Surface normals | `surface-normals` | Render the per-face normals of a clicked surface. | + +## Tool reference + +Each tool lives behind an entry in the Gizmos dashboard popover. Picking a tool puts the visualizer into `'gizmo'` interaction mode and arms the placement gesture described below. After placement, the new entity is auto-selected and its Details panel renders the relevant editors (pose, color, geometry, line, opacity, axes helper) for the gizmo kind. + +### Coordinate system + +Click **Place coordinate system** in the popover, then click any surface to drop a labeled XYZ triad at the picked point. The placed entity carries `ShowAxesHelper` from the start. The Details panel exposes pose and parent only (no opacity, no axes-helper toggle, since the gizmo is itself an axes helper). + +### Reference plane + +Open the **Reference plane** folder. Pick a placement mode (**Free (click to place)** or **Offset from coordinate plane**) and a normal axis (`YZ`, `XZ`, `XY`): + +- **Free (click to place)**: clicking **Place reference plane** arms a single-click gesture. Click anywhere in the scene to drop the plane at that point with the chosen normal. +- **Offset from coordinate plane**: drag the offset slider (in mm) to position the plane along its normal from world origin, then click **Place reference plane** to commit. + +Details for the placed plane: pose, opacity, color. + +### Reference geometry + +Open the **Reference geometry** folder. Pick a placement mode (**At origin** or **Free (click to place)**), a shape (`Box`, `Sphere`, `Capsule`), and toggle **Solid** / **Wireframe**: + +- **At origin** drops the geometry at world origin immediately on **Place reference geometry**. +- **Free** arms a single-click gesture; click a surface to drop it there. + +Details: pose, geometry size (per shape), opacity, axes helper toggle, color. + +### Polyline + +Open the **Polyline** folder. Pick a coordinate space (`World` / `Screen`) and a measurement mode (`Off` / `Per segment` / `Total length`). Click **Place polyline** to arm the tool. + +Each click adds a vertex. A floating confirm panel follows the cursor with these hotkeys: + +- `⌫` undo the last vertex +- `esc` cancel and discard +- `space` commit the current polyline and start a new one +- `↵` confirm and exit + +Details: pose, opacity, color. + +### Arrow + +Open the **Arrow** folder. Pick the orientation source: `Surface normal` (aligns with the clicked face's outward normal), or one of `X`, `Y`, `Z` (world axes). Click **Place arrow** to arm the tool, then click a surface to drop the arrow. + +Details: pose, opacity, axes helper toggle, color. + +### Vertex normals + +Open the **Vertex normals** folder. Adjust the length slider (in mm) for the helper lines, then click **Place vertex normals** to arm the tool. Click a mesh to attach a helper that renders one outward segment per vertex of the clicked surface. + +Details: helper length, opacity, color. + +### Surface normals + +Same flow as Vertex normals but the helper renders one segment per triangle face instead of per vertex. Open **Surface normals**, set length, click **Place surface normals**, then click a surface. + +Details: helper length, opacity, color. + +## Reading and driving plugin state + +Use `useGizmos` to read or mutate the plugin's state from anywhere inside ``. The hook is reactive (Svelte 5 runes), so reading its properties subscribes to changes: + +```svelte + + +

Active gizmo: {gizmos.mode}

+ +``` + +Mutable properties (read/write): + +| Property | Type | Description | +| ---------------------- | -------------------------------- | ---------------------------------------------------------- | +| `mode` | `GizmoMode` | Active tool (`'idle'` when no tool is armed). | +| `planeAxis` | `'yz' \| 'xz' \| 'xy'` | Axis-aligned plane for the reference-plane tool. | +| `planeConstruction` | `'free' \| 'offset'` | Placement strategy for the reference-plane tool. | +| `planeOffset` | `number` | Offset (mm) from world origin in `'offset'` mode. | +| `geometryShape` | `'box' \| 'sphere' \| 'capsule'` | Shape used by the reference-geometry tool. | +| `geometryConstruction` | `'at-origin' \| 'free'` | Placement strategy for reference geometries. | +| `isGeometryWireframe` | `boolean` | Render reference geometries as wireframe instead of solid. | +| `lineSpace` | `'world' \| 'screen'` | Coordinate space used by the polyline tool. | +| `lineMeasure` | `'none' \| 'segment' \| 'total'` | Measurement labels rendered on polylines. | +| `arrowAxis` | `'x' \| 'y' \| 'z' \| 'surface'` | Direction the arrow tool orients to. | +| `vertexNormalsLength` | `number` | Length (mm) of vertex-normals lines. | +| `surfaceNormalsLength` | `number` | Length (mm) of surface-normals lines. | + +Read-only: + +| Property | Description | +| ----------------- | ---------------------------------------------------------- | +| `planeAxisVector` | Cloned `THREE.Vector3` normal for the current `planeAxis`. | +| `geometryTrait` | Pre-configured size trait for the current `geometryShape`. | + +Methods: + +| Method | Description | +| -------- | ---------------------------------------------------------------------- | +| `exit()` | Switch the visualizer back to `'navigate'` and set `mode` to `'idle'`. | + +## Traits + +For lower-level access (e.g. iterating placed gizmos in your own queries), the plugin exports its Koota traits under the `gizmoTraits` namespace: + +```ts +import { gizmoTraits } from '@viamrobotics/motion-tools/plugins' +``` + +Every placed entity carries the generic `Gizmo` marker (with `PendingGizmo` added while the user is still placing it). Specific gizmos additionally carry a typed trait: `ReferencePlane`, `GizmoArrow`, `VertexNormals`, `SurfaceNormals`, or `PolylineMeasure`. Filter on these from your own queries to scope behavior to user-placed gizmos vs. robot frames. + +