mirror of
https://github.com/bevyengine/bevy
synced 2024-11-10 07:04:33 +00:00
render: intitial VisibleEntities component and sort system
This commit is contained in:
parent
ec11a6a5f6
commit
2f5f6e017a
8 changed files with 158 additions and 9 deletions
|
@ -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"
|
||||
|
|
|
@ -11,9 +11,7 @@ pub struct Camera {
|
|||
pub name: Option<String>,
|
||||
}
|
||||
|
||||
pub fn camera_system<T: CameraProjection + Component>(
|
||||
_resources: &mut Resources,
|
||||
) -> Box<dyn Schedulable> {
|
||||
pub fn camera_system<T: CameraProjection + Component>() -> Box<dyn Schedulable> {
|
||||
let mut window_resized_event_reader = EventReader::<WindowResized>::default();
|
||||
let mut window_created_event_reader = EventReader::<WindowCreated>::default();
|
||||
(move |world: &mut SubWorld,
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
mod camera;
|
||||
mod projection;
|
||||
mod visible_entities;
|
||||
|
||||
pub use camera::*;
|
||||
pub use projection::*;
|
||||
pub use visible_entities::*;
|
||||
|
|
45
crates/bevy_render/src/camera/visible_entities.rs
Normal file
45
crates/bevy_render/src/camera/visible_entities.rs
Normal file
|
@ -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<VisibleEntity>,
|
||||
}
|
||||
|
||||
pub fn visible_entities_system(
|
||||
world: &mut SubWorld,
|
||||
camera_query: &mut Query<(Read<Camera>, Read<Transform>, Write<VisibleEntities>)>,
|
||||
entities_query: &mut Query<(Read<Draw>, Read<Transform>)>,
|
||||
) {
|
||||
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
|
||||
}
|
||||
}
|
|
@ -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<T: Default + Send + Sync + 'static> {
|
|||
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(),
|
||||
|
|
|
@ -95,13 +95,18 @@ impl AppPlugin for RenderPlugin {
|
|||
.init_resource::<TextureResourceSystemState>()
|
||||
.init_resource::<AssetRenderResourceBindings>()
|
||||
.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::<OrthographicProjection>,
|
||||
camera::camera_system::<OrthographicProjection>(),
|
||||
)
|
||||
.init_system_to_stage(
|
||||
.add_system_to_stage(
|
||||
bevy_app::stage::POST_UPDATE,
|
||||
camera::camera_system::<PerspectiveProjection>,
|
||||
camera::camera_system::<PerspectiveProjection>(),
|
||||
)
|
||||
// registration order matters here. this must come after all camera_system::<T> 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)
|
||||
|
|
90
examples/3d/z_sort_debug.rs
Normal file
90
examples/3d/z_sort_debug.rs
Normal file
|
@ -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<Time>, _rotator: ComMut<Rotator>, mut rotation: ComMut<Rotation>) {
|
||||
rotation.0 = rotation.0 * Quat::from_rotation_x(3.0 * time.delta_seconds);
|
||||
}
|
||||
|
||||
fn camera_order_color_system(
|
||||
world: &mut SubWorld,
|
||||
camera_query: &mut Query<(Read<Camera>, Read<VisibleEntities>)>,
|
||||
_material_query: &mut Query<Write<StandardMaterial>>,
|
||||
) {
|
||||
for (_camera, visible_entities) in camera_query.iter(world) {
|
||||
for visible_entity in visible_entities.value.iter() {
|
||||
println!("visible_entity: {:?}", visible_entity.order);
|
||||
// let mut material = world.get_component_mut::<StandardMaterial>(visible_entity.entity).unwrap();
|
||||
// println!("entity {:?}", visible_entity.order);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// set up a simple scene with a "parent" cube and a "child" cube
|
||||
fn setup(
|
||||
command_buffer: &mut CommandBuffer,
|
||||
mut meshes: ResMut<Assets<Mesh>>,
|
||||
mut materials: ResMut<Assets<StandardMaterial>>,
|
||||
) {
|
||||
let cube_handle = meshes.add(Mesh::from(shape::Cube { size: 1.0 }));
|
||||
|
||||
command_buffer
|
||||
.build()
|
||||
// parent cube
|
||||
.add_entity(MeshEntity {
|
||||
mesh: cube_handle,
|
||||
material: materials.add(StandardMaterial {
|
||||
shaded: false,
|
||||
..Default::default()
|
||||
}),
|
||||
translation: Translation::new(0.0, 0.0, 1.0),
|
||||
..Default::default()
|
||||
})
|
||||
.add(Rotator)
|
||||
.add_children(|builder| {
|
||||
// child cubes
|
||||
builder
|
||||
.add_entity(MeshEntity {
|
||||
mesh: cube_handle,
|
||||
material: materials.add(StandardMaterial {
|
||||
shaded: false,
|
||||
..Default::default()
|
||||
}),
|
||||
translation: Translation::new(0.0, 0.0, 3.0),
|
||||
..Default::default()
|
||||
})
|
||||
.add_entity(MeshEntity {
|
||||
mesh: cube_handle,
|
||||
material: materials.add(StandardMaterial {
|
||||
shaded: false,
|
||||
..Default::default()
|
||||
}),
|
||||
translation: Translation::new(0.0, 0.0, -3.0),
|
||||
..Default::default()
|
||||
})
|
||||
})
|
||||
// light
|
||||
.add_entity(LightEntity {
|
||||
translation: Translation::new(4.0, -4.0, 5.0),
|
||||
..Default::default()
|
||||
})
|
||||
// camera
|
||||
.add_entity(PerspectiveCameraEntity {
|
||||
transform: Transform::new_sync_disabled(Mat4::look_at_rh(
|
||||
Vec3::new(5.0, 10.0, 10.0),
|
||||
Vec3::new(0.0, 0.0, 0.0),
|
||||
Vec3::new(0.0, 0.0, 1.0),
|
||||
)),
|
||||
..Default::default()
|
||||
});
|
||||
}
|
|
@ -28,7 +28,7 @@ pub use crate::{
|
|||
render_resource::RenderResources,
|
||||
shader::{Shader, ShaderDefs, ShaderStage, ShaderStages},
|
||||
texture::Texture,
|
||||
Camera, Color, ColorSource, OrthographicProjection, PerspectiveProjection,
|
||||
Camera, Color, ColorSource, OrthographicProjection, PerspectiveProjection, VisibleEntities
|
||||
},
|
||||
scene::{Scene, SceneSpawner},
|
||||
sprite::{
|
||||
|
|
Loading…
Reference in a new issue