From 2f5f6e017a03daa4cb126dee2ca244d51cb3e271 Mon Sep 17 00:00:00 2001 From: Carter Anderson Date: Mon, 22 Jun 2020 17:55:48 -0700 Subject: [PATCH] render: intitial VisibleEntities component and sort system --- Cargo.toml | 4 + crates/bevy_render/src/camera/camera.rs | 4 +- crates/bevy_render/src/camera/mod.rs | 2 + .../src/camera/visible_entities.rs | 45 ++++++++++ crates/bevy_render/src/entity.rs | 7 +- crates/bevy_render/src/lib.rs | 13 ++- examples/3d/z_sort_debug.rs | 90 +++++++++++++++++++ src/prelude.rs | 2 +- 8 files changed, 158 insertions(+), 9 deletions(-) create mode 100644 crates/bevy_render/src/camera/visible_entities.rs create mode 100644 examples/3d/z_sort_debug.rs diff --git a/Cargo.toml b/Cargo.toml index 7d44414ec1..c4f68592f5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -87,6 +87,10 @@ path = "examples/3d/spawner.rs" name = "texture" path = "examples/3d/texture.rs" +[[example]] +name = "z_sort_debug" +path = "examples/3d/z_sort_debug.rs" + [[example]] name = "dynamic_plugin_loading" path = "examples/app/dynamic_plugin_loading/main.rs" diff --git a/crates/bevy_render/src/camera/camera.rs b/crates/bevy_render/src/camera/camera.rs index 5589e1a3d8..cb3375fd6f 100644 --- a/crates/bevy_render/src/camera/camera.rs +++ b/crates/bevy_render/src/camera/camera.rs @@ -11,9 +11,7 @@ pub struct Camera { pub name: Option, } -pub fn camera_system( - _resources: &mut Resources, -) -> Box { +pub fn camera_system() -> Box { let mut window_resized_event_reader = EventReader::::default(); let mut window_created_event_reader = EventReader::::default(); (move |world: &mut SubWorld, diff --git a/crates/bevy_render/src/camera/mod.rs b/crates/bevy_render/src/camera/mod.rs index 125dab0f86..ef6647284c 100644 --- a/crates/bevy_render/src/camera/mod.rs +++ b/crates/bevy_render/src/camera/mod.rs @@ -1,5 +1,7 @@ mod camera; mod projection; +mod visible_entities; pub use camera::*; pub use projection::*; +pub use visible_entities::*; diff --git a/crates/bevy_render/src/camera/visible_entities.rs b/crates/bevy_render/src/camera/visible_entities.rs new file mode 100644 index 0000000000..a53a369c0f --- /dev/null +++ b/crates/bevy_render/src/camera/visible_entities.rs @@ -0,0 +1,45 @@ +use crate::{draw::Draw, Camera}; +use bevy_core::float_ord::FloatOrd; +use bevy_transform::prelude::Transform; +use legion::{ + entity::Entity, + prelude::{Read, Write}, + systems::{Query, SubWorld}, +}; + +pub struct VisibleEntity { + pub entity: Entity, + pub order: FloatOrd, +} + +#[derive(Default)] +pub struct VisibleEntities { + pub value: Vec, +} + +pub fn visible_entities_system( + world: &mut SubWorld, + camera_query: &mut Query<(Read, Read, Write)>, + entities_query: &mut Query<(Read, Read)>, +) { + for (_camera, camera_transform, mut visible_entities) in camera_query.iter_mut(world) { + visible_entities.value.clear(); + let camera_position = camera_transform.value.w_axis().truncate(); + + for (entity, (draw, transform)) in entities_query.iter_entities(world) { + if !draw.is_visible { + continue; + } + + let position = transform.value.w_axis().truncate(); + visible_entities.value.push(VisibleEntity { + entity, + order: FloatOrd((camera_position - position).length()), + }) + } + + visible_entities.value.sort_by_key(|e| e.order) + + // TODO: check for big changes in visible entities len() vs capacity() (ex: 2x) and resize to prevent holding unneeded memory + } +} diff --git a/crates/bevy_render/src/entity.rs b/crates/bevy_render/src/entity.rs index bf7a2b9d21..49ae1a374a 100644 --- a/crates/bevy_render/src/entity.rs +++ b/crates/bevy_render/src/entity.rs @@ -1,6 +1,6 @@ use crate::{ base_render_graph, draw::Draw, mesh::Mesh, pipeline::RenderPipelines, Camera, - OrthographicProjection, PerspectiveProjection, WindowOrigin, + OrthographicProjection, PerspectiveProjection, WindowOrigin, VisibleEntities, }; use bevy_asset::Handle; use bevy_derive::EntityArchetype; @@ -22,6 +22,7 @@ pub struct MeshMaterialEntity { pub struct PerspectiveCameraEntity { pub camera: Camera, pub perspective_projection: PerspectiveProjection, + pub visible_entities: VisibleEntities, pub transform: Transform, pub translation: Translation, pub rotation: Rotation, @@ -36,6 +37,7 @@ impl Default for PerspectiveCameraEntity { ..Default::default() }, perspective_projection: Default::default(), + visible_entities: Default::default(), transform: Default::default(), translation: Default::default(), rotation: Default::default(), @@ -48,6 +50,7 @@ impl Default for PerspectiveCameraEntity { pub struct OrthographicCameraEntity { pub camera: Camera, pub orthographic_projection: OrthographicProjection, + pub visible_entities: VisibleEntities, pub transform: Transform, pub translation: Translation, pub rotation: Rotation, @@ -65,6 +68,7 @@ impl OrthographicCameraEntity { window_origin: WindowOrigin::BottomLeft, ..Default::default() }, + visible_entities: Default::default(), transform: Default::default(), translation: Default::default(), rotation: Default::default(), @@ -81,6 +85,7 @@ impl Default for OrthographicCameraEntity { ..Default::default() }, orthographic_projection: Default::default(), + visible_entities: Default::default(), transform: Default::default(), translation: Default::default(), rotation: Default::default(), diff --git a/crates/bevy_render/src/lib.rs b/crates/bevy_render/src/lib.rs index c65801521b..56d5570749 100644 --- a/crates/bevy_render/src/lib.rs +++ b/crates/bevy_render/src/lib.rs @@ -95,13 +95,18 @@ impl AppPlugin for RenderPlugin { .init_resource::() .init_resource::() .add_system_to_stage(bevy_app::stage::PRE_UPDATE, clear_draw_system.system()) - .init_system_to_stage( + .add_system_to_stage( bevy_app::stage::POST_UPDATE, - camera::camera_system::, + camera::camera_system::(), ) - .init_system_to_stage( + .add_system_to_stage( bevy_app::stage::POST_UPDATE, - camera::camera_system::, + camera::camera_system::(), + ) + // registration order matters here. this must come after all camera_system:: systems + .add_system_to_stage( + bevy_app::stage::POST_UPDATE, + visible_entities_system.system(), ) // TODO: turn these "resource systems" into graph nodes and remove the RENDER_RESOURCE stage .init_system_to_stage(stage::RENDER_RESOURCE, mesh_resource_provider_system) diff --git a/examples/3d/z_sort_debug.rs b/examples/3d/z_sort_debug.rs new file mode 100644 index 0000000000..8108e56f86 --- /dev/null +++ b/examples/3d/z_sort_debug.rs @@ -0,0 +1,90 @@ +use bevy::prelude::*; + +struct Rotator; + +fn main() { + App::build() + .add_default_plugins() + .add_startup_system(setup.system()) + .add_system(rotator_system.system()) + .add_system(camera_order_color_system.system()) + .run(); +} + +/// rotates the parent, which will result in the child also rotating +fn rotator_system(time: Res