Log inGet started
World

Builtin Library

Branchmain
Branchesmainpublish
Commit3bb1da2647

README.md

viewport_select

Turns a viewport pointer gesture into an editor selection change, applying the standard modifier semantics, and drives the per-frame bridge that reads real pointer + modifier input. Selection is written into the shared modules.api.editor.selection service's entity scope, so the viewport, the selection outline, and the outliner stay in lockstep.

A left press+release within a few pixels is a click-select; a larger left drag is a marquee (rubber-band) that selects every entity whose screen position falls inside the band. The band is drawn by modules.api.editor.marquee_overlay.

Exports

  • M.applyClick(Sel, scope, hitId, mods) — pure decision: hitId == nil clears (unless a modifier is held); ctrl toggles the hit; shift adds it; neither replaces. Entity ids become { kind = "entity", id } refs.
  • M.applyMarquee(Sel, scope, ids, mods) — pure decision for a completed marquee: an empty band with no modifier clears, an empty band with a modifier leaves the selection unchanged; ctrl toggles each id, shift adds the set, neither replaces with the set.
  • M.worldToScreen(m, w, h, p) — project a world point through a 16-float column-major view-projection matrix and viewport size to viewport pixels (sx, sy), or nil when the point is at/behind the camera. Mirrors the engine's own world_to_screen_px.
  • M.pointInRect(rect, sx, sy) — inclusive screen-rect hit test.
  • M.nearestIcon(cands, cx, cy, thresholdPx) — the nearest icon candidate { id, sx, sy } to the cursor within a pixel threshold, or nil.
  • M.entitiesInRect(rect) — engine-driven: the selectable entity ids whose world position projects inside rect (viewport-pixel space) this frame.
  • M.iconPick(cx, cy) — engine-driven: the entity whose meshless icon is nearest the cursor within ICON_PICK_PX, or nil.
  • M.tick(dt?) — call once per editor frame; prunes dead selection refs, reads pointer press/drag/release + modifiers, and routes a click or a marquee through the pure decisions above.

Notes

  • The decision functions are pure so they can be unit-tested against the real selection service.
  • Icon-pick fallback. A click that hits no mesh/collider (the engine pointer pick returns nil) falls back to selecting the nearest meshless-entity icon (light / camera / audio source / reflection probe) within ICON_PICK_PX, so lights and cameras — invisible to the raycast — are selectable by their billboard. The engine pointer pick wins whenever it hits.
  • Gizmo precedence. A marquee only starts on a frame where the pointer has moved past the click slop AND the transform gizmo is not dragging. tick runs before the gizmo's tick in the editor entrypoint, so by the time a drag passes the slop the gizmo has already had a frame to claim a grabbed handle.