render: intitial VisibleEntities component and sort system

This commit is contained in:
Carter Anderson 2020-06-22 17:55:48 -07:00
parent ec11a6a5f6
commit 2f5f6e017a
8 changed files with 158 additions and 9 deletions

View file

@ -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"

View file

@ -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,

View file

@ -1,5 +1,7 @@
mod camera;
mod projection;
mod visible_entities;
pub use camera::*;
pub use projection::*;
pub use visible_entities::*;

View 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
}
}

View file

@ -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(),

View file

@ -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)

View 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()
});
}

View file

@ -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::{