mirror of
https://github.com/bevyengine/bevy
synced 2025-02-16 14:08:32 +00:00
camera: break out projection components
This commit is contained in:
parent
db27d63b91
commit
fec9034644
11 changed files with 45 additions and 87 deletions
|
@ -1,4 +1,4 @@
|
|||
use bevy_render::{Color, PerspectiveCamera};
|
||||
use bevy_render::{Color, PerspectiveCamera, CameraProjection};
|
||||
use bevy_transform::components::Translation;
|
||||
use bevy_property::Properties;
|
||||
use glam::Mat4;
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
use bevy_app::{Events, GetEventReader};
|
||||
use bevy_property::{Properties, Property};
|
||||
use bevy_property::Properties;
|
||||
use bevy_window::WindowResized;
|
||||
use glam::Mat4;
|
||||
use legion::prelude::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use legion::{prelude::*, storage::Component};
|
||||
|
||||
#[derive(Default, Properties)]
|
||||
pub struct ActiveCamera;
|
||||
|
@ -11,7 +10,7 @@ pub struct ActiveCamera;
|
|||
#[derive(Default, Properties)]
|
||||
pub struct ActiveCamera2d;
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Properties)]
|
||||
pub struct OrthographicCamera {
|
||||
pub left: f32,
|
||||
pub right: f32,
|
||||
|
@ -21,7 +20,7 @@ pub struct OrthographicCamera {
|
|||
pub far: f32,
|
||||
}
|
||||
|
||||
impl OrthographicCamera {
|
||||
impl CameraProjection for OrthographicCamera {
|
||||
fn get_view_matrix(&self) -> Mat4 {
|
||||
let projection = Mat4::orthographic_rh_gl(
|
||||
self.left,
|
||||
|
@ -33,6 +32,10 @@ impl OrthographicCamera {
|
|||
);
|
||||
projection
|
||||
}
|
||||
fn update(&mut self, width: usize, height: usize) {
|
||||
self.right = width as f32;
|
||||
self.top = height as f32;
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for OrthographicCamera {
|
||||
|
@ -48,7 +51,12 @@ impl Default for OrthographicCamera {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub trait CameraProjection {
|
||||
fn get_view_matrix(&self) -> Mat4;
|
||||
fn update(&mut self, width: usize, height: usize);
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Properties)]
|
||||
pub struct PerspectiveCamera {
|
||||
pub fov: f32,
|
||||
pub aspect_ratio: f32,
|
||||
|
@ -56,11 +64,14 @@ pub struct PerspectiveCamera {
|
|||
pub far: f32,
|
||||
}
|
||||
|
||||
impl PerspectiveCamera {
|
||||
pub fn get_view_matrix(&self) -> Mat4 {
|
||||
impl CameraProjection for PerspectiveCamera {
|
||||
fn get_view_matrix(&self) -> Mat4 {
|
||||
let projection = Mat4::perspective_rh_gl(self.fov, self.aspect_ratio, self.near, self.far);
|
||||
projection
|
||||
}
|
||||
fn update(&mut self, width: usize, height: usize) {
|
||||
self.aspect_ratio = width as f32 / height as f32;
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for PerspectiveCamera {
|
||||
|
@ -74,72 +85,24 @@ impl Default for PerspectiveCamera {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Property)]
|
||||
pub enum CameraType {
|
||||
Perspective(PerspectiveCamera),
|
||||
Orthographic(OrthographicCamera),
|
||||
}
|
||||
|
||||
impl CameraType {
|
||||
pub fn default_perspective() -> CameraType {
|
||||
CameraType::Perspective(PerspectiveCamera::default())
|
||||
}
|
||||
|
||||
pub fn default_orthographic() -> CameraType {
|
||||
CameraType::Orthographic(OrthographicCamera::default())
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for CameraType {
|
||||
fn default() -> Self {
|
||||
CameraType::default_perspective()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Properties)]
|
||||
pub struct Camera {
|
||||
pub view_matrix: Mat4,
|
||||
pub camera_type: CameraType,
|
||||
}
|
||||
|
||||
impl Camera {
|
||||
pub fn new(camera_type: CameraType) -> Self {
|
||||
Camera {
|
||||
view_matrix: Mat4::identity(),
|
||||
camera_type,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn update(&mut self, width: u32, height: u32) {
|
||||
self.view_matrix = match &mut self.camera_type {
|
||||
CameraType::Perspective(projection) => {
|
||||
projection.aspect_ratio = width as f32 / height as f32;
|
||||
projection.get_view_matrix()
|
||||
}
|
||||
CameraType::Orthographic(orthographic) => {
|
||||
orthographic.right = width as f32;
|
||||
orthographic.top = height as f32;
|
||||
orthographic.get_view_matrix()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn camera_update_system(resources: &mut Resources) -> Box<dyn Schedulable> {
|
||||
pub fn camera_system<T: CameraProjection + Component>(resources: &mut Resources) -> Box<dyn Schedulable> {
|
||||
let mut window_resized_event_reader = resources.get_event_reader::<WindowResized>();
|
||||
(move |world: &mut SubWorld,
|
||||
window_resized_events: Res<Events<WindowResized>>,
|
||||
query: &mut Query<Write<Camera>>| {
|
||||
query: &mut Query<(Write<Camera>, Write<T>)>| {
|
||||
let primary_window_resized_event = window_resized_event_reader
|
||||
.find_latest(&window_resized_events, |event| event.is_primary);
|
||||
if let Some(primary_window_resized_event) = primary_window_resized_event {
|
||||
for mut camera in query.iter_mut(world) {
|
||||
camera.update(
|
||||
primary_window_resized_event.width,
|
||||
primary_window_resized_event.height,
|
||||
);
|
||||
for (mut camera, mut camera_projection) in query.iter_mut(world) {
|
||||
camera_projection.update(primary_window_resized_event.width, primary_window_resized_event.height);
|
||||
camera.view_matrix = camera_projection.get_view_matrix();
|
||||
}
|
||||
}
|
||||
})
|
||||
.system()
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
use crate::{mesh::Mesh, ActiveCamera, ActiveCamera2d, Camera, CameraType, Renderable};
|
||||
use crate::{mesh::Mesh, ActiveCamera, ActiveCamera2d, Camera, Renderable, OrthographicCamera, PerspectiveCamera};
|
||||
use bevy_asset::Handle;
|
||||
use bevy_derive::EntityArchetype;
|
||||
use bevy_transform::components::{LocalToWorld, Rotation, Scale, Translation};
|
||||
|
@ -17,21 +17,14 @@ pub struct MeshMaterialEntity<T: Default + Send + Sync + 'static> {
|
|||
#[derive(EntityArchetype, Default)]
|
||||
pub struct CameraEntity {
|
||||
pub camera: Camera,
|
||||
pub perspective_camera: PerspectiveCamera,
|
||||
pub active_camera: ActiveCamera,
|
||||
pub local_to_world: LocalToWorld,
|
||||
}
|
||||
|
||||
#[derive(EntityArchetype)]
|
||||
pub struct Camera2dEntity {
|
||||
#[derive(EntityArchetype, Default)]
|
||||
pub struct OrthographicCameraEntity {
|
||||
pub camera: Camera,
|
||||
pub orthographic_camera: OrthographicCamera,
|
||||
pub active_camera_2d: ActiveCamera2d,
|
||||
}
|
||||
|
||||
impl Default for Camera2dEntity {
|
||||
fn default() -> Self {
|
||||
Camera2dEntity {
|
||||
camera: Camera::new(CameraType::default_orthographic()),
|
||||
active_camera_2d: ActiveCamera2d,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -76,11 +76,12 @@ impl AppPlugin for RenderPlugin {
|
|||
.add_asset::<PipelineDescriptor>()
|
||||
.add_asset_loader::<Texture, PngTextureLoader>()
|
||||
.register_component::<Camera>()
|
||||
.register_component::<OrthographicCamera>()
|
||||
.register_component::<PerspectiveCamera>()
|
||||
.register_component::<Renderable>()
|
||||
.register_component::<ActiveCamera>()
|
||||
.register_component::<ActiveCamera2d>()
|
||||
.register_property_type::<Color>()
|
||||
.register_property_type::<CameraType>()
|
||||
.register_property_type::<Range<f32>>()
|
||||
.init_resource::<RenderGraph>()
|
||||
.init_resource::<PipelineAssignments>()
|
||||
|
@ -91,7 +92,8 @@ impl AppPlugin for RenderPlugin {
|
|||
.init_resource::<EntitiesWaitingForAssets>()
|
||||
.init_resource::<TextureResourceSystemState>()
|
||||
.add_system(entity_render_resource_assignments_system())
|
||||
.init_system_to_stage(stage::POST_UPDATE, camera::camera_update_system)
|
||||
.init_system_to_stage(stage::POST_UPDATE, camera::camera_system::<OrthographicCamera>)
|
||||
.init_system_to_stage(stage::POST_UPDATE, camera::camera_system::<PerspectiveCamera>)
|
||||
.add_system_to_stage(
|
||||
stage::PRE_UPDATE,
|
||||
EntitiesWaitingForAssets::clear_system.system(),
|
||||
|
|
|
@ -4,8 +4,8 @@ use super::{WindowDescriptor, WindowId};
|
|||
#[derive(Debug, Clone)]
|
||||
pub struct WindowResized {
|
||||
pub id: WindowId,
|
||||
pub width: u32,
|
||||
pub height: u32,
|
||||
pub width: usize,
|
||||
pub height: usize,
|
||||
pub is_primary: bool,
|
||||
}
|
||||
|
||||
|
|
|
@ -73,8 +73,8 @@ pub fn winit_runner(mut app: App) {
|
|||
let mut resize_events = app.resources.get_mut::<Events<WindowResized>>().unwrap();
|
||||
resize_events.send(WindowResized {
|
||||
id: window_id,
|
||||
height: window.height,
|
||||
width: window.width,
|
||||
height: window.height as usize,
|
||||
width: window.width as usize,
|
||||
is_primary: windows.is_primary(window_id),
|
||||
});
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ fn setup(
|
|||
let texture_handle = asset_server.load("assets/branding/icon.png").unwrap();
|
||||
command_buffer
|
||||
.build()
|
||||
.add_entity(Camera2dEntity::default())
|
||||
.add_entity(OrthographicCameraEntity::default())
|
||||
.add_entity(SpriteEntity {
|
||||
rect: Rect {
|
||||
position: Vec2::new(300.0, 300.0),
|
||||
|
|
|
@ -25,7 +25,7 @@ fn setup(command_buffer: &mut CommandBuffer, asset_server: Res<AssetServer>) {
|
|||
command_buffer
|
||||
.build()
|
||||
// 2d camera
|
||||
.add_entity(Camera2dEntity::default())
|
||||
.add_entity(OrthographicCameraEntity::default())
|
||||
// texture
|
||||
.add_entity(LabelEntity {
|
||||
node: Node::new(
|
||||
|
|
|
@ -58,7 +58,7 @@ fn setup(
|
|||
// ..Default::default()
|
||||
// })
|
||||
// 2d camera
|
||||
.add_entity(Camera2dEntity::default())
|
||||
.add_entity(OrthographicCameraEntity::default())
|
||||
// left vertical fill
|
||||
.add_entity(UiEntity {
|
||||
node: Node::new(
|
||||
|
|
|
@ -23,7 +23,7 @@ fn placement_system(
|
|||
|
||||
fn setup(command_buffer: &mut CommandBuffer, mut materials: ResMut<Assets<ColorMaterial>>) {
|
||||
let mut builder = command_buffer.build();
|
||||
builder.add_entity(Camera2dEntity::default());
|
||||
builder.add_entity(OrthographicCameraEntity::default());
|
||||
|
||||
let mut prev = Vec2::default();
|
||||
let count = 1000;
|
||||
|
|
|
@ -30,7 +30,7 @@ pub use crate::render::{
|
|||
render_resource::resource_name,
|
||||
shader::{Shader, ShaderDefSuffixProvider, ShaderStage, ShaderStages},
|
||||
texture::{Texture, TextureType},
|
||||
ActiveCamera, ActiveCamera2d, Camera, CameraType, Color, ColorSource, Renderable,
|
||||
ActiveCamera, ActiveCamera2d, Camera, OrthographicCamera, PerspectiveCamera, Color, ColorSource, Renderable,
|
||||
};
|
||||
#[cfg(feature = "scene")]
|
||||
pub use crate::scene::{Scene, SceneSpawner};
|
||||
|
|
Loading…
Add table
Reference in a new issue