gliders
Three sailplanes over the salt pan, and the whole 122 seconds of flying they do. KILO is the lead ship the film keeps returning to; BRAVO and CHARLIE are already airborne when the film opens and join KILO for the last pass. They are the demo's only scale reference — a 15-metre wi…
gliders
Three sailplanes over the salt pan, and the whole 122 seconds of flying they do. KILO is the lead ship the film keeps returning to; BRAVO and CHARLIE are already airborne when the film opens and join KILO for the last pass. They are the demo's only scale reference — a 15-metre wing against a 4.5-kilometre cloud.
What it provides
local Gliders = require("greensky.gliders")
Gliders.SHIPS -- { "KILO", "BRAVO", "CHARLIE" }
Gliders.poseAt(ship, t) -- -> position {x,y,z}, forward {x,y,z}
Gliders.poseFull(ship, t) -- + speed, yaw, pitch, bank, rates, load
Gliders.posAt(ship, t) -- -> x, y, z
Gliders.tipAt(ship, side, t) -- a wingtip, side = -1 port / +1 starboard
Every one of them is a pure function of film time. They answer for any
t in 0 .. Film.DURATION, they read no entity, and they do not care
whether the slice has been ticked — which is what lets the camera slice
call poseAt from inside its own update to frame and ride a ship.
greensky/camera uses this for shots 3, 9 and 12.
How a ship is animated
One authored key table per ship, evaluated as a monotone cubic Hermite spline. Everything else is a derivative of it, so there is no second animation to keep in sync and no way for the attitude to disagree with the path:
| what | from |
|---|---|
| forward | normalised dp/dt |
| pitch | asin(forward.y) |
| bank | atan(speed * dyaw/dt / g) — a real coordinated turn |
| ailerons | dbank/dt, opposite sides |
| elevator | dpitch/dt |
| rudder | dyaw/dt |
| wing flex | load factor 1/cos(bank) |
| wingtip vapour | load factor, gated by humidity |
Rates are read over a 0.75 s window. A cubic spline's second derivative ripples inside every segment, so a turn rate read at velocity resolution makes a steady thermal turn look like a shiver; 0.75 s is also about how long an aircraft takes to change bank, so the smoothing is the physics rather than a cover for it.
On top of the path — never in it — the cell throws the ships about from the gust front to the last of the rain, and the pilots work against it. The route the camera reads stays exactly where it was authored.
Where they are
| film time | KILO |
|---|---|
| 0 – 6.4 | parked at the west end of the strip, nose east, one wingtip a hand off the concrete |
| 6.4 – 12.4 | the ground roll: 130 m of concrete, wing level by t = 10.4 |
| 12.4 | rotation and lift-off |
| 12.4 – 17.5 | climb-out, easing right off the centreline |
| 17.5 – 39.2 | the thermal: a 110 m circle at 30 m/s, 42 degrees of bank, climbing 12 m/s |
| 39.2 – 55 | east along the gust front, through the 700 m cloud base at exactly t = 55 |
| 55 – 76 | inside the mass, climbing to 1,370 m, then turning north and coming down |
| 76 – 99 | out into the rain, descending across the pan |
| 99 – 106 | a hard diving turn, wings coming level pointing due south |
| 106 – 122 | the low pass: 68 m/s, 90 m off the flood, all three ships in line |
BRAVO and CHARLIE fly their own thermals — wider and tighter respectively, at their own altitudes — until KILO leaves the turn at t = 39.2. All three exit on the same heading, and from there the wingmen hold a station on KILO that eases into their slot in the final line.
The airframe
Twelve entities under each ship's root, built nose along +Z, span along
±X, up along +Y. Fuselage, nose, canopy, two wing panels with
3.5 degrees of dihedral, two ailerons, a tailplane, a fin, a rudder, and a
wingtip entity each side carrying a TrailRenderer for the vapour.
The root's rotation is yaw(+Y) * pitch(+X) * roll(+Z), composed with
Transform.quatFromAxisAngle and Transform.quatMul.
This pass is a greybox: one flat material, no textures, silhouette only.
Scoped to this part · feeds back into the world's score.