Minor edits

master
Mark 2024-01-23 15:53:50 -08:00
parent 71aac84086
commit b9ed5b2d49
Signed by: Mark
GPG Key ID: C6D63995FE72FD80
5 changed files with 53 additions and 127 deletions

View File

@ -1,45 +1,28 @@
use galactica_content::{Content, FactionHandle, OutfitHandle, ShipHandle, SystemHandle}; use galactica_content::{Content, FactionHandle, OutfitHandle, ShipHandle, SystemHandle};
use galactica_playeragent::PlayerAgent; use galactica_playeragent::PlayerAgent;
use galactica_system::data::ShipPersonality; use galactica_system::data::ShipPersonality;
use galactica_system::phys::{ use galactica_system::phys::{PhysImage, PhysSim, PhysSimShipHandle, PhysStepResources};
ParticleBuilder, PhysSim, PhysSimShipHandle, PhysStepResources, Wrapper,
};
use galactica_util::timing::Timing; use galactica_util::timing::Timing;
use nalgebra::Point2; use nalgebra::Point2;
use rand::seq::SliceRandom;
use std::time::Instant; use std::time::Instant;
#[derive(Clone)]
pub struct GameState {
pub systemsim: PhysSim,
pub timing: Timing,
pub start_instant: Instant,
}
unsafe impl Send for GameState {}
unsafe impl Sync for GameState {}
pub struct Game { pub struct Game {
// Core game data // Core game data
ct: Content, ct: Content,
state: GameState, systemsim: PhysSim,
timing: Timing,
start_instant: Instant,
// Metadata // Metadata
wrapper: Wrapper, // Physics computer
time_scale: f32, time_scale: f32,
last_update: Instant, last_update: Instant,
/// Particles to create this frame.
/// Must be cleared at the start of every frame
/// TODO: better way to handle this?
new_particles: Vec<ParticleBuilder>,
} }
unsafe impl<'a> Send for Game {} unsafe impl<'a> Send for Game {}
impl<'a> Game { impl<'a> Game {
pub fn make_player(&mut self) -> PhysSimShipHandle { pub fn make_player(&mut self) -> PhysSimShipHandle {
let player = self.state.systemsim.add_ship( let player = self.systemsim.add_ship(
&self.ct, &self.ct,
ShipHandle { index: 0 }, ShipHandle { index: 0 },
FactionHandle { index: 0 }, FactionHandle { index: 0 },
@ -47,7 +30,7 @@ impl<'a> Game {
Point2::new(0.0, 4000.0), Point2::new(0.0, 4000.0),
); );
let s = self.state.systemsim.get_ship_mut(&player).unwrap(); let s = self.systemsim.get_ship_mut(&player).unwrap();
s.add_outfits( s.add_outfits(
&self.ct, &self.ct,
[ [
@ -99,52 +82,46 @@ impl<'a> Game {
], ],
); );
let state = GameState { Game {
ct,
systemsim, systemsim,
timing: Timing::new(), timing: Timing::new(),
start_instant: Instant::now(), start_instant: Instant::now(),
};
Game {
ct,
state,
wrapper: Wrapper::new(),
last_update: Instant::now(), last_update: Instant::now(),
time_scale: 1.0, time_scale: 1.0,
new_particles: Vec::new(),
} }
} }
pub fn update_player_controls(&mut self, player: &mut PlayerAgent) { pub fn update_player_controls(&mut self, player: &mut PlayerAgent) {
self.state self.systemsim.update_player_controls(&self.ct, player)
.systemsim
.update_player_controls(&self.ct, player)
} }
pub fn get_state(&self) -> &GameState { pub fn step(&mut self, phys_img: &PhysImage) {
&self.state self.timing.start_frame();
} self.systemsim.step(
PhysStepResources {
pub fn get_particles(&self) -> &Vec<ParticleBuilder> { ct: &self.ct,
&self.new_particles t: self.last_update.elapsed().as_secs_f32() * self.time_scale,
} timing: &mut self.timing,
},
pub fn update(&mut self) { phys_img,
self.state.timing.start_frame(); );
let t: f32 = self.last_update.elapsed().as_secs_f32() * self.time_scale;
self.new_particles.clear();
self.state.systemsim.step(PhysStepResources {
ct: &self.ct,
particles: &mut self.new_particles,
timing: &mut self.state.timing,
wrapper: &mut self.wrapper,
t,
});
self.last_update = Instant::now(); self.last_update = Instant::now();
self.new_particles.shuffle(&mut rand::thread_rng()); self.timing.mark_frame();
self.state.timing.mark_frame(); }
pub fn update_image(&self, phys_img: &mut PhysImage) {
self.systemsim.update_image(phys_img);
}
}
impl Game {
pub fn get_timing(&self) -> &Timing {
&self.timing
}
pub fn get_current_time(&self) -> f32 {
self.start_instant.elapsed().as_secs_f32()
} }
} }

View File

@ -4,7 +4,10 @@ use anyhow::{bail, Result};
use galactica_content::{Content, SystemHandle}; use galactica_content::{Content, SystemHandle};
use galactica_playeragent::{PlayerAgent, PlayerStatus}; use galactica_playeragent::{PlayerAgent, PlayerStatus};
use galactica_render::RenderInput; use galactica_render::RenderInput;
use galactica_system::{data::ShipState, phys::PhysSimShipHandle}; use galactica_system::{
data::ShipState,
phys::{PhysImage, PhysSimShipHandle},
};
use galactica_util::constants::ASSET_CACHE; use galactica_util::constants::ASSET_CACHE;
use nalgebra::Vector2; use nalgebra::Vector2;
use std::{ use std::{
@ -61,19 +64,20 @@ fn try_main() -> Result<()> {
gpu.window().inner_size().width as f32 / gpu.window().inner_size().height as f32, gpu.window().inner_size().width as f32 / gpu.window().inner_size().height as f32,
); );
let mut phys_img = PhysImage::new();
event_loop.run(move |event, _, control_flow| { event_loop.run(move |event, _, control_flow| {
match event { match event {
Event::RedrawRequested(window_id) if window_id == gpu.window().id() => { Event::RedrawRequested(window_id) if window_id == gpu.window().id() => {
let render_input = RenderInput { let render_input = RenderInput {
camera_pos: player.camera.pos, camera_pos: player.camera.pos,
camera_zoom: player.camera.zoom, camera_zoom: player.camera.zoom,
current_time: game.get_state().start_instant.elapsed().as_secs_f32(), current_time: game.get_current_time(),
ct: &content, ct: &content,
systemsim: &game.get_state().systemsim, phys_img: &phys_img,
particles: game.get_particles(),
player: &player, player: &player,
current_system: SystemHandle { index: 0 }, current_system: SystemHandle { index: 0 },
timing: game.get_state().timing.clone(), timing: game.get_timing().clone(),
}; };
match gpu.render(render_input) { match gpu.render(render_input) {
@ -87,29 +91,19 @@ fn try_main() -> Result<()> {
Event::MainEventsCleared => { Event::MainEventsCleared => {
game.update_player_controls(&mut player); game.update_player_controls(&mut player);
game.update(); game.step(&phys_img);
game.update_image(&mut phys_img);
// TODO: clean up // TODO: clean up
let player_status = { let player_status = {
let pos = { let pos = {
let o = &game let o = phys_img.get_ship(&PhysSimShipHandle(player.ship.unwrap()));
.get_state()
.systemsim
.get_ship(&PhysSimShipHandle(player.ship.unwrap()));
if let Some(o) = o { if let Some(o) = o {
match o.get_data().get_state() { match o.ship.get_data().get_state() {
ShipState::Landing { .. } ShipState::Landing { .. }
| ShipState::UnLanding { .. } | ShipState::UnLanding { .. }
| ShipState::Collapsing { .. } | ShipState::Collapsing { .. }
| ShipState::Flying { .. } => { | ShipState::Flying { .. } => Some(*o.rigidbody.translation()),
let r =
&game.get_state().systemsim.get_rigid_body(o.rigid_body);
if let Some(r) = r {
Some(*r.translation())
} else {
None
}
}
ShipState::Landed { target } => { ShipState::Landed { target } => {
let b = content.get_system_object(*target); let b = content.get_system_object(*target);

View File

@ -1,6 +1,6 @@
use galactica_content::{Content, SystemHandle}; use galactica_content::{Content, SystemHandle};
use galactica_playeragent::PlayerAgent; use galactica_playeragent::PlayerAgent;
use galactica_system::phys::{ParticleBuilder, PhysSim}; use galactica_system::phys::PhysImage;
use galactica_util::timing::Timing; use galactica_util::timing::Timing;
use nalgebra::Vector2; use nalgebra::Vector2;
@ -19,7 +19,7 @@ pub struct RenderInput<'a> {
pub camera_zoom: f32, pub camera_zoom: f32,
/// The world state to render /// The world state to render
pub systemsim: &'a PhysSim, pub phys_img: &'a PhysImage,
// TODO: handle overflow. is it a problem? // TODO: handle overflow. is it a problem?
/// The current time, in seconds /// The current time, in seconds
@ -28,9 +28,6 @@ pub struct RenderInput<'a> {
/// Game content /// Game content
pub ct: &'a Content, pub ct: &'a Content,
/// Particles to spawn during this frame
pub particles: &'a Vec<ParticleBuilder>,
/// Time we spent in each part of the game loop /// Time we spent in each part of the game loop
pub timing: Timing, pub timing: Timing,
} }

View File

@ -1,7 +1,6 @@
use galactica_content::Content; use galactica_content::Content;
use galactica_util::constants::{ use galactica_util::constants::{
OBJECT_SPRITE_INSTANCE_LIMIT, PARTICLE_SPRITE_INSTANCE_LIMIT, RADIALBAR_SPRITE_INSTANCE_LIMIT, OBJECT_SPRITE_INSTANCE_LIMIT, RADIALBAR_SPRITE_INSTANCE_LIMIT, UI_SPRITE_INSTANCE_LIMIT,
UI_SPRITE_INSTANCE_LIMIT,
}; };
use glyphon::{FontSystem, SwashCache, TextAtlas, TextRenderer}; use glyphon::{FontSystem, SwashCache, TextAtlas, TextRenderer};
use std::rc::Rc; use std::rc::Rc;
@ -12,10 +11,7 @@ use crate::{
globaluniform::GlobalUniform, globaluniform::GlobalUniform,
vertexbuffer::{ vertexbuffer::{
consts::{SPRITE_INDICES, SPRITE_VERTICES}, consts::{SPRITE_INDICES, SPRITE_VERTICES},
types::{ types::{ObjectInstance, RadialBarInstance, StarfieldInstance, TexturedVertex, UiInstance},
ObjectInstance, ParticleInstance, RadialBarInstance, StarfieldInstance, TexturedVertex,
UiInstance,
},
BufferObject, VertexBuffer, BufferObject, VertexBuffer,
}, },
}; };
@ -24,13 +20,8 @@ use crate::{
pub(crate) struct VertexBuffers { pub(crate) struct VertexBuffers {
// Keeps track of length of each buffer // Keeps track of length of each buffer
// Most of these are reset on each frame. // Most of these are reset on each frame.
//
// The exception is particle_counter, which
// is never reset, and loops back to zero once
// it exceeds buffer length
object_counter: BufferAddress, object_counter: BufferAddress,
ui_counter: BufferAddress, ui_counter: BufferAddress,
particle_counter: BufferAddress,
radialbar_counter: BufferAddress, radialbar_counter: BufferAddress,
starfield_counter: BufferAddress, starfield_counter: BufferAddress,
starfield_limit: BufferAddress, starfield_limit: BufferAddress,
@ -38,7 +29,6 @@ pub(crate) struct VertexBuffers {
object: Rc<VertexBuffer>, object: Rc<VertexBuffer>,
starfield: Rc<VertexBuffer>, starfield: Rc<VertexBuffer>,
ui: Rc<VertexBuffer>, ui: Rc<VertexBuffer>,
particle: Rc<VertexBuffer>,
radialbar: Rc<VertexBuffer>, radialbar: Rc<VertexBuffer>,
} }
@ -47,7 +37,6 @@ impl<'a> VertexBuffers {
Self { Self {
object_counter: 0, object_counter: 0,
ui_counter: 0, ui_counter: 0,
particle_counter: 0,
radialbar_counter: 0, radialbar_counter: 0,
starfield_counter: 0, starfield_counter: 0,
starfield_limit: ct.get_config().starfield_instance_limit, starfield_limit: ct.get_config().starfield_instance_limit,
@ -76,14 +65,6 @@ impl<'a> VertexBuffers {
UI_SPRITE_INSTANCE_LIMIT, UI_SPRITE_INSTANCE_LIMIT,
)), )),
particle: Rc::new(VertexBuffer::new::<TexturedVertex, ParticleInstance>(
"particle",
&device,
Some(SPRITE_VERTICES),
Some(SPRITE_INDICES),
PARTICLE_SPRITE_INSTANCE_LIMIT,
)),
radialbar: Rc::new(VertexBuffer::new::<TexturedVertex, RadialBarInstance>( radialbar: Rc::new(VertexBuffer::new::<TexturedVertex, RadialBarInstance>(
"radial bar", "radial bar",
&device, &device,
@ -102,10 +83,6 @@ impl<'a> VertexBuffers {
&self.object &self.object
} }
pub fn get_particle(&'a self) -> &'a Rc<VertexBuffer> {
&self.particle
}
pub fn get_radialbar(&'a self) -> &'a Rc<VertexBuffer> { pub fn get_radialbar(&'a self) -> &'a Rc<VertexBuffer> {
&self.radialbar &self.radialbar
} }
@ -218,20 +195,4 @@ impl RenderState {
pub fn get_starfield_counter(&self) -> u32 { pub fn get_starfield_counter(&self) -> u32 {
self.vertex_buffers.starfield_counter as u32 self.vertex_buffers.starfield_counter as u32
} }
pub fn push_particle_buffer(&mut self, instance: ParticleInstance) {
self.queue.write_buffer(
&self.vertex_buffers.particle.instances,
ParticleInstance::SIZE * self.vertex_buffers.particle_counter,
bytemuck::cast_slice(&[instance]),
);
self.vertex_buffers.particle_counter += 1;
if self.vertex_buffers.particle_counter == PARTICLE_SPRITE_INSTANCE_LIMIT {
self.vertex_buffers.particle_counter = 0;
}
}
//pub fn get_particle_counter(&self) -> u32 {
// self.vertex_buffers.particle_counter as u32
//}
} }

View File

@ -3,7 +3,7 @@
// TODO: many of these should be moved to a config file or cli option // TODO: many of these should be moved to a config file or cli option
/// We can draw at most this many object sprites on the screen. /// We can draw at most this many object sprites on the screen.
pub const OBJECT_SPRITE_INSTANCE_LIMIT: u64 = 500; pub const OBJECT_SPRITE_INSTANCE_LIMIT: u64 = 2048;
/// We can draw at most this many ui sprites on the screen. /// We can draw at most this many ui sprites on the screen.
pub const UI_SPRITE_INSTANCE_LIMIT: u64 = 100; pub const UI_SPRITE_INSTANCE_LIMIT: u64 = 100;
@ -12,9 +12,6 @@ pub const UI_SPRITE_INSTANCE_LIMIT: u64 = 100;
/// This is fairly small, since we know exactly how many of these we'll draw (for now) /// This is fairly small, since we know exactly how many of these we'll draw (for now)
pub const RADIALBAR_SPRITE_INSTANCE_LIMIT: u64 = 10; pub const RADIALBAR_SPRITE_INSTANCE_LIMIT: u64 = 10;
/// The size of our circular particle buffer. When we create particles, the oldest ones are replaced.
pub const PARTICLE_SPRITE_INSTANCE_LIMIT: u64 = 1000;
/// The maximum number of sprites we can define /// The maximum number of sprites we can define
pub const SPRITE_LIMIT: u32 = 1024; pub const SPRITE_LIMIT: u32 = 1024;