Visibility range takes the model aabb into acount (#15164)

# Objective

I'm building a game where i generate a set of meshes where the transform
is identity, and in each mesh the vertices are offset to where the model
is. When adding visibility ranges to the models i noticed that they only
switched when the distance to the origin changed over the threshold and
all at the same time.

## Solution

I believe that each mesh gets a Aabb generated for use with visibility
testing. So we can use that aabb to calculate a more representative
distance to the mesh.

The code to transform the aabb is taken from the visibility sysyem.

## Testing
I tested the changes locally in my project.

Would you like me to write an example or a test somewhere?
Is there any other code that uses the visibility range, that i should
also update?
This commit is contained in:
Jonathan Nilsson 2024-09-23 22:38:26 +02:00 committed by GitHub
parent 740d1cc9ff
commit 0ebd7fcdf4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -24,6 +24,7 @@ use wgpu::{BufferBindingType, BufferUsages};
use crate::{ use crate::{
camera::Camera, camera::Camera,
primitives::Aabb,
render_resource::BufferVec, render_resource::BufferVec,
renderer::{RenderDevice, RenderQueue}, renderer::{RenderDevice, RenderQueue},
Extract, ExtractSchedule, Render, RenderApp, RenderSet, Extract, ExtractSchedule, Render, RenderApp, RenderSet,
@ -366,7 +367,7 @@ impl VisibleEntityRanges {
pub fn check_visibility_ranges( pub fn check_visibility_ranges(
mut visible_entity_ranges: ResMut<VisibleEntityRanges>, mut visible_entity_ranges: ResMut<VisibleEntityRanges>,
view_query: Query<(Entity, &GlobalTransform), With<Camera>>, view_query: Query<(Entity, &GlobalTransform), With<Camera>>,
mut entity_query: Query<(Entity, &GlobalTransform, &VisibilityRange)>, mut entity_query: Query<(Entity, &GlobalTransform, Option<&Aabb>, &VisibilityRange)>,
) { ) {
visible_entity_ranges.clear(); visible_entity_ranges.clear();
@ -385,12 +386,17 @@ pub fn check_visibility_ranges(
// Check each entity/view pair. Only consider entities with // Check each entity/view pair. Only consider entities with
// [`VisibilityRange`] components. // [`VisibilityRange`] components.
for (entity, entity_transform, visibility_range) in entity_query.iter_mut() { for (entity, entity_transform, maybe_model_aabb, visibility_range) in entity_query.iter_mut() {
let mut visibility = 0; let mut visibility = 0;
for (view_index, &(_, view_position)) in views.iter().enumerate() { for (view_index, &(_, view_position)) in views.iter().enumerate() {
if visibility_range let model_pos = if let Some(model_aabb) = maybe_model_aabb {
.is_visible_at_all((view_position - entity_transform.translation_vec3a()).length()) let world_from_local = entity_transform.affine();
{ world_from_local.transform_point3a(model_aabb.center)
} else {
entity_transform.translation_vec3a()
};
if visibility_range.is_visible_at_all((view_position - model_pos).length()) {
visibility |= 1 << view_index; visibility |= 1 << view_index;
} }
} }