Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions crates/urath-core/src/chunk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,12 @@ pub struct ChunkNeighbors {
}

impl ChunkNeighbors {
/// The chunk size this neighbor set was created for.
#[inline]
pub fn size(&self) -> usize {
self.size
}

/// Create neighbors with all faces treated as air.
pub fn empty(size: usize) -> Self {
Self {
Expand Down
93 changes: 64 additions & 29 deletions crates/urath-wasm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,51 @@ use urath::{
TerrainConfig, TerrainGenerator,
};

pub const FACE_POS_X: u8 = 0;
pub const FACE_NEG_X: u8 = 1;
pub const FACE_POS_Y: u8 = 2;
pub const FACE_NEG_Y: u8 = 3;
pub const FACE_POS_Z: u8 = 4;
pub const FACE_NEG_Z: u8 = 5;

/// Face direction constants exported to JavaScript.
#[wasm_bindgen]
pub fn face_pos_x() -> u8 {
FACE_POS_X
}
#[wasm_bindgen]
pub fn face_neg_x() -> u8 {
FACE_NEG_X
}
#[wasm_bindgen]
pub fn face_pos_y() -> u8 {
FACE_POS_Y
}
#[wasm_bindgen]
pub fn face_neg_y() -> u8 {
FACE_NEG_Y
}
#[wasm_bindgen]
pub fn face_pos_z() -> u8 {
FACE_POS_Z
}
#[wasm_bindgen]
pub fn face_neg_z() -> u8 {
FACE_NEG_Z
}

fn face_from_u8(val: u8) -> Result<Face, JsError> {
match val {
0 => Ok(Face::PosX),
1 => Ok(Face::NegX),
2 => Ok(Face::PosY),
3 => Ok(Face::NegY),
4 => Ok(Face::PosZ),
5 => Ok(Face::NegZ),
_ => Err(JsError::new(&format!("invalid face: {val}, must be 0-5"))),
}
}

/// WASM-exposed chunk that holds voxel data.
#[wasm_bindgen]
pub struct WasmChunk {
Expand Down Expand Up @@ -73,18 +118,10 @@ impl WasmChunk {

/// Extract the border slice for a given face direction.
/// Returns a Uint16Array of size² elements.
pub fn extract_border(&self, face: u8) -> js_sys::Uint16Array {
let f = match face {
0 => Face::PosX,
1 => Face::NegX,
2 => Face::PosY,
3 => Face::NegY,
4 => Face::PosZ,
5 => Face::NegZ,
_ => return js_sys::Uint16Array::new_with_length(0),
};
pub fn extract_border(&self, face: u8) -> Result<js_sys::Uint16Array, JsError> {
let f = face_from_u8(face)?;
let border = self.inner.extract_border(f);
js_sys::Uint16Array::from(&border[..])
Ok(js_sys::Uint16Array::from(&border[..]))
}

/// True if all blocks are air. O(1).
Expand Down Expand Up @@ -117,15 +154,7 @@ impl WasmChunkNeighbors {
/// E.g., calling `set_neighbor(0, neighborChunk)` extracts the NegX (x=0) border
/// from `neighborChunk` and uses it as the PosX neighbor data.
pub fn set_neighbor(&mut self, face: u8, neighbor_chunk: &WasmChunk) -> Result<(), JsError> {
let face = match face {
0 => Face::PosX,
1 => Face::NegX,
2 => Face::PosY,
3 => Face::NegY,
4 => Face::PosZ,
5 => Face::NegZ,
_ => return Ok(()),
};
let face = face_from_u8(face)?;
let border = neighbor_chunk.inner.extract_border(face.opposite());
self.inner
.set_face(face, border)
Expand All @@ -135,15 +164,7 @@ impl WasmChunkNeighbors {
/// Set neighbor border data directly from a Uint16Array (size² elements).
/// Used by workers that don't have the neighbor WasmChunk.
pub fn set_neighbor_border(&mut self, face: u8, data: &[u16]) -> Result<(), JsError> {
let face = match face {
0 => Face::PosX,
1 => Face::NegX,
2 => Face::PosY,
3 => Face::NegY,
4 => Face::PosZ,
5 => Face::NegZ,
_ => return Ok(()),
};
let face = face_from_u8(face)?;
self.inner
.set_face(face, data.to_vec())
.map_err(|e| JsError::new(&e.to_string()))
Expand Down Expand Up @@ -323,6 +344,13 @@ impl WasmGreedyMesher {
chunk: &WasmChunk,
neighbors: &WasmChunkNeighbors,
) -> Result<WasmMeshResult, JsError> {
if neighbors.inner.size() != chunk.inner.size() {
return Err(JsError::new(&format!(
"neighbor size {} does not match chunk size {}",
neighbors.inner.size(),
chunk.inner.size()
)));
}
let mut opaque = MeshOutput::with_capacity(4096);
let mut transparent = MeshOutput::with_capacity(1024);
self.inner
Expand Down Expand Up @@ -385,6 +413,13 @@ impl WasmSurfaceNetsMesher {
chunk: &WasmChunk,
neighbors: &WasmChunkNeighbors,
) -> Result<WasmMeshResult, JsError> {
if neighbors.inner.size() != chunk.inner.size() {
return Err(JsError::new(&format!(
"neighbor size {} does not match chunk size {}",
neighbors.inner.size(),
chunk.inner.size()
)));
}
let mut opaque = MeshOutput::with_capacity(4096);
let mut transparent = MeshOutput::new();
self.inner
Expand Down
Loading