render: intitial VisibleEntities component and sort system
This commit is contained in:
		
							parent
							
								
									ec11a6a5f6
								
							
						
					
					
						commit
						2f5f6e017a
					
				@ -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 New Issue
	
	Block a user