Big project structure reorder
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
4bba01058b
commit
1b91fa94c0
10 changed files with 135 additions and 115 deletions
|
@ -1,10 +1,9 @@
|
||||||
mod aabb;
|
mod aabb;
|
||||||
mod camera;
|
mod camera;
|
||||||
mod chunk;
|
|
||||||
mod geometry;
|
mod geometry;
|
||||||
mod npc;
|
mod npc;
|
||||||
mod quad;
|
|
||||||
mod render_context;
|
mod render_context;
|
||||||
|
mod renderable;
|
||||||
mod state;
|
mod state;
|
||||||
mod text_renderer;
|
mod text_renderer;
|
||||||
mod texture;
|
mod texture;
|
||||||
|
|
10
src/renderable.rs
Normal file
10
src/renderable.rs
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
|
use wgpu::RenderPass;
|
||||||
|
|
||||||
|
use crate::{camera::Camera, render_context::RenderContext, view::View};
|
||||||
|
|
||||||
|
pub trait Renderable {
|
||||||
|
fn update(&mut self, render_context: &RenderContext, dt: Duration, camera: &Camera);
|
||||||
|
fn render<'a>(&'a self, render_pass: &mut RenderPass<'a>, view: &View) -> usize;
|
||||||
|
}
|
|
@ -20,8 +20,8 @@ pub const PRIMITIVE_STATE: wgpu::PrimitiveState = wgpu::PrimitiveState {
|
||||||
strip_index_format: None,
|
strip_index_format: None,
|
||||||
front_face: wgpu::FrontFace::Ccw,
|
front_face: wgpu::FrontFace::Ccw,
|
||||||
cull_mode: None,
|
cull_mode: None,
|
||||||
polygon_mode: wgpu::PolygonMode::Fill,
|
|
||||||
clamp_depth: false,
|
clamp_depth: false,
|
||||||
|
polygon_mode: wgpu::PolygonMode::Fill,
|
||||||
conservative: false,
|
conservative: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -47,6 +47,7 @@ impl State {
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
println!("Using {:?}", adapter.get_info().backend);
|
||||||
|
|
||||||
let (render_device, queue) = adapter
|
let (render_device, queue) = adapter
|
||||||
.request_device(
|
.request_device(
|
||||||
|
|
|
@ -13,11 +13,12 @@ use winit::{
|
||||||
use crate::{
|
use crate::{
|
||||||
camera::{Camera, Projection},
|
camera::{Camera, Projection},
|
||||||
render_context::RenderContext,
|
render_context::RenderContext,
|
||||||
|
renderable::Renderable,
|
||||||
texture::{Texture, TextureManager},
|
texture::{Texture, TextureManager},
|
||||||
time::Time,
|
time::Time,
|
||||||
vertex::{BlockVertex, Vertex},
|
vertex::{BlockVertex, Vertex},
|
||||||
view::View,
|
view::View,
|
||||||
world::World,
|
world::world::World,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct WorldState {
|
pub struct WorldState {
|
||||||
|
@ -428,7 +429,7 @@ impl WorldState {
|
||||||
pub fn update(&mut self, dt: Duration, render_context: &RenderContext) {
|
pub fn update(&mut self, dt: Duration, render_context: &RenderContext) {
|
||||||
self.update_position(dt);
|
self.update_position(dt);
|
||||||
|
|
||||||
self.world.update(dt, render_context, &self.camera);
|
self.world.update(render_context, dt, &self.camera);
|
||||||
|
|
||||||
self.view
|
self.view
|
||||||
.update_view_projection(&self.camera, &self.projection);
|
.update_view_projection(&self.camera, &self.projection);
|
||||||
|
|
41
src/world/block.rs
Normal file
41
src/world/block.rs
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use serde_repr::{Deserialize_repr, Serialize_repr};
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize_repr, Deserialize_repr)]
|
||||||
|
#[repr(u8)]
|
||||||
|
pub enum BlockType {
|
||||||
|
Cobblestone = 1,
|
||||||
|
Dirt = 2,
|
||||||
|
Stone = 3,
|
||||||
|
Grass = 4,
|
||||||
|
Bedrock = 5,
|
||||||
|
Sand = 6,
|
||||||
|
Gravel = 7,
|
||||||
|
Water = 8,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BlockType {
|
||||||
|
#[rustfmt::skip]
|
||||||
|
pub const fn texture_indices(self) -> (usize, usize, usize, usize, usize, usize) {
|
||||||
|
match self {
|
||||||
|
BlockType::Cobblestone => ( 0, 0, 0, 0, 0, 0),
|
||||||
|
BlockType::Dirt => ( 1, 1, 1, 1, 1, 1),
|
||||||
|
BlockType::Stone => ( 2, 2, 2, 2, 2, 2),
|
||||||
|
BlockType::Grass => ( 4, 4, 4, 4, 2, 3),
|
||||||
|
BlockType::Bedrock => ( 5, 5, 5, 5, 5, 5),
|
||||||
|
BlockType::Sand => ( 6, 6, 6, 6, 6, 6),
|
||||||
|
BlockType::Gravel => ( 7, 7, 7, 7, 7, 7),
|
||||||
|
BlockType::Water => ( 8, 8, 8, 8, 8, 8), // up to 71
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const fn is_transparent(self) -> bool {
|
||||||
|
matches!(self, BlockType::Water)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
|
||||||
|
pub struct Block {
|
||||||
|
pub block_type: BlockType,
|
||||||
|
}
|
|
@ -1,81 +1,31 @@
|
||||||
use std::{collections::VecDeque, usize};
|
use std::collections::VecDeque;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
aabb::Aabb,
|
aabb::Aabb,
|
||||||
geometry::{Geometry, GeometryBuffers},
|
geometry::{Geometry, GeometryBuffers},
|
||||||
quad::Quad,
|
|
||||||
vertex::BlockVertex,
|
vertex::BlockVertex,
|
||||||
view::View,
|
view::View,
|
||||||
|
world::{
|
||||||
|
block::{Block, BlockType},
|
||||||
|
face_flags::*,
|
||||||
|
quad::Quad,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
use ahash::{AHashMap, AHashSet};
|
use ahash::{AHashMap, AHashSet};
|
||||||
use cgmath::{Point3, Vector3};
|
use cgmath::{Point3, Vector3};
|
||||||
use noise::utils::{NoiseMapBuilder, PlaneMapBuilder};
|
use noise::utils::{NoiseMapBuilder, PlaneMapBuilder};
|
||||||
use rayon::iter::{IntoParallelIterator, ParallelIterator};
|
use rayon::iter::{IntoParallelIterator, ParallelIterator};
|
||||||
|
|
||||||
use serde::{
|
use serde::{
|
||||||
de::{SeqAccess, Visitor},
|
de::{SeqAccess, Visitor},
|
||||||
ser::{SerializeSeq, Serializer},
|
ser::SerializeSeq,
|
||||||
Deserialize, Serialize,
|
Deserialize, Serialize, Serializer,
|
||||||
};
|
};
|
||||||
use serde_repr::{Deserialize_repr, Serialize_repr};
|
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize_repr, Deserialize_repr)]
|
|
||||||
#[repr(u8)]
|
|
||||||
pub enum BlockType {
|
|
||||||
Cobblestone = 1,
|
|
||||||
Dirt = 2,
|
|
||||||
Stone = 3,
|
|
||||||
Grass = 4,
|
|
||||||
Bedrock = 5,
|
|
||||||
Sand = 6,
|
|
||||||
Gravel = 7,
|
|
||||||
Water = 8,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl BlockType {
|
|
||||||
#[rustfmt::skip]
|
|
||||||
pub const fn texture_indices(self) -> (usize, usize, usize, usize, usize, usize) {
|
|
||||||
match self {
|
|
||||||
BlockType::Cobblestone => ( 0, 0, 0, 0, 0, 0),
|
|
||||||
BlockType::Dirt => ( 1, 1, 1, 1, 1, 1),
|
|
||||||
BlockType::Stone => ( 2, 2, 2, 2, 2, 2),
|
|
||||||
BlockType::Grass => ( 4, 4, 4, 4, 2, 3),
|
|
||||||
BlockType::Bedrock => ( 5, 5, 5, 5, 5, 5),
|
|
||||||
BlockType::Sand => ( 6, 6, 6, 6, 6, 6),
|
|
||||||
BlockType::Gravel => ( 7, 7, 7, 7, 7, 7),
|
|
||||||
BlockType::Water => ( 8, 8, 8, 8, 8, 8), // up to 71
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub const fn is_transparent(self) -> bool {
|
|
||||||
matches!(self, BlockType::Water)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub type FaceFlags = usize;
|
|
||||||
pub const FACE_NONE: FaceFlags = 0;
|
|
||||||
pub const FACE_LEFT: FaceFlags = 1;
|
|
||||||
pub const FACE_RIGHT: FaceFlags = 2;
|
|
||||||
pub const FACE_BOTTOM: FaceFlags = 4;
|
|
||||||
pub const FACE_TOP: FaceFlags = 8;
|
|
||||||
pub const FACE_BACK: FaceFlags = 16;
|
|
||||||
pub const FACE_FRONT: FaceFlags = 32;
|
|
||||||
pub const FACE_ALL: FaceFlags =
|
|
||||||
FACE_LEFT | FACE_RIGHT | FACE_BOTTOM | FACE_TOP | FACE_BACK | FACE_FRONT;
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
|
|
||||||
pub struct Block {
|
|
||||||
pub block_type: BlockType,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub const CHUNK_SIZE: usize = 32;
|
pub const CHUNK_SIZE: usize = 32;
|
||||||
pub const CHUNK_ISIZE: isize = CHUNK_SIZE as isize;
|
pub const CHUNK_ISIZE: isize = CHUNK_SIZE as isize;
|
||||||
|
|
||||||
type ChunkBlocks = [[[Option<Block>; CHUNK_SIZE]; CHUNK_SIZE]; CHUNK_SIZE];
|
|
||||||
|
|
||||||
pub struct Chunk {
|
pub struct Chunk {
|
||||||
pub blocks: ChunkBlocks,
|
pub blocks: [[[Option<Block>; CHUNK_SIZE]; CHUNK_SIZE]; CHUNK_SIZE],
|
||||||
pub buffers: Option<GeometryBuffers<u16>>,
|
pub buffers: Option<GeometryBuffers<u16>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,23 +38,6 @@ impl Default for Chunk {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Serialize for Chunk {
|
|
||||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
|
||||||
where
|
|
||||||
S: Serializer,
|
|
||||||
{
|
|
||||||
let mut seq = serializer.serialize_seq(Some(CHUNK_SIZE.pow(3)))?;
|
|
||||||
for layer in self.blocks.iter() {
|
|
||||||
for row in layer {
|
|
||||||
for block in row {
|
|
||||||
seq.serialize_element(block)?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
seq.end()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct ChunkVisitor;
|
struct ChunkVisitor;
|
||||||
|
|
||||||
impl<'de> Visitor<'de> for ChunkVisitor {
|
impl<'de> Visitor<'de> for ChunkVisitor {
|
||||||
|
@ -131,6 +64,23 @@ impl<'de> Visitor<'de> for ChunkVisitor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Serialize for Chunk {
|
||||||
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
|
where
|
||||||
|
S: Serializer,
|
||||||
|
{
|
||||||
|
let mut seq = serializer.serialize_seq(Some(CHUNK_SIZE.pow(3)))?;
|
||||||
|
for layer in self.blocks.iter() {
|
||||||
|
for row in layer {
|
||||||
|
for block in row {
|
||||||
|
seq.serialize_element(block)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
seq.end()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'de> Deserialize<'de> for Chunk {
|
impl<'de> Deserialize<'de> for Chunk {
|
||||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
where
|
where
|
10
src/world/face_flags.rs
Normal file
10
src/world/face_flags.rs
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
pub type FaceFlags = usize;
|
||||||
|
pub const FACE_NONE: FaceFlags = 0;
|
||||||
|
pub const FACE_LEFT: FaceFlags = 1;
|
||||||
|
pub const FACE_RIGHT: FaceFlags = 2;
|
||||||
|
pub const FACE_BOTTOM: FaceFlags = 4;
|
||||||
|
pub const FACE_TOP: FaceFlags = 8;
|
||||||
|
pub const FACE_BACK: FaceFlags = 16;
|
||||||
|
pub const FACE_FRONT: FaceFlags = 32;
|
||||||
|
pub const FACE_ALL: FaceFlags =
|
||||||
|
FACE_LEFT | FACE_RIGHT | FACE_BOTTOM | FACE_TOP | FACE_BACK | FACE_FRONT;
|
5
src/world/mod.rs
Normal file
5
src/world/mod.rs
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
pub mod block;
|
||||||
|
pub mod chunk;
|
||||||
|
pub mod face_flags;
|
||||||
|
pub mod quad;
|
||||||
|
pub mod world;
|
|
@ -1,12 +1,9 @@
|
||||||
use cgmath::{Point3, Vector3, Zero};
|
use cgmath::{Point3, Vector3, Zero};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
chunk::{
|
|
||||||
BlockType, FaceFlags, FACE_ALL, FACE_BACK, FACE_BOTTOM, FACE_FRONT, FACE_LEFT, FACE_RIGHT,
|
|
||||||
FACE_TOP,
|
|
||||||
},
|
|
||||||
geometry::Geometry,
|
geometry::Geometry,
|
||||||
vertex::BlockVertex,
|
vertex::BlockVertex,
|
||||||
|
world::{block::BlockType, face_flags::*},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
|
@ -2,11 +2,15 @@ use std::{collections::VecDeque, time::Duration};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
camera::Camera,
|
camera::Camera,
|
||||||
chunk::{Block, BlockType, Chunk, CHUNK_ISIZE},
|
|
||||||
geometry::GeometryBuffers,
|
geometry::GeometryBuffers,
|
||||||
npc::Npc,
|
npc::Npc,
|
||||||
render_context::RenderContext,
|
render_context::RenderContext,
|
||||||
|
renderable::Renderable,
|
||||||
view::View,
|
view::View,
|
||||||
|
world::{
|
||||||
|
block::{Block, BlockType},
|
||||||
|
chunk::{Chunk, CHUNK_ISIZE},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
use ahash::AHashMap;
|
use ahash::AHashMap;
|
||||||
use cgmath::{EuclideanSpace, InnerSpace, Point3, Vector3};
|
use cgmath::{EuclideanSpace, InnerSpace, Point3, Vector3};
|
||||||
|
@ -31,34 +35,8 @@ pub const WORLD_HEIGHT: isize = 16 * 16 / CHUNK_ISIZE;
|
||||||
|
|
||||||
const DEBUG_IO: bool = false;
|
const DEBUG_IO: bool = false;
|
||||||
|
|
||||||
impl World {
|
impl Renderable for World {
|
||||||
pub fn new() -> Self {
|
fn update(&mut self, render_context: &RenderContext, dt: Duration, camera: &Camera) {
|
||||||
let chunks = AHashMap::new();
|
|
||||||
let npc = Npc::load();
|
|
||||||
|
|
||||||
let chunk_database = sled::Config::new()
|
|
||||||
.path("chunks")
|
|
||||||
.mode(sled::Mode::HighThroughput)
|
|
||||||
.use_compression(true)
|
|
||||||
.open()
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
Self {
|
|
||||||
chunks,
|
|
||||||
npc,
|
|
||||||
|
|
||||||
chunk_database,
|
|
||||||
chunk_load_queue: VecDeque::new(),
|
|
||||||
chunk_save_queue: VecDeque::new(),
|
|
||||||
chunk_generate_queue: VecDeque::new(),
|
|
||||||
|
|
||||||
highlighted: None,
|
|
||||||
|
|
||||||
unload_timer: Duration::new(0, 0),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn update(&mut self, dt: Duration, render_context: &RenderContext, camera: &Camera) {
|
|
||||||
if let Some(position) = self.chunk_load_queue.pop_front() {
|
if let Some(position) = self.chunk_load_queue.pop_front() {
|
||||||
let chunk = self.chunks.entry(position).or_default();
|
let chunk = self.chunks.entry(position).or_default();
|
||||||
match chunk.load(position, &self.chunk_database) {
|
match chunk.load(position, &self.chunk_database) {
|
||||||
|
@ -144,7 +122,7 @@ impl World {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render<'a>(&'a self, render_pass: &mut RenderPass<'a>, view: &View) -> usize {
|
fn render<'a>(&'a self, render_pass: &mut RenderPass<'a>, view: &View) -> usize {
|
||||||
let mut triangle_count = 0;
|
let mut triangle_count = 0;
|
||||||
|
|
||||||
for (position, chunk) in &self.chunks {
|
for (position, chunk) in &self.chunks {
|
||||||
|
@ -166,6 +144,34 @@ impl World {
|
||||||
|
|
||||||
triangle_count
|
triangle_count
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl World {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
let chunks = AHashMap::new();
|
||||||
|
let npc = Npc::load();
|
||||||
|
|
||||||
|
let chunk_database = sled::Config::new()
|
||||||
|
.path("chunks")
|
||||||
|
.mode(sled::Mode::HighThroughput)
|
||||||
|
.use_compression(true)
|
||||||
|
.open()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
Self {
|
||||||
|
chunks,
|
||||||
|
npc,
|
||||||
|
|
||||||
|
chunk_database,
|
||||||
|
chunk_load_queue: VecDeque::new(),
|
||||||
|
chunk_save_queue: VecDeque::new(),
|
||||||
|
chunk_generate_queue: VecDeque::new(),
|
||||||
|
|
||||||
|
highlighted: None,
|
||||||
|
|
||||||
|
unload_timer: Duration::new(0, 0),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn enqueue_chunk_save(&mut self, position: Point3<isize>, unload: bool) {
|
pub fn enqueue_chunk_save(&mut self, position: Point3<isize>, unload: bool) {
|
||||||
if let Some((_, unload_)) = self
|
if let Some((_, unload_)) = self
|
Loading…
Reference in a new issue