# What Is the Purpose of `src/data/iconOrientation.js` in God's Eye View?

> Discover the purpose of src/data/iconOrientation.js in God's Eye View. This module provides math helpers for orienting, stabilizing, and culling icon billboards in Cesium.

- Repository: [Bilawal Sidhu/gods-eye-view](https://github.com/bilawalsidhu/gods-eye-view)
- Tags: internals
- Published: 2026-09-06

---

**[`src/data/iconOrientation.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/data/iconOrientation.js) is a utility module that provides mathematical helpers for orienting, stabilizing, and culling icon-like billboards in the Cesium-based God's Eye View application.**

This file originated from a critical bug fix during a 2026 playtest, where moving-entity icons incorrectly stuck to the viewport during tracked-orbit camera modes. According to the `bilawalsidhu/gods-eye-view` source code, the module now enables stable, continuous billboard rotation across all camera regimes while keeping computations lightweight.

---

## Why [`src/data/iconOrientation.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/data/iconOrientation.js) Exists

The God's Eye View application renders thousands of moving entities—commercial flights, military aircraft, and AIS vessels—as **billboard icons** on a 3D globe. In tracked-orbit mode, the camera heading is expressed in the entity's reference frame rather than world space, which breaks standard world-to-window orientation calculations.

The module in [`src/data/iconOrientation.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/data/iconOrientation.js) solves this by **projecting the entity's local forward vector onto the camera's right/up basis** rather than using a naive world-to-window probe. This approach delivers correct orientation regardless of camera mode.

---

## Core Functions in [`src/data/iconOrientation.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/data/iconOrientation.js)

### `screenProjectedRotation`: Ground Course to Screen-Space Rotation

The **`screenProjectedRotation`** function transforms an entity's true ground course into a billboard rotation that displays correctly in screen space.

```javascript
// Example: compute a billboard rotation for a moving aircraft
import { screenProjectedRotation, stabilizeScreenRotation } from './iconOrientation.js';

function updateAircraftBillboard(billboard, scene, position, courseDeg) {
  // Get the new rotation (radians) based on current camera and course
  const newRot = screenProjectedRotation(
    scene,
    position,
    courseDeg,
    billboard.rotation
  );

  // Smooth out tiny jitter
  billboard.rotation = stabilizeScreenRotation(
    billboard.rotation,
    newRot
  );
}

```

The implementation (lines 41–50) converts the local forward vector to world space, then projects onto the camera basis. This handles the tracked-orbit case where standard Euler rotations fail.

### `stabilizeScreenRotation`: Dead-Band Jitter Suppression

The **`stabilizeScreenRotation`** function prevents sub-degree noise from causing visible icon twitching.

With a default dead-band of approximately **0.5°**, the function holds the previous rotation when changes fall below this threshold (lines 82–101). This matters for aircraft icons at high zoom levels, where tiny projection variations would otherwise cause distracting shimmy.

### `cameraPoseSignature`: Cheap Change Detection

The **`cameraPoseSignature`** function (lines 332–340) emits a compact, quantized string describing camera position and orientation. This enables inexpensive "did the camera move" checks before recomputing expensive rotation calculations.

Rather than comparing full `Cesium.Matrix4` instances, the consuming code hashes a reduced-precision representation, cutting comparison cost from hundreds of floating-point operations to a single string equality test.

---

## Horizon and Sky Utilities

[`src/data/iconOrientation.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/data/iconOrientation.js) extends beyond pure rotation into atmospheric rendering support.

### `HORIZON_FEATHER_RAD` and `skyBackdropFactor`

- **`HORIZON_FEATHER_RAD`** (lines 112–119): Defines an ≈**1.1° angular band per side** where labels fade via smooth-step interpolation rather than popping at the horizon edge.

- **`skyBackdropFactor`** (lines 167–215): Computes a **0…1 blend value** indicating whether the sky or ground occupies the background behind any world point. This handles both above-surface ray intersections and below-surface eye-plane regimes.

```javascript
// Example: decide label backdrop blending
import { skyBackdropFactor } from './iconOrientation.js';

function computeLabelAlpha(cameraPos, labelPos) {
  const skyFactor = skyBackdropFactor(cameraPos, labelPos);
  // Blend label opacity between ground (0) and sky (1)
  return 0.5 + 0.5 * skyFactor;
}

```

These utilities let detection overlays and traffic labels adapt their contrast automatically based on whether they appear against dark terrain or bright sky.

### `horizonOccluder`: Manual Culling for 3D Tiles

The **`horizonOccluder`** function (lines 226–229) returns a reusable `Cesium.EllipsoidalOccluder` synchronized with current camera position. This provides fast point-in-view checks when the standard Cesium globe is hidden—specifically when using 3D tilesets for detailed urban geometry.

```javascript
// Example: cull a billboard when it falls behind the horizon
import { horizonOccluder } from './iconOrientation.js';

function shouldRenderBillboard(camera, worldPos) {
  const occluder = horizonOccluder(camera);
  return occluder.isPointVisible(worldPos);
}

```

---

## Module Relationships

| File | Role | Connection to [`iconOrientation.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/iconOrientation.js) |
|---|---|---|
| [`src/data/iconOrientation.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/data/iconOrientation.js) | Core orientation utilities | — |
| [`src/data/traffic.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/data/traffic.js) | Moving traffic entity management | Uses rotation helpers for billboard updates |
| [`src/data/trafficFlowStyle.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/data/trafficFlowStyle.js) | Layer styling | Applies orientation-derived transforms |
| [`src/data/trafficPresetStyle.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/data/trafficPresetStyle.js) | Visual preset definitions | Relies on orientation utilities for correct icon alignment |

The rotation functions are consumed by the traffic rendering pipeline, where they transform raw course headings from ADS-B or AIS feeds into correctly-oriented screen sprites.

---

## Summary

- **[`src/data/iconOrientation.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/data/iconOrientation.js)** provides **screen-projected rotation** that works correctly in tracked-orbit camera modes where standard world-space calculations fail.

- **`stabilizeScreenRotation`** eliminates sub-degree jitter with a **0.5° dead-band**, improving visual stability for moving icons.

- **`skyBackdropFactor`** and **`HORIZON_FEATHER_RAD`** enable adaptive label rendering across the horizon boundary with smooth fade transitions.

- **`horizonOccluder`** and **`cameraPoseSignature`** optimize performance through reusable culling structures and cheap change detection.

- The module originated from a **2026 playtest bug** and now underpins correct orientation for all traffic billboard rendering in God's Eye View.

---

## Frequently Asked Questions

### How does `screenProjectedRotation` differ from standard Cesium billboard rotation?

Standard Cesium billboard rotation uses world-space angles, which break when the camera enters **tracked-orbit mode** where heading is relative to the tracked entity. `screenProjectedRotation` (lines 41–50) instead projects the entity's forward vector onto the camera's right/up basis, producing correct screen-space alignment in all camera regimes.

### What is the performance cost of the orientation calculations?

The math is intentionally **lightweight**—pure vector projections without trigonometric loops. `cameraPoseSignature` provides cheap early-exit when the camera hasn't moved, and the `horizonOccluder` is cached and reused. The module was optimized to handle thousands of traffic icons at 60fps.

### Can [`iconOrientation.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/iconOrientation.js) be used with custom entity types beyond traffic?

Yes. The functions are **entity-agnostic**: they accept `scene`, `position`, and `courseDeg` parameters without coupling to the traffic data model. Any billboard-based visualization—weather markers, sensor coverage, or simulation objects—can import and use these utilities.

### Why is horizon feathering handled in this module rather than shaders?

`HORIZON_FEATHER_RAD` and `skyBackdropFactor` serve **label and overlay logic** that runs on the CPU in JavaScript, not the GPU. CPU-side calculation allows JavaScript code to blend label opacity and decide backdrop colors before issuing draw calls, avoiding per-frame uniform updates and keeping shader complexity minimal.