fix(director): seek camera longitude across the shortest dateline arc

This commit is contained in:
Rudy Celekli committed 2026-10-14 14:17:39 -04:00
1 parent 6dd4d0156f
commit 632005d221
4 files changed
+40 -1

No files matched your search

+2
View File
@@ -15,6 +15,8 @@
the five borough cores load and `CCTV_NYC_MAX_SOURCES` changes the cap. The catalog-wide ceiling is
unchanged; extra cameras share it round-robin with the other packs.
- Director timeline seeks cross the dateline along the short longitude arc.
- Treat explicitly current, complete empty vessel coverage as a successful update,
clearing obsolete contacts while retaining stale or incomplete snapshots.
+5
View File
@@ -5310,3 +5310,8 @@ datacenters, dams and the Nepal locator retain that shared credit while displaye
Military fragments stitch by source identity. Different mapped parcels merge only
when their footprints touch or contain one another, never across a seam tolerance gap.
### fix(director): seek camera longitude across the shortest dateline arc
Interpolate longitude with the existing shortest-angle easing, normalize intermediate longitudes, and preserve exact authored endpoints at progress zero and one.
@@ -0,0 +1,26 @@
import test from 'node:test';
import assert from 'node:assert/strict';
import { cameraAtProgress } from './timeline.js';
const camera = (lon) => ({
lat: 10,
lon,
alt: 1000,
heading: 0,
pitch: -40,
roll: 0,
});
test('director seek follows the short dateline arc in both directions', () => {
for (const [a, b] of [
[179, -179],
[-179, 179],
]) {
assert.equal(
Math.abs(cameraAtProgress(camera(a), camera(b), 0.5).lon),
180,
);
assert.equal(cameraAtProgress(camera(a), camera(b), 0).lon, a);
assert.equal(cameraAtProgress(camera(a), camera(b), 1).lon, b);
assert.ok(Math.abs(cameraAtProgress(camera(a), camera(b), 0.25).lon) > 179);
}
assert.equal(cameraAtProgress(camera(20), camera(24), 0.5).lon, 22);
});
+7 -1
View File
@@ -45,7 +45,13 @@ export function cameraAtProgress(fromCamera, toCamera, progress) {
};
return {
lat: lerp(source.lat, target.lat),
lon: lerp(source.lon, target.lon),
lon:
t === 0
? Number(source.lon)
: t === 1
? Number(target.lon)
: ((((lerpAngle(source.lon, target.lon) + 180) % 360) + 360) % 360) -
180,
alt: lerp(source.alt, target.alt),
heading: lerpAngle(source.heading, target.heading),
pitch: lerp(source.pitch, target.pitch),