Changed project name (placeholder), some renames
This commit is contained in:
@@ -0,0 +1,108 @@
|
||||
use std::time::Instant;
|
||||
use flate2::Compression;
|
||||
use flate2::write::DeflateEncoder;
|
||||
use flate2::read::DeflateDecoder;
|
||||
use byteorder::LittleEndian;
|
||||
use byteorder::ByteOrder;
|
||||
use cgmath::Point3;
|
||||
use std::io::Write;
|
||||
use std::convert::TryInto;
|
||||
use std::io::Read;
|
||||
use crate::game::world::{WorldBlock, block};
|
||||
|
||||
pub const SIZE: usize = 32;
|
||||
const SIZE_SQ: usize = SIZE*SIZE;
|
||||
const SIZE_QB: usize = SIZE*SIZE*SIZE;
|
||||
|
||||
pub struct WorldChunk {
|
||||
nodes: Box<[u32]>,
|
||||
blocks: Vec<WorldBlock>
|
||||
}
|
||||
|
||||
impl WorldChunk {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
nodes: vec![0_u32; SIZE_QB as usize].into_boxed_slice(),
|
||||
blocks: Vec::new()
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
let mut num_blocks = 0;
|
||||
for i in 0..SIZE_QB {
|
||||
let idx = (i*4) as usize;
|
||||
let val = u32::from_le_bytes([node_bytes[idx], node_bytes[idx+1], node_bytes[idx+2], node_bytes[idx+3]]);
|
||||
instance.nodes[i as usize] = val;
|
||||
if val > 0 { num_blocks+=1; }
|
||||
}
|
||||
|
||||
// Blocks
|
||||
let mut decoder = DeflateDecoder::new(block_bytes);
|
||||
let mut block_bytes = Vec::with_capacity(SIZE_QB);
|
||||
decoder.read_to_end(&mut block_bytes).expect("Failed to decode");
|
||||
|
||||
for i in 0..num_blocks {
|
||||
let mut block = WorldBlock::new();
|
||||
let idx = i * block::SIZE_QB;
|
||||
block.materials.clone_from_slice(&block_bytes[idx..idx+block::SIZE_QB]);
|
||||
instance.blocks.push(block);
|
||||
}
|
||||
|
||||
instance
|
||||
}
|
||||
|
||||
pub fn all_blocks(&self) -> Vec<(Point3<u32>, &WorldBlock)> {
|
||||
self.nodes.iter().enumerate()
|
||||
.filter(|(_, n)| **n != 0)
|
||||
.map(|(index, node)| {
|
||||
|
||||
let mut idx = index;
|
||||
let z = idx / SIZE_SQ;
|
||||
idx -= z * SIZE_SQ;
|
||||
let y = idx / SIZE;
|
||||
let x = idx % SIZE;
|
||||
|
||||
let pos = Point3{x: x as u32, y: y as u32, z: z as u32};
|
||||
|
||||
let block = &self.blocks[(*node-1) as usize];
|
||||
(pos, block)
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn get_block(&mut self, block_pos: &Point3<u32>) -> &mut WorldBlock {
|
||||
// Get block index
|
||||
let index = (block_pos.x + SIZE as u32 * (block_pos.y + SIZE as u32 * block_pos.z)) as usize;
|
||||
let mut value = self.nodes[index];
|
||||
// Allocate new block
|
||||
if value == 0 {
|
||||
value = (self.blocks.len() + 1) as u32;
|
||||
self.nodes[index] = value;
|
||||
self.blocks.push(WorldBlock::new());
|
||||
}
|
||||
// Return block reference
|
||||
&mut self.blocks[(value-1) as usize]
|
||||
}
|
||||
|
||||
pub fn to_bytes(&self) -> Vec<u8> {
|
||||
let mut bytes = Vec::with_capacity(self.nodes.len()*4 + self.blocks.len()* 32*32*32);
|
||||
|
||||
// Nodes
|
||||
let mut node_bytes = [0_u8; (SIZE_QB*4) as usize];
|
||||
LittleEndian::write_u32_into(&self.nodes, &mut node_bytes);
|
||||
bytes.extend(node_bytes.iter());
|
||||
|
||||
// Blocks
|
||||
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());
|
||||
|
||||
bytes
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user