base_2 0.1.0

Exact fixed-point geometry. Float in, float out, zero drift inside.
Documentation
  • Coverage
  • 100%
    45 out of 45 items documented2 out of 25 items with examples
  • Size
  • Source code size: 37.36 kB This is the summed size of all the files inside the crates.io package for this release.
  • Documentation size: 3.31 MB This is the summed size of all files generated by rustdoc for all configured targets
  • Ø build duration
  • this release: 27s Average build duration of successful builds.
  • all releases: 27s Average build duration of successful builds in releases after 2024-10-23.
  • Links
  • Homepage
  • Avon662/base_2
    1 0 0
  • crates.io
  • Dependencies
  • Versions
  • Owners
  • Avon662

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

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

// 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: ±231 input units with i64, ±295 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

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