Supersplat Selection Tools: A Complete Guide to 8 Interactive Methods

Supersplat provides eight distinct selection tools—rectangular, polygon, lasso, brush, flood-fill, 3D box, 3D sphere, and eyedropper—that operate through an event-driven SVG and canvas overlay system to select Gaussian splats via geometric masks or color matching.

The playcanvas/supersplat repository implements a comprehensive selection system for editing 3D Gaussian splat scenes. These supersplat selection tools enable precise manipulation of point-cloud primitives through multiple geometric input methods, all unified under a consistent event-driven architecture that decouples UI handling from selection logic.

How Supersplat Selection Tools Work

Event-Driven Architecture

All tools follow a standardized lifecycle defined in src/tools/. Each tool receives the global Events bus from src/events.ts, a DOM container for SVG overlays, and (for mask-based tools) a hidden <canvas> element. When a user completes a selection gesture, the tool invokes events.invoke with a select.* event name—such as select.rect, select.byMask, or select.byBox—passing normalized coordinates and an operation mode.

SVG Overlay System

Tools create an SVG element with the class tool-svg hidden appended to the parent container. Specific shapes like <rect>, <polygon>, or <circle> provide real-time visual feedback during interactions. The RectSelection tool updates an SVG <rect> element's x, y, width, and height attributes on every pointermove event, while PolygonSelection accumulates vertices in an SVG <polyline>.

Coordinate Normalization and Operation Modes

Selection coordinates are always normalized to the range [0, 1] relative to the viewport dimensions before dispatch. This ensures consistent behavior across different screen sizes. The operation mode—set, add, or remove—is derived from modifier keys: Shift triggers additive selection, Ctrl triggers subtractive selection, and neither key replaces the current selection.

The 8 Supersplat Selection Tools

RectSelection (src/tools/rect-selection.ts)

The RectSelection tool handles click-drag rectangle selection and single-point picking. Users press the primary pointer button, drag to define an area, and release. If movement occurs, the tool fires select.rect with the bounding box; if the user clicks without dragging, it fires select.point for single-splat selection.

PolygonSelection (src/tools/polygon-selection.ts)

PolygonSelection creates free-form polygon masks through click-based vertex placement. The tool renders an SVG <polyline> connecting vertices. When the final vertex falls within 8 pixels of the first, or upon double-click, the polygon closes. The shape rasterizes to a hidden canvas before invoking select.byMask.

LassoSelection (src/tools/lasso-selection.ts)

The LassoSelection tool captures free-hand drawing through an SVG <polygon>. It accumulates points under timing and spacing heuristics (preventCorners, slowNarrowSpacing) to reduce excessive vertices. Upon pointerup, the tool rasterizes the mask to canvas and dispatches select.byMask.

BrushSelection (src/tools/brush-selection.ts)

BrushSelection enables paint-style mask creation. Users click-drag to paint strokes on a hidden canvas, with brush size adjustable via Alt/Meta + mouse wheel (which fires tool.brushSelection.* events). The tool renders a <circle> cursor and draws line segments directly to the mask canvas, submitting via select.byMask on release.

FloodSelection (src/tools/flood-selection.ts)

The FloodSelection tool implements region-growing based on opacity similarity. Clicking a pixel captures the off-screen rendered image and flood-fills neighboring pixels where opacity differs less than a configurable threshold. The resulting mask triggers select.byMask.

BoxSelection (src/tools/box-selection.ts)

BoxSelection provides 3D axis-aligned box selection using a translate gizmo. Users click to set the box center (at the camera focal point), then drag the gizmo or use UI NumericInput fields to define dimensions. Clicking toolbar buttons fires select.byBox with world position [x, y, z] and extents [lenX, lenY, lenZ].

SphereSelection (src/tools/sphere-selection.ts)

Similar to BoxSelection, SphereSelection uses a TranslateGizmo and SphereShape for spherical volume selection. Users position the center via camera focal point and adjust radius through a numeric input. The tool dispatches select.bySphere with center coordinates and radius values.

EyedropperSelection (src/tools/eyedropper-selection.ts)

The EyedropperSelection tool performs color-based selection without SVG overlays. Clicking a pixel reads its color value, then selects all splats matching within a tolerance threshold. The tool invokes select.colorMatch with normalized coordinates and the threshold value.

Activating and Managing Tools

The ToolManager class in src/tool-manager.ts coordinates tool lifecycle. Activation registers pointer listeners and reveals SVG overlays, while deactivation cleans up state and hides elements.

// Activate the rectangular selection tool
toolManager.activate('rectSelection');   // registers pointer listeners, shows SVG

// Switch to lasso selection (automatically deactivates the previous tool)
toolManager.activate('lassoSelection');

// Perform a box selection via UI button (inside BoxSelection)
setButton.dom.addEventListener('pointerdown', () => {
    // 'add' mode; box centre comes from the gizmo
    events.fire('select.byBox', 'add', [x, y, z, lenX, lenY, lenZ]);
});

The src/selection.ts module registers listeners for all select.* events and manages the active splat collection, decoupling UI handling from model updates.

Summary

  • Eight specialized tools in src/tools/ handle geometric and color-based selection: rectangle, polygon, lasso, brush, flood-fill, box, sphere, and eyedropper.
  • Unified architecture uses the Events bus (src/events.ts) for decoupled communication, with all tools dispatching select.* events containing normalized coordinates.
  • Visual feedback relies on SVG overlays for shape rendering and hidden canvas elements for mask rasterization.
  • Consistent interaction model across all tools supports set, add, and remove modes via Shift and Ctrl modifiers.

Frequently Asked Questions

How do I switch between different selection tools in Supersplat?

Use the ToolManager.activate() method with the tool identifier string. For example, toolManager.activate('rectSelection') enables rectangle mode, while toolManager.activate('lassoSelection') switches to free-hand lasso mode. The manager automatically deactivates the previous tool, removing event listeners and hiding SVG overlays.

What is the difference between polygon and lasso selection in Supersplat?

PolygonSelection (src/tools/polygon-selection.ts) creates shapes through discrete vertex clicks, closing when the final point nears the first or on double-click. LassoSelection (src/tools/lasso-selection.ts) captures continuous free-hand drawing, automatically thinning points to prevent excessive corners. Both rasterize to a hidden canvas and dispatch select.byMask.

How does Supersplat handle additive vs. subtractive selection modes?

All tools derive the operation mode from keyboard modifiers during the pointer event. Holding Shift sets the mode to add (union with existing selection), while holding Ctrl sets it to remove (difference from existing selection). No modifier key sets the mode to set, replacing the current selection entirely.

Can I adjust the brush size when using the brush selection tool?

Yes. While the BrushSelection tool is active, hold Alt or Meta and scroll the mouse wheel to resize the brush radius. The tool listens for tool.brushSelection.* events to update the <circle> cursor visualization and stroke width drawn to the hidden mask canvas.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →