mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-30 16:43:00 +00:00
wgpu cull: refactor per-mesh chunk lookups to per-instance
Preparatory refactor for spatial instance bucketing (#55). Cull previously routed through per-mesh tables (mesh_chunk_idx, mesh_chunk_local_base_vertex, _ebo_first_u32, _lod1_first_u32) to find the chunk and chunk-local offsets for each instance. That assumes a mesh lives in EXACTLY ONE chunk — the assumption holds under the current mesh-keyed planner but breaks under spatial bucketing, where the same mesh can be duplicated across multiple buckets if its instances are scattered. Adds four per-instance arrays (instance_chunk_idx, instance_base_vertex, instance_ebo_first_u32, instance_lod1_first_u32) populated at planning time. The current mesh-keyed planner derives them by translation: instance_chunk_idx[i] = mesh_chunk_idx[instances[i].mesh_id] The spatial-bucket planner (next commit) will populate them directly, allowing the same mesh_id to map to different chunks for different instances. cullModelCpuCompute now reads the per-instance arrays: - frustum_visible_count uses chunks[instance_chunk_idx[i]] - VisibleDrawGpu uses instance_base_vertex / instance_ebo_first_u32 / instance_lod1_first_u32 - LOD-select branch and use_lod1 logic unchanged. Per-mesh tables stay (used by makeChunkRequest, debug logs, the planner itself). Memory cost: 16 bytes × N instances ≈ 16 MB on a 1M-instance scene. Pixel-identical on basic.ifc in both non-streaming and streaming modes. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -232,6 +232,21 @@ struct WgpuModelGpuData {
|
||||
// entries for meshes without LOD1 are 0 and unused.
|
||||
std::vector<uint32_t> mesh_chunk_local_lod1_first_u32;
|
||||
|
||||
// Per-INSTANCE chunk lookup tables. Mirror the per-mesh arrays above,
|
||||
// but resolved at planning time so cull can read them directly without
|
||||
// routing through mesh_id. The split exists because the spatial-
|
||||
// bucketing planner (#55) can place the same mesh in multiple chunks
|
||||
// (mesh data duplicated when its instances live in different buckets)
|
||||
// — under that scheme `mesh_chunk_idx[mesh_id]` is ambiguous, but
|
||||
// `instance_chunk_idx[instance_id]` is always exactly one chunk.
|
||||
// The mesh-keyed planner populates these by translation
|
||||
// (instance_chunk_idx[i] = mesh_chunk_idx[instances[i].mesh_id]);
|
||||
// the spatial-bucket planner populates them directly.
|
||||
std::vector<uint32_t> instance_chunk_idx;
|
||||
std::vector<uint32_t> instance_base_vertex;
|
||||
std::vector<uint32_t> instance_ebo_first_u32;
|
||||
std::vector<uint32_t> instance_lod1_first_u32;
|
||||
|
||||
// Model-shared buffers. Mesh + instance storage are small (<10 MB on
|
||||
// any real scene we've seen); the chunked index buffer lives in Chunk
|
||||
// alongside vertex_storage so streaming can defer both together.
|
||||
|
||||
Reference in New Issue
Block a user