Add the wide world-position family, so a 128-bit consumer can actually use this - #7
Merged
Merged
Conversation
…y use this
Seven functions: fixLerpPositionWide, fixTransformWorldPointWide,
fixInvTransformWorldPointWide, fixMakeWorldTransformWide, fixMulWorldTransformsWide,
fixInvMulWorldTransformsWide, fixToRelativeTransformWide.
WHY, and it is not symmetry for its own sake. A consumer whose world positions are
128-bit cannot call the narrow forms AT ALL -- the parameter type is the thing that
differs. box3d's ludicrous build hit exactly this: moving its AABB onto this library
failed with "assigning to fixPosWide from incompatible type b3Pos", because the AABB is
BUILT from world positions and the position family had nowhere to land. The bounding
volumes and the position family have to cross together or neither can.
Deliberately NOT added: second names for things already here. fixPosWideSub is the wide
SubPos, fixPosWideOffset is the wide OffsetPos, fixPosWideFromVec3/ToVec3 are the wide
ToPos/ToVec3. Four of the eleven a naive port would have written already existed.
THE ONE THAT IS NOT A MECHANICAL WIDENING, ported with its reasoning rather than
re-derived: fixLerpPositionWide computes a + t*(b-a), not (1-t)*a + t*b. Widening the
narrow form directly would multiply an ABSOLUTE 128-bit coordinate and overflow. The
reformulation multiplies only the difference, which is in local range. That is one
rounding instead of two, so it is deliberately NOT bit-identical to the narrow build --
a consumer running both widths carries separate goldens, and no amount of care will make
them agree. The wide answer is the more accurate one.
TESTING -- every function is called, because a header-only function nothing references is
invisible to a passing build:
- local -> wide world -> local, checked against the NARROW rotation round-trip rather
than against the input. My first assertion demanded exact recovery and failed; a
control measurement showed the narrow-only path loses the same 2 ULPs and the wide
route adds none. The property worth pinning is that the 128-bit translation
contributes nothing. Asserting equality with the input would have been asserting that
fixed-point rotation is lossless, which is a different and false claim.
- a frame relative to itself is the identity translation; two frames a local distance
apart at a 2^95 base recover that distance exactly -- the premise of the design.
- lerp endpoints exact at any distance, midpoint exact, monotone along the segment,
and the one-rounding form exact for a representable midpoint.
Proven able to fail: swapping the lerp difference operands breaks four checks including
monotonicity. Both frozen hashes unchanged (0x3e1c7997594d2019, 0xeedc16ea642ffb5f).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Seven functions:
fixLerpPositionWide,fixTransformWorldPointWide,fixInvTransformWorldPointWide,fixMakeWorldTransformWide,fixMulWorldTransformsWide,fixInvMulWorldTransformsWide,fixToRelativeTransformWide.Why — not symmetry for its own sake
A consumer whose world positions are 128-bit cannot call the narrow forms at all; the parameter type is the thing that differs. box3d's ludicrous build hit exactly this — moving its AABB onto this library failed with
assigning to 'fixPosWide' from incompatible type 'b3Pos', because the AABB is built from world positions and the position family had nowhere to land. The bounding volumes and the position family have to cross together, or neither can.Deliberately not added
Second names for things already here.
fixPosWideSubis the wide SubPos,fixPosWideOffsetthe wide OffsetPos,fixPosWideFromVec3/ToVec3the wide ToPos/ToVec3. Four of the eleven a naive port would have written already existed.The one that is not a mechanical widening
fixLerpPositionWidecomputesa + t*(b-a), not(1-t)*a + t*b. Widening the narrow form directly would multiply an absolute 128-bit coordinate and overflow. The reformulation multiplies only the difference, which is in local range.That is one rounding instead of two, so it is deliberately not bit-identical to the narrow build. A consumer running both widths carries separate goldens, and no amount of care will make them agree — the wide answer is the more accurate one. Ported with its reasoning rather than re-derived.
Testing
Every function is called; a header-only function nothing references is invisible to a passing build.
The round-trip test is worth noting. My first assertion demanded exact recovery of the input and failed. A control measurement showed the narrow-only rotate/inv-rotate loses the same 2 ULPs and the wide route adds none — so the property worth pinning is that the 128-bit translation contributes nothing. Asserting equality with the input would have been asserting that fixed-point rotation is lossless, which is a different and false claim.
Also: a frame relative to itself is the identity translation; two frames a local distance apart at a 2^95 base recover that distance exactly (the premise of the design); lerp endpoints exact at any distance, midpoint exact, monotone along the segment.
Proven able to fail: swapping the lerp difference operands breaks four checks including monotonicity. Both frozen hashes unchanged.