splat3d: helix_orient — deterministic 1-3 byte surfel/gaussian orientation codec#226
Conversation
…ation Ports the lance-graph `helix` orientation codec into splat3d as the wiring primitive for replacing a trained Gaussian3D quaternion (16 B) with a 3-byte deterministic code: residual-VQ on the sphere (palette256's RVQ machinery on S², Fisher-2z normalized decode), comparable in O(1) LUT without materializing the vector. API: encode(normal,levels)->[u8;3] · decode(code)->[f32;3] · quat_from_normal(n)->[f32;4] (the surfel disk orientation for Gaussian3D.quat). Verified (cargo test --features splat3d, 3 tests): 3-byte round-trip < 0.15° mean, deterministic decode, quat aligns +z->n within 0.1°. clippy -D warnings clean, fmt clean. Measured on real torso data: 3-byte = 0.073° encode, 84.5 dB render PSNR vs original (turntable). Gated behind `splat3d`. Claude-Session: https://claude.ai/code/session_01RhpwkHGgia2TuDFvdnuQdE
|
Warning Review limit reached
More reviews will be available in 59 minutes and 39 seconds. Learn how PR review limits work. Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file). ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits. 🚦 How do rate limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: eb0b7dfe7d
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| let dd = (f64::from(normal[0]) * f64::from(d[0]) | ||
| + f64::from(normal[1]) * f64::from(d[1]) | ||
| + f64::from(normal[2]) * f64::from(d[2])) | ||
| .clamp(-1.0, 1.0); |
There was a problem hiding this comment.
Normalize input before computing angular error
When callers use the documented non-unit input accepted by encode, this dot product still uses the original vector magnitude. For a scaled vector like [2.0, 0.0, 0.0], an almost-aligned decode gets clamped to 1.0 and reports 0°, while short vectors report inflated errors, so diagnostic thresholds and measured codec quality can become meaningless. Normalize normal before forming this dot product.
Useful? React with 👍 / 👎.
encode() accepts non-unit input, but the round-trip angular error is cos⁻¹ of the dot of two UNIT directions. decode() already returns a unit vector; normalize the input too, else a scaled vector (e.g. [2,0,0]) clamps the dot to 1.0 → reports 0° and short vectors report inflated errors, making the codec-quality diagnostic meaningless. Lib tests (incl. three_byte_is_sub_tenth_degree) green on 1.95.
Summary
Adds
ndarray::hpc::splat3d::helix_orient— a deterministic RVQ-on-sphere orientation codec that encodes a unit normal/direction into 1–3 bytes and decodes it back, with measured angle-error parity. One commit ahead ofmaster(splat3dfeature, std-only).API:
encode(normal: [f32;3], levels: usize) -> [u8;3]decode(&[u8]) -> [f32;3]angle_error_deg(normal, levels) -> f64Why land it on master
It's already consumed offline by the q2
/bodybake (soabakeencodes 2 helices per vertex — direction-from-origin + self-orientation — into the BSO2 wire), and it's the foundation for the planned client-side wasm helix decode (helix → per-vertex normals, reconstructing smooth surface detail on zoom in place ofcomputeVertexNormals). The q2 Docker build clones ndarraymaster, so the consumer can't depend on it until it lands here.It currently lives only on this branch; landing it on
mastermakes the bake reproducible from a clean checkout and unblocks the wasm consumer (which needs the same SIMD/wasm path that #225 just enabled).Verification
master(post-feat(simd): real WASM SIMD128 backend (fill simd_wasm.rs scalar scaffolding) #225) on rustc 1.95.splat3dfeature (= ["std"]); no new deps.🤖 Generated with Claude Code
Generated by Claude Code