mirror of
https://github.com/mat-1/azalea.git
synced 2025-08-02 23:44:38 +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 = [
|
dependencies = [
|
||||||
"azalea-core",
|
"azalea-core",
|
||||||
"azalea-entity",
|
"azalea-entity",
|
||||||
|
"azalea-world",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[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;
|
mod particle;
|
||||||
pub use particle::*;
|
pub use particle::*;
|
||||||
|
|
||||||
|
mod cursor3d;
|
||||||
|
pub use cursor3d::*;
|
||||||
|
|
|
@ -8,3 +8,4 @@ version = "0.1.0"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
azalea-core = {path = "../azalea-core"}
|
azalea-core = {path = "../azalea-core"}
|
||||||
azalea-entity = {path = "../azalea-entity"}
|
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_x = self.min_x;
|
||||||
let mut min_y = self.min_y;
|
let mut min_y = self.min_y;
|
||||||
let mut min_z = self.min_z;
|
let mut min_z = self.min_z;
|
||||||
|
@ -62,22 +62,22 @@ impl AABB {
|
||||||
let mut max_y = self.max_y;
|
let mut max_y = self.max_y;
|
||||||
let mut max_z = self.max_z;
|
let mut max_z = self.max_z;
|
||||||
|
|
||||||
if x < 0.0 {
|
if other.x < 0.0 {
|
||||||
min_x += x;
|
min_x += other.x;
|
||||||
} else if x > 0.0 {
|
} else if other.x > 0.0 {
|
||||||
max_x += x;
|
max_x += other.x;
|
||||||
}
|
}
|
||||||
|
|
||||||
if y < 0.0 {
|
if other.y < 0.0 {
|
||||||
min_y += y;
|
min_y += other.y;
|
||||||
} else if y > 0.0 {
|
} else if other.y > 0.0 {
|
||||||
max_y += y;
|
max_y += other.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
if z < 0.0 {
|
if other.z < 0.0 {
|
||||||
min_z += z;
|
min_z += other.z;
|
||||||
} else if z > 0.0 {
|
} else if other.z > 0.0 {
|
||||||
max_z += z;
|
max_z += other.z;
|
||||||
}
|
}
|
||||||
|
|
||||||
AABB {
|
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 aabb;
|
||||||
mod block_hit_result;
|
mod block_hit_result;
|
||||||
|
mod dimension_collisions;
|
||||||
|
|
||||||
pub use aabb::AABB;
|
pub use aabb::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;
|
||||||
pub use block_hit_result::BlockHitResult;
|
pub use block_hit_result::BlockHitResult;
|
||||||
|
|
||||||
pub enum MoverType {
|
pub enum MoverType {
|
||||||
|
@ -16,6 +18,13 @@ pub enum MoverType {
|
||||||
|
|
||||||
trait HasPhysics {
|
trait HasPhysics {
|
||||||
fn move_entity(&mut self, mover_type: &MoverType, movement: &PositionDelta);
|
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 {
|
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.
|
/// A dimension is a collection of chunks and entities.
|
||||||
|
/// Minecraft calls these "Levels", Fabric calls them "Worlds", Minestom calls them "Instances".
|
||||||
|
/// Yeah.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Dimension {
|
pub struct Dimension {
|
||||||
chunk_storage: ChunkStorage,
|
chunk_storage: ChunkStorage,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue