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.
This commit is contained in:
Richard Zink committed 2026-10-07 21:51:24 +02:00
1 parent 9027099d89
commit f21a967643
2 files changed
+36 -15

No files matched your search

+31 -10
View File
@@ -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') {