Skip to main content

Grid

Struct Grid 

Source
pub struct Grid {
    pub transform: GridTransform,
    pub chunks: HashMap<IVec3, Vxl>,
    pub render_sky: bool,
    pub mip_levels_override: Option<u32>,
}
Expand description

One independent voxel grid in a scene. Holds its world placement and a sparse map of populated chunks. Empty chunk slots are implicit air and skipped during rendering / raycasts.

Each chunk is internally a Vxl with vsid = CHUNK_SIZE_XY — the existing per-chunk renderer (opticast + grouscan + sprites + lighting in roxlap-core) runs on each chunk unchanged. Vertical worlds are built by stacking chunks along grid-local +z.

Fields§

§transform: GridTransform

World placement (origin + rotation).

§chunks: HashMap<IVec3, Vxl>

Sparse chunk storage keyed by (chx, chy, chz) chunk coordinates. A missing entry means the chunk is fully air.

§render_sky: bool

Whether sky pixels rendered for this grid should be composited into the final framebuffer. true is the historical “grid owns its own sky” behaviour: ray misses inside this grid’s frustum paint sky_color into the temp buffer. Set false for grids that are a foreground object (e.g. a ship) — the sky is owned by a single “world” grid (the ground) and other grids should not contribute sky pixels, otherwise their grid-local-frame sky lookup rotates with the grid and visibly fights the world’s sky during compose. See crate::render::render_scene_composed for the masking implementation.

§mip_levels_override: Option<u32>

Override roxlap_core::opticast::OpticastSettings::mip_levels for this grid. None ⇒ use the caller’s value. Some(n) ⇒ cap at n (clamped to [1, settings.mip_levels]). Use to disable multi-mip on a per-grid basis — small grids (rotating ships, billboards) don’t benefit from deep mips and CAN trigger the [[project_axis_aligned_mip_beams]]-style cf-cancellation artifact when near-axis-aligned rays hit the rotated grid. Some(1) = mip-0 only, byte-stable to single-mip.

Implementations§

Source§

impl Grid

Source

pub fn chunk(&self, chunk_idx: IVec3) -> Option<&Vxl>

Borrow the chunk at chunk_idx if it has been materialised. None means the chunk is implicitly all-air.

Source

pub fn chunk_mut(&mut self, chunk_idx: IVec3) -> Option<&mut Vxl>

Mutably borrow a materialised chunk. Returns None for implicit-air chunks; use Grid::ensure_chunk when you need a &mut Vxl for an edit that may write voxels.

Source

pub fn ensure_chunk(&mut self, chunk_idx: IVec3) -> &mut Vxl

Borrow chunk_idx’s Vxl, creating an empty all-air chunk first if it doesn’t exist yet. The returned &mut is valid for editing via roxlap_formats::edit — the new chunk has Vxl::reserve_edit_capacity already applied.

Source

pub fn chunk_count(&self) -> usize

Number of materialised chunks. Implicit-air chunks don’t count.

Source

pub fn chunk_xy_backing(&self) -> Option<ChunkXyBacking<'_>>

S4B.2.c.3: build a per-chunk roxlap_core::GridView table over this grid’s XY chunk footprint at chz = 0.

Returns None if no chz=0 chunk is populated (the entire grid would render as implicit air anyway).

Iterates chunks once to find the chx/chy bounding box, then a second time to fill the row-major Vec<Option<GridView<'_>>>. Empty XY slots (implicit-air chunks inside the box) get None.

Pair with roxlap_core::ChunkGrid + [roxlap_core:: GridView::from_chunk_grid] to drive the Approach B render path:

let backing = grid.chunk_xy_backing().unwrap();
let cg = roxlap_core::ChunkGrid {
    chunks: &backing.chunks,
    origin_chunk_xy: backing.origin_chunk_xy,
    chunks_x: backing.chunks_x,
    chunks_y: backing.chunks_y,
};
let view = roxlap_core::GridView::from_chunk_grid(
    &cg, crate::CHUNK_SIZE_XY,
);

Only chz=0 chunks contribute (multi-z handoff lands in S4B.3); higher-chz chunks in Self::chunks are ignored here.

Source

pub fn chunk_xyz_backing(&self) -> Option<ChunkXyBacking<'_>>

S4B.6.a: 3D-aware version of Self::chunk_xy_backing. Enumerates ALL chunks across the chx/chy/chz bounding box (not just chz=0) so a stacked grid can be rendered once S4B.6.c switches the rasterizer to a chunk-z-aware column walker.

Iterates chunks once for the XYZ bbox, then a second time to fill the row-major-per-z Vec<Option<GridView<'_>>>. Index layout: [(dz * chunks_y + dy) * chunks_x + dx] — matches roxlap_core::ChunkGrid’s indexing exactly.

Returns None for empty grids.

Source§

impl Grid

Source

pub fn set_voxel(&mut self, voxel: IVec3, color: Option<u32>)

Set or carve a single voxel at grid-local coordinate voxel. color = Some(c) inserts a solid voxel of colour c; color = None carves to air.

Inserting in an implicit-air chunk materialises that chunk (allocates a fresh Vxl); carving from a missing chunk is a no-op.

Source

pub fn set_rect(&mut self, lo: IVec3, hi: IVec3, color: Option<u32>)

Set or carve an axis-aligned box [lo, hi] in grid-local voxel coordinates. Inclusive on both ends, like roxlap_formats::edit::set_rect.

The box is decomposed per chunk: each touched chunk receives a set_rect call with the box clipped to its footprint and translated to chunk-local. Inserts materialise missing chunks; carves skip them.

lo and hi may be in any order on each axis — the decomposition normalises them.

Source

pub fn set_sphere(&mut self, centre: IVec3, radius: u32, color: Option<u32>)

Set or carve a sphere of voxels at grid-local centre centre with the given radius. Euclidean distance, like roxlap_formats::edit::set_sphere.

The bounding box of the sphere is enumerated chunk by chunk; each touched chunk receives a set_sphere call with the centre re-expressed in chunk-local coords (the per-chunk call clips the sphere to the chunk’s footprint internally). Chunks the sphere doesn’t actually reach get materialised only if color.is_some() and they fall within the AABB — the per-chunk set_sphere is a no-op for non-overlapping chunks but the materialisation cost remains. A subsequent pre-pass that filters chunks against radius² could avoid this; out of scope for v1.

Source§

impl Grid

Source

pub fn new(transform: GridTransform) -> Self

New empty grid at the given transform — no chunks populated, render_sky = true.

Trait Implementations§

Source§

impl Debug for Grid

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl Freeze for Grid

§

impl RefUnwindSafe for Grid

§

impl Send for Grid

§

impl Sync for Grid

§

impl Unpin for Grid

§

impl UnsafeUnpin for Grid

§

impl UnwindSafe for Grid

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> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

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

Source§

type Error = Infallible

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.