use bevy::prelude::*; use bevy::render::camera::{Camera, CameraProjection}; use bevy::render::view::visibility::*; use bevy::render::primitives::Frustum; use bevy::render::view::VisibleEntities; use bevy::math::Mat4; use crate::screeninfo::ScreenInfo; use crate::viewer::*; use crate::projection::*; #[derive(Component, Debug, Clone, Reflect)] #[reflect(Component, Default)] pub struct OffAxisProjection { pub far: f32, pub projection_matrix: Mat4 } impl CameraProjection for OffAxisProjection { fn get_projection_matrix(&self) -> Mat4 { self.projection_matrix } // what to do on window resize fn update(&mut self, width: f32, height: f32) { // extract sx and sy from matrix // let sx = self.projection_matrix.x_axis.x; // let sy = self.projection_matrix.y_axis.y; } fn far(&self) -> f32 { self.far } } impl Default for OffAxisProjection { fn default() -> Self { Self { far: 1000.0, projection_matrix: make_projection_rh_custom( 45.0f32.to_radians(), 1.3f32, 1.0, 1000.0) } } } pub fn offaxis_camera_setup(mut commands: Commands) { let projection = OffAxisProjection::default(); // let projection = PerspectiveProjection::default(); // position the camera like bevy would do by default for 2D: let transform = Transform::from_xyz(0.0, 0.0, 0.1); // frustum construction code copied from Bevy let view_projection = projection.get_projection_matrix() * transform.compute_matrix().inverse(); let frustum = Frustum::from_view_projection( &view_projection, &transform.translation, &transform.back(), projection.far, ); commands.spawn(( bevy::render::camera::CameraRenderGraph::new(bevy::core_pipeline::core_3d::graph::NAME), projection, frustum, NoFrustumCulling, transform, GlobalTransform::default(), VisibleEntities::default(), Camera::default(), Camera3d::default(), ScreenInfo::new("Test"), Viewer::new(transform.translation) )); }