1
2
Fork 0
mirror of https://github.com/mat-1/azalea.git synced 2025-08-02 06:16:04 +00:00

more shape stuff

This commit is contained in:
mat 2022-06-28 22:54:52 -05:00
parent 78d6f34114
commit 59bfc5bc94
4 changed files with 127 additions and 31 deletions

View file

@ -1,4 +1,4 @@
use crate::{aabb::EPSILON, VoxelShape, AABB};
use crate::{aabb::EPSILON, ArrayVoxelShape, VoxelShape, AABB};
use azalea_block::{Block, BlockState};
use azalea_core::{ChunkPos, ChunkSectionPos, Cursor3d, CursorIterationType};
use azalea_entity::Entity;
@ -76,7 +76,7 @@ impl<'a> BlockCollisions<'a> {
}
impl<'a> Iterator for BlockCollisions<'a> {
type Item = VoxelShape;
type Item = ArrayVoxelShape;
fn next(&mut self) -> Option<Self::Item> {
while let Some(item) = self.cursor.next() {
@ -93,7 +93,7 @@ impl<'a> Iterator for BlockCollisions<'a> {
let pos = item.pos;
let block_state: BlockState = chunk_lock.get(&(&pos).into(), self.dimension.min_y());
let block: &dyn Block = &block_state.into();
let block: Box<dyn Block> = block_state.into();
// TODO: continue if self.only_suffocating_blocks and the block is not suffocating
@ -101,6 +101,7 @@ impl<'a> Iterator for BlockCollisions<'a> {
// let block_shape = block.get_collision_shape();
// if block_shape == Shapes::block() {
if true {
// TODO: this can be optimized
if !self.aabb.intersects_aabb(&AABB {
min_x: item.pos.x as f64,
min_y: item.pos.y as f64,
@ -112,7 +113,11 @@ impl<'a> Iterator for BlockCollisions<'a> {
continue;
}
return block_shape.move_relative(item.pos.x, item.pos.y, item.pos.z);
return Some(block_shape.move_relative(
item.pos.x as f64,
item.pos.y as f64,
item.pos.z as f64,
));
}
// let block_shape = block_shape.move_relative(item.pos.x, item.pos.y, item.pos.z);

View file

@ -1,5 +1,7 @@
use azalea_core::BitSet;
// TODO: every impl of DiscreteVoxelShape could be turned into a single enum as an optimization
pub trait DiscreteVoxelShape {
// public boolean isFullWide(int var1, int var2, int var3) {
// if (var1 >= 0 && var2 >= 0 && var3 >= 0) {
@ -17,6 +19,30 @@ pub trait DiscreteVoxelShape {
// }
// return false;
// }
fn x_size(&self) -> usize;
fn y_size(&self) -> usize;
fn z_size(&self) -> usize;
fn first_full_x(&self) -> usize;
fn first_full_y(&self) -> usize;
fn first_full_z(&self) -> usize;
fn last_full_x(&self) -> usize;
fn last_full_y(&self) -> usize;
fn last_full_z(&self) -> usize;
fn is_empty(&self) -> bool {
if self.first_full_x() >= self.last_full_x() {
return true;
}
if self.first_full_y() >= self.last_full_y() {
return true;
}
if self.first_full_x() >= self.last_full_x() {
return true;
}
false
}
}
#[derive(Default)]

View file

@ -28,12 +28,12 @@ trait HasPhysics {
movement: &Vec3,
entity_bounding_box: &AABB,
dimension: &Dimension,
entity_collisions: Vec<VoxelShape>,
entity_collisions: Vec<Box<dyn VoxelShape>>,
) -> Vec3;
fn collide_with_shapes(
movement: &Vec3,
entity_box: &AABB,
collision_boxes: &Vec<VoxelShape>,
collision_boxes: &Vec<Box<dyn VoxelShape>>,
) -> Vec3;
}
@ -79,7 +79,7 @@ impl HasPhysics for Entity {
movement: &Vec3,
entity_bounding_box: &AABB,
dimension: &Dimension,
entity_collisions: Vec<VoxelShape>,
entity_collisions: Vec<Box<dyn VoxelShape>>,
) -> Vec3 {
let mut collision_boxes = Vec::with_capacity(1); // entity_collisions.len() + 1
@ -98,7 +98,7 @@ impl HasPhysics for Entity {
fn collide_with_shapes(
movement: &Vec3,
entity_box: &AABB,
collision_boxes: &Vec<VoxelShape>,
collision_boxes: &Vec<Box<dyn VoxelShape>>,
) -> Vec3 {
// TODO
*movement

View file

@ -1,40 +1,105 @@
use std::ops::{Add, Index};
use azalea_core::Direction;
use crate::{BitSetDiscreteVoxelShape, DiscreteVoxelShape};
pub struct VoxelShape {
shape: BitSetDiscreteVoxelShape,
faces: Vec<VoxelShape>,
}
pub struct Shapes {}
pub fn block_shape() -> VoxelShape {
pub fn block_shape() -> Box<dyn VoxelShape> {
let mut shape = BitSetDiscreteVoxelShape::new(1, 1, 1);
shape.fill(0, 0, 0);
VoxelShape::new(shape)
VoxelShape::new(Box::new(shape))
}
impl VoxelShape {
pub fn new(shape: BitSetDiscreteVoxelShape) -> Self {
VoxelShape {
shape,
faces: Vec::new(),
}
}
pub trait VoxelShape {
fn shape(&self) -> Box<dyn DiscreteVoxelShape>;
// public VoxelShape move(double var1, double var3, double var5) {
// return (VoxelShape)(this.isEmpty() ? Shapes.empty() : new ArrayVoxelShape(this.shape, new OffsetDoubleList(this.getCoords(Direction.Axis.X), var1), new OffsetDoubleList(this.getCoords(Direction.Axis.Y), var3), new OffsetDoubleList(this.getCoords(Direction.Axis.Z), var5)));
// }
pub fn move_relative(&self, x: i32, y: i32, z: i32) -> Self {
if self.is_empty() {
fn get_x_coords(&self) -> Vec<f64>;
fn get_y_coords(&self) -> Vec<f64>;
fn get_z_coords(&self) -> Vec<f64>;
fn move_relative(&self, x: f64, y: f64, z: f64) -> ArrayVoxelShape {
if self.shape().is_empty() {
return Shapes::empty();
}
// TODO: just offset the vecs now instead of using an OffsetVec
ArrayVoxelShape::new(
self.shape,
OffsetDoubleList::new(self.get_coords(Direction::Axis::X), x),
OffsetDoubleList::new(self.get_coords(Direction::Axis::Y), y),
OffsetDoubleList::new(self.get_coords(Direction::Axis::Z), z),
self.shape(),
self.get_x_coords().iter().map(|c| c + x).collect(),
self.get_y_coords().iter().map(|c| c + y).collect(),
self.get_z_coords().iter().map(|c| c + z).collect(),
)
}
}
pub struct ArrayVoxelShape {
shape: Box<dyn DiscreteVoxelShape>,
faces: Option<Vec<Box<dyn VoxelShape>>>,
pub xs: Vec<f64>,
pub ys: Vec<f64>,
pub zs: Vec<f64>,
}
impl ArrayVoxelShape {
// ArrayVoxelShape(DiscreteVoxelShape var1, DoubleList var2, DoubleList var3, DoubleList var4) {
// super(var1);
// int var5 = var1.getXSize() + 1;
// int var6 = var1.getYSize() + 1;
// int var7 = var1.getZSize() + 1;
// if (var5 == var2.size() && var6 == var3.size() && var7 == var4.size()) {
// this.xs = var2;
// this.ys = var3;
// this.zs = var4;
// } else {
// throw (IllegalArgumentException)Util.pauseInIde(new IllegalArgumentException("Lengths of point arrays must be consistent with the size of the VoxelShape."));
// }
// }
pub fn new(
shape: Box<dyn DiscreteVoxelShape>,
xs: Vec<f64>,
ys: Vec<f64>,
zs: Vec<f64>,
) -> Self {
let x_size = shape.x_size() + 1;
let y_size = shape.y_size() + 1;
let z_size = shape.z_size() + 1;
// Lengths of point arrays must be consistent with the size of the VoxelShape.
assert_eq!(x_size, xs.len());
assert_eq!(y_size, ys.len());
assert_eq!(z_size, zs.len());
Self {
faces: None,
shape,
xs,
ys,
zs,
}
}
}
// mojang moment
// this is probably for an optimization and could probably be optimized more
/// A Vec that adds the given offset when indexing into it.
pub struct OffsetVec<T> {
delegate: Vec<T>,
offset: T,
}
impl<T> OffsetVec<T>
where
T: Add<Output = T>,
{
pub fn new(delegate: Vec<T>, offset: T) -> Self {
Self { delegate, offset }
}
pub fn index(&self, index: usize) -> T {
self.delegate[index] + self.offset
}
pub fn len(&self) -> usize {
self.delegate.len()
}
}