fix: block indexing, added some utility methods

This commit is contained in:
əlemi 2022-07-02 23:59:39 +02:00
parent 5cff6bc208
commit 2e742dd40b
No known key found for this signature in database
GPG key ID: BBCBFE5D7244634E
2 changed files with 34 additions and 13 deletions

View file

@ -1,10 +1,11 @@
from typing import List, Optional, Iterable from typing import List, Optional, Iterable, Tuple
def bit_pack(data:Iterable[int], bits:int, size:int): ... def bit_pack(data:Iterable[int], bits:int, size:int): ...
class Chunk: class Chunk:
def __init__(self, x: int, z: int, bitmask: int, ground_up_continuous: bool): ... def __init__(self, x: int, z: int, bitmask: int, ground_up_continuous: bool): ...
def read(self, chunk_data:bytes): ... def read(self, chunk_data:bytes): ...
def merge(self, other:'Chunk'): ... def merge(self, other:'Chunk'): ...
def get_slice(self, y:int) -> Tuple[Tuple[int, ...], ...]: ...
class World: class World:
def __init__(self): ... def __init__(self): ...

View file

@ -4,6 +4,14 @@ use log::{info, warn};
use pyo3::{exceptions::PyValueError, prelude::*}; use pyo3::{exceptions::PyValueError, prelude::*};
fn abs(v:i32, modulo:i32) -> i32 {
if v < 0 {
return modulo + (v % modulo);
} else {
return v % modulo;
}
}
#[pyfunction] #[pyfunction]
pub fn bit_pack(data: Vec<i32>, bits: i32, size: i32) -> PyResult<Vec<i32>> { pub fn bit_pack(data: Vec<i32>, bits: i32, size: i32) -> PyResult<Vec<i32>> {
if size <= bits { if size <= bits {
@ -77,12 +85,12 @@ pub trait ChunkSection {
// # logging.debug("[%d|%d@%d] Palette section : [%d] %s", ctx.x, ctx.z, ctx.sec, palette_len, str(palette)) // # logging.debug("[%d|%d@%d] Palette section : [%d] %s", ctx.x, ctx.z, ctx.sec, palette_len, str(palette))
let container_size = ChunkFormat340::read_varint(buffer)?; let container_size = ChunkFormat340::read_varint(buffer)?;
let mut block_data = vec![0u64; container_size as usize]; let mut block_data = vec![0u64; container_size as usize];
let mut long_arr: [u8; 8] = [0u8; 8]; let mut recv_buf: [u8; 8] = [0u8; 8];
for i in 0..container_size as usize { for i in 0..container_size as usize {
buffer.read_exact(&mut long_arr)?; buffer.read_exact(&mut recv_buf)?;
let mut tmp: u64 = 0; let mut tmp: u64 = 0;
for j in 0..8 { for j in 0..8 {
tmp |= (long_arr[j] as u64) << (j * 8); tmp |= (recv_buf[j] as u64) << ((7-j) * 8);
} }
block_data[i] = tmp; block_data[i] = tmp;
} }
@ -91,7 +99,7 @@ pub trait ChunkSection {
for y in 0..16 { for y in 0..16 {
for z in 0..16 { for z in 0..16 {
for x in 0..16 { for x in 0..16 {
let i = x + ((y * 16) + z) * 16; let i = (((y * 16) + z) * 16) + x;
let start_byte = (i * bits as usize) / 64; let start_byte = (i * bits as usize) / 64;
let start_offset = (i * bits as usize) % 64; let start_offset = (i * bits as usize) % 64;
let end_byte = ((i + 1) * bits as usize - 1) / 64; let end_byte = ((i + 1) * bits as usize - 1) / 64;
@ -170,8 +178,6 @@ impl ChunkSection for ChunkFormat340 {
} }
} }
// https://stackoverflow.com/questions/41069865/how-to-create-an-in-memory-object-that-can-be-used-as-a-reader-writer-or-seek/50732452#50732452
#[pyclass] #[pyclass]
pub struct Chunk { pub struct Chunk {
pub x: i32, pub x: i32,
@ -253,6 +259,16 @@ impl Chunk {
} }
return Some(old_chunk); //TODO: is this really we want to return? return Some(old_chunk); //TODO: is this really we want to return?
} }
pub fn get_slice(&self, y:u8) -> Vec<Vec<u16>> {
let mut slice = vec![vec![0u16;16];16];
for x in 0..16 {
for z in 0..16 {
slice[x][z] = self.block_states[x][y as usize][z];
}
}
return slice;
}
} }
impl Clone for Chunk { impl Clone for Chunk {
@ -291,17 +307,21 @@ impl World {
} }
pub fn get_block(&self, x: i32, y: i32, z: i32) -> Option<u16> { pub fn get_block(&self, x: i32, y: i32, z: i32) -> Option<u16> {
if let Some(chunk) = self.chunks.get(&(x / 16, z / 16)) { let mut chunk_x = x / 16;
return Some(chunk.block_states[(x % 16) as usize][y as usize][(z % 16) as usize]); let mut chunk_z = z / 16;
if chunk_x < 0 && chunk_x % 16 != 0 { chunk_x-=1; }
if chunk_z < 0 && chunk_z % 16 != 0 { chunk_z-=1; }
if let Some(chunk) = self.chunks.get(&(chunk_x, chunk_z)) {
return Some(chunk.block_states[abs(x, 16) as usize][y as usize][abs(z, 16) as usize]);
} }
None None
} }
pub fn put_block(&mut self, x: usize, y:usize, z:usize, id:u16) -> Option<u16> { pub fn put_block(&mut self, x: i32, y:i32, z:i32, id:u16) -> Option<u16> {
let x_off = x % 16; let z_off = z % 16; let x_off = (x % 16) as usize; let z_off = (z % 16) as usize;
let c = self.chunks.get_mut(&(x as i32 / 16, z as i32 / 16))?; let c = self.chunks.get_mut(&(x as i32 / 16, z as i32 / 16))?;
let old_block = c.block_states[x_off][y][z_off]; let old_block = c.block_states[x_off][y as usize][z_off];
c.block_states[x_off][y][z_off] = id; c.block_states[x_off][y as usize][z_off] = id;
return Some(old_block); return Some(old_block);
} }