Skip to content

Commit a1bb588

Browse files
andrewgazelkaTebaremTestingPlant
authored
feat: arrow entity handling and damage. (#772)
Arrow Entity handling and damage. Arrow hitting blocks and damaging entities Despawn Arrow and clamp velocity properly :) hand animations 👍 fix bow? first_collision rewrite. somewhat fixed arrow through floor --------- Co-authored-by: e1pupper <tebaremahmed@gmail.com> Co-authored-by: TestingPlant <44930139+TestingPlant@users.noreply.github.com>
1 parent 0ccdf77 commit a1bb588

File tree

25 files changed

+564
-432
lines changed

25 files changed

+564
-432
lines changed

Cargo.lock

Lines changed: 3 additions & 14 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ members = [
4040
'crates/hyperion-text',
4141
'crates/hyperion-utils',
4242
'crates/simd-utils',
43-
'crates/spatial',
4443
'crates/system-order',
4544
'events/tag',
4645
'tools/packet-inspector',
@@ -240,9 +239,6 @@ version = '0.10.8'
240239
[workspace.dependencies.simd-utils]
241240
path = 'crates/simd-utils'
242241

243-
[workspace.dependencies.spatial]
244-
path = 'crates/spatial'
245-
246242
[workspace.dependencies.syntect]
247243
default-features = false
248244
version = '5.2.0'

crates/geometry/src/aabb.rs

Lines changed: 29 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -279,64 +279,43 @@ impl Aabb {
279279
}
280280

281281
let dir = ray.direction();
282+
let inv_dir = ray.inv_direction();
282283

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

286287
// X-axis
287-
if dir.x == 0.0 {
288-
// Ray is parallel to X slab
289-
if origin.x < self.min.x || origin.x > self.max.x {
290-
return None; // no intersection if outside slab
291-
}
292-
// else: no constraint from X (t_min, t_max remain infinite)
293-
} else {
294-
let inv_dx = 1.0 / dir.x;
295-
let tx1 = (self.min.x - origin.x) * inv_dx;
296-
let tx2 = (self.max.x - origin.x) * inv_dx;
297-
let t_low = tx1.min(tx2);
298-
let t_high = tx1.max(tx2);
299-
t_min = t_min.max(t_low);
300-
t_max = t_max.min(t_high);
301-
if t_min > t_max {
302-
return None;
303-
}
288+
if dir.x != 0.0 {
289+
let tx1 = (self.min.x - origin.x) * inv_dir.x;
290+
let tx2 = (self.max.x - origin.x) * inv_dir.x;
291+
t_min = t_min.max(tx1.min(tx2));
292+
t_max = t_max.min(tx1.max(tx2));
293+
} else if origin.x < self.min.x || origin.x > self.max.x {
294+
return None; // Ray is parallel to X slab and outside the slab
304295
}
305296

306-
// Y-axis (do the same zero-check logic)
307-
if dir.y == 0.0 {
308-
if origin.y < self.min.y || origin.y > self.max.y {
309-
return None;
310-
}
311-
} else {
312-
let inv_dy = 1.0 / dir.y;
313-
let ty1 = (self.min.y - origin.y) * inv_dy;
314-
let ty2 = (self.max.y - origin.y) * inv_dy;
315-
let t_low = ty1.min(ty2);
316-
let t_high = ty1.max(ty2);
317-
t_min = t_min.max(t_low);
318-
t_max = t_max.min(t_high);
319-
if t_min > t_max {
320-
return None;
321-
}
297+
// Y-axis
298+
if dir.y != 0.0 {
299+
let ty1 = (self.min.y - origin.y) * inv_dir.y;
300+
let ty2 = (self.max.y - origin.y) * inv_dir.y;
301+
t_min = t_min.max(ty1.min(ty2));
302+
t_max = t_max.min(ty1.max(ty2));
303+
} else if origin.y < self.min.y || origin.y > self.max.y {
304+
return None; // Ray is parallel to Y slab and outside the slab
322305
}
323306

324-
// Z-axis (same pattern)
325-
if dir.z == 0.0 {
326-
if origin.z < self.min.z || origin.z > self.max.z {
327-
return None;
328-
}
329-
} else {
330-
let inv_dz = 1.0 / dir.z;
331-
let tz1 = (self.min.z - origin.z) * inv_dz;
332-
let tz2 = (self.max.z - origin.z) * inv_dz;
333-
let t_low = tz1.min(tz2);
334-
let t_high = tz1.max(tz2);
335-
t_min = t_min.max(t_low);
336-
t_max = t_max.min(t_high);
337-
if t_min > t_max {
338-
return None;
339-
}
307+
// Z-axis
308+
if dir.z != 0.0 {
309+
let tz1 = (self.min.z - origin.z) * inv_dir.z;
310+
let tz2 = (self.max.z - origin.z) * inv_dir.z;
311+
t_min = t_min.max(tz1.min(tz2));
312+
t_max = t_max.min(tz1.max(tz2));
313+
} else if origin.z < self.min.z || origin.z > self.max.z {
314+
return None; // Ray is parallel to Z slab and outside the slab
315+
}
316+
317+
if t_min > t_max {
318+
return None;
340319
}
341320

342321
// At this point, t_min and t_max define the intersection range.

crates/geometry/src/ray.rs

Lines changed: 26 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -56,110 +56,57 @@ impl Ray {
5656
self.origin + self.direction * t
5757
}
5858

59-
/// Efficiently traverse through grid cells that the ray intersects using an optimized DDA algorithm.
59+
/// Efficiently traverse through grid cells that the ray intersects using the Amanatides and Woo algorithm.
6060
/// Returns an iterator over the grid cells ([`IVec3`]) that the ray passes through.
6161
pub fn voxel_traversal(&self, bounds_min: IVec3, bounds_max: IVec3) -> VoxelTraversal {
62-
// Convert ray origin to grid coordinates and handle negative coordinates correctly
6362
let current_pos = self.origin.as_ivec3();
6463

65-
// Ensure that the traversal includes the current block
66-
let min_block = IVec3::new(
67-
current_pos.x.min(bounds_min.x),
68-
current_pos.y.min(bounds_min.y),
69-
current_pos.z.min(bounds_min.z),
70-
);
71-
72-
let max_block = IVec3::new(
73-
current_pos.x.max(bounds_max.x),
74-
current_pos.y.max(bounds_max.y),
75-
current_pos.z.max(bounds_max.z),
64+
// Determine stepping direction for each axis
65+
let step = IVec3::new(
66+
if self.direction.x > 0.0 { 1 } else { -1 },
67+
if self.direction.y > 0.0 { 1 } else { -1 },
68+
if self.direction.z > 0.0 { 1 } else { -1 },
7669
);
7770

78-
// Calculate step direction for each axis
79-
let step = IVec3::new(
80-
if self.direction.x > 0.0 {
81-
1
82-
} else if self.direction.x < 0.0 {
83-
-1
71+
// Calculate distance to next voxel boundary for each axis
72+
let next_boundary = Vec3::new(
73+
if step.x > 0 {
74+
current_pos.x as f32 + 1.0 - self.origin.x
8475
} else {
85-
0
76+
self.origin.x - current_pos.x as f32
8677
},
87-
if self.direction.y > 0.0 {
88-
1
89-
} else if self.direction.y < 0.0 {
90-
-1
78+
if step.y > 0 {
79+
current_pos.y as f32 + 1.0 - self.origin.y
9180
} else {
92-
0
81+
self.origin.y - current_pos.y as f32
9382
},
94-
if self.direction.z > 0.0 {
95-
1
96-
} else if self.direction.z < 0.0 {
97-
-1
83+
if step.z > 0 {
84+
current_pos.z as f32 + 1.0 - self.origin.z
9885
} else {
99-
0
86+
self.origin.z - current_pos.z as f32
10087
},
10188
);
10289

103-
// Calculate t_max - distance to next voxel boundary for each axis
90+
// Calculate t_max and t_delta using precomputed inv_direction
10491
let t_max = Vec3::new(
105-
if self.direction.x == 0.0 {
106-
f32::INFINITY
107-
} else {
108-
let next_x = if self.direction.x > 0.0 {
109-
current_pos.x as f32 + 1.0 - self.origin.x
110-
} else {
111-
self.origin.x - current_pos.x as f32
112-
};
113-
next_x * self.inv_direction.x.abs()
114-
},
115-
if self.direction.y == 0.0 {
116-
f32::INFINITY
117-
} else {
118-
let next_y = if self.direction.y > 0.0 {
119-
current_pos.y as f32 + 1.0 - self.origin.y
120-
} else {
121-
self.origin.y - current_pos.y as f32
122-
};
123-
next_y * self.inv_direction.y.abs()
124-
},
125-
if self.direction.z == 0.0 {
126-
f32::INFINITY
127-
} else {
128-
let next_z = if self.direction.z > 0.0 {
129-
current_pos.z as f32 + 1.0 - self.origin.z
130-
} else {
131-
self.origin.z - current_pos.z as f32
132-
};
133-
next_z * self.inv_direction.z.abs()
134-
},
92+
next_boundary.x * self.inv_direction.x.abs(),
93+
next_boundary.y * self.inv_direction.y.abs(),
94+
next_boundary.z * self.inv_direction.z.abs(),
13595
);
13696

137-
// Calculate t_delta - distance between voxel boundaries
13897
let t_delta = Vec3::new(
139-
if self.direction.x == 0.0 {
140-
f32::INFINITY
141-
} else {
142-
self.inv_direction.x.abs()
143-
},
144-
if self.direction.y == 0.0 {
145-
f32::INFINITY
146-
} else {
147-
self.inv_direction.y.abs()
148-
},
149-
if self.direction.z == 0.0 {
150-
f32::INFINITY
151-
} else {
152-
self.inv_direction.z.abs()
153-
},
98+
self.inv_direction.x.abs(),
99+
self.inv_direction.y.abs(),
100+
self.inv_direction.z.abs(),
154101
);
155102

156103
VoxelTraversal {
157104
current_pos,
158105
step,
159106
t_max,
160107
t_delta,
161-
bounds_min: min_block,
162-
bounds_max: max_block,
108+
bounds_min,
109+
bounds_max,
163110
}
164111
}
165112
}

crates/hyperion/Cargo.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ anyhow = { workspace = true }
1111
base64 = { workspace = true }
1212
bitfield-struct = { workspace = true }
1313
bitvec = { workspace = true }
14+
bvh-region = { workspace = true }
1415
bumpalo = { workspace = true }
1516
bytemuck = { workspace = true }
1617
byteorder = { workspace = true }
@@ -71,12 +72,13 @@ valence_protocol = { workspace = true }
7172
valence_registry = { workspace = true }
7273
valence_server = { workspace = true }
7374
valence_text = { workspace = true }
75+
ordered-float = { workspace = true }
7476

7577
[dev-dependencies]
7678
approx = { workspace = true }
7779
divan = { workspace = true }
7880
fastrand = { workspace = true }
79-
spatial = { workspace = true }
81+
hyperion-genmap = { workspace = true }
8082

8183
[lints]
8284
workspace = true

0 commit comments

Comments
 (0)