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:
parent
add3bc9c7e
commit
d6491ac08b
10 changed files with 129 additions and 21 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -183,6 +183,7 @@ dependencies = [
|
|||
name = "azalea-physics"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"azalea-block",
|
||||
"azalea-core",
|
||||
"azalea-entity",
|
||||
"azalea-world",
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
|
||||
|
|
|
@ -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)]
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
mod data;
|
||||
mod physics;
|
||||
|
||||
use azalea_core::{PositionDelta, Vec3};
|
||||
pub use data::*;
|
||||
|
|
|
@ -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
3
azalea-physics/README.md
Normal file
|
@ -0,0 +1,3 @@
|
|||
# Azalea Physics
|
||||
|
||||
Physics for Minecraft entities.
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue