cars: add time-based traffic profile with weekend and Sunday peaks
This commit is contained in:
1 parent
19a2759685
commit
e3250a34da
2 files changed
+77
-22
No files matched your search
Vendored
+55
-21
@@ -3359,6 +3359,58 @@ var CAR_LANE_PX = CAR_TUN.lanePx || 2.6;
|
||||
var CAR_BRIGHT = CAR_TUN.brightness || 1.3;
|
||||
var CAR_SPEED = CAR_TUN.speed || 1;
|
||||
var CAR_DENS = CAR_TUN.density || 1;
|
||||
var CAR_TIME_CFG = CAR_TUN.timeProfile || {};
|
||||
var CAR_TIME_ON = CAR_TIME_CFG.enabled !== false;
|
||||
function carSmoothstep(a, b, x) {
|
||||
var t = Math.max(0, Math.min(1, (x - a) / Math.max(1e-6, b - a)));
|
||||
return t * t * (3 - 2 * t);
|
||||
}
|
||||
function carGaussian(hh, center, width) {
|
||||
var d = hh - center;
|
||||
if (d > 12) d -= 24;
|
||||
if (d < -12) d += 24;
|
||||
var w = Math.max(0.25, width);
|
||||
return Math.exp(-(d * d) / (2 * w * w));
|
||||
}
|
||||
function carWeekendFactor(dow, hh) {
|
||||
var sat = (typeof CAR_TIME_CFG.saturday === 'number') ? CAR_TIME_CFG.saturday : 0.65;
|
||||
var sun = (typeof CAR_TIME_CFG.sunday === 'number') ? CAR_TIME_CFG.sunday : 0.55;
|
||||
var work = (typeof CAR_TIME_CFG.weekday === 'number') ? CAR_TIME_CFG.weekday : 1.0;
|
||||
function wOf(d) { return d === 0 ? sun : (d === 6 ? sat : work); }
|
||||
var f = wOf(dow);
|
||||
if (hh >= 23) f = f + (wOf((dow + 1) % 7) - f) * (hh - 23);
|
||||
else if (hh < 1) f = wOf((dow + 6) % 7) + (f - wOf((dow + 6) % 7)) * hh;
|
||||
return Math.max(0.15, Math.min(1.5, f));
|
||||
}
|
||||
function carRushFactor(hh, dow) {
|
||||
if (!CAR_TIME_ON || typeof hh !== 'number') return 1;
|
||||
var morningPeak = (typeof CAR_TIME_CFG.morningPeak === 'number') ? CAR_TIME_CFG.morningPeak : 7.7;
|
||||
var morningWidth = (typeof CAR_TIME_CFG.morningWidth === 'number') ? CAR_TIME_CFG.morningWidth : 1.2;
|
||||
var morningGain = (typeof CAR_TIME_CFG.morningGain === 'number') ? CAR_TIME_CFG.morningGain : 0.55;
|
||||
var eveningPeak = (typeof CAR_TIME_CFG.eveningPeak === 'number') ? CAR_TIME_CFG.eveningPeak : 17.5;
|
||||
var eveningWidth = (typeof CAR_TIME_CFG.eveningWidth === 'number') ? CAR_TIME_CFG.eveningWidth : 1.4;
|
||||
var eveningGain = (typeof CAR_TIME_CFG.eveningGain === 'number') ? CAR_TIME_CFG.eveningGain : 0.75;
|
||||
var nightReduction = (typeof CAR_TIME_CFG.nightReduction === 'number') ? CAR_TIME_CFG.nightReduction : 0.70;
|
||||
var fridayGain = (typeof CAR_TIME_CFG.fridayEveningGain === 'number') ? CAR_TIME_CFG.fridayEveningGain : 0.35;
|
||||
var sundayEveningPeak = (typeof CAR_TIME_CFG.sundayEveningPeak === 'number') ? CAR_TIME_CFG.sundayEveningPeak : 18.5;
|
||||
var sundayEveningWidth = (typeof CAR_TIME_CFG.sundayEveningWidth === 'number') ? CAR_TIME_CFG.sundayEveningWidth : 1.8;
|
||||
var sundayEveningGain = (typeof CAR_TIME_CFG.sundayEveningGain === 'number') ? CAR_TIME_CFG.sundayEveningGain : 0.85;
|
||||
|
||||
var rush = 1;
|
||||
rush += morningGain * carGaussian(hh, morningPeak, morningWidth);
|
||||
rush += eveningGain * carGaussian(hh, eveningPeak, eveningWidth);
|
||||
|
||||
if (dow === 5) rush += fridayGain * carGaussian(hh, 18.0, 1.6);
|
||||
if (dow === 0) rush += sundayEveningGain * carGaussian(hh, sundayEveningPeak, sundayEveningWidth);
|
||||
|
||||
var nightEdge = -1;
|
||||
if (hh >= 22) nightEdge = carSmoothstep(22, 24, hh);
|
||||
else if (hh < 5) nightEdge = 1 - carSmoothstep(3, 5, hh);
|
||||
if (nightEdge >= 0) rush *= 1 - nightReduction * nightEdge;
|
||||
|
||||
if (typeof dow === 'number') rush *= carWeekendFactor(dow, hh);
|
||||
return Math.max(0.12, Math.min(2.2, rush));
|
||||
}
|
||||
// Gaussian spread of traffic around the motorway network: sigma (spreadKm)
|
||||
// and the floor that distant side roads keep (spreadFloor).
|
||||
var CAR_SIGMA = carMetres((CAR_TUN.spreadKm || 25) * 1000);
|
||||
@@ -6590,30 +6642,12 @@ window.clouds3dRender = function(target) {
|
||||
var carPxScale = Math.max(0.45, Math.min(1.25, gl.drawingBufferHeight / 1080));
|
||||
var tCurve = Math.max(0, Math.min(1, (carNight - 0.10) / 0.40));
|
||||
tCurve = tCurve * tCurve * (3 - 2 * tCurve); // smoothstep
|
||||
// rush-hour shaping: busy evening/early morning, quiet 23:00-04:00
|
||||
// Time-based traffic profile: weekday rush peaks, quiet deep night,
|
||||
// reduced weekend traffic, and a Sunday-evening commuter bump.
|
||||
var rush = 1;
|
||||
var tDay = window.__currentDayProgress;
|
||||
if (typeof tDay === 'number') {
|
||||
var hh = tDay * 24;
|
||||
var nightPos = hh >= 23 ? (hh - 23) / 5 : (hh < 4 ? (hh + 1) / 5 : -1);
|
||||
if (nightPos >= 0) {
|
||||
var edge = Math.min(1, Math.min(nightPos, 1 - nightPos) * 5);
|
||||
edge = edge * edge * (3 - 2 * edge);
|
||||
rush = 1 - 0.65 * edge; // dips to 0.35
|
||||
}
|
||||
// weekend factor (window.__flightDow: 0=Sun..6=Sat), blended
|
||||
// smoothly over the hour around midnight so nothing pops
|
||||
var dow = window.__flightDow;
|
||||
if (typeof dow === 'number') {
|
||||
var wOf = function (d) { return d === 0 ? 0.55 : (d === 6 ? 0.65 : 1); };
|
||||
var fNow = wOf(dow);
|
||||
if (hh >= 23) {
|
||||
fNow = fNow + (wOf((dow + 1) % 7) - fNow) * (hh - 23);
|
||||
} else if (hh < 1) {
|
||||
fNow = wOf((dow + 6) % 7) + (fNow - wOf((dow + 6) % 7)) * hh;
|
||||
}
|
||||
rush *= fNow;
|
||||
}
|
||||
rush = carRushFactor(tDay * 24, window.__flightDow);
|
||||
}
|
||||
gl.useProgram(carProg);
|
||||
gl.uniformMatrix4fv(carUniforms.proj, false, proj);
|
||||
|
||||
Reference in new issue
Block a user