aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--azalea-physics/src/collision/shape.rs73
1 files changed, 61 insertions, 12 deletions
diff --git a/azalea-physics/src/collision/shape.rs b/azalea-physics/src/collision/shape.rs
index 63dd1b4d..13c2f0d6 100644
--- a/azalea-physics/src/collision/shape.rs
+++ b/azalea-physics/src/collision/shape.rs
@@ -190,9 +190,9 @@ impl Shapes {
} else {
VoxelShape::Array(ArrayVoxelShape::new(
DiscreteVoxelShape::BitSet(var8),
- var5.get_list(),
- var6.get_list(),
- var7.get_list(),
+ var5.get_list().into(),
+ var6.get_list().into(),
+ var7.get_list().into(),
))
}
}
@@ -595,9 +595,9 @@ pub struct ArrayVoxelShape {
#[allow(dead_code)]
faces: Option<Box<[VoxelShape]>>,
- pub xs: Box<[f64]>,
- pub ys: Box<[f64]>,
- pub zs: Box<[f64]>,
+ xs: CompactArray<f64>,
+ ys: CompactArray<f64>,
+ zs: CompactArray<f64>,
}
#[derive(Clone, Debug, PartialEq)]
@@ -607,13 +607,18 @@ pub struct CubeVoxelShape {
#[allow(dead_code)]
faces: Option<Vec<VoxelShape>>,
- x_coords: Box<[f64]>,
- y_coords: Box<[f64]>,
- z_coords: Box<[f64]>,
+ x_coords: CompactArray<f64>,
+ y_coords: CompactArray<f64>,
+ z_coords: CompactArray<f64>,
}
impl ArrayVoxelShape {
- pub fn new(shape: DiscreteVoxelShape, xs: Box<[f64]>, ys: Box<[f64]>, zs: Box<[f64]>) -> Self {
+ pub fn new(
+ shape: DiscreteVoxelShape,
+ xs: CompactArray<f64>,
+ ys: CompactArray<f64>,
+ zs: CompactArray<f64>,
+ ) -> Self {
let x_size = shape.size(Axis::X) + 1;
let y_size = shape.size(Axis::Y) + 1;
let z_size = shape.size(Axis::Z) + 1;
@@ -638,7 +643,7 @@ impl ArrayVoxelShape {
#[inline]
fn get_coords(&self, axis: Axis) -> &[f64] {
- axis.choose(&self.xs, &self.ys, &self.zs)
+ axis.choose(&self.xs, &self.ys, &self.zs).as_slice()
}
}
@@ -663,7 +668,7 @@ impl CubeVoxelShape {
&self.shape
}
- fn calculate_coords(shape: &DiscreteVoxelShape, axis: Axis) -> Box<[f64]> {
+ fn calculate_coords(shape: &DiscreteVoxelShape, axis: Axis) -> CompactArray<f64> {
let size = shape.size(axis);
(0..=size).map(|i| i as f64 / size as f64).collect()
@@ -672,6 +677,7 @@ impl CubeVoxelShape {
#[inline]
fn get_coords(&self, axis: Axis) -> &[f64] {
axis.choose(&self.x_coords, &self.y_coords, &self.z_coords)
+ .as_slice()
}
fn find_index(&self, axis: Axis, coord: f64) -> i32 {
@@ -699,6 +705,49 @@ impl CubePointRange {
}
}
+#[derive(Clone, Debug, PartialEq)]
+pub enum CompactArray<T: Clone + Copy> {
+ Box(Box<[T]>),
+ Inline([T; 1]),
+}
+impl<T: Clone + Copy> CompactArray<T> {
+ fn as_slice(&self) -> &[T] {
+ match self {
+ CompactArray::Box(slice) => slice,
+ CompactArray::Inline(arr) => arr,
+ }
+ }
+ fn len(&self) -> usize {
+ match self {
+ CompactArray::Box(slice) => slice.len(),
+ CompactArray::Inline(arr) => arr.len(),
+ }
+ }
+}
+impl<T: Clone + Copy> From<Box<[T]>> for CompactArray<T> {
+ fn from(value: Box<[T]>) -> Self {
+ if value.len() == 1 {
+ Self::Inline([value[0]])
+ } else {
+ Self::Box(value)
+ }
+ }
+}
+impl<T: Clone + Copy, const N: usize> From<[T; N]> for CompactArray<T> {
+ fn from(value: [T; N]) -> Self {
+ if value.len() == 1 {
+ Self::Inline([value[0]])
+ } else {
+ Self::Box(Box::new(value))
+ }
+ }
+}
+impl<T: Clone + Copy> FromIterator<T> for CompactArray<T> {
+ fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
+ Self::from(Box::from_iter(iter))
+ }
+}
+
#[cfg(test)]
mod tests {
use super::*;