pub struct WorldPos {
pub sector: I64Vec3,
pub local: DVec3,
}Expand description
An absolute position: sector index plus a local offset in metres.
§Canonical form
A normalized WorldPos keeps local in [0, SECTOR_SIZE) on every axis —
a half-open, non-negative range rather than a range centred on zero.
That makes sector literally floor(absolute / SECTOR_SIZE), i.e. the
index of the grid cell the position is in, which is exactly what the
streaming loader, the broadphase partition and interest management want as a
key (one spatial structure, three consumers — see docs/notes/simulation.md).
A centred range would buy one bit of precision and cost that identity, plus
an off-by-half in every consumer that hashes a cell.
The fields are public because this is a plain data type, but a hand-built
value may be denormalized. Arithmetic through the operators below always
returns normalized values; WorldPos::new normalizes on construction, and
WorldPos::normalize canonicalizes anything.
§Out-of-range positions
A position that would leave the addressable volume saturates at the
boundary sector (i64::MIN / i64::MAX); it never wraps. Wrapping would
teleport a ship from one edge of the universe to the other and every
downstream distance test would silently agree with it. Saturation is lossy
but monotone, obvious in a debugger, and idempotent under repeated
normalization.
Fields§
§sector: I64Vec3Sector index on each axis.
local: DVec3Offset within the sector, in metres. Normalized to [0, SECTOR_SIZE).
Implementations§
Source§impl WorldPos
impl WorldPos
Sourcepub fn from_offset(offset: DVec3) -> Self
pub fn from_offset(offset: DVec3) -> Self
Builds a position from an offset relative to the origin of sector
(0, 0, 0).
Convenient for small worlds and tests. Note that the argument is a plain
DVec3 offset, not a render-space Vec3.
Sourcepub const fn from_sector(sector: I64Vec3) -> Self
pub const fn from_sector(sector: I64Vec3) -> Self
Builds a position at the origin of sector.
Sourcepub fn normalize(self) -> Self
pub fn normalize(self) -> Self
Returns the canonical form of this position: local inside
[0, SECTOR_SIZE) with the overflow carried into sector.
Exact — no bits are lost — because SECTOR_SIZE is a power of two.
Idempotent, including for saturated and non-finite inputs.
A non-finite local is a bug upstream: debug builds assert, release
builds propagate the NaN/infinity rather than inventing a plausible
position.
Sourcepub fn rebase(&mut self)
pub fn rebase(&mut self)
Canonicalizes in place. Same operation as WorldPos::normalize, named
for the physics-side vocabulary (“rebase on sector crossing”).
Sourcepub fn is_normalized(&self) -> bool
pub fn is_normalized(&self) -> bool
Whether local is already inside [0, SECTOR_SIZE) on every axis.
Sourcepub fn delta(self, origin: Self) -> DVec3
pub fn delta(self, origin: Self) -> DVec3
The vector from origin to self, in metres.
This — not any absolute coordinate — is what physics, queries and rendering actually consume.
§Precision
The sector difference is taken in i128, so it cannot wrap even between
opposite corners of the addressable volume, and the largest possible
delta (2^84 m) is nowhere near f64 overflow. The result is therefore
always finite and never wrong by wraparound.
Scaling the index difference by SECTOR_SIZE is always exact — it
only shifts the exponent of a power of two. What is not always exact is
the i128 -> f64 conversion of the difference itself, which is
injective only below 2^53. So:
- |Δsector| ≤ 2^53 (a separation up to
2^73 m≈ 998 000 light-years — the Milky Way and its satellites, ten times over): the sector term is exact, and the only rounding is thelocaldifference and the final addition, i.e. sub-nanometre. - Beyond that: the delta degrades to
f64’s ordinary relative precision, aboutd * 2^-53for a separation ofdmetres —2^31 m≈ 2.1 million km ≈ 0.014 AU at the full 2.04-billion-light-year span. Honest, finite and monotone, but a question nobody should be asking: anything that far away should have been culled on sector distance long before a metre-valued delta was wanted.
The boundary is pinned by a test.
Sourcepub fn distance_squared(self, other: Self) -> f64
pub fn distance_squared(self, other: Self) -> f64
Squared distance between two positions, in metres².
Beware the dynamic range: squaring an intergalactic delta stays finite
in f64 ((2^84)^2 = 2^168) but is only useful for comparisons.
Sourcepub fn relative_to(self, origin: Self) -> Vec3
pub fn relative_to(self, origin: Self) -> Vec3
Converts to camera-relative render space.
This is the only sanctioned path from a WorldPos to a Vec3
anywhere in the engine. A plain Vec3 never holds an absolute position:
it is always an offset from the render origin (typically the camera’s
WorldPos), which is what keeps the GPU’s f32 transforms free of
jitter no matter where in the galaxy the camera is.
The delta is computed in f64 and narrowed to f32 exactly once, here.
Anything far enough away for that narrowing to matter is far enough away
to have been culled.
Sourcepub fn translated(self, offset: DVec3) -> Self
pub fn translated(self, offset: DVec3) -> Self
Moves by offset metres, renormalizing.
Trait Implementations§
Source§impl AddAssign<DVec3> for WorldPos
impl AddAssign<DVec3> for WorldPos
Source§fn add_assign(&mut self, offset: DVec3)
fn add_assign(&mut self, offset: DVec3)
+= operation. Read more