Compare commits

..

No commits in common. "a2b88af3752c6c30eb804702ba03db53f95e5d0c" and "ec796ff97444467dbd8154c41ce4dcb808c0141a" have entirely different histories.

19 changed files with 150 additions and 253 deletions

23
TODO.md
View File

@ -1,8 +1,9 @@
# Specific projects # Specific projects
## Currently working on: ## Currently working on:
- first: sticky effects - first: remove object array
- first: read state from image so we can add objects? - first: sticky particles
- first: rework timings
- clickable buttons - clickable buttons
- planet outfitter - planet outfitter
@ -38,7 +39,7 @@
- Faster handles (better than a hashmap?) - Faster handles (better than a hashmap?)
- Check for handle leaks - Check for handle leaks
- 🌟 Log/warning system - 🌟 Log/warning system
- Clean up & faster frame timings (average) - Clean up & faster frame timings
- 🌟 Handle lost focus - 🌟 Handle lost focus
- User config file - User config file
- 🌟 Document content - 🌟 Document content
@ -105,7 +106,7 @@
- Trigger sprite reel when firing (requires: non-removable outfits) - Trigger sprite reel when firing (requires: non-removable outfits)
- then: ship tint - then: ship tint
- then: frame timing randomness - then: frame timing randomness
- then: leaks during collapse (needs effect physics) - then: leaks during collapse (needs particle physics)
- then: passive engine glow, ease in/out - then: passive engine glow, ease in/out
- Sprite color variation - Sprite color variation
@ -115,11 +116,12 @@
- Cache direcory - Cache direcory
- How to pack? - How to pack?
## Effect physics ## Particle physics
- Effect should stick to their ships. How? - Particles should stick to their ships. How?
- Land and unland effects - Particle compute shader
- Land and unland particles
- Effect on fire gun - Effect on fire gun
- Effect / sprite color variation - Particle / sprite color variation
## Sound effects ## Sound effects
- Sound effects - Sound effects
@ -144,11 +146,12 @@
- Ship death damage and force events - Ship death damage and force events
- Gun fire effect - Gun fire effect
- Sprite color variation - Sprite color variation
- Multi-particle effects
- Better loading - Better loading
- incremental? - incremental?
- Higher texture limit (16 x 8096 x 8096 isn't enough) - Higher texture limit (16 x 8096 x 8096 isn't enough)
- GPU limits? (texture size, texture number, effect/sprite limits) - GPU limits? (texture size, texture number, particle/sprite limits)
- Effect when a ship is damaged (events) - Particles when a ship is damaged (events)
- Sticky radar - Sticky radar
- Arbitrary size resource names - Arbitrary size resource names

2
assets

@ -1 +1 @@
Subproject commit c8e08d445a2a38cc7059dd8075770ba8398655e2 Subproject commit e51b880b91e712214db025d97c9fbb3ccb3df7c3

View File

@ -1,5 +1,5 @@
[effect."small explosion"] [effect."small explosion"]
sprite = "effect::explosion::small" sprite = "particle::explosion::small"
lifetime = "inherit" lifetime = "inherit"
inherit_velocity = "target" inherit_velocity = "target"
size = 8.0 size = 8.0
@ -11,7 +11,7 @@ fade_rng = 0.1
[effect."large explosion"] [effect."large explosion"]
sprite = "effect::explosion::large" sprite = "particle::explosion::large"
lifetime = "inherit" lifetime = "inherit"
inherit_velocity = "target" inherit_velocity = "target"
size = 25.0 size = 25.0
@ -23,7 +23,7 @@ fade_rng = 0.1
[effect."huge explosion"] [effect."huge explosion"]
sprite = "effect::explosion::huge" sprite = "particle::explosion::huge"
lifetime = "inherit" lifetime = "inherit"
inherit_velocity = "target" inherit_velocity = "target"
size = 50.0 size = 50.0
@ -35,7 +35,7 @@ fade_rng = 0.1
[effect."blue spark"] [effect."blue spark"]
sprite = "effect::spark::blue" sprite = "particle::spark::blue"
lifetime = 0.5 lifetime = 0.5
lifetime_rng = 0.5 lifetime_rng = 0.5
inherit_velocity = "parent" inherit_velocity = "parent"
@ -48,7 +48,7 @@ fade = 0.2
fade_rng = 0.1 fade_rng = 0.1
[effect."yellow spark"] [effect."yellow spark"]
sprite = "effect::spark::yellow" sprite = "particle::spark::yellow"
lifetime = "inherit" lifetime = "inherit"
inherit_velocity = "parent" inherit_velocity = "parent"
size = 4.0 size = 4.0
@ -60,7 +60,7 @@ fade = 0.2
fade_rng = 0.1 fade_rng = 0.1
[effect."red spark"] [effect."red spark"]
sprite = "effect::spark::red" sprite = "particle::spark::red"
lifetime = "inherit" lifetime = "inherit"
inherit_velocity = "parent" inherit_velocity = "parent"
size = 4.0 size = 4.0
@ -74,9 +74,9 @@ fade_rng = 0.1
# Every effect has a parent, some effects have a target # Every effect has a parent, some effects have a target
[effect."blaster impact"] [effect."blaster impact"]
sprite = "effect::blaster" sprite = "particle::blaster"
lifetime = "inherit" # number in seconds or inherit from sprite lifetime = "inherit" # number in seconds or inherit from sprite
lifetime_rng = 0.0 # Random variation of lifetime (up to this value) lifetime_rng = 0.0 # Random variation of lifetime (up to this value)
size = 3.0 # sprite size, in game units size = 3.0 # sprite size, in game units
size_rng = 1.0 # random size variation size_rng = 1.0 # random size variation
@ -102,4 +102,6 @@ fade_rng = 0.1
# TODO: # TODO:
# effect probabilities & variants # effect probabilities & variants
# multiple particles in one effect
# document: effect vs particle
# sprite lifetime/fps variation (and effects inherit lifetime later) # sprite lifetime/fps variation (and effects inherit lifetime later)

View File

@ -51,7 +51,7 @@ gun.projectile.collider.ball.radius = 2.0
gun.projectile.impact_effect = "blaster impact" gun.projectile.impact_effect = "blaster impact"
gun.projectile.expire_effect.sprite = "effect::blaster" gun.projectile.expire_effect.sprite = "particle::blaster"
gun.projectile.expire_effect.lifetime = "inherit" gun.projectile.expire_effect.lifetime = "inherit"
gun.projectile.expire_effect.size = 3.0 gun.projectile.expire_effect.size = 3.0
gun.projectile.expire_effect.velocity_scale_parent = 1.0 gun.projectile.expire_effect.velocity_scale_parent = 1.0

View File

@ -105,111 +105,111 @@ section.on.bot = "stop"
section.on.timing.fps = 60 section.on.timing.fps = 60
section.on.frames = ["ui/planet-button-on.png"] section.on.frames = ["ui/planet-button-on.png"]
[sprite."effect::blaster"] [sprite."particle::blaster"]
timing.duration = 0.15 timing.duration = 0.15
frames = [ frames = [
"effect/blaster/01.png", "particle/blaster/01.png",
"effect/blaster/02.png", "particle/blaster/02.png",
"effect/blaster/03.png", "particle/blaster/03.png",
"effect/blaster/04.png", "particle/blaster/04.png",
] ]
[sprite."effect::explosion::tiny"] [sprite."particle::explosion::tiny"]
timing.fps = 15 timing.fps = 15
frames = [ frames = [
"effect/explosion-tiny/01.png", "particle/explosion-tiny/01.png",
"effect/explosion-tiny/02.png", "particle/explosion-tiny/02.png",
"effect/explosion-tiny/03.png", "particle/explosion-tiny/03.png",
"effect/explosion-tiny/04.png", "particle/explosion-tiny/04.png",
"effect/explosion-tiny/05.png", "particle/explosion-tiny/05.png",
"effect/explosion-tiny/06.png", "particle/explosion-tiny/06.png",
] ]
[sprite."effect::explosion::small"] [sprite."particle::explosion::small"]
timing.fps = 15 timing.fps = 15
frames = [ frames = [
"effect/explosion-small/01.png", "particle/explosion-small/01.png",
"effect/explosion-small/02.png", "particle/explosion-small/02.png",
"effect/explosion-small/03.png", "particle/explosion-small/03.png",
"effect/explosion-small/04.png", "particle/explosion-small/04.png",
"effect/explosion-small/05.png", "particle/explosion-small/05.png",
"effect/explosion-small/06.png", "particle/explosion-small/06.png",
"effect/explosion-small/07.png", "particle/explosion-small/07.png",
] ]
[sprite."effect::explosion::medium"] [sprite."particle::explosion::medium"]
timing.fps = 15 timing.fps = 15
frames = [ frames = [
"effect/explosion-medium/01.png", "particle/explosion-medium/01.png",
"effect/explosion-medium/02.png", "particle/explosion-medium/02.png",
"effect/explosion-medium/03.png", "particle/explosion-medium/03.png",
"effect/explosion-medium/04.png", "particle/explosion-medium/04.png",
"effect/explosion-medium/05.png", "particle/explosion-medium/05.png",
"effect/explosion-medium/06.png", "particle/explosion-medium/06.png",
"effect/explosion-medium/07.png", "particle/explosion-medium/07.png",
"effect/explosion-medium/08.png", "particle/explosion-medium/08.png",
] ]
[sprite."effect::explosion::large"] [sprite."particle::explosion::large"]
timing.fps = 15 timing.fps = 15
frames = [ frames = [
"effect/explosion-large/01.png", "particle/explosion-large/01.png",
"effect/explosion-large/02.png", "particle/explosion-large/02.png",
"effect/explosion-large/03.png", "particle/explosion-large/03.png",
"effect/explosion-large/04.png", "particle/explosion-large/04.png",
"effect/explosion-large/05.png", "particle/explosion-large/05.png",
"effect/explosion-large/06.png", "particle/explosion-large/06.png",
"effect/explosion-large/07.png", "particle/explosion-large/07.png",
"effect/explosion-large/08.png", "particle/explosion-large/08.png",
"effect/explosion-large/09.png", "particle/explosion-large/09.png",
] ]
[sprite."effect::explosion::huge"] [sprite."particle::explosion::huge"]
timing.fps = 15 timing.fps = 15
frames = [ frames = [
"effect/explosion-huge/01.png", "particle/explosion-huge/01.png",
"effect/explosion-huge/02.png", "particle/explosion-huge/02.png",
"effect/explosion-huge/03.png", "particle/explosion-huge/03.png",
"effect/explosion-huge/04.png", "particle/explosion-huge/04.png",
"effect/explosion-huge/05.png", "particle/explosion-huge/05.png",
"effect/explosion-huge/06.png", "particle/explosion-huge/06.png",
"effect/explosion-huge/07.png", "particle/explosion-huge/07.png",
"effect/explosion-huge/08.png", "particle/explosion-huge/08.png",
"effect/explosion-huge/09.png", "particle/explosion-huge/09.png",
"effect/explosion-huge/10.png", "particle/explosion-huge/10.png",
] ]
[sprite."effect::spark::blue"] [sprite."particle::spark::blue"]
timing.duration = 0.3 timing.duration = 0.3
top = "reverse" top = "reverse"
bot = "reverse" bot = "reverse"
frames = [ frames = [
"effect/spark-blue/01.png", "particle/spark-blue/01.png",
"effect/spark-blue/02.png", "particle/spark-blue/02.png",
"effect/spark-blue/03.png", "particle/spark-blue/03.png",
"effect/spark-blue/04.png", "particle/spark-blue/04.png",
"effect/spark-blue/05.png", "particle/spark-blue/05.png",
] ]
[sprite."effect::spark::yellow"] [sprite."particle::spark::yellow"]
timing.duration = 0.3 timing.duration = 0.3
timing.rng = 0.2 timing.rng = 0.2
frames = [ frames = [
"effect/spark-yellow/01.png", "particle/spark-yellow/01.png",
"effect/spark-yellow/02.png", "particle/spark-yellow/02.png",
"effect/spark-yellow/03.png", "particle/spark-yellow/03.png",
"effect/spark-yellow/04.png", "particle/spark-yellow/04.png",
"effect/spark-yellow/05.png", "particle/spark-yellow/05.png",
] ]
[sprite."effect::spark::red"] [sprite."particle::spark::red"]
timing.duration = 0.3 timing.duration = 0.3
timing.rng = 0.2 timing.rng = 0.2
frames = [ frames = [
"effect/spark-red/01.png", "particle/spark-red/01.png",
"effect/spark-red/02.png", "particle/spark-red/02.png",
"effect/spark-red/03.png", "particle/spark-red/03.png",
] ]

View File

@ -124,46 +124,46 @@ pub(crate) mod syntax {
} }
} }
/// The effect a projectile will spawn when it hits something /// The particle a projectile will spawn when it hits something
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct Effect { pub struct Effect {
/// This effect's handle /// This effect's handle
pub handle: EffectHandle, pub handle: EffectHandle,
/// The sprite to use for this effect. /// The sprite to use for this particle.
pub sprite: SpriteHandle, pub sprite: SpriteHandle,
/// The height of this effect, in game units. /// The height of this particle, in game units.
pub size: f32, pub size: f32,
/// Random size variation /// Random size variation
pub size_rng: f32, pub size_rng: f32,
/// How many seconds this effect should live /// How many seconds this particle should live
pub lifetime: f32, pub lifetime: f32,
/// Random lifetime variation /// Random lifetime variation
pub lifetime_rng: f32, pub lifetime_rng: f32,
/// The angle this effect points once spawned, in radians /// The angle this particle points once spawned, in radians
pub angle: f32, pub angle: f32,
/// Random angle variation, in radians /// Random angle variation, in radians
pub angle_rng: f32, pub angle_rng: f32,
/// How fast this effect spins, in radians/sec /// How fast this particle spins, in radians/sec
pub angvel: f32, pub angvel: f32,
/// Random angvel variation /// Random angvel variation
pub angvel_rng: f32, pub angvel_rng: f32,
/// The amount of this effect's parent's velocity to inherit /// The amount of this particle's parent's velocity to inherit
pub velocity_scale_parent: f32, pub velocity_scale_parent: f32,
/// Parent velocity random variation /// Parent velocity random variation
pub velocity_scale_parent_rng: f32, pub velocity_scale_parent_rng: f32,
/// The amount of this effect's parent's target velocity to inherit. /// The amount of this particle's parent's target velocity to inherit.
/// If there is no target, this is zero. /// If there is no target, this is zero.
pub velocity_scale_target: f32, pub velocity_scale_target: f32,

View File

@ -229,10 +229,10 @@ pub struct Projectile {
/// The angle variation of this projectile, in radians /// The angle variation of this projectile, in radians
pub angle_rng: f32, pub angle_rng: f32,
/// The effect this projectile will spawn when it hits something /// The particle this projectile will spawn when it hits something
pub impact_effect: Option<EffectHandle>, pub impact_effect: Option<EffectHandle>,
/// The effect this projectile will spawn when it expires /// The particle this projectile will spawn when it expires
pub expire_effect: Option<EffectHandle>, pub expire_effect: Option<EffectHandle>,
/// Collider parameters for this projectile /// Collider parameters for this projectile

View File

@ -403,7 +403,7 @@ impl crate::Build for Ship {
// We apply this pointwise so that local points inside the collider work as we expect. // We apply this pointwise so that local points inside the collider work as we expect.
// //
// If we don't, rapier2 will compute local points pre-rotation, // If we don't, rapier2 will compute local points pre-rotation,
// which will break effect placement on top of ships (i.e, collapse effects) // which will break particle placement on top of ships (i.e, collapse effects)
Rotation2::new(to_radians(-90.0)) Rotation2::new(to_radians(-90.0))
* Point2::new(x[0] * (size / 2.0) * aspect, x[1] * size / 2.0) * Point2::new(x[0] * (size / 2.0) * aspect, x[1] * size / 2.0)
}) })

View File

@ -9,7 +9,7 @@ use std::time::Instant;
pub struct Game { pub struct Game {
// Core game data // Core game data
ct: Content, ct: Content,
phys_sim: PhysSim, systemsim: PhysSim,
timing: Timing, timing: Timing,
start_instant: Instant, start_instant: Instant,
@ -22,7 +22,7 @@ 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.phys_sim.add_ship( let player = self.systemsim.add_ship(
&self.ct, &self.ct,
ShipHandle { index: 0 }, ShipHandle { index: 0 },
FactionHandle { index: 0 }, FactionHandle { index: 0 },
@ -30,7 +30,7 @@ impl<'a> Game {
Point2::new(0.0, 4000.0), Point2::new(0.0, 4000.0),
); );
let s = self.phys_sim.get_ship_mut(&player).unwrap(); let s = self.systemsim.get_ship_mut(&player).unwrap();
s.add_outfits( s.add_outfits(
&self.ct, &self.ct,
[ [
@ -44,9 +44,9 @@ impl<'a> Game {
} }
pub fn new(ct: Content) -> Self { pub fn new(ct: Content) -> Self {
let mut phys_sim = PhysSim::new(&ct, SystemHandle { index: 0 }); let mut systemsim = PhysSim::new(&ct, SystemHandle { index: 0 });
let a = phys_sim.add_ship( let a = systemsim.add_ship(
&ct, &ct,
ShipHandle { index: 0 }, ShipHandle { index: 0 },
FactionHandle { index: 1 }, FactionHandle { index: 1 },
@ -54,7 +54,7 @@ impl<'a> Game {
Point2::new(1000.0, 0.0), Point2::new(1000.0, 0.0),
); );
let s = phys_sim.get_ship_mut(&a).unwrap(); let s = systemsim.get_ship_mut(&a).unwrap();
s.add_outfits( s.add_outfits(
&ct, &ct,
[ [
@ -64,7 +64,7 @@ impl<'a> Game {
], ],
); );
let a = phys_sim.add_ship( let a = systemsim.add_ship(
&ct, &ct,
ShipHandle { index: 0 }, ShipHandle { index: 0 },
FactionHandle { index: 0 }, FactionHandle { index: 0 },
@ -72,7 +72,7 @@ impl<'a> Game {
Point2::new(200.0, 2000.0), Point2::new(200.0, 2000.0),
); );
let s = phys_sim.get_ship_mut(&a).unwrap(); let s = systemsim.get_ship_mut(&a).unwrap();
s.add_outfits( s.add_outfits(
&ct, &ct,
[ [
@ -84,7 +84,7 @@ impl<'a> Game {
Game { Game {
ct, ct,
phys_sim, systemsim,
timing: Timing::new(), timing: Timing::new(),
start_instant: Instant::now(), start_instant: Instant::now(),
last_update: Instant::now(), last_update: Instant::now(),
@ -93,12 +93,12 @@ impl<'a> Game {
} }
pub fn update_player_controls(&mut self, player: &mut PlayerAgent) { pub fn update_player_controls(&mut self, player: &mut PlayerAgent) {
self.phys_sim.update_player_controls(&self.ct, player) self.systemsim.update_player_controls(&self.ct, player)
} }
pub fn step(&mut self, phys_img: &PhysImage) { pub fn step(&mut self, phys_img: &PhysImage) {
self.timing.start_frame(); self.timing.start_frame();
self.phys_sim.step( self.systemsim.step(
PhysStepResources { PhysStepResources {
ct: &self.ct, ct: &self.ct,
t: self.last_update.elapsed().as_secs_f32() * self.time_scale, t: self.last_update.elapsed().as_secs_f32() * self.time_scale,
@ -112,7 +112,7 @@ impl<'a> Game {
} }
pub fn update_image(&self, phys_img: &mut PhysImage) { pub fn update_image(&self, phys_img: &mut PhysImage) {
self.phys_sim.update_image(phys_img); self.systemsim.update_image(phys_img);
} }
} }

View File

@ -4,7 +4,6 @@ struct InstanceInput {
@location(2) texture_index: vec2<u32>, @location(2) texture_index: vec2<u32>,
@location(3) texture_fade: f32, @location(3) texture_fade: f32,
@location(4) object_index: u32, @location(4) object_index: u32,
@location(5) color: vec4<f32>,
}; };
struct VertexInput { struct VertexInput {
@ -19,7 +18,6 @@ struct VertexOutput {
@location(2) texture_coords_a: vec2<f32>, @location(2) texture_coords_a: vec2<f32>,
@location(3) texture_index_b: u32, @location(3) texture_index_b: u32,
@location(4) texture_coords_b: vec2<f32>, @location(4) texture_coords_b: vec2<f32>,
@location(5) color: vec4<f32>,
}; };
@ -139,7 +137,8 @@ fn vertex_main(
); );
} }
out.color = instance.color;
out.tween = instance.texture_fade; out.tween = instance.texture_fade;
// Texture 0 is special, it's the empty texture // Texture 0 is special, it's the empty texture
@ -213,7 +212,7 @@ fn fragment_main(in: VertexOutput) -> @location(0) vec4<f32> {
texture_a, texture_a,
texture_b, texture_b,
in.tween in.tween
) * in.color; );
return color; return color;

View File

@ -1,4 +1,4 @@
//! GPUState routines for drawing objects in a system //! GPUState routines for drawing items in a systemsim
use bytemuck; use bytemuck;
use galactica_system::data::ShipState; use galactica_system::data::ShipState;
@ -88,7 +88,6 @@ impl GPUState {
texture_index: anim_state.texture_index(), texture_index: anim_state.texture_index(),
texture_fade: anim_state.fade, texture_fade: anim_state.fade,
object_index: idx as u32, object_index: idx as u32,
color: [1.0, 1.0, 1.0, 1.0],
}); });
if { if {
@ -128,7 +127,6 @@ impl GPUState {
texture_index: anim_state.texture_index(), texture_index: anim_state.texture_index(),
texture_fade: anim_state.fade, texture_fade: anim_state.fade,
object_index: self.state.get_object_counter() as u32, object_index: self.state.get_object_counter() as u32,
color: [1.0, 1.0, 1.0, 1.0],
}); });
} }
} }
@ -191,7 +189,6 @@ impl GPUState {
texture_index: anim_state.texture_index(), texture_index: anim_state.texture_index(),
texture_fade: anim_state.fade, texture_fade: anim_state.fade,
object_index: idx as u32, object_index: idx as u32,
color: [1.0, 1.0, 1.0, 1.0],
}); });
} }
} }
@ -249,7 +246,6 @@ impl GPUState {
texture_index: [texture_a, texture_a], texture_index: [texture_a, texture_a],
texture_fade: 1.0, texture_fade: 1.0,
object_index: idx as u32, object_index: idx as u32,
color: [1.0, 1.0, 1.0, 1.0],
}); });
} }
} }
@ -314,7 +310,6 @@ impl GPUState {
texture_index: anim_state.texture_index(), texture_index: anim_state.texture_index(),
texture_fade: anim_state.fade, texture_fade: anim_state.fade,
object_index: idx as u32, object_index: idx as u32,
color: [1.0, 1.0, 1.0, p.get_fade()],
}); });
} }
} }

View File

@ -35,7 +35,14 @@ impl FpsIndicator {
self.buffer.set_text( self.buffer.set_text(
&mut state.text_font_system, &mut state.text_font_system,
&input.timing.get_string(), &format!(
"Frame: {:#?} ({:05.00})\nShips: {:05.02}%\nPhys: {:05.02}%\n",
input.timing.frame,
1.0 / input.timing.frame.as_secs_f32(),
100.0 * (input.timing.physics_sim.as_secs_f32() / input.timing.frame.as_secs_f32()),
100.0
* (input.timing.physics_ship.as_secs_f32() / input.timing.frame.as_secs_f32()),
),
Attrs::new().family(Family::Monospace), Attrs::new().family(Family::Monospace),
Shaping::Basic, Shaping::Basic,
); );

View File

@ -95,11 +95,6 @@ pub struct ObjectInstance {
/// Which object this instance is for /// Which object this instance is for
pub object_index: u32, pub object_index: u32,
/// This lets us color sprites dynamically:
/// Each fragment's color is multiplied by this value.
/// Fill this array with ones if no recoloring should be done.
pub color: [f32; 4],
} }
impl BufferObject for ObjectInstance { impl BufferObject for ObjectInstance {
@ -129,12 +124,6 @@ impl BufferObject for ObjectInstance {
shader_location: 4, shader_location: 4,
format: wgpu::VertexFormat::Uint32, format: wgpu::VertexFormat::Uint32,
}, },
// Color
wgpu::VertexAttribute {
offset: mem::size_of::<[f32; 4]>() as wgpu::BufferAddress,
shader_location: 5,
format: wgpu::VertexFormat::Float32x4,
},
], ],
} }
} }

View File

@ -5,23 +5,23 @@ use rapier2d::dynamics::{RigidBodyBuilder, RigidBodyHandle, RigidBodyType};
use crate::phys::{PhysStepResources, PhysWrapper}; use crate::phys::{PhysStepResources, PhysWrapper};
/// A single instance of an effect /// Instructions to create a new particle
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct PhysEffect { pub struct PhysEffect {
/// The sprite to use for this effect /// The sprite to use for this particle
pub anim: SpriteAutomaton, pub anim: SpriteAutomaton,
/// This effect's velocity, in world coordinates /// This particle's velocity, in world coordinates
pub rigid_body: RigidBodyHandle, pub rigid_body: RigidBodyHandle,
/// This effect's lifetime, in seconds /// This particle's lifetime, in seconds
lifetime: f32, lifetime: f32,
/// The size of this effect, /// The size of this particle,
/// given as height in world units. /// given as height in world units.
pub size: f32, pub size: f32,
/// Fade this effect over this many seconds as it expires /// Fade this particle over this many seconds as it expires
pub fade: f32, pub fade: f32,
/// If true, this effect has been destroyed, /// If true, this effect has been destroyed,
@ -30,7 +30,7 @@ pub struct PhysEffect {
} }
impl PhysEffect { impl PhysEffect {
/// Create a new effect inside `Wrapper` /// Create a new particle inside `Wrapper`
pub fn new( pub fn new(
ct: &Content, ct: &Content,
wrapper: &mut PhysWrapper, wrapper: &mut PhysWrapper,
@ -104,9 +104,4 @@ impl PhysEffect {
pub fn is_destroyed(&self) -> bool { pub fn is_destroyed(&self) -> bool {
self.is_destroyed self.is_destroyed
} }
/// The remaining lifetime of this effect, in seconds
pub fn remaining_lifetime(&self) -> f32 {
self.lifetime
}
} }

View File

@ -69,7 +69,7 @@ impl ShipCollapseSequence {
// The fraction of this collapse sequence that has been played // The fraction of this collapse sequence that has been played
let frac_done = self.elapsed / self.total_length; let frac_done = self.elapsed / self.total_length;
// TODO: slight random offset for event effects // TODO: slight random offset for event particles
// Trigger collapse events // Trigger collapse events
for event in &ship_content.collapse.events { for event in &ship_content.collapse.events {
@ -109,7 +109,7 @@ impl ShipCollapseSequence {
// Create collapse effects // Create collapse effects
for spawner in &ship_content.collapse.effects { for spawner in &ship_content.collapse.effects {
// Probability of adding an effect instance this frame. // Probability of adding a particle this frame.
// The area of this function over [0, 1] should be 1. // The area of this function over [0, 1] should be 1.
let pdf = |x: f32| { let pdf = |x: f32| {
let f = 0.2; let f = 0.2;

View File

@ -416,7 +416,7 @@ impl PhysShip {
} }
} }
/// Spawn this frame's effects /// Spawn this frame's particles
fn step_effects( fn step_effects(
&mut self, &mut self,
res: &mut PhysStepResources, res: &mut PhysStepResources,

View File

@ -93,12 +93,3 @@ pub struct PhysEffectImage {
/// The effect's rigidbody /// The effect's rigidbody
pub rigidbody: RigidBody, pub rigidbody: RigidBody,
} }
impl PhysEffectImage {
/// Get this effect's fade value
pub fn get_fade(&self) -> f32 {
let f = self.effect.fade;
let l = self.effect.remaining_lifetime();
return 1f32.min(l / f);
}
}

View File

@ -257,7 +257,6 @@ impl PhysSim {
res.timing.start_physics_sim(); res.timing.start_physics_sim();
// Update physics // Update physics
res.timing.start_physics_step();
self.wrapper.step(res.t); self.wrapper.step(res.t);
// Handle collision events // Handle collision events
@ -282,15 +281,12 @@ impl PhysSim {
self.collide_projectile_ship(&mut res, a, b); self.collide_projectile_ship(&mut res, a, b);
} }
} }
res.timing.mark_physics_step();
res.timing.start_physics_proj();
// Step and garbage-collect projectiles // Step and garbage-collect projectiles
self.projectiles.retain(|_, proj| { self.projectiles.retain(|_, proj| {
proj.step(&mut res, &mut self.new, &mut self.wrapper); proj.step(&mut res, &mut self.new, &mut self.wrapper);
!proj.should_remove() !proj.should_remove()
}); });
res.timing.mark_physics_proj();
// Step and garbage-collect ships // Step and garbage-collect ships
res.timing.start_physics_ships(); res.timing.start_physics_ships();
@ -300,13 +296,11 @@ impl PhysSim {
}); });
res.timing.mark_physics_ships(); res.timing.mark_physics_ships();
res.timing.start_physics_effects();
// Step and garbage-collect effects // Step and garbage-collect effects
self.effects.retain_mut(|x| { self.effects.retain_mut(|x| {
x.step(&res, &mut self.wrapper); x.step(&res, &mut self.wrapper);
!x.is_destroyed() !x.is_destroyed()
}); });
res.timing.mark_physics_effects();
// Process new objects // Process new objects
for p in self.new.projectiles.iter() { for p in self.new.projectiles.iter() {
@ -371,8 +365,8 @@ impl PhysSim {
self.projectiles.values() self.projectiles.values()
} }
/// Iterate over all effects in this physics system /// Iterate over all particles in this physics system
pub fn iter_effects(&self) -> impl Iterator<Item = &PhysEffect> + '_ { pub fn iter_particles(&self) -> impl Iterator<Item = &PhysEffect> + '_ {
self.effects.iter() self.effects.iter()
} }
} }

View File

@ -9,25 +9,13 @@ pub struct Timing {
pub frame: Duration, pub frame: Duration,
frame_timer: Instant, frame_timer: Instant,
/// The total time we spent simulating physics /// The time we spent simulating physics
pub physics_sim: Duration, pub physics_sim: Duration,
physics_sim_timer: Instant, physics_sim_timer: Instant,
/// The time we spent updating physics state
pub physics_step: Duration,
physics_step_timer: Instant,
/// The time we spent updating physics ships /// The time we spent updating physics ships
pub physics_ship: Duration, pub physics_ship: Duration,
physics_ship_timer: Instant, physics_ship_timer: Instant,
/// The time we spent updating physics projectiles
pub physics_proj: Duration,
physics_proj_timer: Instant,
/// The time we spent updating effects
pub physics_effect: Duration,
physics_effect_timer: Instant,
} }
// TODO: document each duration // TODO: document each duration
@ -39,12 +27,6 @@ impl Timing {
frame: Duration::ZERO, frame: Duration::ZERO,
physics_sim: Duration::ZERO, physics_sim: Duration::ZERO,
physics_ship: Duration::ZERO, physics_ship: Duration::ZERO,
physics_effect: Duration::ZERO,
physics_proj: Duration::ZERO,
physics_step: Duration::ZERO,
physics_effect_timer: Instant::now(),
physics_proj_timer: Instant::now(),
physics_step_timer: Instant::now(),
physics_sim_timer: Instant::now(), physics_sim_timer: Instant::now(),
physics_ship_timer: Instant::now(), physics_ship_timer: Instant::now(),
frame_timer: Instant::now(), frame_timer: Instant::now(),
@ -56,88 +38,28 @@ impl Timing {
self.frame_timer = Instant::now(); self.frame_timer = Instant::now();
} }
/// Record total frame compute time
pub fn mark_frame(&mut self) {
self.frame = self.frame_timer.elapsed();
}
/// Start physics sim timer /// Start physics sim timer
pub fn start_physics_sim(&mut self) { pub fn start_physics_sim(&mut self) {
self.physics_sim_timer = Instant::now(); self.physics_sim_timer = Instant::now();
} }
/// Record physics simulation time
pub fn mark_physics_sim(&mut self) {
self.physics_sim = self.physics_sim_timer.elapsed();
}
/// Start physics ship timer /// Start physics ship timer
pub fn start_physics_ships(&mut self) { pub fn start_physics_ships(&mut self) {
self.physics_ship_timer = Instant::now(); self.physics_ship_timer = Instant::now();
} }
/// Record total frame compute time
pub fn mark_frame(&mut self) {
self.frame = self.frame_timer.elapsed();
}
/// Record physics simulation time
pub fn mark_physics_sim(&mut self) {
self.physics_sim = self.physics_sim_timer.elapsed();
}
/// Record physics ship update time /// Record physics ship update time
pub fn mark_physics_ships(&mut self) { pub fn mark_physics_ships(&mut self) {
self.physics_ship = self.physics_ship_timer.elapsed(); self.physics_ship = self.physics_ship_timer.elapsed();
} }
/// Start physics step timer
pub fn start_physics_step(&mut self) {
self.physics_step_timer = Instant::now();
}
/// Record physics ship update time
pub fn mark_physics_step(&mut self) {
self.physics_step = self.physics_step_timer.elapsed();
}
/// Start physics ship timer
pub fn start_physics_proj(&mut self) {
self.physics_proj_timer = Instant::now();
}
/// Record physics ship update time
pub fn mark_physics_proj(&mut self) {
self.physics_proj = self.physics_proj_timer.elapsed();
}
/// Start physics ship timer
pub fn start_physics_effects(&mut self) {
self.physics_effect_timer = Instant::now();
}
/// Record physics ship update time
pub fn mark_physics_effects(&mut self) {
self.physics_effect = self.physics_effect_timer.elapsed();
}
/// Get current timing values as a pretty string
pub fn get_string(&self) -> String {
let mut s = String::new();
//s.push_str(&format!(
// "Overall {:6.00} fps\n\n",
// 1.0 / self.frame.as_secs_f32()
//));
let f = self.physics_sim.as_secs_f32();
s.push_str(&format!("Phys {:6.00} fps\n", 1.0 / f));
s.push_str(&format!(
"Step {:6.02}%\n",
100.0 * self.physics_step.as_secs_f32() / f
));
s.push_str(&format!(
"Proj {:05.02}%\n",
100.0 * self.physics_proj.as_secs_f32() / f
));
s.push_str(&format!(
"Ships {:05.02}%\n",
100.0 * self.physics_ship.as_secs_f32() / f
));
s.push_str(&format!(
"Efcts {:05.02}%",
100.0 * self.physics_effect.as_secs_f32() / f
));
return s;
}
} }