mirror of
https://github.com/mat-1/azalea.git
synced 2025-08-02 23:44:38 +00:00
backup because i'm about to delete shapes
This commit is contained in:
parent
d6491ac08b
commit
78d6f34114
8 changed files with 216 additions and 46 deletions
|
@ -1,8 +1,4 @@
|
||||||
use crate::{McBufReadable, McBufWritable};
|
use std::ops::Deref;
|
||||||
use std::{
|
|
||||||
io::{Read, Write},
|
|
||||||
ops::Deref,
|
|
||||||
};
|
|
||||||
|
|
||||||
/// A Vec<u8> that isn't prefixed by a VarInt with the size.
|
/// A Vec<u8> that isn't prefixed by a VarInt with the size.
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
|
@ -27,30 +23,3 @@ impl From<&str> for UnsizedByteArray {
|
||||||
Self(s.as_bytes().to_vec())
|
Self(s.as_bytes().to_vec())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Represents Java's BitSet, a list of bits.
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
|
||||||
pub struct BitSet {
|
|
||||||
data: Vec<u64>,
|
|
||||||
}
|
|
||||||
|
|
||||||
// the Index trait requires us to return a reference, but we can't do that
|
|
||||||
impl BitSet {
|
|
||||||
pub fn index(&self, index: usize) -> bool {
|
|
||||||
(self.data[index / 64] & (1u64 << (index % 64))) != 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl McBufReadable for BitSet {
|
|
||||||
fn read_from(buf: &mut impl Read) -> Result<Self, String> {
|
|
||||||
Ok(Self {
|
|
||||||
data: Vec::<u64>::read_from(buf)?,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl McBufWritable for BitSet {
|
|
||||||
fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
|
|
||||||
self.data.write_into(buf)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
58
azalea-core/src/bitset.rs
Normal file
58
azalea-core/src/bitset.rs
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
use azalea_buf::{McBufReadable, McBufWritable};
|
||||||
|
use std::io::{Read, Write};
|
||||||
|
|
||||||
|
/// Represents Java's BitSet, a list of bits.
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Hash, Default)]
|
||||||
|
pub struct BitSet {
|
||||||
|
data: Vec<u64>,
|
||||||
|
}
|
||||||
|
|
||||||
|
// the Index trait requires us to return a reference, but we can't do that
|
||||||
|
impl BitSet {
|
||||||
|
pub fn new(size: usize) -> Self {
|
||||||
|
BitSet {
|
||||||
|
data: vec![0; size.div_ceil(64)],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn index(&self, index: usize) -> bool {
|
||||||
|
(self.data[index / 64] & (1u64 << (index % 64))) != 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl McBufReadable for BitSet {
|
||||||
|
fn read_from(buf: &mut impl Read) -> Result<Self, String> {
|
||||||
|
Ok(Self {
|
||||||
|
data: Vec::<u64>::read_from(buf)?,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl McBufWritable for BitSet {
|
||||||
|
fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
|
||||||
|
self.data.write_into(buf)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BitSet {
|
||||||
|
pub fn set(&mut self, bit_index: usize) {
|
||||||
|
self.data[bit_index / 64] |= 1u64 << (bit_index % 64);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_bitset() {
|
||||||
|
let mut bitset = BitSet::new(64);
|
||||||
|
assert_eq!(bitset.index(0), false);
|
||||||
|
assert_eq!(bitset.index(1), false);
|
||||||
|
assert_eq!(bitset.index(2), false);
|
||||||
|
bitset.set(1);
|
||||||
|
assert_eq!(bitset.index(0), false);
|
||||||
|
assert_eq!(bitset.index(1), true);
|
||||||
|
assert_eq!(bitset.index(2), false);
|
||||||
|
}
|
||||||
|
}
|
|
@ -28,3 +28,6 @@ pub use particle::*;
|
||||||
|
|
||||||
mod cursor3d;
|
mod cursor3d;
|
||||||
pub use cursor3d::*;
|
pub use cursor3d::*;
|
||||||
|
|
||||||
|
mod bitset;
|
||||||
|
pub use bitset::*;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::{aabb::EPSILON, AABB};
|
use crate::{aabb::EPSILON, VoxelShape, AABB};
|
||||||
use azalea_block::{Block, BlockState};
|
use azalea_block::{Block, BlockState};
|
||||||
use azalea_core::{ChunkPos, ChunkSectionPos, Cursor3d, CursorIterationType};
|
use azalea_core::{ChunkPos, ChunkSectionPos, Cursor3d, CursorIterationType};
|
||||||
use azalea_entity::Entity;
|
use azalea_entity::Entity;
|
||||||
|
@ -97,7 +97,7 @@ impl<'a> Iterator for BlockCollisions<'a> {
|
||||||
|
|
||||||
// TODO: continue if self.only_suffocating_blocks and the block is not suffocating
|
// TODO: continue if self.only_suffocating_blocks and the block is not suffocating
|
||||||
|
|
||||||
let block_shape = VoxelShape {};
|
let block_shape = crate::block_shape();
|
||||||
// let block_shape = block.get_collision_shape();
|
// let block_shape = block.get_collision_shape();
|
||||||
// if block_shape == Shapes::block() {
|
// if block_shape == Shapes::block() {
|
||||||
if true {
|
if true {
|
||||||
|
@ -126,5 +126,3 @@ impl<'a> Iterator for BlockCollisions<'a> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct VoxelShape {}
|
|
||||||
|
|
97
azalea-physics/src/discrete_voxel_shape.rs
Normal file
97
azalea-physics/src/discrete_voxel_shape.rs
Normal file
|
@ -0,0 +1,97 @@
|
||||||
|
use azalea_core::BitSet;
|
||||||
|
|
||||||
|
pub trait DiscreteVoxelShape {
|
||||||
|
// public boolean isFullWide(int var1, int var2, int var3) {
|
||||||
|
// if (var1 >= 0 && var2 >= 0 && var3 >= 0) {
|
||||||
|
// return var1 < this.xSize && var2 < this.ySize && var3 < this.zSize ? this.isFull(var1, var2, var3) : false;
|
||||||
|
// } else {
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// pub fn is_full_wide(&self, x: i32, y: i32, z: i32) -> bool {
|
||||||
|
// // TODO: can this be u32 instead of i32?
|
||||||
|
// if x >= 0 && y >= 0 && z >= 0 {
|
||||||
|
// if x < self.x_size as i32 && y < self.y_size as i32 && z < self.z_size as i32 {
|
||||||
|
// return self.is_full(x, y, z);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct BitSetDiscreteVoxelShape {
|
||||||
|
x_size: u32,
|
||||||
|
y_size: u32,
|
||||||
|
z_size: u32,
|
||||||
|
|
||||||
|
storage: BitSet,
|
||||||
|
x_min: u32,
|
||||||
|
y_min: u32,
|
||||||
|
z_min: u32,
|
||||||
|
x_max: u32,
|
||||||
|
y_max: u32,
|
||||||
|
z_max: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BitSetDiscreteVoxelShape {
|
||||||
|
// public BitSetDiscreteVoxelShape(int var1, int var2, int var3) {
|
||||||
|
// super(var1, var2, var3);
|
||||||
|
// this.storage = new BitSet(var1 * var2 * var3);
|
||||||
|
// this.xMin = var1;
|
||||||
|
// this.yMin = var2;
|
||||||
|
// this.zMin = var3;
|
||||||
|
// }
|
||||||
|
pub fn new(x_min: u32, y_min: u32, z_min: u32) -> Self {
|
||||||
|
BitSetDiscreteVoxelShape {
|
||||||
|
x_size: x_min,
|
||||||
|
y_size: y_min,
|
||||||
|
z_size: z_min,
|
||||||
|
|
||||||
|
storage: BitSet::new((x_min * y_min * z_min).try_into().unwrap()),
|
||||||
|
x_min,
|
||||||
|
y_min,
|
||||||
|
z_min,
|
||||||
|
x_max: 0,
|
||||||
|
y_max: 0,
|
||||||
|
z_max: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// private void fillUpdateBounds(int var1, int var2, int var3, boolean var4) {
|
||||||
|
// this.storage.set(this.getIndex(var1, var2, var3));
|
||||||
|
// if (var4) {
|
||||||
|
// this.xMin = Math.min(this.xMin, var1);
|
||||||
|
// this.yMin = Math.min(this.yMin, var2);
|
||||||
|
// this.zMin = Math.min(this.zMin, var3);
|
||||||
|
// this.xMax = Math.max(this.xMax, var1 + 1);
|
||||||
|
// this.yMax = Math.max(this.yMax, var2 + 1);
|
||||||
|
// this.zMax = Math.max(this.zMax, var3 + 1);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
fn fill_update_bounds(&mut self, x: u32, y: u32, z: u32, update: bool) {
|
||||||
|
self.storage.set(self.get_index(x, y, z));
|
||||||
|
if update {
|
||||||
|
self.x_min = std::cmp::min(self.x_min, x);
|
||||||
|
self.y_min = std::cmp::min(self.y_min, y);
|
||||||
|
self.z_min = std::cmp::min(self.z_min, z);
|
||||||
|
self.x_max = std::cmp::max(self.x_max, x + 1);
|
||||||
|
self.y_max = std::cmp::max(self.y_max, y + 1);
|
||||||
|
self.z_max = std::cmp::max(self.z_max, z + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// public void fill(int var1, int var2, int var3) {
|
||||||
|
// this.fillUpdateBounds(var1, var2, var3, true);
|
||||||
|
// }
|
||||||
|
pub fn fill(&mut self, x: u32, y: u32, z: u32) {
|
||||||
|
self.fill_update_bounds(x, y, z, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// protected int getIndex(int var1, int var2, int var3) {
|
||||||
|
// return (var1 * this.ySize + var2) * this.zSize + var3;
|
||||||
|
// }
|
||||||
|
fn get_index(&self, x: u32, y: u32, z: u32) -> usize {
|
||||||
|
((x * self.y_size + y) * self.z_size + z) as usize
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,13 +1,17 @@
|
||||||
mod aabb;
|
mod aabb;
|
||||||
mod block_hit_result;
|
mod block_hit_result;
|
||||||
mod dimension_collisions;
|
mod dimension_collisions;
|
||||||
|
mod discrete_voxel_shape;
|
||||||
|
mod shape;
|
||||||
|
|
||||||
pub use aabb::AABB;
|
pub use aabb::*;
|
||||||
use azalea_core::{PositionDelta, PositionXYZ, Vec3};
|
use azalea_core::{PositionDelta, PositionXYZ, Vec3};
|
||||||
use azalea_entity::Entity;
|
use azalea_entity::Entity;
|
||||||
use azalea_world::Dimension;
|
use azalea_world::Dimension;
|
||||||
pub use block_hit_result::BlockHitResult;
|
pub use block_hit_result::*;
|
||||||
use dimension_collisions::CollisionGetter;
|
use dimension_collisions::CollisionGetter;
|
||||||
|
pub use discrete_voxel_shape::*;
|
||||||
|
pub use shape::*;
|
||||||
|
|
||||||
pub enum MoverType {
|
pub enum MoverType {
|
||||||
Own,
|
Own,
|
||||||
|
@ -24,12 +28,12 @@ trait HasPhysics {
|
||||||
movement: &Vec3,
|
movement: &Vec3,
|
||||||
entity_bounding_box: &AABB,
|
entity_bounding_box: &AABB,
|
||||||
dimension: &Dimension,
|
dimension: &Dimension,
|
||||||
// entity_collisions: Vec<VoxelShape>
|
entity_collisions: Vec<VoxelShape>,
|
||||||
) -> Vec3;
|
) -> Vec3;
|
||||||
fn collide_with_shapes(
|
fn collide_with_shapes(
|
||||||
movement: &Vec3,
|
movement: &Vec3,
|
||||||
entity_box: &AABB,
|
entity_box: &AABB,
|
||||||
// collision_boxes: Vec<VoxelShape>,
|
collision_boxes: &Vec<VoxelShape>,
|
||||||
) -> Vec3;
|
) -> Vec3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,25 +79,26 @@ impl HasPhysics for Entity {
|
||||||
movement: &Vec3,
|
movement: &Vec3,
|
||||||
entity_bounding_box: &AABB,
|
entity_bounding_box: &AABB,
|
||||||
dimension: &Dimension,
|
dimension: &Dimension,
|
||||||
// entity_collisions: Vec<VoxelShape>
|
entity_collisions: Vec<VoxelShape>,
|
||||||
) -> Vec3 {
|
) -> Vec3 {
|
||||||
let mut collision_boxes = Vec::with_capacity(1); // entity_collisions.len() + 1
|
let mut collision_boxes = Vec::with_capacity(1); // entity_collisions.len() + 1
|
||||||
|
|
||||||
// if !entity_collisions.is_empty() { add to collision_boxes }
|
if !entity_collisions.is_empty() {
|
||||||
|
collision_boxes.extend(entity_collisions);
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: world border
|
// TODO: world border
|
||||||
|
|
||||||
let block_collisions =
|
let block_collisions =
|
||||||
dimension.get_block_collisions(entity, entity_bounding_box.expand_towards(movement));
|
dimension.get_block_collisions(entity, entity_bounding_box.expand_towards(movement));
|
||||||
collision_boxes.extend(block_collisions);
|
collision_boxes.extend(block_collisions);
|
||||||
// Self::collide_with_shapes(movement, &entity_bounding_box, &collision_boxes)
|
Self::collide_with_shapes(movement, &entity_bounding_box, &collision_boxes)
|
||||||
Self::collide_with_shapes(movement, &entity_bounding_box)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn collide_with_shapes(
|
fn collide_with_shapes(
|
||||||
movement: &Vec3,
|
movement: &Vec3,
|
||||||
entity_box: &AABB,
|
entity_box: &AABB,
|
||||||
// collision_boxes: Vec<VoxelShape>,
|
collision_boxes: &Vec<VoxelShape>,
|
||||||
) -> Vec3 {
|
) -> Vec3 {
|
||||||
// TODO
|
// TODO
|
||||||
*movement
|
*movement
|
||||||
|
|
40
azalea-physics/src/shape.rs
Normal file
40
azalea-physics/src/shape.rs
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
use azalea_core::Direction;
|
||||||
|
|
||||||
|
use crate::{BitSetDiscreteVoxelShape, DiscreteVoxelShape};
|
||||||
|
|
||||||
|
pub struct VoxelShape {
|
||||||
|
shape: BitSetDiscreteVoxelShape,
|
||||||
|
faces: Vec<VoxelShape>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Shapes {}
|
||||||
|
|
||||||
|
pub fn block_shape() -> VoxelShape {
|
||||||
|
let mut shape = BitSetDiscreteVoxelShape::new(1, 1, 1);
|
||||||
|
shape.fill(0, 0, 0);
|
||||||
|
VoxelShape::new(shape)
|
||||||
|
}
|
||||||
|
|
||||||
|
impl VoxelShape {
|
||||||
|
pub fn new(shape: BitSetDiscreteVoxelShape) -> Self {
|
||||||
|
VoxelShape {
|
||||||
|
shape,
|
||||||
|
faces: Vec::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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() {
|
||||||
|
return Shapes::empty();
|
||||||
|
}
|
||||||
|
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),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
use azalea_buf::BitSet;
|
|
||||||
use azalea_buf::McBuf;
|
use azalea_buf::McBuf;
|
||||||
|
use azalea_core::BitSet;
|
||||||
use packet_macros::GamePacket;
|
use packet_macros::GamePacket;
|
||||||
|
|
||||||
#[derive(Clone, Debug, McBuf, GamePacket)]
|
#[derive(Clone, Debug, McBuf, GamePacket)]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue