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

important collision things

This commit is contained in:
mat 2022-06-26 20:08:22 -05:00
parent 99cba524d6
commit add3bc9c7e
8 changed files with 203 additions and 14 deletions

1
Cargo.lock generated
View file

@ -185,6 +185,7 @@ version = "0.1.0"
dependencies = [
"azalea-core",
"azalea-entity",
"azalea-world",
]
[[package]]

108
azalea-core/src/cursor3d.rs Normal file
View file

@ -0,0 +1,108 @@
pub struct Cursor3d {
index: usize,
origin_x: i32,
origin_y: i32,
origin_z: i32,
width: usize,
height: usize,
depth: usize,
end: usize,
}
impl Iterator for Cursor3d {
type Item = CursorIteration;
fn next(&mut self) -> Option<Self::Item> {
if self.index == self.end {
return None;
}
let x = self.index % self.width;
let r = self.index / self.width;
let y = r % self.height;
let z = r / self.height;
self.index += 1;
let mut iteration_type = 0;
if x == 0 || x == self.width - 1 {
iteration_type += 1;
}
if y == 0 || y == self.height - 1 {
iteration_type += 1;
}
if z == 0 || z == self.depth - 1 {
iteration_type += 1;
}
Some(CursorIteration {
x: self.origin_x + x as i32,
y: self.origin_y + y as i32,
z: self.origin_z + z as i32,
iteration_type: iteration_type.into(),
})
}
}
#[repr(u8)]
pub enum CursorIterationType {
Inside = 0,
Face = 1,
Edge = 2,
Corner = 3,
}
pub struct CursorIteration {
pub x: i32,
pub y: i32,
pub z: i32,
pub iteration_type: CursorIterationType,
}
impl Cursor3d {
pub fn new(
origin_x: i32,
origin_y: i32,
origin_z: i32,
end_x: i32,
end_y: i32,
end_z: i32,
) -> Self {
let width = (end_x - origin_x + 1)
.try_into()
.expect("Impossible width.");
let height = (end_y - origin_y + 1)
.try_into()
.expect("Impossible height.");
let depth = (end_z - origin_z + 1)
.try_into()
.expect("Impossible depth.");
Self {
index: 0,
origin_x,
origin_y,
origin_z,
width,
height,
depth,
end: width * height * depth,
}
}
}
impl From<u8> for CursorIterationType {
fn from(value: u8) -> Self {
match value {
0 => CursorIterationType::Inside,
1 => CursorIterationType::Face,
2 => CursorIterationType::Edge,
3 => CursorIterationType::Corner,
_ => panic!("Invalid iteration type"),
}
}
}

View file

@ -25,3 +25,6 @@ pub use delta::*;
mod particle;
pub use particle::*;
mod cursor3d;
pub use cursor3d::*;

View file

@ -8,3 +8,4 @@ version = "0.1.0"
[dependencies]
azalea-core = {path = "../azalea-core"}
azalea-entity = {path = "../azalea-entity"}
azalea-world = {path = "../azalea-world"}

View file

@ -53,7 +53,7 @@ impl AABB {
}
}
pub fn expand_towards(&mut self, x: f64, y: f64, z: f64) -> AABB {
pub fn expand_towards(&mut self, other: &Vec3) -> AABB {
let mut min_x = self.min_x;
let mut min_y = self.min_y;
let mut min_z = self.min_z;
@ -62,22 +62,22 @@ impl AABB {
let mut max_y = self.max_y;
let mut max_z = self.max_z;
if x < 0.0 {
min_x += x;
} else if x > 0.0 {
max_x += x;
if other.x < 0.0 {
min_x += other.x;
} else if other.x > 0.0 {
max_x += other.x;
}
if y < 0.0 {
min_y += y;
} else if y > 0.0 {
max_y += y;
if other.y < 0.0 {
min_y += other.y;
} else if other.y > 0.0 {
max_y += other.y;
}
if z < 0.0 {
min_z += z;
} else if z > 0.0 {
max_z += z;
if other.z < 0.0 {
min_z += other.z;
} else if other.z > 0.0 {
max_z += other.z;
}
AABB {

View file

@ -0,0 +1,48 @@
use azalea_entity::Entity;
use azalea_world::Dimension;
use crate::AABB;
trait CollisionGetter {
fn get_block_collisions<'a>(
&'a self,
entity: Option<&Entity>,
aabb: AABB,
) -> BlockCollisions<'a>;
}
impl CollisionGetter for Dimension {
fn get_block_collisions<'a>(
&'a self,
entity: Option<&Entity>,
aabb: AABB,
) -> BlockCollisions<'a> {
BlockCollisions::new(self, entity, aabb)
}
}
pub struct BlockCollisions<'a> {
dimension: &'a Dimension,
// context: CollisionContext,
aabb: AABB,
}
impl<'a> BlockCollisions<'a> {
pub fn new(dimension: &'a Dimension, entity: Option<&Entity>, aabb: AABB) -> Self {
Self { dimension, aabb }
}
}
impl Iterator for BlockCollisions<'a> {
type Item = VoxelShape;
fn next(&mut self) -> Option<Self::Item> {
loop {
if !self.cursor.advance() {
return None;
}
}
}
}
pub struct VoxelShape {}

View file

@ -1,9 +1,11 @@
mod aabb;
mod block_hit_result;
mod dimension_collisions;
pub use aabb::AABB;
use azalea_core::{PositionDelta, PositionXYZ, Vec3};
use azalea_entity::Entity;
use azalea_world::Dimension;
pub use block_hit_result::BlockHitResult;
pub enum MoverType {
@ -16,6 +18,13 @@ pub enum MoverType {
trait HasPhysics {
fn move_entity(&mut self, mover_type: &MoverType, movement: &PositionDelta);
fn collide_bounding_box(
entity: Option<&Self>,
movement: &Vec3,
entity_bounding_box: &AABB,
dimension: &Dimension,
// entity_collisions: Vec<VoxelShape>
) -> Vec3;
}
impl HasPhysics for Entity {
@ -55,5 +64,22 @@ impl HasPhysics for Entity {
// }
// }
// fn collide_bounding_box(self: )
fn collide_bounding_box(
entity: Option<&Self>,
movement: &Vec3,
entity_bounding_box: &AABB,
dimension: &Dimension,
// entity_collisions: Vec<VoxelShape>
) -> Vec3 {
let mut collision_boxes = Vec::with_capacity(1); // entity_collisions.len() + 1
// if !entity_collisions.is_empty() { add to collision_boxes }
// TODO: world border
let block_collisions =
dimension.get_block_collisions(entity, entity_bounding_box.expand_towards(movement));
collision_boxes.extend(block_collisions);
Self::collide_with_shapes(movement, &entity_bounding_box, &collision_boxes)
}
}

View file

@ -28,6 +28,8 @@ mod tests {
}
/// A dimension is a collection of chunks and entities.
/// Minecraft calls these "Levels", Fabric calls them "Worlds", Minestom calls them "Instances".
/// Yeah.
#[derive(Debug)]
pub struct Dimension {
chunk_storage: ChunkStorage,