From f21a9676433dd4ac3cf5ea9c0d18c4e0c3e179c6 Mon Sep 17 00:00:00 2001 From: Richard Zink Date: Wed, 7 Oct 2026 21:51:24 +0200 Subject: [PATCH] Separate flight and fetch directions via URL params Two independent URL parameters: #flight=N|NE|E|SE|S|SW|W|NW (camera motion direction) #fetch=N|NE|E|SE|S|SW|W|NW (tile collection direction) Example: #flight=E&fetch=N -> camera flies east, corridor built north (perpendicular to flight). Lets you test what happens when the corridor orientation doesn't match the camera's flight path. URL parsing supports & and ; as separators, plus multiple keys in one hash. window.__flightDir and window.__fetchDir are exposed separately so JS code can react to each. --- background.html | 41 +++++++++++++++++++++++++++++++---------- vendor/clouds3d.js | 10 +++++----- 2 files changed, 36 insertions(+), 15 deletions(-) diff --git a/background.html b/background.html index fedf31b..6ce828a 100644 --- a/background.html +++ b/background.html @@ -513,24 +513,45 @@ window.__clouds2dStarted = true; try { window.__noiseDataUri = 'data:image/png;base64,PLACEHOLDER'; var noiseDataUri = 'data:image/png;base64,PLACEHOLDER'; -// URL override for easy A/B testing: #renderer=clouds2d / #renderer=clouds3d -var _urlRenderer = (location.hash.match(/renderer=(\w+)/) || [])[1]; +// Parse URL hash params: #key=value&key=value... +// Supported: #renderer=clouds2d|clouds3d|vanta, #flight=N|NE|E|SE|S|SW|W|NW, +// #fetch=N|NE|E|SE|S|SW|W|NW +function _parseHashParams(hash) { + var out = {}; + hash = (hash || '').replace(/^#/, ''); + var pairs = hash.split(/[&;]/); + for (var i = 0; i < pairs.length; i++) { + var eq = pairs[i].indexOf('='); + if (eq > 0) { + out[pairs[i].slice(0, eq).toLowerCase()] = pairs[i].slice(eq + 1); + } + } + return out; +} +var _hashParams = _parseHashParams(location.hash); + +// Renderer override +var _urlRenderer = _hashParams.renderer; var renderer = _urlRenderer || (window.CONFIG && window.CONFIG.renderer) || 'vanta'; -// Flight direction for ground-tile corridor (N, NE, E, SE, S, SW, W, NW). -// Default 'N' (= +Z world) so behaviour is unchanged when hash is absent. -var _urlFlight = (location.hash.match(/flight=(\w+)/) || [])[1]; +// Compass directions for flight and fetch (independent). Each direction +// has cos/sin (corridor rotation matrix) and dx/dz (camera motion unit vec). var FLIGHT_DIRS = { - N: { cos: 0.0, sin: 1.0, dx: 0, dz: 1 }, + N: { cos: 0.0, sin: 1.0, dx: 0, dz: 1 }, NE: { cos: 0.7071068, sin: 0.7071068, dx: 0.7071068, dz: 0.7071068 }, - E: { cos: 1.0, sin: 0.0, dx: 1, dz: 0 }, + E: { cos: 1.0, sin: 0.0, dx: 1, dz: 0 }, SE: { cos: 0.7071068, sin:-0.7071068, dx: 0.7071068, dz:-0.7071068 }, - S: { cos: 0.0, sin:-1.0, dx: 0, dz:-1 }, + S: { cos: 0.0, sin:-1.0, dx: 0, dz:-1 }, SW: { cos:-0.7071068, sin:-0.7071068, dx:-0.7071068, dz:-0.7071068 }, - W: { cos:-1.0, sin: 0.0, dx:-1, dz: 0 }, + W: { cos:-1.0, sin: 0.0, dx:-1, dz: 0 }, NW: { cos:-0.7071068, sin: 0.7071068, dx:-0.7071068, dz: 0.7071068 } }; -window.__flightDir = FLIGHT_DIRS[_urlFlight && FLIGHT_DIRS[_urlFlight.toUpperCase()] ? _urlFlight.toUpperCase() : 'N']; +function _pickDir(key) { + var raw = (_hashParams[key] || 'N').toUpperCase(); + return FLIGHT_DIRS[raw] || FLIGHT_DIRS.N; +} +window.__flightDir = _pickDir('flight'); +window.__fetchDir = _pickDir('fetch'); var useVanta = (renderer !== 'clouds2d' && renderer !== 'clouds3d'); var effect; if (useVanta && typeof VANTA !== 'undefined') { diff --git a/vendor/clouds3d.js b/vendor/clouds3d.js index e8e0fb4..a57cb5a 100644 --- a/vendor/clouds3d.js +++ b/vendor/clouds3d.js @@ -285,11 +285,11 @@ function init(canvas) { var GROUND_TILE_URL = 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/'; var GROUND_TILE_Z = 11; var GROUND_TILE_SIZE = 256; -// Camera flight direction. Set from window.__flightDir (URL: #flight=N|NE|E|...). -// Default is N (= +Z forward). Each flight direction rotates the -// corridor so its long axis follows the camera path. -var GROUND_TRAVEL_COS = (window.__flightDir && window.__flightDir.cos) || 0.0; -var GROUND_TRAVEL_SIN = (window.__flightDir && window.__flightDir.sin) || 1.0; +// Fetch direction: which way the tile corridor is oriented. +// Independent of flight direction (set via #fetch=N|NE|E|...). +// Default N (= +Z, canvas Y = +Z). +var GROUND_TRAVEL_COS = (window.__fetchDir && window.__fetchDir.cos) || 0.0; +var GROUND_TRAVEL_SIN = (window.__fetchDir && window.__fetchDir.sin) || 1.0; var GROUND_CORRIDOR_LONG = 25; // tiles along travel direction (~3.5 min of flight at uSpeed=1) var GROUND_CORRIDOR_PERP = 5; // tiles perpendicular to travel var GROUND_BUFFER_LONG = 11; // refetch when this close to forward edge