From b897dc312e46ddb17ab0433666f3b609e5d0df19 Mon Sep 17 00:00:00 2001 From: awtterpip Date: Thu, 14 Mar 2024 18:00:56 -0500 Subject: [PATCH] fix projection --- crates/bevy_xr/src/camera.rs | 45 +++++++++++++++++++++++++++++------- 1 file changed, 37 insertions(+), 8 deletions(-) diff --git a/crates/bevy_xr/src/camera.rs b/crates/bevy_xr/src/camera.rs index 5ffde09..913262b 100644 --- a/crates/bevy_xr/src/camera.rs +++ b/crates/bevy_xr/src/camera.rs @@ -1,41 +1,50 @@ -use bevy::app::{App, Plugin}; +use bevy::app::{App, Plugin, PostUpdate}; use bevy::core_pipeline::core_3d::graph::Core3d; use bevy::core_pipeline::core_3d::Camera3d; use bevy::core_pipeline::tonemapping::{DebandDither, Tonemapping}; use bevy::ecs::bundle::Bundle; use bevy::ecs::component::Component; use bevy::ecs::reflect::ReflectComponent; +use bevy::ecs::schedule::IntoSystemConfigs; use bevy::math::{Mat4, Vec3A}; +use bevy::reflect::std_traits::ReflectDefault; use bevy::reflect::Reflect; use bevy::render::camera::{ Camera, CameraMainTextureUsages, CameraProjection, CameraProjectionPlugin, CameraRenderGraph, Exposure, }; +use bevy::render::extract_component::{ExtractComponent, ExtractComponentPlugin}; use bevy::render::primitives::Frustum; -use bevy::render::view::{ColorGrading, VisibleEntities}; +use bevy::render::view::{update_frusta, ColorGrading, VisibilitySystems, VisibleEntities}; use bevy::transform::components::{GlobalTransform, Transform}; +use bevy::transform::TransformSystem; pub struct XrCameraPlugin; impl Plugin for XrCameraPlugin { fn build(&self, app: &mut App) { app.add_plugins(CameraProjectionPlugin::::default()); + app.add_systems( + PostUpdate, + update_frusta:: + .after(TransformSystem::TransformPropagate) + .before(VisibilitySystems::UpdatePerspectiveFrusta), + ); + app.add_plugins(ExtractComponentPlugin::::default()); } } -#[derive(Clone, Copy, Component, Reflect, Debug)] -#[reflect(Component)] +#[derive(Debug, Clone, Component, Reflect, ExtractComponent)] +#[reflect(Component, Default)] pub struct XrProjection { pub projection_matrix: Mat4, pub near: f32, - pub far: f32, } impl Default for XrProjection { fn default() -> Self { Self { near: 0.1, - far: 1000., projection_matrix: Mat4::IDENTITY, } } @@ -53,12 +62,32 @@ impl CameraProjection for XrProjection { fn update(&mut self, _width: f32, _height: f32) {} fn far(&self) -> f32 { - self.far + let far = self.projection_matrix.to_cols_array()[14] + / (self.projection_matrix.to_cols_array()[10] + 1.0); + + far } // TODO calculate this properly fn get_frustum_corners(&self, _z_near: f32, _z_far: f32) -> [Vec3A; 8] { - Default::default() + let ndc_corners = [ + Vec3A::new(1.0, -1.0, 1.0), // Bottom-right far + Vec3A::new(1.0, 1.0, 1.0), // Top-right far + Vec3A::new(-1.0, 1.0, 1.0), // Top-left far + Vec3A::new(-1.0, -1.0, 1.0), // Bottom-left far + Vec3A::new(1.0, -1.0, -1.0), // Bottom-right near + Vec3A::new(1.0, 1.0, -1.0), // Top-right near + Vec3A::new(-1.0, 1.0, -1.0), // Top-left near + Vec3A::new(-1.0, -1.0, -1.0), // Bottom-left near + ]; + + let mut view_space_corners = [Vec3A::ZERO; 8]; + let inverse_matrix = self.projection_matrix.inverse(); + for (i, corner) in ndc_corners.into_iter().enumerate() { + view_space_corners[i] = inverse_matrix.transform_point3a(corner); + } + + view_space_corners } }