mirror of
https://github.com/griffi-gh/kubi.git
synced 2024-12-22 11:58:21 -06:00
should be all working now
This commit is contained in:
parent
2637838be9
commit
096db79b12
|
@ -10,3 +10,4 @@ log = "0.4"
|
||||||
env_logger = "0.10"
|
env_logger = "0.10"
|
||||||
strum = { version = "0.24", features = ["derive"] }
|
strum = { version = "0.24", features = ["derive"] }
|
||||||
glam = { version = "0.22", features = ["debug-glam-assert", "mint", "fast-math"] }
|
glam = { version = "0.22", features = ["debug-glam-assert", "mint", "fast-math"] }
|
||||||
|
hashbrown = "0.13"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use glam::{Vec2, IVec2};
|
use glam::{Vec2, IVec2};
|
||||||
use glium::Display;
|
use glium::Display;
|
||||||
use std::collections::HashMap;
|
use hashbrown::HashMap;
|
||||||
use crate::game::options::GameOptions;
|
use crate::game::options::GameOptions;
|
||||||
|
|
||||||
mod chunk;
|
mod chunk;
|
||||||
|
@ -50,16 +50,20 @@ impl World {
|
||||||
if !self.chunks.contains_key(&position) {
|
if !self.chunks.contains_key(&position) {
|
||||||
self.chunks.insert(position, Chunk::new(position));
|
self.chunks.insert(position, Chunk::new(position));
|
||||||
}
|
}
|
||||||
let chunk = self.chunks.get_mut(&position).unwrap();
|
{
|
||||||
if x == 0 || z == 0 || x == render_dist || z == render_dist {
|
//we only need mutable reference here:
|
||||||
chunk.desired = ChunkState::Loaded;
|
let chunk = self.chunks.get_mut(&position).unwrap();
|
||||||
} else {
|
if x == 0 || z == 0 || x == render_dist || z == render_dist {
|
||||||
chunk.desired = ChunkState::Rendered;
|
chunk.desired = ChunkState::Loaded;
|
||||||
|
} else {
|
||||||
|
chunk.desired = ChunkState::Rendered;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if matches!(chunk.state, ChunkState::Nothing) {
|
//borrow chunk immutably
|
||||||
|
let chunk = self.chunks.get(&position).unwrap();
|
||||||
|
if matches!(chunk.state, ChunkState::Nothing) && matches!(chunk.desired, ChunkState::Loaded | ChunkState::Rendered) {
|
||||||
self.thread.queue_load(position);
|
self.thread.queue_load(position);
|
||||||
}
|
} else if matches!(chunk.state, ChunkState::Loaded) && matches!(chunk.desired, ChunkState::Rendered) {
|
||||||
if matches!(chunk.state, ChunkState::Loaded) && matches!(chunk.desired, ChunkState::Rendered) {
|
|
||||||
fn all_some<'a>(x: [Option<&'a Chunk>; 4]) -> Option<[&'a Chunk; 4]> {
|
fn all_some<'a>(x: [Option<&'a Chunk>; 4]) -> Option<[&'a Chunk; 4]> {
|
||||||
Some([x[0]?, x[1]?, x[2]?, x[3]?])
|
Some([x[0]?, x[1]?, x[2]?, x[3]?])
|
||||||
}
|
}
|
||||||
|
@ -70,33 +74,43 @@ impl World {
|
||||||
neighbors[2].block_data.is_some() &&
|
neighbors[2].block_data.is_some() &&
|
||||||
neighbors[3].block_data.is_some()
|
neighbors[3].block_data.is_some()
|
||||||
} {
|
} {
|
||||||
self.thread.queue_mesh(chunk, neighbors);
|
self.thread.queue_mesh(
|
||||||
|
position,
|
||||||
|
chunk.block_data.clone().unwrap(),
|
||||||
|
[
|
||||||
|
neighbors[0].block_data.clone().unwrap(),
|
||||||
|
neighbors[1].block_data.clone().unwrap(),
|
||||||
|
neighbors[2].block_data.clone().unwrap(),
|
||||||
|
neighbors[3].block_data.clone().unwrap(),
|
||||||
|
]
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Handle Unload
|
//Unloads and state downgrades
|
||||||
self.chunks.retain(|_, chunk| !matches!(chunk.desired, ChunkState::Unload));
|
self.chunks.retain(|_, chunk| {
|
||||||
|
|
||||||
//State downgrades
|
|
||||||
for (_, chunk) in &mut self.chunks {
|
|
||||||
match chunk.desired {
|
match chunk.desired {
|
||||||
|
// Chunk unload
|
||||||
|
ChunkState::Unload => false,
|
||||||
// Any => Nothing downgrade
|
// Any => Nothing downgrade
|
||||||
ChunkState::Nothing => {
|
ChunkState::Nothing => {
|
||||||
chunk.block_data = None;
|
chunk.block_data = None;
|
||||||
chunk.mesh = None;
|
chunk.mesh = None;
|
||||||
chunk.state = ChunkState::Nothing;
|
chunk.state = ChunkState::Nothing;
|
||||||
|
true
|
||||||
},
|
},
|
||||||
//Render => Loaded downgrade
|
//Render => Loaded downgrade
|
||||||
ChunkState::Loaded if matches!(chunk.state, ChunkState::Rendering | ChunkState::Rendered) => {
|
ChunkState::Loaded if matches!(chunk.state, ChunkState::Rendering | ChunkState::Rendered) => {
|
||||||
chunk.mesh = None;
|
chunk.mesh = None;
|
||||||
chunk.state = ChunkState::Loaded;
|
chunk.state = ChunkState::Loaded;
|
||||||
|
true
|
||||||
},
|
},
|
||||||
_ => ()
|
_ => true
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
//Apply changes from threads
|
//Apply changes from threads
|
||||||
self.thread.apply_tasks(&mut self.chunks, display);
|
self.thread.apply_tasks(&mut self.chunks, display);
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ pub enum ChunkState {
|
||||||
Rendered,
|
Rendered,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type ChunkData = [[[Block; CHUNK_SIZE]; CHUNK_HEIGHT]; CHUNK_SIZE];
|
pub type ChunkData = Box<[[[Block; CHUNK_SIZE]; CHUNK_HEIGHT]; CHUNK_SIZE]>;
|
||||||
|
|
||||||
pub struct Chunk {
|
pub struct Chunk {
|
||||||
pub position: IVec2,
|
pub position: IVec2,
|
||||||
|
|
|
@ -1,10 +1,7 @@
|
||||||
use glam::IVec2;
|
use glam::IVec2;
|
||||||
use glium::{Display, VertexBuffer, IndexBuffer, index::PrimitiveType};
|
use glium::{Display, VertexBuffer, IndexBuffer, index::PrimitiveType};
|
||||||
use std::{
|
use std::{mem, thread::{self, JoinHandle}};
|
||||||
thread::{self, JoinHandle},
|
use hashbrown::HashMap;
|
||||||
collections::HashMap,
|
|
||||||
mem
|
|
||||||
};
|
|
||||||
use super::chunk::{Chunk, ChunkData, ChunkState};
|
use super::chunk::{Chunk, ChunkData, ChunkState};
|
||||||
use crate::game::shaders::chunk::Vertex as ChunkVertex;
|
use crate::game::shaders::chunk::Vertex as ChunkVertex;
|
||||||
|
|
||||||
|
@ -38,20 +35,12 @@ impl WorldThreading {
|
||||||
log::warn!("load: discarded {}, reason: new task started", position);
|
log::warn!("load: discarded {}, reason: new task started", position);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn queue_mesh(&mut self, chunk: &Chunk, neighbors: [&Chunk; 4]) {
|
pub fn queue_mesh(&mut self, position: IVec2, chunk: ChunkData, neighbor_data: [ChunkData; 4]) {
|
||||||
let position = chunk.position;
|
|
||||||
let data = chunk.block_data.expect("Chunk has no mesh!");
|
|
||||||
let neighbor_data = [
|
|
||||||
neighbors[0].block_data.expect("Chunk has no mesh!"),
|
|
||||||
neighbors[1].block_data.expect("Chunk has no mesh!"),
|
|
||||||
neighbors[2].block_data.expect("Chunk has no mesh!"),
|
|
||||||
neighbors[3].block_data.expect("Chunk has no mesh!"),
|
|
||||||
];
|
|
||||||
let handle = thread::spawn(move || {
|
let handle = thread::spawn(move || {
|
||||||
mesh_gen::generate_mesh(position, data, neighbor_data)
|
mesh_gen::generate_mesh(position, chunk, neighbor_data)
|
||||||
});
|
});
|
||||||
if self.mesh_tasks.insert(chunk.position, Some(handle)).is_some() {
|
if self.mesh_tasks.insert(position, Some(handle)).is_some() {
|
||||||
log::warn!("mesh: discarded {}, reason: new task started", chunk.position);
|
log::warn!("mesh: discarded {}, reason: new task started", position);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn apply_tasks(&mut self, chunks: &mut HashMap<IVec2, Chunk>, display: &Display) {
|
pub fn apply_tasks(&mut self, chunks: &mut HashMap<IVec2, Chunk>, display: &Display) {
|
||||||
|
|
|
@ -4,5 +4,5 @@ use crate::game::{
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn generate_chunk() -> ChunkData {
|
pub fn generate_chunk() -> ChunkData {
|
||||||
[[[Block::Stone; CHUNK_SIZE]; CHUNK_HEIGHT]; CHUNK_SIZE]
|
Box::new([[[Block::Stone; CHUNK_SIZE]; CHUNK_HEIGHT]; CHUNK_SIZE])
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue