mirror of
https://github.com/mat-1/azalea.git
synced 2025-08-02 23:44:38 +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"
|
name = "azalea-physics"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"azalea-block",
|
||||||
"azalea-core",
|
"azalea-core",
|
||||||
"azalea-entity",
|
"azalea-entity",
|
||||||
"azalea-world",
|
"azalea-world",
|
||||||
|
|
|
@ -8,7 +8,7 @@ use std::mem;
|
||||||
|
|
||||||
impl BlockState {
|
impl BlockState {
|
||||||
/// Transmutes a u32 to a block state.
|
/// Transmutes a u32 to a block state.
|
||||||
///
|
///
|
||||||
/// # Safety
|
/// # Safety
|
||||||
/// The `state_id` should be a valid block state.
|
/// The `state_id` should be a valid block state.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
use crate::BlockPos;
|
||||||
|
|
||||||
pub struct Cursor3d {
|
pub struct Cursor3d {
|
||||||
index: usize,
|
index: usize,
|
||||||
|
|
||||||
|
@ -37,15 +39,18 @@ impl Iterator for Cursor3d {
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(CursorIteration {
|
Some(CursorIteration {
|
||||||
x: self.origin_x + x as i32,
|
pos: BlockPos {
|
||||||
y: self.origin_y + y as i32,
|
x: self.origin_x + x as i32,
|
||||||
z: self.origin_z + z as i32,
|
y: self.origin_y + y as i32,
|
||||||
|
z: self.origin_z + z as i32,
|
||||||
|
},
|
||||||
iteration_type: iteration_type.into(),
|
iteration_type: iteration_type.into(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[repr(u8)]
|
#[repr(u8)]
|
||||||
|
#[derive(Eq, PartialEq, Debug)]
|
||||||
pub enum CursorIterationType {
|
pub enum CursorIterationType {
|
||||||
Inside = 0,
|
Inside = 0,
|
||||||
Face = 1,
|
Face = 1,
|
||||||
|
@ -54,9 +59,7 @@ pub enum CursorIterationType {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct CursorIteration {
|
pub struct CursorIteration {
|
||||||
pub x: i32,
|
pub pos: BlockPos,
|
||||||
pub y: i32,
|
|
||||||
pub z: i32,
|
|
||||||
pub iteration_type: CursorIterationType,
|
pub iteration_type: CursorIterationType,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -134,6 +134,9 @@ impl ChunkSectionPos {
|
||||||
pub fn new(x: i32, y: i32, z: i32) -> Self {
|
pub fn new(x: i32, y: i32, z: i32) -> Self {
|
||||||
ChunkSectionPos { x, y, z }
|
ChunkSectionPos { x, y, z }
|
||||||
}
|
}
|
||||||
|
pub fn block_to_section_coord(block: i32) -> i32 {
|
||||||
|
block >> 4
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/// The coordinates of a block inside a chunk.
|
/// The coordinates of a block inside a chunk.
|
||||||
#[derive(Clone, Copy, Debug, Default, PartialEq)]
|
#[derive(Clone, Copy, Debug, Default, PartialEq)]
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
mod data;
|
mod data;
|
||||||
mod physics;
|
|
||||||
|
|
||||||
use azalea_core::{PositionDelta, Vec3};
|
use azalea_core::{PositionDelta, Vec3};
|
||||||
pub use data::*;
|
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
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
azalea-block = {path = "../azalea-block"}
|
||||||
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"}
|
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 {
|
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_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;
|
||||||
|
@ -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_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;
|
||||||
|
@ -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_x = self.min_x - x;
|
||||||
let min_y = self.min_y - y;
|
let min_y = self.min_y - y;
|
||||||
let min_z = self.min_z - z;
|
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_entity::Entity;
|
||||||
use azalea_world::Dimension;
|
use azalea_world::{Chunk, Dimension};
|
||||||
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
use crate::AABB;
|
pub trait CollisionGetter {
|
||||||
|
|
||||||
trait CollisionGetter {
|
|
||||||
fn get_block_collisions<'a>(
|
fn get_block_collisions<'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
entity: Option<&Entity>,
|
entity: Option<&Entity>,
|
||||||
|
@ -25,23 +27,103 @@ pub struct BlockCollisions<'a> {
|
||||||
dimension: &'a Dimension,
|
dimension: &'a Dimension,
|
||||||
// context: CollisionContext,
|
// context: CollisionContext,
|
||||||
aabb: AABB,
|
aabb: AABB,
|
||||||
|
|
||||||
|
cursor: Cursor3d,
|
||||||
|
only_suffocating_blocks: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> BlockCollisions<'a> {
|
impl<'a> BlockCollisions<'a> {
|
||||||
pub fn new(dimension: &'a Dimension, entity: Option<&Entity>, aabb: AABB) -> Self {
|
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;
|
type Item = VoxelShape;
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
loop {
|
while let Some(item) = self.cursor.next() {
|
||||||
if !self.cursor.advance() {
|
if item.iteration_type == CursorIterationType::Corner {
|
||||||
return None;
|
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_entity::Entity;
|
||||||
use azalea_world::Dimension;
|
use azalea_world::Dimension;
|
||||||
pub use block_hit_result::BlockHitResult;
|
pub use block_hit_result::BlockHitResult;
|
||||||
|
use dimension_collisions::CollisionGetter;
|
||||||
|
|
||||||
pub enum MoverType {
|
pub enum MoverType {
|
||||||
Own,
|
Own,
|
||||||
|
@ -25,6 +26,11 @@ trait HasPhysics {
|
||||||
dimension: &Dimension,
|
dimension: &Dimension,
|
||||||
// entity_collisions: Vec<VoxelShape>
|
// entity_collisions: Vec<VoxelShape>
|
||||||
) -> Vec3;
|
) -> Vec3;
|
||||||
|
fn collide_with_shapes(
|
||||||
|
movement: &Vec3,
|
||||||
|
entity_box: &AABB,
|
||||||
|
// collision_boxes: Vec<VoxelShape>,
|
||||||
|
) -> Vec3;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HasPhysics for Entity {
|
impl HasPhysics for Entity {
|
||||||
|
@ -80,6 +86,16 @@ impl HasPhysics for Entity {
|
||||||
let block_collisions =
|
let block_collisions =
|
||||||
dimension.get_block_collisions(entity, entity_bounding_box.expand_towards(movement));
|
dimension.get_block_collisions(entity, entity_bounding_box.expand_towards(movement));
|
||||||
collision_boxes.extend(block_collisions);
|
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
Add a link
Reference in a new issue