From 8bb00e26be52d35089154107fb1606897639545d Mon Sep 17 00:00:00 2001 From: lukas0008 Date: Fri, 30 Aug 2024 17:40:55 +0200 Subject: [PATCH] Make ChunkData use Vector2 instead of ChunkCoordinates --- pumpkin-world/src/chunk.rs | 7 +- pumpkin-world/src/coordinates.rs | 15 +-- pumpkin-world/src/level.rs | 6 +- pumpkin-world/src/lib.rs | 1 + pumpkin-world/src/radial_chunk_iterator.rs | 8 +- pumpkin-world/src/vector2.rs | 105 ++++++++++++++++++ pumpkin-world/src/world_gen/generator.rs | 5 +- .../src/world_gen/generic_generator.rs | 7 +- pumpkin/src/server.rs | 3 +- 9 files changed, 127 insertions(+), 30 deletions(-) create mode 100644 pumpkin-world/src/vector2.rs diff --git a/pumpkin-world/src/chunk.rs b/pumpkin-world/src/chunk.rs index 2e7ba0d2..0ceddf82 100644 --- a/pumpkin-world/src/chunk.rs +++ b/pumpkin-world/src/chunk.rs @@ -7,8 +7,9 @@ use serde::{Deserialize, Serialize}; use crate::{ block::BlockId, - coordinates::{ChunkCoordinates, ChunkRelativeBlockCoordinates, Height}, + coordinates::{ChunkRelativeBlockCoordinates, Height}, level::{ChunkNotGeneratedError, WorldError}, + vector2::Vector2, WORLD_HEIGHT, }; @@ -18,7 +19,7 @@ const CHUNK_VOLUME: usize = CHUNK_AREA * WORLD_HEIGHT; pub struct ChunkData { pub blocks: ChunkBlocks, - pub position: ChunkCoordinates, + pub position: Vector2, } pub struct ChunkBlocks { @@ -187,7 +188,7 @@ impl Index for ChunkBlocks { } impl ChunkData { - pub fn from_bytes(chunk_data: Vec, at: ChunkCoordinates) -> Result { + pub fn from_bytes(chunk_data: Vec, at: Vector2) -> Result { if fastnbt::from_bytes::(&chunk_data).expect("Failed reading chunk status.") != ChunkStatus::Full { diff --git a/pumpkin-world/src/coordinates.rs b/pumpkin-world/src/coordinates.rs index 45073442..b474a136 100644 --- a/pumpkin-world/src/coordinates.rs +++ b/pumpkin-world/src/coordinates.rs @@ -4,7 +4,7 @@ use derive_more::derive::{AsMut, AsRef, Display, Into}; use num_traits::{PrimInt, Signed, Unsigned}; use serde::{Deserialize, Serialize}; -use crate::{WORLD_LOWEST_Y, WORLD_MAX_Y}; +use crate::{vector2::Vector2, WORLD_LOWEST_Y, WORLD_MAX_Y}; #[derive( Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq, AsRef, AsMut, Into, Display, @@ -98,7 +98,7 @@ pub struct ChunkRelativeBlockCoordinates { } impl ChunkRelativeBlockCoordinates { - pub fn with_chunk_coordinates(self, chunk_coordinates: ChunkCoordinates) -> BlockCoordinates { + pub fn with_chunk_coordinates(self, chunk_coordinates: Vector2) -> BlockCoordinates { BlockCoordinates { x: *self.x as i32 + chunk_coordinates.x * 16, y: self.y, @@ -114,10 +114,7 @@ pub struct ChunkRelativeXZBlockCoordinates { } impl ChunkRelativeXZBlockCoordinates { - pub fn with_chunk_coordinates( - &self, - chunk_coordinates: ChunkCoordinates, - ) -> XZBlockCoordinates { + pub fn with_chunk_coordinates(&self, chunk_coordinates: Vector2) -> XZBlockCoordinates { XZBlockCoordinates { x: *self.x as i32 + chunk_coordinates.x * 16, z: *self.z as i32 + chunk_coordinates.z * 16, @@ -132,9 +129,3 @@ impl ChunkRelativeXZBlockCoordinates { } } } - -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub struct ChunkCoordinates { - pub x: i32, - pub z: i32, -} diff --git a/pumpkin-world/src/level.rs b/pumpkin-world/src/level.rs index e066c464..0d4cf4b0 100644 --- a/pumpkin-world/src/level.rs +++ b/pumpkin-world/src/level.rs @@ -12,7 +12,7 @@ use tokio::sync::mpsc; use crate::{ chunk::ChunkData, - coordinates::ChunkCoordinates, + vector2::Vector2, world_gen::{get_world_gen, Seed, WorldGenerator}, }; @@ -138,7 +138,7 @@ impl Level { /// Note: The order of the output chunks will almost never be in the same order as the order of input chunks pub async fn fetch_chunks( &self, - chunks: &[ChunkCoordinates], + chunks: &[Vector2], channel: mpsc::Sender>, ) { chunks.into_par_iter().copied().for_each(|at| { @@ -165,7 +165,7 @@ impl Level { }) } - fn read_chunk(save_file: &SaveFile, at: ChunkCoordinates) -> Result { + fn read_chunk(save_file: &SaveFile, at: Vector2) -> Result { let region = ( ((at.x as f32) / 32.0).floor() as i32, ((at.z as f32) / 32.0).floor() as i32, diff --git a/pumpkin-world/src/lib.rs b/pumpkin-world/src/lib.rs index bad06b92..8d0c9170 100644 --- a/pumpkin-world/src/lib.rs +++ b/pumpkin-world/src/lib.rs @@ -10,6 +10,7 @@ pub mod item; mod level; pub mod radial_chunk_iterator; pub mod vector3; +pub mod vector2; mod world_gen; pub const WORLD_HEIGHT: usize = 384; diff --git a/pumpkin-world/src/radial_chunk_iterator.rs b/pumpkin-world/src/radial_chunk_iterator.rs index 5eccb469..f75acb7d 100644 --- a/pumpkin-world/src/radial_chunk_iterator.rs +++ b/pumpkin-world/src/radial_chunk_iterator.rs @@ -1,9 +1,9 @@ -use crate::coordinates::ChunkCoordinates; +use crate::vector2::Vector2; pub struct RadialIterator { radius: u32, direction: usize, - current: ChunkCoordinates, + current: Vector2, step_size: i32, steps_taken: u32, steps_in_direction: i32, @@ -14,7 +14,7 @@ impl RadialIterator { RadialIterator { radius, direction: 0, - current: ChunkCoordinates { x: 0, z: 0 }, + current: Vector2::new(0, 0), step_size: 1, steps_taken: 0, steps_in_direction: 0, @@ -23,7 +23,7 @@ impl RadialIterator { } impl Iterator for RadialIterator { - type Item = ChunkCoordinates; + type Item = Vector2; fn next(&mut self) -> Option { if self.steps_taken >= self.radius * self.radius * 4 { diff --git a/pumpkin-world/src/vector2.rs b/pumpkin-world/src/vector2.rs new file mode 100644 index 00000000..241aea28 --- /dev/null +++ b/pumpkin-world/src/vector2.rs @@ -0,0 +1,105 @@ +use std::ops::{Add, Div, Mul, Neg, Sub}; + +use num_traits::Float; + +#[derive(Clone, Copy, Debug, PartialEq)] +pub struct Vector2 { + pub x: T, + pub z: T, +} + +impl Vector2 { + pub fn new(x: T, z: T) -> Self { + Vector2 { x, z } + } + + pub fn length_squared(&self) -> T { + self.x * self.x + self.z * self.z + } + + pub fn add(&self, other: &Vector2) -> Self { + Vector2 { + x: self.x + other.x, + z: self.z + other.z, + } + } + + pub fn sub(&self, other: &Vector2) -> Self { + Vector2 { + x: self.x - other.x, + z: self.z - other.z, + } + } + + pub fn multiply(self, x: T, z: T) -> Self { + Self { + x: self.x * x, + z: self.z * z, + } + } +} + +impl Vector2 { + pub fn length(&self) -> T { + self.length_squared().sqrt() + } + pub fn normalize(&self) -> Self { + let length = self.length(); + Vector2 { + x: self.x / length, + z: self.z / length, + } + } +} + +impl Mul for Vector2 { + type Output = Self; + + fn mul(self, scalar: T) -> Self { + Self { + x: self.x * scalar, + z: self.z * scalar, + } + } +} + +impl Add for Vector2 { + type Output = Vector2; + fn add(self, rhs: Self) -> Self::Output { + Self { + x: self.x + rhs.x, + z: self.z + rhs.z, + } + } +} + +impl Neg for Vector2 { + type Output = Self; + + fn neg(self) -> Self { + Vector2 { + x: -self.x, + z: -self.z, + } + } +} + +impl From<(T, T)> for Vector2 { + fn from((x, z): (T, T)) -> Self { + Vector2 { x, z } + } +} + +pub trait Math: + Mul + + Neg + + Add + + Div + + Sub + + Sized +{ +} +impl Math for f64 {} +impl Math for f32 {} +impl Math for i32 {} +impl Math for i64 {} diff --git a/pumpkin-world/src/world_gen/generator.rs b/pumpkin-world/src/world_gen/generator.rs index c5a10480..14e2a5aa 100644 --- a/pumpkin-world/src/world_gen/generator.rs +++ b/pumpkin-world/src/world_gen/generator.rs @@ -3,7 +3,8 @@ use static_assertions::assert_obj_safe; use crate::biome::Biome; use crate::block::BlockId; use crate::chunk::ChunkData; -use crate::coordinates::{BlockCoordinates, ChunkCoordinates, XZBlockCoordinates}; +use crate::coordinates::{BlockCoordinates, XZBlockCoordinates}; +use crate::vector2::Vector2; use crate::world_gen::Seed; pub trait GeneratorInit { @@ -12,7 +13,7 @@ pub trait GeneratorInit { pub trait WorldGenerator: Sync + Send { #[allow(dead_code)] - fn generate_chunk(&self, at: ChunkCoordinates) -> ChunkData; + fn generate_chunk(&self, at: Vector2) -> ChunkData; } assert_obj_safe! {WorldGenerator} diff --git a/pumpkin-world/src/world_gen/generic_generator.rs b/pumpkin-world/src/world_gen/generic_generator.rs index d6a60ea5..0f71589c 100644 --- a/pumpkin-world/src/world_gen/generic_generator.rs +++ b/pumpkin-world/src/world_gen/generic_generator.rs @@ -1,8 +1,7 @@ use crate::{ chunk::{ChunkBlocks, ChunkData}, - coordinates::{ - ChunkCoordinates, ChunkRelativeBlockCoordinates, ChunkRelativeXZBlockCoordinates, - }, + coordinates::{ChunkRelativeBlockCoordinates, ChunkRelativeXZBlockCoordinates}, + vector2::Vector2, WORLD_LOWEST_Y, WORLD_MAX_Y, }; @@ -28,7 +27,7 @@ impl Gen } impl WorldGenerator for GenericGenerator { - fn generate_chunk(&self, at: ChunkCoordinates) -> ChunkData { + fn generate_chunk(&self, at: Vector2) -> ChunkData { let mut blocks = ChunkBlocks::default(); for x in 0..16u8 { diff --git a/pumpkin/src/server.rs b/pumpkin/src/server.rs index c673cbc9..54576787 100644 --- a/pumpkin/src/server.rs +++ b/pumpkin/src/server.rs @@ -370,8 +370,7 @@ impl Server { Err(_) => continue, }; #[cfg(debug_assertions)] - if chunk_data.position == (pumpkin_world::coordinates::ChunkCoordinates { x: 0, z: 0 }) - { + if chunk_data.position == (0, 0).into() { use pumpkin_protocol::bytebuf::ByteBuffer; let mut test = ByteBuffer::empty(); CChunkData(&chunk_data).write(&mut test);