SOURCE / PINNED RELEASE
Made of little things.
Poly Dogfight
- Release
- b8511ee374e3…
- Author-recorded commit
- 5579434b9d8b…
- License
- LICENSE
- Author’s source reference
- nostr://npub1ye5ptcxfyyxl5vjvdjar2ua3f0hynkjzpx552mu5snj3qmx5pzjscpknpr/wss%3A%2F%2Fgit.napplet.soy%2F/n-44f63e5422b
Archive hash verified: bcadd2430d8ea2bc…. The source-to-build association is the author’s claim; it has not been independently rebuilt.
/**
* The single source of truth for the planet's shape. The renderer displaces the
* planet mesh with terrainHeight and the flight sim uses it for ground collision.
*/
import { WORLD_SEED } from './constants.ts';
import { createNoise3, fbm, smoothstep } from './noise.ts';
const continents = createNoise3(WORLD_SEED);
const ridges = createNoise3(WORLD_SEED + 1);
const detail = createNoise3(WORLD_SEED + 2);
const warp = createNoise3(WORLD_SEED + 3);
function normalize3(x: number, y: number, z: number): [number, number, number] {
const len = Math.hypot(x, y, z) || 1;
return [x / len, y / len, z / len];
}
/** The Great Rift: a canyon cut into a raised plateau along part of a great circle. */
export const RIFT = (() => {
const normal = normalize3(0.35, 0.82, 0.45);
// Two tangent axes spanning the great circle's plane.
const e1 = normalize3(-normal[1], normal[0], 0);
const e2: [number, number, number] = [
normal[1] * e1[2] - normal[2] * e1[1],
normal[2] * e1[0] - normal[0] * e1[2],
normal[0] * e1[1] - normal[1] * e1[0],
];
return { normal, e1, e2, arcStart: 0.2, arcEnd: 2.5 };
})();
/** Returns the angle along the rift and the signed angular distance from its centreline. */
export function riftCoordinates(x: number, y: number, z: number): { along: number; across: number } {
const { normal, e1, e2 } = RIFT;
const along = Math.atan2(
x * e2[0] + y * e2[1] + z * e2[2],
x * e1[0] + y * e1[1] + z * e1[2],
);
const wiggle = 0.028 * Math.sin(along * 7.0) + 0.012 * Math.sin(along * 19.0 + 1.3);
const across = Math.asin(Math.max(-1, Math.min(1, x * normal[0] + y * normal[1] + z * normal[2]))) + wiggle;
return { along, across };
}
/**
* Height above sea level (metres) of the ground in the unit direction (x, y, z).
* Negative values are sea floor; the sea surface is at 0.
*/
export function terrainHeight(x: number, y: number, z: number): number {
const wx = x + 0.22 * warp(x * 2.1, y * 2.1, z * 2.1);
const wy = y + 0.22 * warp(y * 2.1 + 5.2, z * 2.1, x * 2.1);
const wz = z + 0.22 * warp(z * 2.1, x * 2.1 + 9.7, y * 2.1);
const base = fbm(continents, wx * 1.3, wy * 1.3, wz * 1.3, 5) + 0.05;
let h: number;
if (base <= 0) {
h = Math.max(-70, base * 160);
} else {
// Gentle lowlands near the coast, rising into ridged mountain chains inland.
const lowland = 34 * Math.pow(base, 1.15);
let ridge = 0;
let amp = 1;
let freq = 3.2;
for (let o = 0; o < 3; o++) {
const r = 1 - Math.abs(ridges(wx * freq, wy * freq, wz * freq));
ridge += amp * r * r;
amp *= 0.45;
freq *= 2.1;
}
const mountains = 62 * (ridge - 0.45) * smoothstep(0.06, 0.3, base);
h = 2 + lowland + Math.max(0, mountains);
}
// Surface detail fades out toward the coast so beaches stay clean.
if (base > 0) h += fbm(detail, x * 11, y * 11, z * 11, 2) * 5 * smoothstep(0.02, 0.16, base);
// The Great Rift plateau and canyon.
const { along, across } = riftCoordinates(x, y, z);
const arcMask =
smoothstep(RIFT.arcStart - 0.15, RIFT.arcStart + 0.1, along) *
(1 - smoothstep(RIFT.arcEnd - 0.1, RIFT.arcEnd + 0.15, along));
if (arcMask > 0) {
const d = Math.abs(across) + 0.01 * detail(x * 30, y * 30, z * 30);
const plateau = (52 + 8 * detail(x * 6, y * 6, z * 6)) * smoothstep(0.17, 0.11, d) * arcMask;
if (plateau > 0) h = Math.max(h, plateau);
const channel = smoothstep(0.05, 0.03, d) * arcMask;
if (channel > 0) h = h + (6 - h) * channel;
}
return h;
}
/** Ground or sea surface height used for crashes and shadows. */
export function surfaceHeight(x: number, y: number, z: number): number {
return Math.max(0, terrainHeight(x, y, z));
}
