Planner · screen recording
Gaussian splat capture · 2026

Vantage

Draw a polygon on a map; it plans the convergent flight, proves the path clears the buildings, and exports a flyable mission. Watch it plan one above.

Why I built it

Motivation

Every mapping planner I tried was built for orthomosaics. A splat wants the opposite of what an orthomosaic wants.

Litchi Hub, DroneDeploy, and Pix4Dcapture all plan the same shape: one nadir grid at a fixed altitude, tuned for stitching a flat top-down map. Point that at a building and you get a beautiful roof and no facades at all, because no photo in the set ever looked sideways at a wall.

Gaussian splatting wants many convergent views of the same surface from different angles, at consistent ground sample distance, without motion blur. That is a different planning problem, not a parameter tweak on the old one. So I wrote a planner that optimizes for the reconstruction instead of the map.

The other half of the problem is that you only find out a capture failed after you have landed, offloaded the cards, and waited on a train. I wanted the plan checked before the flight: does this path clear the building, and will these photos actually see every surface I care about?

Vantage planning a flight over Hendricks Chapel: the generated path with camera footprints and converging view frustums over Google's photorealistic 3D mesh, with the mission readout panel on the right. Hendricks Chapel · planned

What it does

Engineering
85% Surfaces seen from 3+ angles

Scored on the Hendricks Chapel run above: 85% covered, 5% partial, 10% unseen. Every unseen patch is clickable in the 3D view and explains why it is red.

4 Oblique passes

A nadir grid, up to four non-aliasing oblique crosshatch passes, and perimeter rings that fly outside the boundary and look inward at facades.

0.9 cm/px Oblique ground sample distance

Altitude and oblique GSD are two-way coupled. Set either and the other follows, so resolution is a decision rather than an outcome.

111 Waypoints, auto-split

174 photos across two sub-missions, split at line boundaries under Litchi's 99-waypoint cap and a derated battery budget.

0 Unresolved clearance conflicts

Nothing raised, truncated, detoured, or flagged on that plan. Edges the resolver cannot solve are flagged in 3D with a reason instead of silently passing.

7 Drone presets

DJI Mavic 4 Pro by default, plus six other DJI and Autel bodies, each carrying its own camera geometry and battery numbers.

Convergent, not nadir

The grid is a boustrophedon sweep with line and photo spacing derived from the selected drone's camera, and the suggested grid angle minimizes the number of flight lines. The obliques and standoff rings are what put a camera on the sides of things.

The mesh is an instrument

Google's Photorealistic 3D Tiles are downward-raycast into a heightfield of 10 m columns with per-column LOD confidence, then indexed into a BVH. That structure holds altitude above buildings, proves the path clears them, and occludes visibility tests.

Gaps get planned away

A next-best-view planner clusters unseen and partial patches and proposes extra standoff or lateral passes, selected greedily by coverage gained per second under a flight-time budget. It runs automatically, and it is undoable.

How it works

Plan · verify · repair · export

Pressing Generate runs a four-stage pipeline, and every stage can tell you it failed.

First the terrain: raycast the tile mesh into the heightfield so the planner knows what is under and beside the aircraft. Then clearance, where a two-phase resolver lifts, truncates, or laterally detours the path around anything it hits. Then coverage, which samples the surface by area and scores each sample by how many distinct viewing angles the mission gives it, with the BVH doing occlusion. Then repair, which spends a flight-time budget buying back the worst gaps.

Lighting is planned too. Sun elevation and azimuth are computed for the takeoff point and the chosen capture time, and the app warns when the sun is low enough to throw long shadows or drifts enough during the flight that shadows move mid-capture. The 3D view can relight the mesh with the real sun position and overlay how much of each surface sample sits in shadow.

It is vanilla TypeScript with no UI framework, on three.js, 3d-tiles-renderer, and three-mesh-bvh, shipped as a static bundle with 141 tests across 12 files. There is no backend, no account, and no telemetry; missions live in your browser.

Capture DJI Mavic 4 Pro · 4 oblique passes Flight 60 m AGL · −45° gimbal · 4.0 m/s 0.9 cm/px oblique GSD · finish: RTH Mission preview 18:35 flight · 3.57 km · 0.46 ha 111 waypoints · 174 photos · 2 sub-missions Lighting Sun 50° · 252° W drift +4° az / −3° elev over 18 min Coverage · distinct angles 85% covered · 5% partial · 10% unseen Clearance check 0 raised · 0 truncated · 0 detoured 0 flagged · 0 passes added · +0:00 flight

Readout from the Hendricks Chapel plan pictured above.

What it does not do

Known limits

A planning aid, not obstacle avoidance

Clearance is checked against a photogrammetric mesh, not against the world. Thin structures (antennas, wires, cranes) can be missing from that mesh entirely. Fly with visual observers.

Mesh quality bounds analysis quality

Google's tiles are photogrammetry: roofs are bumpy and per-triangle normals are too noisy to use for facing tests. Coverage scoring is only ever as good as the surface it samples.

Rough edges I know about

Every drone constant is still marked for verification against manufacturer spec sheets. The lateral detour is greedy and wedges on concave geometry, where it flags the edge rather than solving it. There is no wind model.

Try it · see it run

Hosted · no key needed
Live planner

Draw a polygon and watch it plan

The full planner is hosted and runs in the browser. You don't need an install, an account, or an API key of your own: search an address, draw a boundary, and generate a mission. Source is closed for now.

Open Vantage →
Live splat · drag to orbit

A splat reconstructed from a Vantage-planned flight. Drag to orbit.