mirror of
https://github.com/bevyengine/bevy
synced 2024-11-22 12:43:34 +00:00
Check for NaN in Camera::world_to_screen()
(#3268)
# Objective - Checks for NaN in computed NDC space coordinates, fixing unexpected NaN in a fallible (`Option<T>`) function. ## Solution - Adds a NaN check, in addition to the existing NDC bounds checks. - This is a helper function, and should have no performance impact to the engine itself. - This will help prevent hard-to-trace NaN propagation in user code, by returning `None` instead of `Some(NaN)`. Depends on https://github.com/bevyengine/bevy/pull/3269 for CI error fix.
This commit is contained in:
parent
bf96f266d7
commit
38c7d5eb9e
2 changed files with 12 additions and 4 deletions
|
@ -55,13 +55,17 @@ impl Camera {
|
|||
let world_to_ndc: Mat4 =
|
||||
self.projection_matrix * camera_transform.compute_matrix().inverse();
|
||||
let ndc_space_coords: Vec3 = world_to_ndc.project_point3(world_position);
|
||||
// NDC z-values outside of 0 < z < 1 are behind the camera and are thus not in screen space
|
||||
// NDC z-values outside of 0 < z < 1 are outside the camera frustum and are thus not in screen space
|
||||
if ndc_space_coords.z < 0.0 || ndc_space_coords.z > 1.0 {
|
||||
return None;
|
||||
}
|
||||
// Once in NDC space, we can discard the z element and rescale x/y to fit the screen
|
||||
let screen_space_coords = (ndc_space_coords.truncate() + Vec2::ONE) / 2.0 * window_size;
|
||||
Some(screen_space_coords)
|
||||
if !screen_space_coords.is_nan() {
|
||||
Some(screen_space_coords)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -54,13 +54,17 @@ impl Camera {
|
|||
let world_to_ndc: Mat4 =
|
||||
self.projection_matrix * camera_transform.compute_matrix().inverse();
|
||||
let ndc_space_coords: Vec3 = world_to_ndc.project_point3(world_position);
|
||||
// NDC z-values outside of 0 < z < 1 are behind the camera and are thus not in screen space
|
||||
// NDC z-values outside of 0 < z < 1 are outside the camera frustum and are thus not in screen space
|
||||
if ndc_space_coords.z < 0.0 || ndc_space_coords.z > 1.0 {
|
||||
return None;
|
||||
}
|
||||
// Once in NDC space, we can discard the z element and rescale x/y to fit the screen
|
||||
let screen_space_coords = (ndc_space_coords.truncate() + Vec2::ONE) / 2.0 * window_size;
|
||||
Some(screen_space_coords)
|
||||
if !screen_space_coords.is_nan() {
|
||||
Some(screen_space_coords)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue