mirror of
https://github.com/italicsjenga/valence.git
synced 2024-12-23 22:41:30 +11:00
Fix math in chunk module
This commit is contained in:
parent
d22f1edae1
commit
dc46f27d5d
|
@ -25,7 +25,7 @@ use crate::protocol::packets::s2c::play::{
|
||||||
BlockUpdate, ChunkDataAndUpdateLight, S2cPlayPacket, UpdateSectionBlocks,
|
BlockUpdate, ChunkDataAndUpdateLight, S2cPlayPacket, UpdateSectionBlocks,
|
||||||
};
|
};
|
||||||
use crate::protocol::{Encode, VarInt, VarLong};
|
use crate::protocol::{Encode, VarInt, VarLong};
|
||||||
use crate::util::log2_ceil;
|
use crate::util::bits_needed;
|
||||||
|
|
||||||
mod paletted_container;
|
mod paletted_container;
|
||||||
|
|
||||||
|
@ -556,7 +556,7 @@ impl<C: Config> LoadedChunk<C> {
|
||||||
|b| b.to_raw().into(),
|
|b| b.to_raw().into(),
|
||||||
4,
|
4,
|
||||||
8,
|
8,
|
||||||
log2_ceil(BlockState::max_raw().into()),
|
bits_needed(BlockState::max_raw().into()),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
@ -566,7 +566,7 @@ impl<C: Config> LoadedChunk<C> {
|
||||||
|b| b.0.into(),
|
|b| b.0.into(),
|
||||||
0,
|
0,
|
||||||
3,
|
3,
|
||||||
log2_ceil(biome_registry_len),
|
bits_needed(biome_registry_len - 1),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
@ -612,7 +612,7 @@ impl<C: Config> LoadedChunk<C> {
|
||||||
|
|
||||||
debug_assert_eq!(bits.count_ones(), 1);
|
debug_assert_eq!(bits.count_ones(), 1);
|
||||||
|
|
||||||
let idx = i * USIZE_BITS + log2_ceil(bits);
|
let idx = i * USIZE_BITS + bits.trailing_zeros() as usize;
|
||||||
let block = sect.block_states.get(idx);
|
let block = sect.block_states.get(idx);
|
||||||
|
|
||||||
let global_x = pos.x * 16 + (idx % 16) as i32;
|
let global_x = pos.x * 16 + (idx % 16) as i32;
|
||||||
|
|
|
@ -5,7 +5,7 @@ use arrayvec::ArrayVec;
|
||||||
|
|
||||||
use crate::chunk::{compact_u64s_len, encode_compact_u64s};
|
use crate::chunk::{compact_u64s_len, encode_compact_u64s};
|
||||||
use crate::protocol::{Encode, VarInt};
|
use crate::protocol::{Encode, VarInt};
|
||||||
use crate::util::log2_ceil;
|
use crate::util::bits_needed;
|
||||||
|
|
||||||
/// `HALF_LEN` must be equal to `ceil(LEN / 2)`.
|
/// `HALF_LEN` must be equal to `ceil(LEN / 2)`.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
|
@ -17,7 +17,8 @@ pub enum PalettedContainer<T, const LEN: usize, const HALF_LEN: usize> {
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Indirect<T, const LEN: usize, const HALF_LEN: usize> {
|
pub struct Indirect<T, const LEN: usize, const HALF_LEN: usize> {
|
||||||
/// Each element is a unique instance of `T`.
|
/// Each element is a unique instance of `T`. The length of the palette is
|
||||||
|
/// always ≥2.
|
||||||
palette: ArrayVec<T, 16>,
|
palette: ArrayVec<T, 16>,
|
||||||
/// Each half-byte is an index into `palette`.
|
/// Each half-byte is an index into `palette`.
|
||||||
indices: [u8; HALF_LEN],
|
indices: [u8; HALF_LEN],
|
||||||
|
@ -147,7 +148,7 @@ impl<T: Copy + Eq + Default, const LEN: usize, const HALF_LEN: usize>
|
||||||
/// force conversion to the direct representation while encoding.
|
/// force conversion to the direct representation while encoding.
|
||||||
/// - **`direct_bits`**: The minimum number of bits required to represent
|
/// - **`direct_bits`**: The minimum number of bits required to represent
|
||||||
/// all instances of the element type. If `N` is the total number of
|
/// all instances of the element type. If `N` is the total number of
|
||||||
/// possible values, then `DIRECT_BITS` is `ceil(log2(N))`.
|
/// possible values, then `DIRECT_BITS` is `floor(log2(N - 1)) + 1`.
|
||||||
pub fn encode_mc_format<W, F>(
|
pub fn encode_mc_format<W, F>(
|
||||||
&self,
|
&self,
|
||||||
mut writer: W,
|
mut writer: W,
|
||||||
|
@ -177,7 +178,7 @@ impl<T: Copy + Eq + Default, const LEN: usize, const HALF_LEN: usize>
|
||||||
VarInt(0).encode(&mut writer)?;
|
VarInt(0).encode(&mut writer)?;
|
||||||
}
|
}
|
||||||
Self::Indirect(ind) => {
|
Self::Indirect(ind) => {
|
||||||
let bits_per_entry = min_indirect_bits.max(log2_ceil(ind.palette.len()));
|
let bits_per_entry = min_indirect_bits.max(bits_needed(ind.palette.len() - 1));
|
||||||
|
|
||||||
// Encode as direct if necessary.
|
// Encode as direct if necessary.
|
||||||
if bits_per_entry > max_indirect_bits {
|
if bits_per_entry > max_indirect_bits {
|
||||||
|
|
15
src/util.rs
15
src/util.rs
|
@ -127,15 +127,12 @@ pub fn ray_box_intersect(ro: Vec3<f64>, rd: Vec3<f64>, bb: Aabb<f64>) -> Option<
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Calculates the log base 2 rounded up.
|
/// Calculates the minimum number of bits needed to represent the integer `n`.
|
||||||
pub(crate) const fn log2_ceil(n: usize) -> usize {
|
/// Also known as `floor(log2(n)) + 1`.
|
||||||
debug_assert!(n != 0);
|
///
|
||||||
|
/// This returns `0` if `n` is `0`.
|
||||||
// TODO: replace with `n.wrapping_next_power_of_two().trailing_zeros()`.
|
pub(crate) const fn bits_needed(n: usize) -> usize {
|
||||||
match n.checked_next_power_of_two() {
|
(usize::BITS - n.leading_zeros()) as _
|
||||||
Some(n) => n.trailing_zeros() as usize,
|
|
||||||
None => 0_u64.trailing_zeros() as usize,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
Loading…
Reference in a new issue