diff options
Diffstat (limited to 'src/tacmap')
| -rw-r--r-- | src/tacmap/body_render.rs | 24 | ||||
| -rw-r--r-- | src/tacmap/camera.rs | 6 | ||||
| -rw-r--r-- | src/tacmap/orbit_render.rs | 107 | ||||
| -rw-r--r-- | src/tacmap/render.rs | 4 |
4 files changed, 91 insertions, 50 deletions
diff --git a/src/tacmap/body_render.rs b/src/tacmap/body_render.rs index 8b32532..92ac13f 100644 --- a/src/tacmap/body_render.rs +++ b/src/tacmap/body_render.rs @@ -1,7 +1,7 @@ use std::error::Error; use crate::solar_system::Kilometers; -use crate::timeman::Second; +use crate::timeman::{SYSTEM_TICK_INTERVAL, Second}; use crate::wgpuctx::{WgpuCtx, pipeline::RenderPipelineBuilder}; use super::*; @@ -92,6 +92,18 @@ impl BodyRenderer return Ok(()); } + //Round to the nearest tick + let tick_time = match self.last_time { + Some(last_time) => { + let this_tick = time / SYSTEM_TICK_INTERVAL; + let last_tick = last_time / SYSTEM_TICK_INTERVAL; + + if this_tick == last_tick { return Ok(()) } + this_tick * SYSTEM_TICK_INTERVAL + } + None => 0 + }; + self.last_time = Some(time); let (_, bodies_buffer) = match &self.body_instance_buffer { @@ -101,11 +113,11 @@ impl BodyRenderer let bodies = solar_system.bodies(); let body_instances = bodies.iter().map(|body| { - let position = body.position(); - let origin = match body.get_orbits() { - Some(origin_id) => { - let origin_body = &bodies[origin_id]; - origin_body.position() + let position = body.relative_position(); + let origin = match body.get_orbit() { + Some(orbit) => { + let origin_body = &bodies[orbit.parent()]; + origin_body.relative_position() }, None => cgmath::Vector3::new(0.0, 0.0, 0.0) }; diff --git a/src/tacmap/camera.rs b/src/tacmap/camera.rs index 5efc24c..57856e2 100644 --- a/src/tacmap/camera.rs +++ b/src/tacmap/camera.rs @@ -4,7 +4,7 @@ use cgmath::{InnerSpace, Point3, Rad, Vector2, Vector3, perspective}; use winit::event::ElementState; use winit::keyboard::KeyCode; -use crate::solar_system::{self, BodyId, Kilometers, SolarSystem}; +use crate::solar_system::{self, Kilometers, SolarSystem}; use crate::ui; use crate::wgpuctx::WgpuCtx; @@ -16,7 +16,7 @@ pub struct Camera yaw: Rad<f32>, scale: f32, - target: Option<solar_system::BodyId>, + target: Option<solar_system::body::BodyId>, buffer: wgpu::Buffer, staging_buffer: wgpu::Buffer, @@ -166,7 +166,7 @@ impl Camera pub fn set_target( &mut self, - target: Option<solar_system::BodyId>) + target: Option<solar_system::body::BodyId>) { if target == self.target { return; } if !target.is_some() || !self.target.is_some() { diff --git a/src/tacmap/orbit_render.rs b/src/tacmap/orbit_render.rs index a6a90d1..c003366 100644 --- a/src/tacmap/orbit_render.rs +++ b/src/tacmap/orbit_render.rs @@ -1,6 +1,8 @@ +use std::error::Error; + use super::*; -use crate::solar_system::BodyId; +use crate::solar_system::body::{BodyId, OrbitalBody}; use crate::timeman::{SYSTEM_TICK_INTERVAL, Second}; use crate::wgpuctx::{WgpuCtx, pipeline::RenderPipelineBuilder}; @@ -68,6 +70,52 @@ impl OrbitRenderer pub fn mark_to_rebuild(&mut self) { self.needs_rebuild = true; } + fn create_orbit_buffer_for_body( + &self, + wgpuctx: &WgpuCtx, + body: &OrbitalBody, + time: Second) + -> (usize, Option<wgpu::Buffer>) + { + let orbit = match body.get_orbit() { + Some(orbit) => orbit, + None => return (0, None) + }; + + let period = body.orbital_period(); + + let num_points = ((period / (SYSTEM_TICK_INTERVAL)) as usize).clamp(90, 360); + let period_interval = period as f64 / num_points as f64; + + let mut points = vec![ + OrbitVertex::default();(num_points+1)*2]; + + for i in 0..num_points { + let position = body.calculate_orbit_at( + time + (i as f64 * period_interval) as Second); + + points[i*2].origin_id = orbit.parent() as _; + points[i*2].position = [ + position.x as f32, + position.y as f32, + position.z as f32 + ]; + + points[(i*2)+1] = points[i*2]; + } + points[num_points*2] = points[0]; + points[num_points*2+1] = points[1]; + + let buffer = wgpuctx.create_buffer_init( + &wgpu::util::BufferInitDescriptor { + label: None, + usage: wgpu::BufferUsages::VERTEX, + contents: bytemuck::cast_slice(&points) + } + ); + ((num_points+1)*2, Some(buffer)) + } + pub fn rebuild( &mut self, wgpuctx: &WgpuCtx, @@ -123,41 +171,6 @@ impl OrbitRenderer } )); self.origin_buffer = Some(origin_buffer); - - self.orbit_vertex_buffers = Some(bodies.iter().map(|body| { - if !body.does_orbit() { return (0, None); } - - let period = body.orbital_period(); - let num_points = ((period / (SYSTEM_TICK_INTERVAL)) as usize).clamp(180, 360*4); - let period_interval = period as f64 / num_points as f64; - - let mut points = vec![ - OrbitVertex::default();(num_points+1)*2]; - for i in 0..num_points { - let position = body.calculate_orbit_at( - (i as f64 * period_interval) as Second); - - points[i*2].origin_id = body.get_orbits().unwrap() as _; - points[i*2].position = [ - position.x as f32, - position.y as f32, - position.z as f32 - ]; - - points[(i*2)+1] = points[i*2].clone(); - } - points[num_points*2] = points[0].clone(); - points[num_points*2+1] = points[1].clone(); - - let buffer = wgpuctx.create_buffer_init( - &wgpu::util::BufferInitDescriptor { - label: None, - usage: wgpu::BufferUsages::VERTEX, - contents: bytemuck::cast_slice(&points) - } - ); - ((num_points+1)*2, Some(buffer)) - }).collect::<Vec<_>>()); } pub fn update( @@ -165,11 +178,23 @@ impl OrbitRenderer wgpuctx: &WgpuCtx, solar_system: &SolarSystem, time: Second) + -> Result<(), Box<dyn Error>> { if self.last_time.is_some_and(|t| { t == time }) { - return; + return Ok(()); } + let tick_time = match self.last_time { + Some(last_time) => { + let this_tick = time / SYSTEM_TICK_INTERVAL; + let last_tick = last_time / SYSTEM_TICK_INTERVAL; + + if this_tick == last_tick { return Ok(()) } + this_tick * SYSTEM_TICK_INTERVAL + } + None => 0 + }; + self.last_time = Some(time); let positions = solar_system.bodies().iter().map(|body| { let pos = solar_system.body_position(body); @@ -180,8 +205,14 @@ impl OrbitRenderer Some(buffer) => { wgpuctx.queue().write_buffer(buffer, 0, bytemuck::cast_slice(&positions)); }, - None => { return; } + None => { return Err(Box::new(NeedsRebuildError)); } }; + + let bodies = solar_system.bodies(); + self.orbit_vertex_buffers = Some(bodies.iter().map(|body| { + self.create_orbit_buffer_for_body(wgpuctx, body, tick_time) + }).collect::<Vec<_>>()); + Ok(()) } pub fn render( diff --git a/src/tacmap/render.rs b/src/tacmap/render.rs index fd93941..58efae0 100644 --- a/src/tacmap/render.rs +++ b/src/tacmap/render.rs @@ -3,10 +3,8 @@ use std::error::Error; use wgpu::RenderPass; -use crate::solar_system::Kilometers; use crate::tacmap::camera::Camera; -use crate::timeman::{DAY, SYSTEM_TICK_INTERVAL}; -use crate::{solar_system::{SolarSystem, SystemId}, timeman::Second, vertex::{self, Vertex}, wgpuctx::{WgpuCtx, pipeline::RenderPipelineBuilder}}; +use crate::wgpuctx::{WgpuCtx, pipeline::RenderPipelineBuilder}; #[derive(Debug, Clone)] pub struct NeedsRebuildError; |
