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 entity handling and damage. #772

Draft
wants to merge 24 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
ecacefc
Arrow Entity handling and damage.
Tebarem Dec 19, 2024
c604a53
Arrow hitting blocks and damaging entities
Tebarem Dec 19, 2024
1bb1901
Despawn Arrow and clamp velocity properly :)
Tebarem Dec 19, 2024
263adfd
hand animations :thumbsup:
Tebarem Dec 19, 2024
c5f07d8
fix bow?
Tebarem Dec 19, 2024
973cf57
first_collision rewrite. somewhat fixed arrow through floor
Tebarem Dec 20, 2024
58d2e3f
Arrow Entity handling and damage.
Tebarem Dec 19, 2024
f6129d3
Arrow hitting blocks and damaging entities
Tebarem Dec 19, 2024
b413b32
Despawn Arrow and clamp velocity properly :)
Tebarem Dec 19, 2024
d2715d2
hand animations :thumbsup:
Tebarem Dec 19, 2024
60a7470
fix bow?
Tebarem Dec 19, 2024
7142da6
first_collision rewrite. somewhat fixed arrow through floor
Tebarem Dec 20, 2024
b4f69eb
updated some stuff and when position updates.
Tebarem Dec 20, 2024
1dc359b
Merge branch 'arrows' of https://github.com/hyperion-mc/hyperion into…
Tebarem Dec 20, 2024
a33b4cf
stash apply
Tebarem Dec 20, 2024
799b358
fix
andrewgazelka Dec 20, 2024
28a4e2f
Voxel Traversal and Ray changes.
Tebarem Dec 21, 2024
5903cc4
Merge branch 'arrows' of https://github.com/hyperion-mc/hyperion into…
Tebarem Dec 21, 2024
877962b
ray changes DDA-> Amanadites and woo algorithim
Tebarem Dec 21, 2024
201f6dd
Arrows Collisions Complete. No more crashing i think! :)
Tebarem Dec 22, 2024
4fd90ac
Merge remote-tracking branch 'origin/main' into arrows
andrewgazelka Dec 22, 2024
4d59a8b
test updates.
Tebarem Dec 22, 2024
c063332
Merge branch 'arrows' of https://github.com/hyperion-mc/hyperion into…
Tebarem Dec 22, 2024
5cd21a7
update
andrewgazelka Dec 22, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 2 additions & 14 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 0 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ members = [
'crates/hyperion-text',
'crates/hyperion-utils',
'crates/simd-utils',
'crates/spatial',
'crates/system-order',
'events/tag',
'tools/antithesis-bot',
Expand Down Expand Up @@ -237,9 +236,6 @@ version = '0.10.8'
[workspace.dependencies.simd-utils]
path = 'crates/simd-utils'

[workspace.dependencies.spatial]
path = 'crates/spatial'

[workspace.dependencies.syntect]
default-features = false
version = '5.2.0'
Expand Down
75 changes: 25 additions & 50 deletions crates/geometry/src/aabb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -279,64 +279,39 @@ impl Aabb {
}

let dir = ray.direction();
let inv_dir = ray.inv_direction();

// For each axis, handle zero direction:
// Initialize t_min and t_max to the range of possible values
let (mut t_min, mut t_max) = (f32::NEG_INFINITY, f32::INFINITY);

// X-axis
if dir.x == 0.0 {
// Ray is parallel to X slab
if origin.x < self.min.x || origin.x > self.max.x {
return None; // no intersection if outside slab
}
// else: no constraint from X (t_min, t_max remain infinite)
} else {
let inv_dx = 1.0 / dir.x;
let tx1 = (self.min.x - origin.x) * inv_dx;
let tx2 = (self.max.x - origin.x) * inv_dx;
let t_low = tx1.min(tx2);
let t_high = tx1.max(tx2);
t_min = t_min.max(t_low);
t_max = t_max.min(t_high);
if t_min > t_max {
return None;
}
if dir.x != 0.0 {
let tx1 = (self.min.x - origin.x) * inv_dir.x;
let tx2 = (self.max.x - origin.x) * inv_dir.x;
t_min = t_min.max(tx1.min(tx2));
t_max = t_max.min(tx1.max(tx2));
} else if origin.x < self.min.x || origin.x > self.max.x {
return None; // Ray is parallel to X slab and outside the slab
}

// Y-axis (do the same zero-check logic)
if dir.y == 0.0 {
if origin.y < self.min.y || origin.y > self.max.y {
return None;
}
} else {
let inv_dy = 1.0 / dir.y;
let ty1 = (self.min.y - origin.y) * inv_dy;
let ty2 = (self.max.y - origin.y) * inv_dy;
let t_low = ty1.min(ty2);
let t_high = ty1.max(ty2);
t_min = t_min.max(t_low);
t_max = t_max.min(t_high);
if t_min > t_max {
return None;
}
// Y-axis
if dir.y != 0.0 {
let ty1 = (self.min.y - origin.y) * inv_dir.y;
let ty2 = (self.max.y - origin.y) * inv_dir.y;
t_min = t_min.max(ty1.min(ty2));
t_max = t_max.min(ty1.max(ty2));
} else if origin.y < self.min.y || origin.y > self.max.y {
return None; // Ray is parallel to Y slab and outside the slab
}

// Z-axis (same pattern)
if dir.z == 0.0 {
if origin.z < self.min.z || origin.z > self.max.z {
return None;
}
} else {
let inv_dz = 1.0 / dir.z;
let tz1 = (self.min.z - origin.z) * inv_dz;
let tz2 = (self.max.z - origin.z) * inv_dz;
let t_low = tz1.min(tz2);
let t_high = tz1.max(tz2);
t_min = t_min.max(t_low);
t_max = t_max.min(t_high);
if t_min > t_max {
return None;
}
// Z-axis
if dir.z != 0.0 {
let tz1 = (self.min.z - origin.z) * inv_dir.z;
let tz2 = (self.max.z - origin.z) * inv_dir.z;
t_min = t_min.max(tz1.min(tz2));
t_max = t_max.min(tz1.max(tz2));
} else if origin.z < self.min.z || origin.z > self.max.z {
return None; // Ray is parallel to Z slab and outside the slab
}

// At this point, t_min and t_max define the intersection range.
Expand Down
117 changes: 33 additions & 84 deletions crates/geometry/src/ray.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,110 +56,57 @@ impl Ray {
self.origin + self.direction * t
}

/// Efficiently traverse through grid cells that the ray intersects using an optimized DDA algorithm.
/// Efficiently traverse through grid cells that the ray intersects using the Amanatides and Woo algorithm.
/// 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
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),
// Determine stepping direction for each axis
let step = IVec3::new(
if self.direction.x > 0.0 { 1 } else { -1 },
if self.direction.y > 0.0 { 1 } else { -1 },
if self.direction.z > 0.0 { 1 } else { -1 },
);

// Calculate step direction for each axis
let step = IVec3::new(
if self.direction.x > 0.0 {
1
} else if self.direction.x < 0.0 {
-1
// Calculate distance to next voxel boundary for each axis
let next_boundary = Vec3::new(
if step.x > 0 {
current_pos.x as f32 + 1.0 - self.origin.x
} else {
0
self.origin.x - current_pos.x as f32
},
if self.direction.y > 0.0 {
1
} else if self.direction.y < 0.0 {
-1
if step.y > 0 {
current_pos.y as f32 + 1.0 - self.origin.y
} else {
0
self.origin.y - current_pos.y as f32
},
if self.direction.z > 0.0 {
1
} else if self.direction.z < 0.0 {
-1
if step.z > 0 {
current_pos.z as f32 + 1.0 - self.origin.z
} else {
0
self.origin.z - current_pos.z as f32
},
);

// Calculate t_max - distance to next voxel boundary for each axis
// Calculate t_max and t_delta using precomputed inv_direction
let t_max = Vec3::new(
if self.direction.x == 0.0 {
f32::INFINITY
} else {
let next_x = if self.direction.x > 0.0 {
current_pos.x as f32 + 1.0 - self.origin.x
} else {
self.origin.x - current_pos.x as f32
};
next_x * self.inv_direction.x.abs()
},
if self.direction.y == 0.0 {
f32::INFINITY
} else {
let next_y = if self.direction.y > 0.0 {
current_pos.y as f32 + 1.0 - self.origin.y
} else {
self.origin.y - current_pos.y as f32
};
next_y * self.inv_direction.y.abs()
},
if self.direction.z == 0.0 {
f32::INFINITY
} else {
let next_z = if self.direction.z > 0.0 {
current_pos.z as f32 + 1.0 - self.origin.z
} else {
self.origin.z - current_pos.z as f32
};
next_z * self.inv_direction.z.abs()
},
next_boundary.x * self.inv_direction.x.abs(),
next_boundary.y * self.inv_direction.y.abs(),
next_boundary.z * self.inv_direction.z.abs(),
);

// Calculate t_delta - distance between voxel boundaries
let t_delta = Vec3::new(
if self.direction.x == 0.0 {
f32::INFINITY
} else {
self.inv_direction.x.abs()
},
if self.direction.y == 0.0 {
f32::INFINITY
} else {
self.inv_direction.y.abs()
},
if self.direction.z == 0.0 {
f32::INFINITY
} else {
self.inv_direction.z.abs()
},
self.inv_direction.x.abs(),
self.inv_direction.y.abs(),
self.inv_direction.z.abs(),
);

VoxelTraversal {
current_pos,
step,
t_max,
t_delta,
bounds_min: min_block,
bounds_max: max_block,
bounds_min,
bounds_max,
}
}
}
Expand Down Expand Up @@ -201,12 +148,14 @@ impl Iterator for VoxelTraversal {
self.current_pos.z += self.step.z;
self.t_max.z += self.t_delta.z;
}
} else if self.t_max.y < self.t_max.z {
self.current_pos.y += self.step.y;
self.t_max.y += self.t_delta.y;
} else {
self.current_pos.z += self.step.z;
self.t_max.z += self.t_delta.z;
if self.t_max.y < self.t_max.z {
self.current_pos.y += self.step.y;
self.t_max.y += self.t_delta.y;
} else {
self.current_pos.z += self.step.z;
self.t_max.z += self.t_delta.z;
}
}

Some(current)
Expand Down
3 changes: 2 additions & 1 deletion crates/hyperion/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ anyhow = { workspace = true }
base64 = { workspace = true }
bitfield-struct = { workspace = true }
bitvec = { workspace = true }
bvh-region = { workspace = true }
bumpalo = { workspace = true }
bytemuck = { workspace = true }
byteorder = { workspace = true }
Expand Down Expand Up @@ -70,12 +71,12 @@ valence_protocol = { workspace = true }
valence_registry = { workspace = true }
valence_server = { workspace = true }
valence_text = { workspace = true }
ordered-float = { workspace = true }

[dev-dependencies]
approx = { workspace = true }
divan = { workspace = true }
fastrand = { workspace = true }
spatial = { workspace = true }

[lints]
workspace = true
Expand Down
Loading
Loading