Implement basic culling
This commit is contained in:
parent
ce1c286801
commit
99caa01032
|
@ -104,7 +104,14 @@ fn build_func(id: usize, textures: Arc<RwLock<render::TextureManager>>, work_rec
|
|||
continue;
|
||||
}
|
||||
|
||||
for verts in &PRECOMPUTED_VERTS {
|
||||
for dir in Direction::all() {
|
||||
|
||||
let offset = dir.get_offset();
|
||||
let other = snapshot.get_block(x + offset.0, y + offset.1, z + offset.2);
|
||||
if other.renderable() {
|
||||
continue;
|
||||
}
|
||||
|
||||
let stone = render::Renderer::get_texture(&textures, rng.choose(&[
|
||||
"minecraft:blocks/lava_flow",
|
||||
"minecraft:blocks/stone",
|
||||
|
@ -112,7 +119,7 @@ fn build_func(id: usize, textures: Arc<RwLock<render::TextureManager>>, work_rec
|
|||
"minecraft:blocks/sand",
|
||||
]).unwrap());
|
||||
solid_count += 6;
|
||||
for vert in verts {
|
||||
for vert in dir.get_verts() {
|
||||
let mut vert = vert.clone();
|
||||
// TODO
|
||||
vert.r = 255;
|
||||
|
@ -152,38 +159,80 @@ fn build_func(id: usize, textures: Arc<RwLock<render::TextureManager>>, work_rec
|
|||
}
|
||||
}
|
||||
|
||||
const PRECOMPUTED_VERTS: [[BlockVertex; 4]; 6] = [
|
||||
[ // Up
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum Direction {
|
||||
Up,
|
||||
Down,
|
||||
North,
|
||||
South,
|
||||
West,
|
||||
East,
|
||||
}
|
||||
|
||||
impl Direction {
|
||||
pub fn all() -> Vec<Direction> {
|
||||
vec![
|
||||
Direction::Up, Direction::Down,
|
||||
Direction::North, Direction::South,
|
||||
Direction::West, Direction::East,
|
||||
]
|
||||
}
|
||||
|
||||
pub fn get_verts(&self) -> &'static [BlockVertex; 4] {
|
||||
match *self {
|
||||
Direction::Up => PRECOMPUTED_VERTS[0],
|
||||
Direction::Down => PRECOMPUTED_VERTS[1],
|
||||
Direction::North => PRECOMPUTED_VERTS[2],
|
||||
Direction::South => PRECOMPUTED_VERTS[3],
|
||||
Direction::West => PRECOMPUTED_VERTS[4],
|
||||
Direction::East => PRECOMPUTED_VERTS[5],
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_offset(&self) -> (i32, i32, i32) {
|
||||
match *self {
|
||||
Direction::Up => (0, 1, 0),
|
||||
Direction::Down => (0, -1, 0),
|
||||
Direction::North => (0, 0, -1),
|
||||
Direction::South => (0, 0, 1),
|
||||
Direction::West => (-1, 0, 0),
|
||||
Direction::East => (1, 0, 0),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const PRECOMPUTED_VERTS: [&'static [BlockVertex; 4]; 6] = [
|
||||
&[ // Up
|
||||
BlockVertex::base(0.0, 1.0, 0.0, 0, 0),
|
||||
BlockVertex::base(1.0, 1.0, 0.0, 1, 0),
|
||||
BlockVertex::base(0.0, 1.0, 1.0, 0, 1),
|
||||
BlockVertex::base(1.0, 1.0, 1.0, 1, 1),
|
||||
],
|
||||
[ // Down
|
||||
&[ // Down
|
||||
BlockVertex::base(0.0, 0.0, 0.0, 0, 1),
|
||||
BlockVertex::base(0.0, 0.0, 1.0, 0, 0),
|
||||
BlockVertex::base(1.0, 0.0, 0.0, 1, 1),
|
||||
BlockVertex::base(1.0, 0.0, 1.0, 1, 0),
|
||||
],
|
||||
[ // North
|
||||
&[ // North
|
||||
BlockVertex::base(0.0, 0.0, 0.0, 1, 1),
|
||||
BlockVertex::base(1.0, 0.0, 0.0, 0, 1),
|
||||
BlockVertex::base(0.0, 1.0, 0.0, 1, 0),
|
||||
BlockVertex::base(1.0, 1.0, 0.0, 0, 0),
|
||||
],
|
||||
[ // South
|
||||
&[ // South
|
||||
BlockVertex::base(0.0, 0.0, 1.0, 0, 1),
|
||||
BlockVertex::base(0.0, 1.0, 1.0, 0, 0),
|
||||
BlockVertex::base(1.0, 0.0, 1.0, 1, 1),
|
||||
BlockVertex::base(1.0, 1.0, 1.0, 1, 0),
|
||||
],
|
||||
[ // West
|
||||
&[ // West
|
||||
BlockVertex::base(0.0, 0.0, 0.0, 0, 1),
|
||||
BlockVertex::base(0.0, 1.0, 0.0, 0, 0),
|
||||
BlockVertex::base(0.0, 0.0, 1.0, 1, 1),
|
||||
BlockVertex::base(0.0, 1.0, 1.0, 1, 0),
|
||||
],
|
||||
[ // East
|
||||
&[ // East
|
||||
BlockVertex::base(1.0, 0.0, 0.0, 1, 1),
|
||||
BlockVertex::base(1.0, 0.0, 1.0, 0, 1),
|
||||
BlockVertex::base(1.0, 1.0, 0.0, 1, 0),
|
||||
|
|
113
src/world/mod.rs
113
src/world/mod.rs
|
@ -43,7 +43,7 @@ impl World {
|
|||
pub fn get_block(&self, x: i32, y: i32, z: i32) -> &'static block::Block {
|
||||
match self.chunks.get(&CPos(x >> 4, z >> 4)) {
|
||||
Some(ref chunk) => chunk.get_block(x & 0xF, y, z & 0xF),
|
||||
None => block::AIR.base(),
|
||||
None => block::MISSING.base(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -158,57 +158,82 @@ impl World {
|
|||
let mut data = Cursor::new(data);
|
||||
|
||||
let cpos = CPos(x, z);
|
||||
let chunk = if new {
|
||||
self.chunks.insert(cpos, Chunk::new(cpos));
|
||||
self.chunks.get_mut(&cpos).unwrap()
|
||||
} else {
|
||||
if !self.chunks.contains_key(&cpos) {
|
||||
return Ok(());
|
||||
}
|
||||
self.chunks.get_mut(&cpos).unwrap()
|
||||
};
|
||||
{
|
||||
let chunk = if new {
|
||||
self.chunks.insert(cpos, Chunk::new(cpos));
|
||||
self.chunks.get_mut(&cpos).unwrap()
|
||||
} else {
|
||||
if !self.chunks.contains_key(&cpos) {
|
||||
return Ok(());
|
||||
}
|
||||
self.chunks.get_mut(&cpos).unwrap()
|
||||
};
|
||||
|
||||
for i in 0 .. 16 {
|
||||
if mask & (1 << i) == 0 {
|
||||
continue;
|
||||
}
|
||||
if chunk.sections[i].is_none() {
|
||||
chunk.sections[i] = Some(Section::new(i as u8));
|
||||
}
|
||||
let section = chunk.sections[i as usize].as_mut().unwrap();
|
||||
section.dirty = true;
|
||||
|
||||
let bit_size = try!(data.read_u8());
|
||||
let mut block_map = HashMap::new();
|
||||
if bit_size <= 8 {
|
||||
let count = try!(VarInt::read_from(&mut data)).0;
|
||||
for i in 0 .. count {
|
||||
let id = try!(VarInt::read_from(&mut data)).0;
|
||||
block_map.insert(i as usize, id);
|
||||
}
|
||||
}
|
||||
|
||||
let bits = try!(LenPrefixed::<VarInt, u64>::read_from(&mut data)).data;
|
||||
let m = bit::Map::from_raw(bits, bit_size as usize);
|
||||
|
||||
for i in 0 .. 4096 {
|
||||
let val = m.get(i);
|
||||
let block_id = block_map.get(&val).map(|v| *v as usize).unwrap_or(val);
|
||||
let block = block::get_block_by_vanilla_id(block_id);
|
||||
let i = i as i32;
|
||||
section.set_block(
|
||||
i & 0xF,
|
||||
i >> 8,
|
||||
(i >> 4) & 0xF,
|
||||
block
|
||||
);
|
||||
}
|
||||
|
||||
try!(data.read_exact(&mut section.block_light.data));
|
||||
try!(data.read_exact(&mut section.sky_light.data));
|
||||
}
|
||||
}
|
||||
for i in 0 .. 16 {
|
||||
if mask & (1 << i) == 0 {
|
||||
continue;
|
||||
}
|
||||
if chunk.sections[i].is_none() {
|
||||
chunk.sections[i] = Some(Section::new(i as u8));
|
||||
for pos in [
|
||||
(-1, 0, 0), (1, 0, 0),
|
||||
(0, -1, 0), (0, 1, 0),
|
||||
(0, 0, -1), (0, 0, 1)].into_iter() {
|
||||
self.flag_section_dirty(x + pos.0, i as i32 + pos.1, z + pos.2);
|
||||
}
|
||||
let section = chunk.sections[i as usize].as_mut().unwrap();
|
||||
|
||||
let bit_size = try!(data.read_u8());
|
||||
let mut block_map = HashMap::new();
|
||||
if bit_size <= 8 {
|
||||
let count = try!(VarInt::read_from(&mut data)).0;
|
||||
for i in 0 .. count {
|
||||
let id = try!(VarInt::read_from(&mut data)).0;
|
||||
block_map.insert(i as usize, id);
|
||||
}
|
||||
}
|
||||
|
||||
let bits = try!(LenPrefixed::<VarInt, u64>::read_from(&mut data)).data;
|
||||
let m = bit::Map::from_raw(bits, bit_size as usize);
|
||||
|
||||
for i in 0 .. 4096 {
|
||||
let val = m.get(i);
|
||||
let block_id = block_map.get(&val).map(|v| *v as usize).unwrap_or(val);
|
||||
let block = block::get_block_by_vanilla_id(block_id);
|
||||
let i = i as i32;
|
||||
section.set_block(
|
||||
i & 0xF,
|
||||
i >> 8,
|
||||
(i >> 4) & 0xF,
|
||||
block
|
||||
);
|
||||
}
|
||||
|
||||
try!(data.read_exact(&mut section.block_light.data));
|
||||
try!(data.read_exact(&mut section.sky_light.data));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn flag_section_dirty(&mut self, x: i32, y: i32, z: i32) {
|
||||
if y < 0 || y > 15 {
|
||||
return;
|
||||
}
|
||||
let cpos = CPos(x, z);
|
||||
if let Some(chunk) = self.chunks.get_mut(&cpos) {
|
||||
if let Some(sec) = chunk.sections[y as usize].as_mut() {
|
||||
sec.dirty = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Snapshot {
|
||||
|
@ -308,7 +333,7 @@ impl Chunk {
|
|||
fn get_block(&self, x: i32, y: i32, z: i32) -> &'static block::Block {
|
||||
let s_idx = y >> 4;
|
||||
if s_idx < 0 || s_idx > 15 {
|
||||
return block::AIR.base();
|
||||
return block::MISSING.base();
|
||||
}
|
||||
match self.sections[s_idx as usize].as_ref() {
|
||||
Some(sec) => sec.get_block(x, y & 0xF, z),
|
||||
|
|
Loading…
Reference in New Issue