Skip to main content

InstancedCluster

Struct InstancedCluster 

Source
pub struct InstancedCluster {
Show 14 fields pub vertex_offset: usize, pub vertex_count: usize, pub index_offset: usize, pub index_count: usize, pub texture_slot: usize, pub normal_map_slot: usize, pub material: MaterialUniforms, pub cluster_bb_min: [f32; 3], pub cluster_bb_max: [f32; 3], pub local_bb_min: [f32; 3], pub local_bb_max: [f32; 3], pub cull_distance: f32, pub instances: Vec<[[f32; 4]; 4]>, pub lod_alternates: Vec<LodSlice>,
}
Expand description

One GPU-instanced draw: a shared mesh slice + material rendered at many world-space transforms in a single drawIndexedInstanced / cmd_draw_indexed (instance_count > 1). The cluster has a single union AABB across all instances; it is frustum-tested as a whole. Cluster culling trades per- instance precision for one draw call instead of N.

Fields§

§vertex_offset: usize

Byte offset into the shared vertex buffer. Currently unused because every backend keeps the shared vertex buffer bound at offset 0 and append_mesh rebases indices accordingly; retained for symmetry with DrawObject and future per-cluster vertex bindings.

§vertex_count: usize

Number of vertices this cluster’s mesh occupies in the shared vertex buffer, starting at vertex_offset. Used by the shrinkable-seed compaction to relocate the cluster’s geometry region when streamed-mesh gaps are removed from the shared buffer.

§index_offset: usize

Element offset into the shared index buffer.

§index_count: usize

Number of indices per instance.

§texture_slot: usize

Index into the shared texture pool for this cluster’s albedo map.

§normal_map_slot: usize

Index into the shared texture pool for this cluster’s normal map, or NO_NORMAL_MAP_SLOT when the cluster has no normal map.

§material: MaterialUniforms

Per-cluster material scalars, identical for every instance.

§cluster_bb_min: [f32; 3]

Union AABB of all per-instance world AABBs; used for cluster-wide frustum culling. A degenerate (NaN) box disables culling.

§cluster_bb_max: [f32; 3]

Upper corner of the cluster’s union world AABB.

§local_bb_min: [f32; 3]

Mesh-local (object-space) AABB, identical for every instance. The GPU-driven instanced path transforms this by each instance’s model matrix to get a per-instance world AABB for per-instance frustum/distance/Hi-Z culling; the union AABB above is only the whole-cluster bound.

§local_bb_max: [f32; 3]

Upper corner of the mesh-local bind AABB.

§cull_distance: f32

View-distance cutoff applied to the cluster centre. 0 = no cutoff.

§instances: Vec<[[f32; 4]; 4]>

Per-instance column-major model matrices. Uploaded to a transient GPU buffer each frame.

§lod_alternates: Vec<LodSlice>

LOD1..N slices for this cluster’s mesh, in ascending switch_distance order. Empty when the mesh declared lod_levels <= 1. Each per-instance LOD is picked from camera distance to that instance’s translation; the per-pass draw loop partitions instances by their picked LOD and issues one drawIndexedInstanced per non-empty bucket. The vertex set is shared with LOD0 (QEM decimation preserves vertices), so only (index_offset, index_count) varies per slice.

Implementations§

Source§

impl InstancedCluster

Source

pub fn cullable(&self) -> bool

True when the cluster AABB encodes valid finite bounds suitable for frustum / distance culling.

Source

pub fn lod_buckets(&self, cam_pos: [f32; 3]) -> Vec<InstancedLodBucket>

Partition the cluster’s instances into LOD buckets keyed by camera distance to each instance’s translation. Returns one entry per non-empty bucket, in mesh-LOD order (LOD0 first). With no alternates every instance lands in a single LOD0 bucket so the caller’s loop degenerates to the legacy one-drawIndexedInstanced path.

Per-instance distance uses the model-matrix translation rather than a transformed-AABB centre: close enough for distance-keyed swaps without paying the per-instance AABB transform every pass.

Source

pub fn try_for_each_lod_bucket<E>( &self, cam_pos: [f32; 3], visit: impl FnMut(usize, usize, &[[[f32; 4]; 4]]) -> Result<(), E>, ) -> Result<(), E>

Visit each non-empty LOD bucket for this cluster, calling visit(index_offset, index_count, instances) once per bucket in mesh-LOD order (LOD0 first). Stops and returns the first error a visit produces.

In the common no-alternates case instances borrows self.instances directly (no allocation, no copy) so a caller that memcpy’s the slice into a GPU buffer skips the wholesale clone that the owned lod_buckets makes. Clusters that declared LOD alternates still regroup their instances per LOD (a copy that separate per-LOD draw calls genuinely require); that path reuses lod_buckets.

Source

pub fn for_each_lod_bucket( &self, cam_pos: [f32; 3], visit: impl FnMut(usize, usize, &[[[f32; 4]; 4]]), )

Infallible try_for_each_lod_bucket for callers whose per-bucket work cannot fail.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.