chore(workspace): fix formatting and clippy warnings

This commit is contained in:
Serkyo 2026-05-16 19:05:53 +02:00
parent 61a7fb0ed5
commit 5659469e17
8 changed files with 225 additions and 66 deletions

View file

@ -81,8 +81,8 @@ impl ApplicationHandler for App {
let config_str = std::fs::read_to_string("assets/data/worldgen/default.json")
.expect("Failed to read worldgen config");
#[allow(clippy::expect_used)]
let worldgen_config: shared::generator::WorldGenConfig = serde_json::from_str(&config_str)
.expect("Failed to parse worldgen config");
let worldgen_config: shared::generator::WorldGenConfig =
serde_json::from_str(&config_str).expect("Failed to parse worldgen config");
let seed = 4_813_530;
@ -90,10 +90,18 @@ impl ApplicationHandler for App {
let chunk = generator.generate_chunk(shared::world::ChunkPos::new(0, 0, 0));
let (vertices, indices) = meshing::generate_mesh(&chunk);
tracing::info!("Generated Mesh with {} vertices and {} indices!", vertices.len(), indices.len());
tracing::info!(
"Generated Mesh with {} vertices and {} indices!",
vertices.len(),
indices.len()
);
#[allow(clippy::expect_used)]
self.renderer.as_mut().expect("Renderer initialized").update_mesh(&vertices, &indices).expect("Failed to upload terrain to GPU");
self.renderer
.as_mut()
.expect("Renderer initialized")
.update_mesh(&vertices, &indices)
.expect("Failed to upload terrain to GPU");
}
fn window_event(&mut self, event_loop: &ActiveEventLoop, _id: WindowId, event: WindowEvent) {

View file

@ -1,7 +1,11 @@
use shared::world::{BlockId, CHUNK_SIZE, Chunk};
use renderer::mesh::Vertex;
use shared::world::{BlockId, CHUNK_SIZE, Chunk};
#[allow(clippy::cast_precision_loss, clippy::cast_possible_truncation)]
#[allow(
clippy::cast_precision_loss,
clippy::cast_possible_truncation,
clippy::too_many_lines
)]
pub fn generate_mesh(chunk: &Chunk) -> (Vec<Vertex>, Vec<u32>) {
let mut vertices = Vec::new();
let mut indices = Vec::new();
@ -22,69 +26,180 @@ pub fn generate_mesh(chunk: &Chunk) -> (Vec<Vertex>, Vec<u32>) {
if y == CHUNK_SIZE - 1 || chunk.get(x, y + 1, z) == BlockId::AIR {
let base_idx = vertices.len() as u32;
vertices.push(Vertex { position: [fx - 0.5, fy + 0.5, fz + 0.5], color: [0.2, 0.8, 0.2] });
vertices.push(Vertex { position: [fx + 0.5, fy + 0.5, fz + 0.5], color: [0.2, 0.8, 0.2] });
vertices.push(Vertex { position: [fx + 0.5, fy + 0.5, fz - 0.5], color: [0.2, 0.8, 0.2] });
vertices.push(Vertex { position: [fx - 0.5, fy + 0.5, fz - 0.5], color: [0.2, 0.8, 0.2] });
vertices.push(Vertex {
position: [fx - 0.5, fy + 0.5, fz + 0.5],
color: [0.2, 0.8, 0.2],
});
vertices.push(Vertex {
position: [fx + 0.5, fy + 0.5, fz + 0.5],
color: [0.2, 0.8, 0.2],
});
vertices.push(Vertex {
position: [fx + 0.5, fy + 0.5, fz - 0.5],
color: [0.2, 0.8, 0.2],
});
vertices.push(Vertex {
position: [fx - 0.5, fy + 0.5, fz - 0.5],
color: [0.2, 0.8, 0.2],
});
indices.extend_from_slice(&[
base_idx, base_idx + 1, base_idx + 2,
base_idx + 2, base_idx + 3, base_idx,
base_idx,
base_idx + 1,
base_idx + 2,
base_idx + 2,
base_idx + 3,
base_idx,
]);
}
if y == 0 || chunk.get(x, y - 1, z) == BlockId::AIR {
let base_idx = vertices.len() as u32;
vertices.push(Vertex { position: [fx - 0.5, fy - 0.5, fz - 0.5], color: [0.1, 0.4, 0.1] });
vertices.push(Vertex { position: [fx + 0.5, fy - 0.5, fz - 0.5], color: [0.1, 0.4, 0.1] });
vertices.push(Vertex { position: [fx + 0.5, fy - 0.5, fz + 0.5], color: [0.1, 0.4, 0.1] });
vertices.push(Vertex { position: [fx - 0.5, fy - 0.5, fz + 0.5], color: [0.1, 0.4, 0.1] });
indices.extend_from_slice(&[base_idx, base_idx + 1, base_idx + 2, base_idx + 2, base_idx + 3, base_idx]);
vertices.push(Vertex {
position: [fx - 0.5, fy - 0.5, fz - 0.5],
color: [0.1, 0.4, 0.1],
});
vertices.push(Vertex {
position: [fx + 0.5, fy - 0.5, fz - 0.5],
color: [0.1, 0.4, 0.1],
});
vertices.push(Vertex {
position: [fx + 0.5, fy - 0.5, fz + 0.5],
color: [0.1, 0.4, 0.1],
});
vertices.push(Vertex {
position: [fx - 0.5, fy - 0.5, fz + 0.5],
color: [0.1, 0.4, 0.1],
});
indices.extend_from_slice(&[
base_idx,
base_idx + 1,
base_idx + 2,
base_idx + 2,
base_idx + 3,
base_idx,
]);
}
if x == CHUNK_SIZE - 1 || chunk.get(x + 1, y, z) == BlockId::AIR {
let base_idx = vertices.len() as u32;
vertices.push(Vertex { position: [fx + 0.5, fy - 0.5, fz + 0.5], color: [0.15, 0.6, 0.15] });
vertices.push(Vertex { position: [fx + 0.5, fy - 0.5, fz - 0.5], color: [0.15, 0.6, 0.15] });
vertices.push(Vertex { position: [fx + 0.5, fy + 0.5, fz - 0.5], color: [0.15, 0.6, 0.15] });
vertices.push(Vertex { position: [fx + 0.5, fy + 0.5, fz + 0.5], color: [0.15, 0.6, 0.15] });
indices.extend_from_slice(&[base_idx, base_idx + 1, base_idx + 2, base_idx + 2, base_idx + 3, base_idx]);
vertices.push(Vertex {
position: [fx + 0.5, fy - 0.5, fz + 0.5],
color: [0.15, 0.6, 0.15],
});
vertices.push(Vertex {
position: [fx + 0.5, fy - 0.5, fz - 0.5],
color: [0.15, 0.6, 0.15],
});
vertices.push(Vertex {
position: [fx + 0.5, fy + 0.5, fz - 0.5],
color: [0.15, 0.6, 0.15],
});
vertices.push(Vertex {
position: [fx + 0.5, fy + 0.5, fz + 0.5],
color: [0.15, 0.6, 0.15],
});
indices.extend_from_slice(&[
base_idx,
base_idx + 1,
base_idx + 2,
base_idx + 2,
base_idx + 3,
base_idx,
]);
}
if x == 0 || chunk.get(x - 1, y, z) == BlockId::AIR {
let base_idx = vertices.len() as u32;
vertices.push(Vertex { position: [fx - 0.5, fy - 0.5, fz - 0.5], color: [0.15, 0.6, 0.15] });
vertices.push(Vertex { position: [fx - 0.5, fy - 0.5, fz + 0.5], color: [0.15, 0.6, 0.15] });
vertices.push(Vertex { position: [fx - 0.5, fy + 0.5, fz + 0.5], color: [0.15, 0.6, 0.15] });
vertices.push(Vertex { position: [fx - 0.5, fy + 0.5, fz - 0.5], color: [0.15, 0.6, 0.15] });
indices.extend_from_slice(&[base_idx, base_idx + 1, base_idx + 2, base_idx + 2, base_idx + 3, base_idx]);
vertices.push(Vertex {
position: [fx - 0.5, fy - 0.5, fz - 0.5],
color: [0.15, 0.6, 0.15],
});
vertices.push(Vertex {
position: [fx - 0.5, fy - 0.5, fz + 0.5],
color: [0.15, 0.6, 0.15],
});
vertices.push(Vertex {
position: [fx - 0.5, fy + 0.5, fz + 0.5],
color: [0.15, 0.6, 0.15],
});
vertices.push(Vertex {
position: [fx - 0.5, fy + 0.5, fz - 0.5],
color: [0.15, 0.6, 0.15],
});
indices.extend_from_slice(&[
base_idx,
base_idx + 1,
base_idx + 2,
base_idx + 2,
base_idx + 3,
base_idx,
]);
}
if z == CHUNK_SIZE - 1 || chunk.get(x, y, z + 1) == BlockId::AIR {
let base_idx = vertices.len() as u32;
vertices.push(Vertex { position: [fx - 0.5, fy - 0.5, fz + 0.5], color: [0.18, 0.7, 0.18] });
vertices.push(Vertex { position: [fx + 0.5, fy - 0.5, fz + 0.5], color: [0.18, 0.7, 0.18] });
vertices.push(Vertex { position: [fx + 0.5, fy + 0.5, fz + 0.5], color: [0.18, 0.7, 0.18] });
vertices.push(Vertex { position: [fx - 0.5, fy + 0.5, fz + 0.5], color: [0.18, 0.7, 0.18] });
indices.extend_from_slice(&[base_idx, base_idx + 1, base_idx + 2, base_idx + 2, base_idx + 3, base_idx]);
vertices.push(Vertex {
position: [fx - 0.5, fy - 0.5, fz + 0.5],
color: [0.18, 0.7, 0.18],
});
vertices.push(Vertex {
position: [fx + 0.5, fy - 0.5, fz + 0.5],
color: [0.18, 0.7, 0.18],
});
vertices.push(Vertex {
position: [fx + 0.5, fy + 0.5, fz + 0.5],
color: [0.18, 0.7, 0.18],
});
vertices.push(Vertex {
position: [fx - 0.5, fy + 0.5, fz + 0.5],
color: [0.18, 0.7, 0.18],
});
indices.extend_from_slice(&[
base_idx,
base_idx + 1,
base_idx + 2,
base_idx + 2,
base_idx + 3,
base_idx,
]);
}
if z == 0 || chunk.get(x, y, z - 1) == BlockId::AIR {
let base_idx = vertices.len() as u32;
vertices.push(Vertex { position: [fx + 0.5, fy - 0.5, fz - 0.5], color: [0.18, 0.7, 0.18] });
vertices.push(Vertex { position: [fx - 0.5, fy - 0.5, fz - 0.5], color: [0.18, 0.7, 0.18] });
vertices.push(Vertex { position: [fx - 0.5, fy + 0.5, fz - 0.5], color: [0.18, 0.7, 0.18] });
vertices.push(Vertex { position: [fx + 0.5, fy + 0.5, fz - 0.5], color: [0.18, 0.7, 0.18] });
indices.extend_from_slice(&[base_idx, base_idx + 1, base_idx + 2, base_idx + 2, base_idx + 3, base_idx]);
vertices.push(Vertex {
position: [fx + 0.5, fy - 0.5, fz - 0.5],
color: [0.18, 0.7, 0.18],
});
vertices.push(Vertex {
position: [fx - 0.5, fy - 0.5, fz - 0.5],
color: [0.18, 0.7, 0.18],
});
vertices.push(Vertex {
position: [fx - 0.5, fy + 0.5, fz - 0.5],
color: [0.18, 0.7, 0.18],
});
vertices.push(Vertex {
position: [fx + 0.5, fy + 0.5, fz - 0.5],
color: [0.18, 0.7, 0.18],
});
indices.extend_from_slice(&[
base_idx,
base_idx + 1,
base_idx + 2,
base_idx + 2,
base_idx + 3,
base_idx,
]);
}
}
}
}
(vertices, indices)
}
}

View file

@ -1,6 +1,6 @@
use crate::create_gpu_buffer;
use crate::{error::RendererError, mesh::Vertex};
use crate::sync::SyncPrimitives;
use crate::{error::RendererError, mesh::Vertex};
use ash::{Device, Instance, khr, vk};
use gpu_allocator::vulkan::{Allocation, Allocator};
@ -299,7 +299,8 @@ impl Renderer {
mvp_bytes,
);
self.device.cmd_draw_indexed(cmd, self.index_count, 1, 0, 0, 0);
self.device
.cmd_draw_indexed(cmd, self.index_count, 1, 0, 0, 0);
}
}
@ -339,26 +340,34 @@ impl Renderer {
}
/// Replaces the currently rendering mesh with a new set of vertices and indices.
///
///
/// # Errors
/// Returns a `RendererError` if new Vulkan buffers cannot be allocated or created.
#[allow(clippy::cast_possible_truncation)]
pub fn update_mesh(&mut self, vertices: &[Vertex], indices: &[u32]) -> Result<(), RendererError> {
pub fn update_mesh(
&mut self,
vertices: &[Vertex],
indices: &[u32],
) -> Result<(), RendererError> {
unsafe {
let _ = self.device.device_wait_idle();
let _ = self.allocator.free(std::ptr::read(&raw const self.vertex_allocation));
let _ = self
.allocator
.free(std::ptr::read(&raw const self.vertex_allocation));
self.device.destroy_buffer(self.vertex_buffer, None);
let _ = self.allocator.free(std::ptr::read(&raw const self.index_allocation));
let _ = self
.allocator
.free(std::ptr::read(&raw const self.index_allocation));
self.device.destroy_buffer(self.index_buffer, None);
}
let (v_buf, v_alloc) = create_gpu_buffer(
&self.device,
&mut self.allocator,
bytemuck::cast_slice(vertices),
vk::BufferUsageFlags::VERTEX_BUFFER,
&self.device,
&mut self.allocator,
bytemuck::cast_slice(vertices),
vk::BufferUsageFlags::VERTEX_BUFFER,
"Chunk Vertex Buffer",
)?;

View file

@ -8,24 +8,29 @@ pub mod world_server;
use std::fs;
use shared::{generator::{VoxelGenerator, WorldGenConfig}, world::ChunkPos};
use shared::{
generator::{VoxelGenerator, WorldGenConfig},
world::ChunkPos,
};
use tracing::{debug, info};
fn main() {
tracing_subscriber::fmt()
.with_env_filter(
tracing_subscriber::EnvFilter::try_from_default_env()
.unwrap_or_else(|_| tracing_subscriber::EnvFilter::new("debug"))
.unwrap_or_else(|_| tracing_subscriber::EnvFilter::new("debug")),
)
.init();
info!("Starting Project Catalyst server");
#[allow(clippy::expect_used)]
let config_str = fs::read_to_string("assets/data/worldgen/default.json").expect("Failed to read worldgen config");
let config_str = fs::read_to_string("assets/data/worldgen/default.json")
.expect("Failed to read worldgen config");
#[allow(clippy::expect_used)]
let worldgen_config: WorldGenConfig = serde_json::from_str(&config_str).expect("Failed to parse worldgen config");
let worldgen_config: WorldGenConfig =
serde_json::from_str(&config_str).expect("Failed to parse worldgen config");
info!("Successfully loaded world configuration");
debug!("Base height: {}", worldgen_config.base_height);
@ -42,5 +47,8 @@ fn main() {
let spawn_chunk = world.get_chunk(ChunkPos::new(0, 0, 0));
tracing::info!("Spawn chunk generated. Block at (0,0,0) is {}", spawn_chunk.get(0, 0, 0).0);
}
tracing::info!(
"Spawn chunk generated. Block at (0,0,0) is {}",
spawn_chunk.get(0, 0, 0).0
);
}

View file

@ -1,6 +1,9 @@
//! Authoritative chunk storage and generation logic for the server.
use shared::{generator::VoxelGenerator, world::{Chunk, ChunkPos}};
use shared::{
generator::VoxelGenerator,
world::{Chunk, ChunkPos},
};
use std::collections::HashMap;
/// The server's authoritative representation of the world.
@ -21,8 +24,8 @@ impl ServerWorld {
/// Retrieves a reference to the chunk at the given position, generating it if necessary.
pub fn get_chunk(&mut self, pos: ChunkPos) -> &Chunk {
self.chunks.entry(pos).or_insert_with(|| {
self.generator.generate_chunk(pos)
})
self.chunks
.entry(pos)
.or_insert_with(|| self.generator.generate_chunk(pos))
}
}
}

View file

@ -39,10 +39,14 @@ impl VoxelGenerator {
/// Generates a complete voxel chunk for the specified position.
#[must_use]
#[allow(clippy::cast_precision_loss, clippy::cast_possible_wrap, clippy::cast_possible_truncation)]
#[allow(
clippy::cast_precision_loss,
clippy::cast_possible_wrap,
clippy::cast_possible_truncation
)]
pub fn generate_chunk(&self, pos: ChunkPos) -> Chunk {
let mut chunk = Chunk::default();
for x in 0..CHUNK_SIZE {
for z in 0..CHUNK_SIZE {
let global_x = (pos.x * CHUNK_SIZE as i32) + x as i32;
@ -78,4 +82,4 @@ impl VoxelGenerator {
}
chunk
}
}
}

View file

@ -3,5 +3,5 @@
//! This crate contains data structures and constants that are used by both
//! the client and the server.
pub mod generator;
pub mod world;
pub mod generator;

View file

@ -11,7 +11,19 @@ pub const CHUNK_VOLUME: usize = CHUNK_SIZE * CHUNK_SIZE * CHUNK_SIZE;
/// A unique identifier representing a type of block in the world.
#[repr(transparent)]
#[derive(
Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize, Pod, Zeroable,
Copy,
Clone,
Debug,
Default,
PartialEq,
Eq,
PartialOrd,
Ord,
Hash,
Serialize,
Deserialize,
Pod,
Zeroable,
)]
pub struct BlockId(pub u16);
@ -72,4 +84,4 @@ impl ChunkPos {
pub fn new(x: i32, y: i32, z: i32) -> Self {
Self { x, y, z }
}
}
}