Look and walk
Navigation modes
Switched via the 🧭 Nav tool rail (command: setNavMode).
| Orbit | Fly | |
|---|---|---|
| Left-drag | Rotate (around the target) | Turn the view |
Shift + left / right / middle | Pan | — |
| Wheel | Zoom (toward the target) | Move forward/back |
W A S D | — | Move |
Space / Ctrl | — | Up/down |
Shift | — | Speed up |
| Double-click | Move to that point | Move to that point |
Space + drag | Temporary pan | (disabled — conflicts with forward/back movement) |
Orbit is for surveying the whole structure, Fly is for slipping into tight spots like under a girder or at a bearing. Fly has no movement limits.
⇧1 returns to the overview home view (home), and ⇧2 zooms to the current selection (zoomToSelection).
Looking from a fixed direction
lookAlong views the whole dataset from a given direction. axis is the direction the camera is placed — i.e. "which side you're looking from".
oniyanma.execute('lookAlong', { axis: [0, 0, 1] }) // look straight down from above
oniyanma.execute('lookAlong', { axis: [1, 0, 0] }) // from the +X sideFor an exact position, pass the camera position and target as real coordinates (m) with setCameraReal. The current position is available from getCamera.
Sections
The ▤ Section tool rail. Sliders for axis (X / Y / Z), position, and thickness clip the display to an axis-aligned slab in the aligned frame. Both position and thickness are relative values from 0 to 1, a fraction of the whole dataset's extent.
Useful when a structure in front is in the way, like when looking at a crack on the underside of a deck slab. Points aren't deleted, so what's selectable, measurable, and exportable stays the same.
The command is setSection; pass { on: false } to turn it off.
Appearance
The 🎨 Display tool rail.
| Item | Options | Command |
|---|---|---|
| Color | RGB / intensity / elevation / classification | setColorMode |
| Point size | 0.5–8 px (attenuates with distance) | setPointSize |
| EDL shading | 0–2. 0 is off | setEdl |
| Grid / axes | Toggle | setGrid |
| Point budget | Upper bound on resident points | setBudget |
| Render backend | WebGL / WebGPU | setBackend |
Elevation color takes its range from percentiles before mapping onto Turbo, so it isn't dragged around by outliers like noise below a water surface. It never collapses to a single color.
EDL highlights the point cloud's relief with shading. It helps on point clouds without RGB, or when you want to see the edge of a crack.
Render backend
The default is WebGPU, switchable to WebGL at runtime. Geometry is shared backend-independently, and attributes are unified to Float32 so both backends can use them. The WebGPU backend is a dynamic import, so it's only loaded when you switch to it.
Point shape is square on the WebGPU side (circular via discard was skipped due to a spec difference in PointsNodeMaterial). On the WebGL side, circular vs. square is chosen per device (below).
Per-device render budget
Point clouds have extreme overdraw and exhaust the fragment (fill) bandwidth first. iPad / iPhone GPUs have an order of magnitude less of this than a PC's discrete GPU, so the defaults are lowered.
The check is "touch points > 1". iPadOS Safari sends a Mac UA string, so the UA alone can't distinguish it from a PC.
| Desktop | Mobile | |
|---|---|---|
| Render-buffer scale cap | 1.5 | 1.0 |
| Point budget (default) | 3.5 M | 1.2 M |
| Resident-point lower cap | 6 M | 2.5 M |
| Decode workers | up to 6 | up to 3 |
| Uploads / frame | 400K points | 200K points |
| Upload-pending queue cap | 1.5M points | 600K points |
| Point shape (WebGL) | Circular | Square |
Points are squares on mobile because discard disables the Apple GPU's (TBDR) hidden-surface removal, forcing even hidden points to be shaded.
The upload-pending queue has a cap because a moving camera can keep "decoding keeps up but uploading falls behind" going indefinitely, and without a cap, arrays of several MB per node would pile up (on iPad Safari the tab crashes after about a minute, and to the user it just looks like "it suddenly reloaded"). Overflow is dropped oldest-first and returned to pending so it can be requested again.
The point budget and EDL can be overridden manually from the display panel. To override the automatic detection itself, append ?quality=high|low (kept around for on-device A/B testing, since devtools aren't available on iPad to compare settings side by side).
Add to Home Screen (iPad)
On iPad, using Safari's share button → "Add to Home Screen" is recommended. The tab bar and address bar disappear for a full-screen view, giving the point cloud that much more vertical space. Once opened from the icon it behaves just like regular Safari — no extra setup needed.
Doesn't work offline
Adding it to the Home Screen doesn't extend what works beyond regular Safari. The point cloud fetches COPC piece by piece over byte range, so it can't display anywhere without a signal.
In full-screen mode there's no address bar, so you can't view and copy the URL. To invite someone into the same room, press "Invite link" in the 👥 Share tool rail (→ Collaborating).