Purpose of iconOrientation.js in God's Eye View: Icon Orientation and Horizon Culling

src/data/iconOrientation.js serves as the central mathematics-utility module that supplies icon-orientation, horizon-culling, and camera-pose helpers for real-time moving-entity visualization.

This module enables accurate billboard rendering for commercial flights, military aircraft, and AIS vessels by solving critical mathematical challenges: maintaining camera-facing orientation while pointing along true world courses, suppressing projection jitter, and efficiently culling geometry hidden behind the Earth's curvature. Located at src/data/iconOrientation.js, it exports pure functions that work with CesiumJS primitives to keep visualizations performant and geographically accurate without relying on the globe's depth buffer.

Core Mathematical Responsibilities

The module handles five distinct computational domains required for stable icon rendering in a planetary-scale visualization.

Screen-Space Rotation Computation

The screenProjectedRotation(scene, position, courseDeg, previous?) function calculates the billboard heading required to align an icon with its true world course while keeping it camera-facing. It implements a stable camera-basis approximation that functions correctly even when the icon moves off-screen or the camera operates in tracked-orbit mode.

This utility accepts a Cesium scene instance, a Cartesian3 world position, the entity's course in degrees, and an optional previous rotation value for continuity. According to the God's Eye View source code, this is the primary method used by flight tracking layers to align aircraft icons with their actual heading vectors.

Rotation Stabilization

To suppress sub-degree jitter caused by projection noise, the module exports stabilizeScreenRotation(previous, next, deadbandRad?). This function applies a dead-band filter on the shortest wrapped angular difference between frames, preventing visual flicker when slight camera movements project to large angular changes at distance.

The optional deadbandRad parameter controls the angular threshold in radians below which changes are ignored, ensuring smooth animation even with noisy GPS or ADS-B data feeds.

Sky-Backdrop Analysis

The skyBackdropFactor(cameraPosition, position, featherRad?) function determines how much sky versus ground lies behind a world point, returning a smooth blend value between 0 (ground) and 1 (sky). This calculation combines an ellipsoidal occlusion test with an eye-plane test to determine label readability against varying backgrounds.

Detection overlays in the visualization use this factor to dynamically adjust contrast, ensuring text remains legible whether positioned over terrain or atmosphere.

Horizon Occlusion Culling

For performance optimization, horizonOccluder(camera) exposes a shared Cesium.EllipsoidalOccluder instance that culls icons behind the horizon when the globe geometry is hidden. The function must be invoked once per tick to maintain an updated camera position within the occluder.

This utility is critical for radio and AIS vessel layers, as it prevents rendering resources from being wasted on entities that are geometrically occluded by the Earth's curvature.

Camera Pose Signature

The cameraPoseSignature(camera) function generates a cheap string fingerprint of the current camera state, rounding position to approximately 10-meter precision and angles to roughly 0.06 degrees. Entity visualization layers use this signature to gate costly rotation recomputations, only updating billboard orientations when the camera has actually moved significantly.

This optimization prevents unnecessary matrix calculations during static observation periods, improving frame rates during long-haul flight tracking scenarios.

Implementation Examples

The following patterns demonstrate common usage of the orientation utilities within the God's Eye View codebase:

import {
  screenProjectedRotation,
  stabilizeScreenRotation,
  horizonOccluder,
  skyBackdropFactor,
  cameraPoseSignature,
} from './iconOrientation.js';

// Compute billboard rotation for an aircraft icon
function updateAircraftBillboard(billboard, scene, aircraft) {
  const { position, courseDeg } = aircraft;
  const rot = screenProjectedRotation(scene, position, courseDeg, billboard.rotation);
  billboard.rotation = stabilizeScreenRotation(billboard.rotation, rot);
}

// Cull icons behind the horizon
function cullBehindHorizon(iconPosition, camera) {
  const occluder = horizonOccluder(camera);
  return occluder.isPointVisible(iconPosition);
}

// Fade label backgrounds based on sky presence
function computeLabelBlend(cameraPos, labelPos) {
  return skyBackdropFactor(cameraPos, labelPos);
}

// Gate rotation updates using camera pose signature
let lastSignature = '';
function needsRotationUpdate(camera) {
  const sig = cameraPoseSignature(camera);
  const changed = sig !== lastSignature;
  lastSignature = sig;
  return changed;
}

Integration with Entity Visualization Layers

The src/data/iconOrientation.js module acts as a shared dependency across multiple entity layers in the God's Eye View repository:

  • src/data/flights.js invokes screenProjectedRotation to align commercial and military flight icons with their real-world courses.
  • src/data/radio.js utilizes horizonOccluder to hide radio icons when they pass below the horizon line.
  • src/data/aisLiveVessels.js imports cameraPoseSignature to implement efficient rotation gating for maritime vessel billboards.
  • src/data/detection.js leverages skyBackdropFactor to blend detection overlays appropriately against sky or ground backgrounds.

Summary

  • src/data/iconOrientation.js provides the mathematical foundation for billboard orientation and horizon culling in God's Eye View.
  • Screen-space rotation functions align icons with true courses while maintaining camera-facing alignment.
  • Stabilization filters suppress angular jitter using dead-band thresholds on wrapped angular differences.
  • Horizon culling via Cesium.EllipsoidalOccluder prevents rendering of occluded entities, saving GPU resources.
  • Camera pose signatures enable efficient update gating, recomputing rotations only when camera movement exceeds 10 meters or 0.06 degrees.

Frequently Asked Questions

What is the primary purpose of iconOrientation.js in God's Eye View?

The module serves as a centralized mathematics utility that computes screen-space orientations for entity billboards, culls objects behind the planetary horizon, and tracks camera pose changes to optimize rendering performance. It bridges the gap between world-coordinate tracking data and camera-facing visual representations without depending on Cesium's depth buffer.

How does horizon culling work in iconOrientation.js?

The horizonOccluder(camera) function returns a Cesium.EllipsoidalOccluder instance that tests whether world points are visible from the current camera position relative to the Earth's ellipsoid. This geometric test is significantly faster than per-pixel depth testing and is called once per tick to maintain a shared occlusion state across all entity layers.

What is the cameraPoseSignature function used for?

cameraPoseSignature(camera) generates a compact string representation of the camera's position and orientation, quantized to approximately 10-meter and 0.06-degree precision. Visualization layers compare this signature between frames to determine whether expensive rotation calculations are necessary, effectively throttling updates when the viewer remains stationary.

Why is rotation stabilization necessary for entity visualization?

Without stabilization, minor projection noise and floating-point precision errors cause billboard orientations to jitter sub-degree amounts each frame. The stabilizeScreenRotation function applies a dead-band filter on angular differences, ensuring that only significant heading changes (exceeding the configurable deadbandRad threshold) result in visual updates, producing smooth, professional animation for tracked entities.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →