Skip to content

Implement LCC and SPZ encoding pipelines with comprehensive tests#7

Merged
merlotqi merged 8 commits into
mainfrom
feat/xgrids-lcc
Jun 3, 2026
Merged

Implement LCC and SPZ encoding pipelines with comprehensive tests#7
merlotqi merged 8 commits into
mainfrom
feat/xgrids-lcc

Conversation

@merlotqi
Copy link
Copy Markdown
Owner

@merlotqi merlotqi commented Jun 3, 2026

No description provided.

merlotqi and others added 8 commits June 2, 2026 13:21
Implement the inverse of the LCC reader — encoding DataTable columns into
the LCC binary format (data.bin, shcoef.bin, index.bin, meta.lcc).

New files:
- src/io/lcc_encoder.h/.cpp — encode functions (rotation 10-10-10-2,
  color RGBA, scale exp→uint16, SH 11-10-11, full 32-byte splat record)
- include/splat/io/lcc_writer.h — public API (LccWriteConfig, writeLcc)
- src/io/lcc_writer.cpp — full pipeline: range collection, quadtree
  spatial partition, per-cell encoding, file output with nlohmann::json
- tests/lcc_writer_test.cpp — 12 round-trip tests for all encoders

Fixes:
- cmake/FindWebP.cmake: add libsharpyuv for WebP 1.4+ compatibility
- lccClamp: fix inverted upper-bound ternary (returned x instead of hi)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Extract shared decode helpers (decodePositions/Scales/Colors/Alphas/Rotations/SH)
  for reuse across legacy v2-v3 and v4 NGSP paths
- Add NgspFileHeader struct, TOC parser, and ZSTD stream decompressor
- Implement readSpzV4: parse 32-byte header, ZSTD decompress per-stream,
  decode attributes via shared helpers, build DataTable
- Modify readSpz to detect v4 NGSP magic (0x5053474E) and dispatch
- Legacy v2-v3 GZip path preserved unchanged via readSpzLegacy

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- spz_encoder.h/.cpp: encodePosition (int24), encodeScale (log->uint8),
  encodeColor (SH DC->uint8), encodeAlpha (sigmoid->uint8),
  encodeRotation (smallest-three 9-bit packing), encodeSH (bucket quantize)
- spz_writer.h/.cpp: DataTable -> per-splat encode -> ZSTD multi-stream
  compression -> NgspFileHeader + TOC -> .spz v4 file output
- Configurable SH quantization via SpzWriteOptions (sh1Bits/shRestBits)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Iter 2 (Writer):
- spz_writer_test.cpp: round-trip tests (no SH, with SH, single splat)

Iter 3 (CoordinateConverter):
- include/splat/maths/coordinate-converter.h: 16-system enum, converter struct
- src/maths/coordinate-converter.cpp: within-family sign flips,
  cross-family R_x(±π/2) analytic rotation for pos/quat/SH bands 0-1
- coordinate_converter_test.cpp: identity, within-family, cross-family
  round-trip, all 16 systems

Fix: add missing <cmath> include in spz_encoder.h for std::exp

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Covers v4 NGSP (ZSTD multi-stream) and v2-v3 legacy (GZip) formats:
- File layout with header, TOC, attribute stream ordering
- Per-attribute encoding formulas: position (int24), scale (log),
  color (SH DC), alpha (sigmoid), rotation (smallest-three),
  spherical harmonics (bucket quantization)
- Coordinate system conventions (RUB default)
- File detection logic
- References to the official SPZ repository

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Reader:
- Lcc2Scene/Lcc2Node data structures (Eigen bounding box, optional 3dgs/mesh refs)
- JSON tree parse with recursive node builder
- Format dispatch by file extension (PLY/SPZ/SOG via existing readers)
- Lazy loading with file-index cache
- flattenLcc2Scene: collect all leaf data + concatenate

Writer:
- Quadtree spatial partition (reused from LCC1)
- Per-cell SPZ file output via writeSpz
- Two-level JSON tree: root → cell nodes → LOD leaves
- Auto GUID generation, configurable cell size and output name

~380 lines total (vs LCC1's ~1200). LCC2 delegates encoding to
standard formats — no custom binary codec needed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@merlotqi merlotqi merged commit 619f8d9 into main Jun 3, 2026
1 of 3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant