base_2 0.1.0

Exact fixed-point geometry. Float in, float out, zero drift inside.
Documentation
# base_2

Exact fixed-point geometry. Float in, float out, zero drift inside.

## The problem

Floating point geometry drifts. Every transform, every frame, every physics tick adds a tiny error. Over time vertices shift, collision checks disagree, and multiplayer clients desync. The root cause is always the same: floating point math is approximate by design.

## The fix

`base_2` intercepts your geometry once, freezes it to exact 64-bit integers, and gives you back two representations:

- **Exact `i64`** — for logic, physics, collision. Deterministic on a given platform.
- **Clean `f32`** — freshly derived from the exact source every frame, for your GPU.

Error is introduced exactly once, at freeze time, bounded at ≤ 2^-33 of your input unit. It does not grow with subsequent operations.

## Quick start

```rust
use base_2::api::Mesh;

// load from any float source — STL, OBJ, GLTF, engine mesh, etc.
let mesh = Mesh::from_floats(&float_verts)
    .translate(10.0, 0.0, 0.0)
    .rotate_quat(0.0, 0.0, 0.707, 0.707);

// compute once per frame
let pts = mesh.compute();

let gpu   = pts.to_f32();  // clean floats for renderer — derived fresh each frame
let logic = pts.to_i64();  // exact integers for physics and collision
```

## Game engine integration

```rust
// freeze on load — once
let mesh = Mesh::from_floats(&engine_mesh.vertices);

// every frame
mesh.translate(player.x, player.y, player.z)
    .rotate_quat(player.qx, player.qy, player.qz, player.qw);

let pts = mesh.compute();
renderer.upload(pts.to_f32());    // GPU gets clean floats
physics.update(pts.to_i64());     // logic gets exact integers
```

No epsilon tuning. No tolerance stacking. No "works on my machine" bugs.
Multiplayer clients running the same logic get the same integers — deterministic on a given platform.

## Coordinate system

Internally, 1 unit = 2^-32 of your input unit.

- **Resolution**: 2^-32 per input unit
- **Range**: ±2^31 input units with `i64`, ±2^95 input units with `i128`
- **Overflow**: predictable — `i64` always uses all 64 bits, worst-case behavior is known upfront

Units are user-defined. Pass millimeters, game units, or anything else — as long as you are consistent.

## Transforms

```rust
mesh.translate(x, y, z)                    // set translation
mesh.scale(x, y, z)                        // set scale
mesh.rotate(rx, ry, rz)                    // Euler angles — simple but has gimbal lock
mesh.rotate_quat(qx, qy, qz, qw)          // quaternion — preferred, no gimbal lock
```

All setters overwrite — pass the absolute current transform each frame, not a delta.
Transforms are applied fresh from the original frozen points every call to `compute()`.

## Why `base_2`?

The 2^-32 scaling is not arbitrary. It means every coordinate uses all 64 bits, giving uniform precision across the entire range. There is no false headroom, no "works on small inputs but breaks on large ones." Overflow behavior is always worst-case, always documented, always the same.

It is the fixed-point equivalent of Rust's ownership model: honest about what it costs, in exchange for guarantees you can rely on.

## License

Apache 2.0