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:
parent
99cba524d6
commit
add3bc9c7e
8 changed files with 203 additions and 14 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -185,6 +185,7 @@ version = "0.1.0"
|
|||
dependencies = [
|
||||
"azalea-core",
|
||||
"azalea-entity",
|
||||
"azalea-world",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
108
azalea-core/src/cursor3d.rs
Normal file
108
azalea-core/src/cursor3d.rs
Normal 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"),
|
||||
}
|
||||
}
|
||||
}
|
|
@ -25,3 +25,6 @@ pub use delta::*;
|
|||
|
||||
mod particle;
|
||||
pub use particle::*;
|
||||
|
||||
mod cursor3d;
|
||||
pub use cursor3d::*;
|
||||
|
|
|
@ -8,3 +8,4 @@ version = "0.1.0"
|
|||
[dependencies]
|
||||
azalea-core = {path = "../azalea-core"}
|
||||
azalea-entity = {path = "../azalea-entity"}
|
||||
azalea-world = {path = "../azalea-world"}
|
||||
|
|
|
@ -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 {
|
||||
|
|
48
azalea-physics/src/dimension_collisions.rs
Normal file
48
azalea-physics/src/dimension_collisions.rs
Normal 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 {}
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Add table
Reference in a new issue