pub mod camera; pub mod render; mod tacmap { pub use super::render; pub use super::camera; } use std::cell::RefCell; use std::time::Duration; use winit::event::ElementState; use winit::keyboard::KeyCode; use crate::GameState; use crate::canvas::Canvas; use crate::solar_system::SolarSystem; use crate::solar_system::SystemId; use crate::timeman::TimeMan; use crate::ui; use crate::wgpuctx::RenderPassBuilder; use crate::wgpuctx::SceneCtx; use crate::wgpuctx::WgpuCtx; use render::*; use camera::*; pub struct TacticalMap { canvas: Canvas, camera: Camera, pmatrix: Projection, camera_controller: CameraController, system_for_render: Option, body_renderer: BodyRenderer, grid_renderer: GridRenderer, orbit_renderer: OrbitRenderer } impl TacticalMap { pub fn new( wgpuctx: &WgpuCtx, position: winit::dpi::LogicalPosition, size: winit::dpi::LogicalSize) -> Self { let surface_size = winit::dpi::PhysicalSize::new( wgpuctx.surface_config().width, wgpuctx.surface_config().height ); let canvas = Canvas::new( wgpuctx, surface_size, position, size).unwrap(); let camera = Camera::new( wgpuctx, cgmath::Vector3::new(0.0, 0.0, 1.0), cgmath::Deg(0.0), cgmath::Rad(0.0)); let projection = Projection::new( surface_size.width, surface_size.height, cgmath::Deg(60.0), (0.01, 1000.0)); Self { canvas: canvas, camera: camera, pmatrix: projection, camera_controller: CameraController::new(), system_for_render: None, body_renderer: BodyRenderer::new(wgpuctx), grid_renderer: GridRenderer::new(wgpuctx), orbit_renderer: OrbitRenderer::new(wgpuctx), } } pub fn resize( &mut self, wgpuctx: &WgpuCtx, width: u32, height: u32) { self.canvas.resize(wgpuctx, width, height); self.pmatrix.resize(width, height); } pub fn update( &mut self, solar_system: &SolarSystem, ui_state: &mut ui::State, dt: Duration) { ui_state.camera_info.camera_scale = self.camera.get_scale(); ui_state.camera_info.camera_pos = Some(self.camera.get_abs_position()); ui_state.camera_info.camera_rot = Some(self.camera.get_rotation()); self.camera.set_target(ui_state.camera_info.target); self.camera_controller.update(&mut self.camera, solar_system, ui_state, dt); } pub fn keyboard_input( &mut self, key_code: KeyCode, key_state: ElementState) { self.camera_controller.keyboard_input(key_code, key_state); } pub fn draw( &mut self, wgpuctx: &WgpuCtx, solar_system: &SolarSystem, timeman: &TimeMan, ) -> Result<(), wgpu::SurfaceError> { self.camera.update_buffer(wgpuctx, &self.pmatrix); if self.system_for_render.is_none() || self.system_for_render.unwrap() != solar_system.id() { self.body_renderer.mark_to_rebuild(); self.orbit_renderer.mark_to_rebuild(); } self.system_for_render = Some(solar_system.id()); //Update buffers for the current system and time. self.body_renderer.rebuild(wgpuctx, solar_system); self.orbit_renderer.rebuild(wgpuctx, solar_system); self.orbit_renderer.update(wgpuctx, solar_system, timeman.seconds()); match self.body_renderer.update( wgpuctx, solar_system, timeman.seconds()) { Ok(()) => {}, Err(e) => println!("Tactical map render update error: {}", e) } let mut scene = SceneCtx::from_view_default(wgpuctx, self.canvas.view(), Some("Tactical map scene")); let pass_builder = RenderPassBuilder::new(Some("Tactical map render pass"), scene.view()) .clear_color(wgpu::Color { r: 0.0, g: 0.0, b: 0.1, a: 1.0 }); self.camera.stage_changes(scene.encoder_mut()); { let mut pass = pass_builder.build_from_scene(&mut scene); self.grid_renderer.render(&mut pass, &self.camera); self.orbit_renderer.render(&mut pass, &self.camera); self.body_renderer.render(&mut pass, &self.camera); } scene.submit(wgpuctx); Ok(()) } pub fn present( &mut self, screen_pass: &mut wgpu::RenderPass) -> Result<(), wgpu::SurfaceError> { self.canvas.present(screen_pass)?; Ok(()) } } // impl SystemViewport