use super::*; use crate::scene; use legion::{Query, World}; use std::sync::{Arc, Mutex, RwLock}; #[derive(Debug, Clone)] pub struct MeshInstance { // TODO put useful data in here mesh: scene::MeshComponent, transform: scene::TransformComponent, } #[derive(Debug, Default)] pub struct FrameData { meshes: Vec, } pub struct MeshPass { world: Arc>, mesh_query: Query<( &'static scene::MeshComponent, &'static scene::TransformComponent, )>, } impl MeshPass { pub fn new(world: Arc>) -> Arc> { let mesh_query = Query::new(); Arc::new(RwLock::new(Self { world, mesh_query })) } } impl RenderPass for MeshPass { type FrameData = FrameData; fn create_frame_data(&mut self) -> FrameData { FrameData::default() } fn begin_frame(&mut self, data: &mut FrameData, phases: &mut PhaseList) { println!("MeshPass::begin_frame()"); phases.insert_pre(PrePhase::VertexSkinning); phases.insert_viewport(ViewportPhase::Depth); phases.insert_viewport(ViewportPhase::Opaque); phases.insert_viewport(ViewportPhase::Transparent); let world = self.world.read().unwrap(); let meshes = Mutex::new(Vec::new()); self.mesh_query.par_for_each_chunk(&*world, |chunk| { let chunk_meshes: Vec = chunk .into_iter() .map(|(mesh, transform)| MeshInstance { mesh: mesh.to_owned(), transform: transform.to_owned(), }) .collect(); meshes.lock().unwrap().extend_from_slice(&chunk_meshes); }); data.meshes = meshes.into_inner().unwrap(); } fn render_pre(&self, phase: PrePhase, data: &FrameData, cmds: &mut gpu::RenderBundleEncoder) { println!("MeshPass::render_pre(phase: {:?})", phase); } fn render_viewport( &self, phase: ViewportPhase, data: &FrameData, viewport: &ViewportData, cmds: &mut gpu::RenderBundleEncoder, ) { println!("MeshPass::render_viewport(phase: {:?})", phase); } }