Metadata-Version: 2.3
Name: whitebox-plugin-videojs-threejs
Version: 0.1.2
Summary: Three.js integration for VideoJS
License: GNU Affero General Public License v3
Author: Milos
Author-email: hello@example.org
Requires-Python: >=3.14.0
Classifier: License :: Other/Proprietary License
Classifier: Programming Language :: Python :: 3
Description-Content-Type: text/markdown

# Whitebox Plugin - Three.js for VideoJS

This is a plugin for [whitebox](https://gitlab.com/whitebox-aero) that provides Three.js integration VideoJS players.

## Video360 projection and leveling contract

`DualFisheyeProjectedVideo` keeps the horizontal 2:1 dual-fisheye layout
identified by `whitebox.video360.dual-fisheye-hstack.v1`: stream 0 is the
left square half and stream 1 is the right square half. The shader owns that
projection; equirectangular inputs are not supported.

The optional `projection` prop defaults to that profile. The optional
`onLevelingReady` callback receives a generation-bound capability after the
Three.js sphere and renderer are ready, and receives `null` when that generation
is retired. Existing `options` and `onReady` behavior is unchanged.

The capability contains only:

```js
{
  projection: "whitebox.video360.dual-fisheye-hstack.v1",
  frame: "whitebox.video360.leveling-root.v1",
  apply({ frame, gravity }),
  clear(),
}
```

The leveling-root frame is the right-handed Three.js root/world frame: `+X`
world (viewer-left with the current `+Z` camera target), `+Y` up, and `+Z`
target-forward. Device producers own camera-specific raw-to-root calibration.
`gravity` is a finite three-element unit vector expressed in that frame. The
renderer defensively normalizes values within `1e-3` of unit length and rejects
all other values. Gravity contains no yaw information; root leveling applies
the shortest deterministic rotation directly from root gravity to world down
`[0, -1, 0]` and adds no intentional twist. OrbitControls and the user camera
remain independent of leveling.

Independently, the shader source direction and `THREE.SphereGeometry` vertex
use different numeric bases for the same UV. The dual-fisheye projection domain
maps source `(x, y, z)` to sphere vertex `(z, y, -x)` using the fixed `+90°` Y
basis matrix:

```text
    [ 0  0  1 ]
B = [ 0  1  0 ]
    [-1  0  0 ]
```

This basis belongs only to panorama texture sampling and projection tests. It
must not be applied to root leveling, OrbitControls, or the camera. Keeping the
projection mapping separate preserves shader presentation while canonical
side and front/back gravity rotate around the visible roll and pitch axes.

`SphereGeometry` stores its vertical UV as `1-v`. The shader therefore uses
`(vUv.y - 0.5) * pi` for its internal source latitude so source and geometry Y
have the same sign. Its final fisheye texture V calculation uses the paired
opposite sign, `0.5 - fy * 0.5`; these two signs must change together. Their
effects cancel algebraically, preserving the existing sampled texture exactly.

`apply` and `clear` return promises. A promise resolves `true` only after a
render used that exact latest root transform. Superseded or retired work
resolves `false`; invalid frame/vector input rejects and resets the source root
to neutral. Leveling never modifies the camera, OrbitControls, Video.js player,
texture, or shader resources.


Each post-initialization Video.js `loadstart` retires the old leveling source
generation, resets its root to neutral, and publishes a fresh capability. When
the tech and video element are unchanged, this does not recreate player or
Three.js resources.

## Installation

Install the plugin to whitebox:

```bash
poetry add whitebox-plugin-videojs-threejs
```

## Additional Instructions

- [Plugin Development Guide](https://docs.whitebox.aero/plugin_guide/#plugin-development-workflow)
- [Plugin Testing Guide](https://docs.whitebox.aero/plugin_guide/#testing-plugins)
- [Contributing Guidelines](https://docs.whitebox.aero/development_guide/#contributing)

