MCPcopy Create free account
hub / github.com/Bloom-Engine/engine / raycast_scene_all

Function raycast_scene_all

native/shared/src/picking.rs:151–221  ·  view source on GitHub ↗

Q6: Raycast against all visible scene nodes. Returns ALL hits sorted by distance. Used by editors for alt-click cycling through occluded objects.

(
    scene: &SceneGraph,
    origin: &[f32; 3],
    direction: &[f32; 3],
    max_results: usize,
)

Source from the content-addressed store, hash-verified

149/// Q6: Raycast against all visible scene nodes. Returns ALL hits sorted by distance.
150/// Used by editors for alt-click cycling through occluded objects.
151pub fn raycast_scene_all(
152 scene: &SceneGraph,
153 origin: &[f32; 3],
154 direction: &[f32; 3],
155 max_results: usize,
156) -> Vec<PickResult> {
157 let mut results: Vec<PickResult> = Vec::new();
158
159 for (handle, node) in scene.nodes.iter() {
160 if !node.visible || node.indices.is_empty() {
161 continue;
162 }
163
164 let inv_transform = mat4_inverse_local(&node.transform);
165 let local_origin = mat4_transform_point(&inv_transform, origin);
166 let local_dir = mat4_transform_dir(&inv_transform, direction);
167
168 let mut node_best_dist = f32::MAX;
169 let mut node_best: Option<PickResult> = None;
170
171 for tri in node.indices.chunks(3) {
172 if tri.len() < 3 { continue; }
173 let v0 = &node.vertices[tri[0] as usize];
174 let v1 = &node.vertices[tri[1] as usize];
175 let v2 = &node.vertices[tri[2] as usize];
176
177 if let Some((t, u, v)) = ray_triangle_intersection(
178 &local_origin, &local_dir,
179 &v0.position, &v1.position, &v2.position,
180 ) {
181 if t > 0.0 && t < node_best_dist {
182 node_best_dist = t;
183 let hit_local = [
184 local_origin[0] + local_dir[0] * t,
185 local_origin[1] + local_dir[1] * t,
186 local_origin[2] + local_dir[2] * t,
187 ];
188 let hit_world = mat4_transform_point(&node.transform, &hit_local);
189 let w = 1.0 - u - v;
190 let normal = [
191 v0.normal[0] * w + v1.normal[0] * u + v2.normal[0] * v,
192 v0.normal[1] * w + v1.normal[1] * u + v2.normal[1] * v,
193 v0.normal[2] * w + v1.normal[2] * u + v2.normal[2] * v,
194 ];
195 let nl = (normal[0]*normal[0] + normal[1]*normal[1] + normal[2]*normal[2]).sqrt();
196 let normal = if nl > 1e-6 {
197 [normal[0]/nl, normal[1]/nl, normal[2]/nl]
198 } else {
199 [0.0, 1.0, 0.0]
200 };
201 node_best = Some(PickResult {
202 hit: true,
203 handle,
204 distance: t,
205 point: hit_world,
206 normal,
207 });
208 }

Callers 7

bloom_scene_pick_allFunction · 0.85
bloom_scene_pick_allFunction · 0.85
bloom_scene_pick_allFunction · 0.85
bloom_scene_pick_allFunction · 0.85
bloom_scene_pick_allFunction · 0.85
bloom_scene_pick_allFunction · 0.85
bloom_scene_pick_allFunction · 0.85

Calls 6

mat4_inverse_localFunction · 0.85
mat4_transform_dirFunction · 0.85
iterMethod · 0.80
mat4_transform_pointFunction · 0.70
pushMethod · 0.45

Tested by

no test coverage detected