refactor(spatial): local visibility calculation

This commit is contained in:
Nova
2025-10-22 15:51:21 -07:00
parent 429a6efcee
commit 04e20a3bbf

View File

@@ -19,6 +19,7 @@ use mint::Vector3;
use parking_lot::{Mutex, RwLock}; use parking_lot::{Mutex, RwLock};
use rustc_hash::FxHashMap; use rustc_hash::FxHashMap;
use std::fmt::Debug; use std::fmt::Debug;
use std::sync::atomic::Ordering;
use std::sync::{Arc, OnceLock, Weak}; use std::sync::{Arc, OnceLock, Weak};
use std::{f32, ptr}; use std::{f32, ptr};
@@ -88,14 +89,18 @@ fn despawn_unneeded_spatial_nodes(query: Query<(Entity, &SpatialNode)>, cmds: Pa
fn update_spatial_nodes(mut query: Query<(&mut BevyTransform, &SpatialNode, &mut Visibility)>) { fn update_spatial_nodes(mut query: Query<(&mut BevyTransform, &SpatialNode, &mut Visibility)>) {
query query
.par_iter_mut() .iter_mut()
.for_each(|(mut transform, spatial_node, mut vis)| { .for_each(|(mut transform, spatial_node, mut vis)| {
let _span = debug_span!("updating spatial node").entered(); let _span = debug_span!("updating spatial node").entered();
let Some(spatial) = spatial_node.0.upgrade() else { let Some(spatial) = spatial_node.0.upgrade() else {
return; return;
}; };
// Set visibility based on node enabled state // Set visibility based on node enabled state
if spatial.node().is_some_and(|v| v.enabled()) { if spatial
.node()
.is_some_and(|v| v.enabled.load(Ordering::Relaxed))
&& spatial.local_visible()
{
*vis = Visibility::Inherited; *vis = Visibility::Inherited;
} else { } else {
*vis = Visibility::Hidden; *vis = Visibility::Hidden;
@@ -225,6 +230,15 @@ impl Spatial {
*self.transform.read() *self.transform.read()
} }
fn local_visible(&self) -> bool {
// Check our own scale by looking at matrix column lengths
let mat = self.local_transform();
let x_scale = mat.x_axis.length_squared();
let y_scale = mat.y_axis.length_squared();
let z_scale = mat.z_axis.length_squared();
!(x_scale == 0.0 && y_scale == 0.0 && z_scale == 0.0)
}
/// Check if this node or any ancestor has zero scale (for visibility culling) /// Check if this node or any ancestor has zero scale (for visibility culling)
pub fn visible(&self) -> bool { pub fn visible(&self) -> bool {
// Check parent chain // Check parent chain
@@ -235,12 +249,7 @@ impl Spatial {
} }
// Check our own scale by looking at matrix column lengths // Check our own scale by looking at matrix column lengths
let mat = self.local_transform(); self.local_visible()
let x_scale = mat.x_axis.length_squared();
let y_scale = mat.y_axis.length_squared();
let z_scale = mat.z_axis.length_squared();
!(x_scale == 0.0 || y_scale == 0.0 || z_scale == 0.0)
} }
pub fn global_transform(&self) -> Mat4 { pub fn global_transform(&self) -> Mat4 {
let parent_transform = self let parent_transform = self