ifcviewer: shrink vertex format from 16 to 12 bytes (oct i8x2 normals)

Replace i16x2 octahedral normals with i8x2, filling the 2-byte padding
after position and saving 4 bytes per vertex. int8 gives ~1.4 deg
worst-case angular error — invisible for BIM geometry which is
overwhelmingly axis-aligned. 25% VBO reduction; sidecar files shrink
~15% overall (5.4 GB -> 4.6 GB on a 111-model test scene). Bumps
sidecar format to v7.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Dion Moult
2026-04-20 12:26:29 +10:00
parent dbe68b48f2
commit 3015f758ba
4 changed files with 85 additions and 155 deletions
+4 -2
View File
@@ -39,7 +39,9 @@ static constexpr uint32_t SIDECAR_MAGIC = 0x49465657; // "IFVW"
// where meshoptimizer decimation produced useful output.
// v6 = VBO vertices quantized to 16 B/vertex (pos u16x3 + normal oct i16x2 +
// color u8x4). Dequant basis is per-mesh MeshInfo.local_aabb_min/max.
static constexpr uint32_t SIDECAR_VERSION = 6;
// v7 = VBO vertices shrunk to 12 B/vertex (normal oct i8x2 replaces i16x2,
// eliminating 2-byte pad + saving 2 bytes on normal).
static constexpr uint32_t SIDECAR_VERSION = 7;
static constexpr uint32_t SIDECAR_ENDIAN = 0x01020304;
// Fixed-size element record. Strings are stored as (offset, length) pairs
@@ -61,7 +63,7 @@ struct PackedElementInfo {
// re-running the iterator. v6 schema: instanced + quantized geometry.
struct SidecarData {
// Per-model GPU geometry (local coords). Raw VBO bytes at the
// INSTANCED_VERTEX_STRIDE_BYTES layout (16 B/vertex as of v6).
// INSTANCED_VERTEX_STRIDE_BYTES layout (12 B/vertex as of v7).
std::vector<uint8_t> vertices;
std::vector<uint32_t> indices;