Skip to content

Commit

Permalink
Make ChunkData use Vector2 instead of ChunkCoordinates
Browse files Browse the repository at this point in the history
  • Loading branch information
lukas0008 committed Aug 30, 2024
1 parent 5f05a18 commit 8bb00e2
Show file tree
Hide file tree
Showing 9 changed files with 127 additions and 30 deletions.
7 changes: 4 additions & 3 deletions pumpkin-world/src/chunk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
};

Expand All @@ -18,7 +19,7 @@ const CHUNK_VOLUME: usize = CHUNK_AREA * WORLD_HEIGHT;

pub struct ChunkData {
pub blocks: ChunkBlocks,
pub position: ChunkCoordinates,
pub position: Vector2<i32>,
}

pub struct ChunkBlocks {
Expand Down Expand Up @@ -187,7 +188,7 @@ impl Index<ChunkRelativeBlockCoordinates> for ChunkBlocks {
}

impl ChunkData {
pub fn from_bytes(chunk_data: Vec<u8>, at: ChunkCoordinates) -> Result<Self, WorldError> {
pub fn from_bytes(chunk_data: Vec<u8>, at: Vector2<i32>) -> Result<Self, WorldError> {
if fastnbt::from_bytes::<ChunkStatus>(&chunk_data).expect("Failed reading chunk status.")
!= ChunkStatus::Full
{
Expand Down
15 changes: 3 additions & 12 deletions pumpkin-world/src/coordinates.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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<i32>) -> BlockCoordinates {
BlockCoordinates {
x: *self.x as i32 + chunk_coordinates.x * 16,
y: self.y,
Expand All @@ -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<i32>) -> XZBlockCoordinates {
XZBlockCoordinates {
x: *self.x as i32 + chunk_coordinates.x * 16,
z: *self.z as i32 + chunk_coordinates.z * 16,
Expand All @@ -132,9 +129,3 @@ impl ChunkRelativeXZBlockCoordinates {
}
}
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct ChunkCoordinates {
pub x: i32,
pub z: i32,
}
6 changes: 3 additions & 3 deletions pumpkin-world/src/level.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use tokio::sync::mpsc;

use crate::{
chunk::ChunkData,
coordinates::ChunkCoordinates,
vector2::Vector2,
world_gen::{get_world_gen, Seed, WorldGenerator},
};

Expand Down Expand Up @@ -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<i32>],
channel: mpsc::Sender<Result<ChunkData, WorldError>>,
) {
chunks.into_par_iter().copied().for_each(|at| {
Expand All @@ -165,7 +165,7 @@ impl Level {
})
}

fn read_chunk(save_file: &SaveFile, at: ChunkCoordinates) -> Result<ChunkData, WorldError> {
fn read_chunk(save_file: &SaveFile, at: Vector2<i32>) -> Result<ChunkData, WorldError> {
let region = (
((at.x as f32) / 32.0).floor() as i32,
((at.z as f32) / 32.0).floor() as i32,
Expand Down
1 change: 1 addition & 0 deletions pumpkin-world/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
8 changes: 4 additions & 4 deletions pumpkin-world/src/radial_chunk_iterator.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use crate::coordinates::ChunkCoordinates;
use crate::vector2::Vector2;

pub struct RadialIterator {
radius: u32,
direction: usize,
current: ChunkCoordinates,
current: Vector2<i32>,
step_size: i32,
steps_taken: u32,
steps_in_direction: i32,
Expand All @@ -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,
Expand All @@ -23,7 +23,7 @@ impl RadialIterator {
}

impl Iterator for RadialIterator {
type Item = ChunkCoordinates;
type Item = Vector2<i32>;

fn next(&mut self) -> Option<Self::Item> {
if self.steps_taken >= self.radius * self.radius * 4 {
Expand Down
105 changes: 105 additions & 0 deletions pumpkin-world/src/vector2.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
use std::ops::{Add, Div, Mul, Neg, Sub};

use num_traits::Float;

#[derive(Clone, Copy, Debug, PartialEq)]
pub struct Vector2<T> {
pub x: T,
pub z: T,
}

impl<T: Math + Copy> Vector2<T> {
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<T>) -> Self {
Vector2 {
x: self.x + other.x,
z: self.z + other.z,
}
}

pub fn sub(&self, other: &Vector2<T>) -> 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<T: Math + Copy + Float> Vector2<T> {
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<T: Math + Copy> Mul<T> for Vector2<T> {
type Output = Self;

fn mul(self, scalar: T) -> Self {
Self {
x: self.x * scalar,
z: self.z * scalar,
}
}
}

impl<T: Math + Copy> Add for Vector2<T> {
type Output = Vector2<T>;
fn add(self, rhs: Self) -> Self::Output {
Self {
x: self.x + rhs.x,
z: self.z + rhs.z,
}
}
}

impl<T: Math + Copy> Neg for Vector2<T> {
type Output = Self;

fn neg(self) -> Self {
Vector2 {
x: -self.x,
z: -self.z,
}
}
}

impl<T> From<(T, T)> for Vector2<T> {
fn from((x, z): (T, T)) -> Self {
Vector2 { x, z }
}
}

pub trait Math:
Mul<Output = Self>
+ Neg<Output = Self>
+ Add<Output = Self>
+ Div<Output = Self>
+ Sub<Output = Self>
+ Sized
{
}
impl Math for f64 {}
impl Math for f32 {}
impl Math for i32 {}
impl Math for i64 {}
5 changes: 3 additions & 2 deletions pumpkin-world/src/world_gen/generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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<i32>) -> ChunkData;
}
assert_obj_safe! {WorldGenerator}

Expand Down
7 changes: 3 additions & 4 deletions pumpkin-world/src/world_gen/generic_generator.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
use crate::{
chunk::{ChunkBlocks, ChunkData},
coordinates::{
ChunkCoordinates, ChunkRelativeBlockCoordinates, ChunkRelativeXZBlockCoordinates,
},
coordinates::{ChunkRelativeBlockCoordinates, ChunkRelativeXZBlockCoordinates},
vector2::Vector2,
WORLD_LOWEST_Y, WORLD_MAX_Y,
};

Expand All @@ -28,7 +27,7 @@ impl<B: BiomeGenerator + GeneratorInit, T: TerrainGenerator + GeneratorInit> Gen
}

impl<B: BiomeGenerator, T: TerrainGenerator> WorldGenerator for GenericGenerator<B, T> {
fn generate_chunk(&self, at: ChunkCoordinates) -> ChunkData {
fn generate_chunk(&self, at: Vector2<i32>) -> ChunkData {
let mut blocks = ChunkBlocks::default();

for x in 0..16u8 {
Expand Down
3 changes: 1 addition & 2 deletions pumpkin/src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit 8bb00e2

Please sign in to comment.