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;
|
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(&[
|
let stone = render::Renderer::get_texture(&textures, rng.choose(&[
|
||||||
"minecraft:blocks/lava_flow",
|
"minecraft:blocks/lava_flow",
|
||||||
"minecraft:blocks/stone",
|
"minecraft:blocks/stone",
|
||||||
|
@ -112,7 +119,7 @@ fn build_func(id: usize, textures: Arc<RwLock<render::TextureManager>>, work_rec
|
||||||
"minecraft:blocks/sand",
|
"minecraft:blocks/sand",
|
||||||
]).unwrap());
|
]).unwrap());
|
||||||
solid_count += 6;
|
solid_count += 6;
|
||||||
for vert in verts {
|
for vert in dir.get_verts() {
|
||||||
let mut vert = vert.clone();
|
let mut vert = vert.clone();
|
||||||
// TODO
|
// TODO
|
||||||
vert.r = 255;
|
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] = [
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
[ // Up
|
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(0.0, 1.0, 0.0, 0, 0),
|
||||||
BlockVertex::base(1.0, 1.0, 0.0, 1, 0),
|
BlockVertex::base(1.0, 1.0, 0.0, 1, 0),
|
||||||
BlockVertex::base(0.0, 1.0, 1.0, 0, 1),
|
BlockVertex::base(0.0, 1.0, 1.0, 0, 1),
|
||||||
BlockVertex::base(1.0, 1.0, 1.0, 1, 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, 0.0, 0, 1),
|
||||||
BlockVertex::base(0.0, 0.0, 1.0, 0, 0),
|
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, 0.0, 1, 1),
|
||||||
BlockVertex::base(1.0, 0.0, 1.0, 1, 0),
|
BlockVertex::base(1.0, 0.0, 1.0, 1, 0),
|
||||||
],
|
],
|
||||||
[ // North
|
&[ // North
|
||||||
BlockVertex::base(0.0, 0.0, 0.0, 1, 1),
|
BlockVertex::base(0.0, 0.0, 0.0, 1, 1),
|
||||||
BlockVertex::base(1.0, 0.0, 0.0, 0, 1),
|
BlockVertex::base(1.0, 0.0, 0.0, 0, 1),
|
||||||
BlockVertex::base(0.0, 1.0, 0.0, 1, 0),
|
BlockVertex::base(0.0, 1.0, 0.0, 1, 0),
|
||||||
BlockVertex::base(1.0, 1.0, 0.0, 0, 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, 0.0, 1.0, 0, 1),
|
||||||
BlockVertex::base(0.0, 1.0, 1.0, 0, 0),
|
BlockVertex::base(0.0, 1.0, 1.0, 0, 0),
|
||||||
BlockVertex::base(1.0, 0.0, 1.0, 1, 1),
|
BlockVertex::base(1.0, 0.0, 1.0, 1, 1),
|
||||||
BlockVertex::base(1.0, 1.0, 1.0, 1, 0),
|
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, 0.0, 0.0, 0, 1),
|
||||||
BlockVertex::base(0.0, 1.0, 0.0, 0, 0),
|
BlockVertex::base(0.0, 1.0, 0.0, 0, 0),
|
||||||
BlockVertex::base(0.0, 0.0, 1.0, 1, 1),
|
BlockVertex::base(0.0, 0.0, 1.0, 1, 1),
|
||||||
BlockVertex::base(0.0, 1.0, 1.0, 1, 0),
|
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, 0.0, 1, 1),
|
||||||
BlockVertex::base(1.0, 0.0, 1.0, 0, 1),
|
BlockVertex::base(1.0, 0.0, 1.0, 0, 1),
|
||||||
BlockVertex::base(1.0, 1.0, 0.0, 1, 0),
|
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 {
|
pub fn get_block(&self, x: i32, y: i32, z: i32) -> &'static block::Block {
|
||||||
match self.chunks.get(&CPos(x >> 4, z >> 4)) {
|
match self.chunks.get(&CPos(x >> 4, z >> 4)) {
|
||||||
Some(ref chunk) => chunk.get_block(x & 0xF, y, z & 0xF),
|
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 mut data = Cursor::new(data);
|
||||||
|
|
||||||
let cpos = CPos(x, z);
|
let cpos = CPos(x, z);
|
||||||
let chunk = if new {
|
{
|
||||||
self.chunks.insert(cpos, Chunk::new(cpos));
|
let chunk = if new {
|
||||||
self.chunks.get_mut(&cpos).unwrap()
|
self.chunks.insert(cpos, Chunk::new(cpos));
|
||||||
} else {
|
self.chunks.get_mut(&cpos).unwrap()
|
||||||
if !self.chunks.contains_key(&cpos) {
|
} else {
|
||||||
return Ok(());
|
if !self.chunks.contains_key(&cpos) {
|
||||||
}
|
return Ok(());
|
||||||
self.chunks.get_mut(&cpos).unwrap()
|
}
|
||||||
};
|
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 {
|
for i in 0 .. 16 {
|
||||||
if mask & (1 << i) == 0 {
|
if mask & (1 << i) == 0 {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if chunk.sections[i].is_none() {
|
for pos in [
|
||||||
chunk.sections[i] = Some(Section::new(i as u8));
|
(-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(())
|
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 {
|
pub struct Snapshot {
|
||||||
|
@ -308,7 +333,7 @@ impl Chunk {
|
||||||
fn get_block(&self, x: i32, y: i32, z: i32) -> &'static block::Block {
|
fn get_block(&self, x: i32, y: i32, z: i32) -> &'static block::Block {
|
||||||
let s_idx = y >> 4;
|
let s_idx = y >> 4;
|
||||||
if s_idx < 0 || s_idx > 15 {
|
if s_idx < 0 || s_idx > 15 {
|
||||||
return block::AIR.base();
|
return block::MISSING.base();
|
||||||
}
|
}
|
||||||
match self.sections[s_idx as usize].as_ref() {
|
match self.sections[s_idx as usize].as_ref() {
|
||||||
Some(sec) => sec.get_block(x, y & 0xF, z),
|
Some(sec) => sec.get_block(x, y & 0xF, z),
|
||||||
|
|
Loading…
Reference in New Issue