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:
parent
78d6f34114
commit
59bfc5bc94
4 changed files with 127 additions and 31 deletions
|
@ -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);
|
||||
|
|
|
@ -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)]
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue