Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: arrow and some raycast changes. #658

Merged
merged 11 commits into from
Dec 7, 2024
3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ inherits = 'release'
lto = 'fat'
panic = 'abort'

[profile.dev]
incremental = true

[workspace]
members = [
'crates/bvh-region',
Expand Down
28 changes: 16 additions & 12 deletions crates/geometry/src/ray.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,16 +46,20 @@ impl Ray {
/// Returns an iterator over the grid cells ([`IVec3`]) that the ray passes through.
pub fn voxel_traversal(&self, bounds_min: IVec3, bounds_max: IVec3) -> VoxelTraversal {
// Convert ray origin to grid coordinates and handle negative coordinates correctly
#[allow(clippy::cast_possible_truncation)]
let current_pos = if self.origin.x < 0.0 || self.origin.y < 0.0 || self.origin.z < 0.0 {
IVec3::new(
self.origin.x.floor() as i32,
self.origin.y.floor() as i32,
self.origin.z.floor() as i32,
)
} else {
self.origin.as_ivec3()
};
let current_pos = self.origin.as_ivec3();

// Ensure that the traversal includes the current block
let min_block = IVec3::new(
current_pos.x.min(bounds_min.x),
current_pos.y.min(bounds_min.y),
current_pos.z.min(bounds_min.z),
);

let max_block = IVec3::new(
current_pos.x.max(bounds_max.x),
current_pos.y.max(bounds_max.y),
current_pos.z.max(bounds_max.z),
);

// Calculate step direction for each axis
let step = IVec3::new(
Expand Down Expand Up @@ -140,8 +144,8 @@ impl Ray {
step,
t_max,
t_delta,
bounds_min,
bounds_max,
bounds_min: min_block,
bounds_max: max_block,
}
}
}
Expand Down
103 changes: 32 additions & 71 deletions crates/hyperion/src/egress/sync_entity_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,12 @@ use glam::Vec3;
use hyperion_inventory::PlayerInventory;
use hyperion_utils::EntityExt;
use tracing::{error, info_span};
use valence_protocol::{ByteAngle, RawBytes, VarInt, packets::play};
use valence_protocol::{RawBytes, VarInt, packets::play};

use crate::{
Prev,
net::{Compose, ConnectionId},
simulation::{
Pitch, Position, Velocity, Xp, Yaw, animation::ActiveAnimation, metadata::MetadataChanges,
},
simulation::{Position, Velocity, Xp, animation::ActiveAnimation, metadata::MetadataChanges},
system_registry::{SYNC_ENTITY_POSITION, SystemId},
util::TracingExt,
};
Expand Down Expand Up @@ -224,96 +222,59 @@ impl Module for EntityStateSyncModule {
},
);

// Add a new system specifically for projectiles (arrows)
system!(
"entity_velocity_sync",
world,
&Compose($),
&Velocity,
)
.multi_threaded()
.kind::<flecs::pipeline::OnStore>()
.tracing_each_entity(
info_span!("entity_velocity_sync"),
move |entity, (compose, velocity)| {
let run = || {
let entity_id = VarInt(entity.minecraft_id());
let world = entity.world();

if velocity.velocity != Vec3::ZERO {
let pkt = play::EntityVelocityUpdateS2c {
entity_id,
velocity: (*velocity).try_into()?,
};

compose.broadcast(&pkt, system_id).send(&world)?;
}

anyhow::Ok(())
};

if let Err(e) = run() {
error!("failed to run velocity sync: {e}");
}
},
);

system!(
"entity_state_sync",
"projectile_sync",
world,
&Compose($),
&Position,
&Yaw,
&Pitch,
?&ConnectionId,
&(Prev, Position),
&mut Velocity,
)
.multi_threaded()
.kind::<flecs::pipeline::OnStore>()
.kind::<flecs::pipeline::PreStore>()
.tracing_each_entity(
info_span!("entity_state_sync"),
move |entity, (compose, position, yaw, pitch, io)| {
let run = || {
let entity_id = VarInt(entity.minecraft_id());

let io = io.copied();

let world = entity.world();
info_span!("projectile_sync"),
move |entity, (compose, position, previous_position, velocity)| {
let entity_id = VarInt(entity.minecraft_id());
let world = entity.world();
let chunk_pos = position.to_chunk();

let chunk_pos = position.to_chunk();
let position_delta = **position - **previous_position;
let needs_teleport = position_delta.abs().max_element() >= 8.0;
let changed_position = **position != **previous_position;

let pkt = play::EntityPositionS2c {
if changed_position && !needs_teleport {
let pkt = play::MoveRelativeS2c {
entity_id,
position: position.as_dvec3(),
yaw: ByteAngle::from_degrees(**yaw),
pitch: ByteAngle::from_degrees(**pitch),
#[allow(clippy::cast_possible_truncation)]
delta: (position_delta * 4096.0).to_array().map(|x| x as i16),
on_ground: false,
};

compose
.broadcast_local(&pkt, chunk_pos, system_id)
.exclude(io)
.send(&world)?;
.send(&world)
.unwrap();
}

// todo: unsure if we always want to set this
let pkt = play::EntitySetHeadYawS2c {
// Sync velocity if non-zero
if velocity.velocity != Vec3::ZERO {
let pkt = play::EntityVelocityUpdateS2c {
entity_id,
head_yaw: ByteAngle::from_degrees(**yaw),
velocity: (*velocity).try_into().unwrap_or_else(|_| {
Velocity::ZERO
.try_into()
.expect("failed to convert velocity to i16")
}),
};

compose
.broadcast(&pkt, system_id)
.exclude(io)
.send(&world)?;

anyhow::Ok(())
};
if let Err(e) = run() {
error!("failed to run sync_position: {e}");
compose.broadcast(&pkt, system_id).send(&world).unwrap();
// velocity.velocity = Vec3::ZERO;
}
},
);

track_previous::<Position>(world);
track_previous::<Yaw>(world);
track_previous::<Pitch>(world);
}
}
6 changes: 6 additions & 0 deletions crates/hyperion/src/simulation/blocks/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ pub enum TrySetBlockDeltaError {
pub struct RayCollision {
pub distance: f32,
pub location: IVec3,
pub normal: Vec3,
pub block: BlockState,
}

Expand Down Expand Up @@ -133,12 +134,16 @@ impl Blocks {
continue;
};

let collision_point = ray.origin() + ray.direction() * min_dist.into_inner();
let collision_normal = (collision_point - origin).normalize();

match &min {
Some(current_min) => {
if min_dist.into_inner() < current_min.distance {
min = Some(RayCollision {
distance: min_dist.into_inner(),
location: cell,
normal: collision_normal,
block,
});
}
Expand All @@ -147,6 +152,7 @@ impl Blocks {
min = Some(RayCollision {
distance: min_dist.into_inner(),
location: cell,
normal: collision_normal,
block,
});
}
Expand Down
Loading
Loading