Loading world, not working yet
This commit is contained in:
+16
-11
@@ -27,19 +27,24 @@ impl App {
|
|||||||
world: World::new("default".to_string())
|
world: World::new("default".to_string())
|
||||||
};
|
};
|
||||||
|
|
||||||
let timer = Instant::now();
|
|
||||||
for x in 0..16 {
|
// let timer = Instant::now();
|
||||||
for z in 0..16 {
|
// for x in 0..16 {
|
||||||
let pos = &Point3{x,y:0,z};
|
// for z in 0..16 {
|
||||||
let block = app.world.gen_block(pos);
|
// let pos = &Point3{x,y:0,z};
|
||||||
content.write(pos, block);
|
// let block = app.world.gen_block(pos);
|
||||||
}
|
// content.write(pos, block);
|
||||||
}
|
// }
|
||||||
println!("Generated in {}", timer.elapsed().as_secs_f32());
|
// }
|
||||||
|
// println!("Generated in {}", timer.elapsed().as_secs_f32());
|
||||||
|
|
||||||
|
// let timer = Instant::now();
|
||||||
|
// app.world.save();
|
||||||
|
// println!("Saved in {}", timer.elapsed().as_secs_f32());
|
||||||
|
|
||||||
let timer = Instant::now();
|
let timer = Instant::now();
|
||||||
app.world.save();
|
app.world.load();
|
||||||
println!("Saved in {}", timer.elapsed().as_secs_f32());
|
println!("Loaded in {}", timer.elapsed().as_secs_f32());
|
||||||
|
|
||||||
// let pos = &Point3{x:1,y:0,z:0};
|
// let pos = &Point3{x:1,y:0,z:0};
|
||||||
// let block = app.world.gen_block(pos);
|
// let block = app.world.gen_block(pos);
|
||||||
|
|||||||
@@ -4,17 +4,18 @@ use std::io::Write;
|
|||||||
use flate2::{write::DeflateEncoder, Compression};
|
use flate2::{write::DeflateEncoder, Compression};
|
||||||
|
|
||||||
pub const SIZE: usize = 32;
|
pub const SIZE: usize = 32;
|
||||||
|
pub const SIZE_QB: usize = SIZE*SIZE*SIZE;
|
||||||
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct WorldBlock {
|
pub struct WorldBlock {
|
||||||
pub materials: [u8;(SIZE*SIZE*SIZE) as usize]
|
pub materials: [u8;SIZE_QB]
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WorldBlock {
|
impl WorldBlock {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
materials: [0_u8; (SIZE*SIZE*SIZE) as usize]
|
materials: [0_u8; SIZE_QB]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+38
-7
@@ -1,13 +1,15 @@
|
|||||||
use flate2::Compression;
|
use flate2::Compression;
|
||||||
use flate2::write::DeflateEncoder;
|
use flate2::write::DeflateEncoder;
|
||||||
|
use flate2::read::DeflateDecoder;
|
||||||
use byteorder::LittleEndian;
|
use byteorder::LittleEndian;
|
||||||
use byteorder::ByteOrder;
|
use byteorder::ByteOrder;
|
||||||
use cgmath::Point3;
|
use cgmath::Point3;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use crate::app::world::WorldBlock;
|
use std::convert::TryInto;
|
||||||
|
use crate::app::world::{WorldBlock, block};
|
||||||
|
|
||||||
pub const SIZE: u32 = 32;
|
pub const SIZE: u32 = 32;
|
||||||
|
const SIZE_QB: u32 = SIZE*SIZE*SIZE;
|
||||||
|
|
||||||
pub struct WorldChunk {
|
pub struct WorldChunk {
|
||||||
nodes: Box<[u32]>,
|
nodes: Box<[u32]>,
|
||||||
@@ -17,7 +19,7 @@ pub struct WorldChunk {
|
|||||||
impl WorldChunk {
|
impl WorldChunk {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
nodes: vec![0_u32; (SIZE*SIZE*SIZE) as usize].into_boxed_slice(),
|
nodes: vec![0_u32; SIZE_QB as usize].into_boxed_slice(),
|
||||||
blocks: Vec::new()
|
blocks: Vec::new()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -40,17 +42,46 @@ impl WorldChunk {
|
|||||||
let mut bytes = Vec::with_capacity(self.nodes.len()*4 + self.blocks.len()* 32*32*32);
|
let mut bytes = Vec::with_capacity(self.nodes.len()*4 + self.blocks.len()* 32*32*32);
|
||||||
|
|
||||||
// Nodes
|
// Nodes
|
||||||
let mut node_bytes = [0_u8; (SIZE*SIZE*SIZE*4) as usize];
|
let mut node_bytes = [0_u8; (SIZE_QB*4) as usize];
|
||||||
LittleEndian::write_u32_into(&self.nodes, &mut node_bytes);
|
LittleEndian::write_u32_into(&self.nodes, &mut node_bytes);
|
||||||
bytes.extend(node_bytes.iter());
|
bytes.extend(node_bytes.iter());
|
||||||
|
|
||||||
// Blocks
|
// Blocks
|
||||||
let mut encoder = DeflateEncoder::new(Vec::new(), Compression::fast());
|
// let mut encoder = DeflateEncoder::new(Vec::new(), Compression::fast());
|
||||||
|
// for block in self.blocks.iter() {
|
||||||
|
// encoder.write_all(&block.materials).unwrap();
|
||||||
|
// }
|
||||||
|
// bytes.extend(encoder.finish().unwrap());
|
||||||
|
|
||||||
for block in self.blocks.iter() {
|
for block in self.blocks.iter() {
|
||||||
encoder.write_all(&block.materials).unwrap();
|
bytes.extend(&block.materials);
|
||||||
}
|
}
|
||||||
bytes.extend(encoder.finish().unwrap());
|
|
||||||
|
|
||||||
bytes
|
bytes
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn from_bytes(bytes: Vec<u8>) -> Self {
|
||||||
|
let mut instance = Self::new();
|
||||||
|
let (node_bytes, block_bytes) = bytes.split_at((SIZE_QB*4) as usize);
|
||||||
|
|
||||||
|
// Nodes
|
||||||
|
for i in 0..SIZE_QB {
|
||||||
|
let idx = (i*4) as usize;
|
||||||
|
instance.nodes[i as usize] = u32::from_le_bytes([node_bytes[idx], node_bytes[idx+1], node_bytes[idx+2], node_bytes[idx+3]]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Blocks
|
||||||
|
let block_num = block_bytes.len() / block::SIZE_QB;
|
||||||
|
println!("block_num {}", block_num);
|
||||||
|
for i in 0..block_num {
|
||||||
|
let mut block = WorldBlock::new();
|
||||||
|
let idx = i * block::SIZE_QB;
|
||||||
|
for j in 0..block::SIZE_QB {
|
||||||
|
block.materials[j] = block_bytes[idx+j];
|
||||||
|
}
|
||||||
|
instance.blocks.push(block);
|
||||||
|
}
|
||||||
|
|
||||||
|
instance
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -4,6 +4,7 @@ pub mod block;
|
|||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
|
use std::io::Read;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use cgmath::Point3;
|
use cgmath::Point3;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
@@ -42,6 +43,39 @@ impl World {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn load(&mut self) {
|
||||||
|
// Get directory
|
||||||
|
let mut dir = dirs::data_local_dir().unwrap();
|
||||||
|
dir.push("Voxelgame");
|
||||||
|
if !dir.is_dir() {
|
||||||
|
println!("Not exists: {:?}", dir);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load all chunks
|
||||||
|
for entry in fs::read_dir(dir).unwrap() {
|
||||||
|
let path: PathBuf = entry.unwrap().path();
|
||||||
|
if path.extension().unwrap().to_str() != Some("dat") {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let stem = path.file_stem().unwrap().to_str().unwrap();
|
||||||
|
if !stem.starts_with("chunk") {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let s: Vec<&str> = stem.split("_").collect();
|
||||||
|
let pos = Point3{x: s[1].parse::<u32>().unwrap(), y: s[2].parse::<u32>().unwrap(), z: s[3].parse::<u32>().unwrap()};
|
||||||
|
|
||||||
|
let mut bytes = Vec::new();
|
||||||
|
let mut file = fs::File::open(path).expect("Failed to open file");
|
||||||
|
file.read_to_end(&mut bytes).expect("Failed to read file");
|
||||||
|
let chunk = WorldChunk::from_bytes(bytes);
|
||||||
|
|
||||||
|
println!("loaded {:?}", pos);
|
||||||
|
self.chunks.insert(pos, chunk);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn gen_block(&mut self, block_pos: &Point3<u32>) -> &WorldBlock {
|
pub fn gen_block(&mut self, block_pos: &Point3<u32>) -> &WorldBlock {
|
||||||
// Split world space to chunk and block space
|
// Split world space to chunk and block space
|
||||||
let ch_pos = block_pos / chunk::SIZE;
|
let ch_pos = block_pos / chunk::SIZE;
|
||||||
|
|||||||
Reference in New Issue
Block a user