CameraProjection::compute_frustum (#11139)
Frustum computation is nontrivial amount of code private in `update_frusta` system. Make it public. This is needed to decide which entities to spawn/despawn in `Update` based on camera changes. But if `Update` also changed camera, frustum is not yet recomputed. Technically it is probably possible to run an iteration of `update_frusta` system by a user in `Update` schedule after propagating `GlobalTransform` to the cameras, but it is easier to just compute frustum manually using API added in this PR. Also replace two places where this code is used. --------- Co-authored-by: vero <email@atlasdostal.com>
This commit is contained in:
parent
1974723a63
commit
08654ad8d8
@ -45,14 +45,7 @@ impl Default for Camera2dBundle {
|
|||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
let transform = Transform::default();
|
let transform = Transform::default();
|
||||||
let view_projection =
|
let frustum = projection.compute_frustum(&GlobalTransform::from(transform));
|
||||||
projection.get_projection_matrix() * transform.compute_matrix().inverse();
|
|
||||||
let frustum = Frustum::from_view_projection_custom_far(
|
|
||||||
&view_projection,
|
|
||||||
&transform.translation,
|
|
||||||
&transform.back(),
|
|
||||||
projection.far(),
|
|
||||||
);
|
|
||||||
Self {
|
Self {
|
||||||
camera_render_graph: CameraRenderGraph::new(SubGraph2d),
|
camera_render_graph: CameraRenderGraph::new(SubGraph2d),
|
||||||
projection,
|
projection,
|
||||||
@ -84,14 +77,7 @@ impl Camera2dBundle {
|
|||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
let transform = Transform::from_xyz(0.0, 0.0, far - 0.1);
|
let transform = Transform::from_xyz(0.0, 0.0, far - 0.1);
|
||||||
let view_projection =
|
let frustum = projection.compute_frustum(&GlobalTransform::from(transform));
|
||||||
projection.get_projection_matrix() * transform.compute_matrix().inverse();
|
|
||||||
let frustum = Frustum::from_view_projection_custom_far(
|
|
||||||
&view_projection,
|
|
||||||
&transform.translation,
|
|
||||||
&transform.back(),
|
|
||||||
projection.far(),
|
|
||||||
);
|
|
||||||
Self {
|
Self {
|
||||||
camera_render_graph: CameraRenderGraph::new(SubGraph3d),
|
camera_render_graph: CameraRenderGraph::new(SubGraph3d),
|
||||||
projection,
|
projection,
|
||||||
|
|||||||
@ -1,12 +1,14 @@
|
|||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::ops::{Div, DivAssign, Mul, MulAssign};
|
use std::ops::{Div, DivAssign, Mul, MulAssign};
|
||||||
|
|
||||||
|
use crate::primitives::Frustum;
|
||||||
use bevy_app::{App, Plugin, PostStartup, PostUpdate};
|
use bevy_app::{App, Plugin, PostStartup, PostUpdate};
|
||||||
use bevy_ecs::{prelude::*, reflect::ReflectComponent};
|
use bevy_ecs::{prelude::*, reflect::ReflectComponent};
|
||||||
use bevy_math::{AspectRatio, Mat4, Rect, Vec2, Vec3A};
|
use bevy_math::{AspectRatio, Mat4, Rect, Vec2, Vec3A};
|
||||||
use bevy_reflect::{
|
use bevy_reflect::{
|
||||||
std_traits::ReflectDefault, GetTypeRegistration, Reflect, ReflectDeserialize, ReflectSerialize,
|
std_traits::ReflectDefault, GetTypeRegistration, Reflect, ReflectDeserialize, ReflectSerialize,
|
||||||
};
|
};
|
||||||
|
use bevy_transform::components::GlobalTransform;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
/// Adds [`Camera`](crate::camera::Camera) driver systems for a given projection type.
|
/// Adds [`Camera`](crate::camera::Camera) driver systems for a given projection type.
|
||||||
@ -60,6 +62,21 @@ pub trait CameraProjection {
|
|||||||
fn update(&mut self, width: f32, height: f32);
|
fn update(&mut self, width: f32, height: f32);
|
||||||
fn far(&self) -> f32;
|
fn far(&self) -> f32;
|
||||||
fn get_frustum_corners(&self, z_near: f32, z_far: f32) -> [Vec3A; 8];
|
fn get_frustum_corners(&self, z_near: f32, z_far: f32) -> [Vec3A; 8];
|
||||||
|
|
||||||
|
/// Compute camera frustum for camera with given projection and transform.
|
||||||
|
///
|
||||||
|
/// This code is called by [`update_frusta`](crate::view::visibility::update_frusta) system
|
||||||
|
/// for each camera to update its frustum.
|
||||||
|
fn compute_frustum(&self, camera_transform: &GlobalTransform) -> Frustum {
|
||||||
|
let view_projection =
|
||||||
|
self.get_projection_matrix() * camera_transform.compute_matrix().inverse();
|
||||||
|
Frustum::from_view_projection_custom_far(
|
||||||
|
&view_projection,
|
||||||
|
&camera_transform.translation(),
|
||||||
|
&camera_transform.back(),
|
||||||
|
self.far(),
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A configurable [`CameraProjection`] that can select its projection type at runtime.
|
/// A configurable [`CameraProjection`] that can select its projection type at runtime.
|
||||||
|
|||||||
@ -281,14 +281,7 @@ pub fn update_frusta<T: Component + CameraProjection + Send + Sync + 'static>(
|
|||||||
>,
|
>,
|
||||||
) {
|
) {
|
||||||
for (transform, projection, mut frustum) in &mut views {
|
for (transform, projection, mut frustum) in &mut views {
|
||||||
let view_projection =
|
*frustum = projection.compute_frustum(transform);
|
||||||
projection.get_projection_matrix() * transform.compute_matrix().inverse();
|
|
||||||
*frustum = Frustum::from_view_projection_custom_far(
|
|
||||||
&view_projection,
|
|
||||||
&transform.translation(),
|
|
||||||
&transform.back(),
|
|
||||||
projection.far(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user