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

more physics stuff

This commit is contained in:
mat 2022-06-26 23:15:31 -05:00
parent add3bc9c7e
commit d6491ac08b
10 changed files with 129 additions and 21 deletions

1
Cargo.lock generated
View file

@ -183,6 +183,7 @@ dependencies = [
name = "azalea-physics"
version = "0.1.0"
dependencies = [
"azalea-block",
"azalea-core",
"azalea-entity",
"azalea-world",

View file

@ -8,7 +8,7 @@ use std::mem;
impl BlockState {
/// Transmutes a u32 to a block state.
///
///
/// # Safety
/// The `state_id` should be a valid block state.
#[inline]

View file

@ -1,3 +1,5 @@
use crate::BlockPos;
pub struct Cursor3d {
index: usize,
@ -37,15 +39,18 @@ impl Iterator for Cursor3d {
}
Some(CursorIteration {
x: self.origin_x + x as i32,
y: self.origin_y + y as i32,
z: self.origin_z + z as i32,
pos: BlockPos {
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)]
#[derive(Eq, PartialEq, Debug)]
pub enum CursorIterationType {
Inside = 0,
Face = 1,
@ -54,9 +59,7 @@ pub enum CursorIterationType {
}
pub struct CursorIteration {
pub x: i32,
pub y: i32,
pub z: i32,
pub pos: BlockPos,
pub iteration_type: CursorIterationType,
}

View file

@ -134,6 +134,9 @@ impl ChunkSectionPos {
pub fn new(x: i32, y: i32, z: i32) -> Self {
ChunkSectionPos { x, y, z }
}
pub fn block_to_section_coord(block: i32) -> i32 {
block >> 4
}
}
/// The coordinates of a block inside a chunk.
#[derive(Clone, Copy, Debug, Default, PartialEq)]

View file

@ -1,5 +1,4 @@
mod data;
mod physics;
use azalea_core::{PositionDelta, Vec3};
pub use data::*;

View file

@ -6,6 +6,7 @@ version = "0.1.0"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
azalea-block = {path = "../azalea-block"}
azalea-core = {path = "../azalea-core"}
azalea-entity = {path = "../azalea-entity"}
azalea-world = {path = "../azalea-world"}

3
azalea-physics/README.md Normal file
View file

@ -0,0 +1,3 @@
# Azalea Physics
Physics for Minecraft entities.

View file

@ -15,7 +15,7 @@ pub struct AABB {
}
impl AABB {
pub fn contract(&mut self, x: f64, y: f64, z: f64) -> AABB {
pub fn contract(&self, x: f64, y: f64, z: f64) -> AABB {
let mut min_x = self.min_x;
let mut min_y = self.min_y;
let mut min_z = self.min_z;
@ -53,7 +53,7 @@ impl AABB {
}
}
pub fn expand_towards(&mut self, other: &Vec3) -> AABB {
pub fn expand_towards(&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;
@ -91,7 +91,7 @@ impl AABB {
}
}
pub fn inflate(&mut self, x: f64, y: f64, z: f64) -> AABB {
pub fn inflate(&self, x: f64, y: f64, z: f64) -> AABB {
let min_x = self.min_x - x;
let min_y = self.min_y - y;
let min_z = self.min_z - z;

View file

@ -1,9 +1,11 @@
use crate::{aabb::EPSILON, AABB};
use azalea_block::{Block, BlockState};
use azalea_core::{ChunkPos, ChunkSectionPos, Cursor3d, CursorIterationType};
use azalea_entity::Entity;
use azalea_world::Dimension;
use azalea_world::{Chunk, Dimension};
use std::sync::{Arc, Mutex};
use crate::AABB;
trait CollisionGetter {
pub trait CollisionGetter {
fn get_block_collisions<'a>(
&'a self,
entity: Option<&Entity>,
@ -25,23 +27,103 @@ pub struct BlockCollisions<'a> {
dimension: &'a Dimension,
// context: CollisionContext,
aabb: AABB,
cursor: Cursor3d,
only_suffocating_blocks: bool,
}
impl<'a> BlockCollisions<'a> {
pub fn new(dimension: &'a Dimension, entity: Option<&Entity>, aabb: AABB) -> Self {
Self { dimension, aabb }
let origin_x = (aabb.min_x - EPSILON) as i32 - 1;
let origin_y = (aabb.max_x + EPSILON) as i32 + 1;
let origin_z = (aabb.min_y - EPSILON) as i32 - 1;
let end_x = (aabb.max_y + EPSILON) as i32 + 1;
let end_y = (aabb.min_z - EPSILON) as i32 - 1;
let end_z = (aabb.max_z + EPSILON) as i32 + 1;
let cursor = Cursor3d::new(origin_x, origin_y, origin_z, end_x, end_y, end_z);
Self {
dimension,
aabb,
cursor,
only_suffocating_blocks: false,
}
}
fn get_chunk(&self, block_x: i32, block_z: i32) -> Option<&Arc<Mutex<Chunk>>> {
let chunk_x = ChunkSectionPos::block_to_section_coord(block_x);
let chunk_z = ChunkSectionPos::block_to_section_coord(block_z);
let chunk_pos = ChunkPos::new(chunk_x, chunk_z);
// TODO: minecraft caches chunk here
// int chunkX = SectionPos.blockToSectionCoord(blockX);
// int chunkZ = SectionPos.blockToSectionCoord(blockZ);
// long chunkPosLong = ChunkPos.asLong(chunkX, chunkZ);
// if (this.cachedBlockGetter != null && this.cachedBlockGetterPos == var5) {
// return this.cachedBlockGetter;
// } else {
// BlockGetter var7 = this.collisionGetter.getChunkForCollisions(chunkX, chunkZ);
// this.cachedBlockGetter = var7;
// this.cachedBlockGetterPos = chunkPosLong;
// return var7;
// }
let chunk = self.dimension[&chunk_pos].as_ref();
return chunk;
}
}
impl Iterator for BlockCollisions<'a> {
impl<'a> Iterator for BlockCollisions<'a> {
type Item = VoxelShape;
fn next(&mut self) -> Option<Self::Item> {
loop {
if !self.cursor.advance() {
return None;
while let Some(item) = self.cursor.next() {
if item.iteration_type == CursorIterationType::Corner {
continue;
}
let chunk = self.get_chunk(item.pos.x, item.pos.z);
let chunk = match chunk {
Some(chunk) => chunk,
None => continue,
};
let chunk_lock = chunk.lock().unwrap();
let pos = item.pos;
let block_state: BlockState = chunk_lock.get(&(&pos).into(), self.dimension.min_y());
let block: &dyn Block = &block_state.into();
// TODO: continue if self.only_suffocating_blocks and the block is not suffocating
let block_shape = VoxelShape {};
// let block_shape = block.get_collision_shape();
// if block_shape == Shapes::block() {
if true {
if !self.aabb.intersects_aabb(&AABB {
min_x: item.pos.x as f64,
min_y: item.pos.y as f64,
min_z: item.pos.z as f64,
max_x: (item.pos.x + 1) as f64,
max_y: (item.pos.y + 1) as f64,
max_z: (item.pos.z + 1) as f64,
}) {
continue;
}
return block_shape.move_relative(item.pos.x, item.pos.y, item.pos.z);
}
// let block_shape = block_shape.move_relative(item.pos.x, item.pos.y, item.pos.z);
// if (!Shapes.joinIsNotEmpty(block_shape, this.entityShape, BooleanOp.AND)) {
// continue;
// }
// return block_shape;
}
None
}
}

View file

@ -7,6 +7,7 @@ use azalea_core::{PositionDelta, PositionXYZ, Vec3};
use azalea_entity::Entity;
use azalea_world::Dimension;
pub use block_hit_result::BlockHitResult;
use dimension_collisions::CollisionGetter;
pub enum MoverType {
Own,
@ -25,6 +26,11 @@ trait HasPhysics {
dimension: &Dimension,
// entity_collisions: Vec<VoxelShape>
) -> Vec3;
fn collide_with_shapes(
movement: &Vec3,
entity_box: &AABB,
// collision_boxes: Vec<VoxelShape>,
) -> Vec3;
}
impl HasPhysics for Entity {
@ -80,6 +86,16 @@ impl HasPhysics for Entity {
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)
// Self::collide_with_shapes(movement, &entity_bounding_box, &collision_boxes)
Self::collide_with_shapes(movement, &entity_bounding_box)
}
fn collide_with_shapes(
movement: &Vec3,
entity_box: &AABB,
// collision_boxes: Vec<VoxelShape>,
) -> Vec3 {
// TODO
*movement
}
}