Added sticky particles
parent
a2b88af375
commit
98b460aba9
|
@ -1,75 +1,71 @@
|
||||||
[effect."small explosion"]
|
[effect."small explosion"]
|
||||||
sprite = "effect::explosion::small"
|
sprite = "effect::explosion::small"
|
||||||
lifetime = "inherit"
|
lifetime = "inherit"
|
||||||
inherit_velocity = "target"
|
|
||||||
size = 8.0
|
size = 8.0
|
||||||
size_rng = 1.6
|
size_rng = 1.6
|
||||||
angle_rng = 360
|
angle_rng = 360
|
||||||
velocity_scale_parent = 1.0
|
|
||||||
fade = 0.2
|
fade = 0.2
|
||||||
fade_rng = 0.1
|
fade_rng = 0.1
|
||||||
|
velocity.sticky = "parent"
|
||||||
|
|
||||||
|
|
||||||
[effect."large explosion"]
|
[effect."large explosion"]
|
||||||
sprite = "effect::explosion::large"
|
sprite = "effect::explosion::large"
|
||||||
lifetime = "inherit"
|
lifetime = "inherit"
|
||||||
inherit_velocity = "target"
|
|
||||||
size = 25.0
|
size = 25.0
|
||||||
size_rng = 5.0
|
size_rng = 5.0
|
||||||
angle_rng = 360
|
angle_rng = 360
|
||||||
velocity_scale_parent = 1.0
|
|
||||||
fade = 0.2
|
fade = 0.2
|
||||||
fade_rng = 0.1
|
fade_rng = 0.1
|
||||||
|
velocity.sticky = "parent"
|
||||||
|
|
||||||
|
|
||||||
[effect."huge explosion"]
|
[effect."huge explosion"]
|
||||||
sprite = "effect::explosion::huge"
|
sprite = "effect::explosion::huge"
|
||||||
lifetime = "inherit"
|
lifetime = "inherit"
|
||||||
inherit_velocity = "target"
|
|
||||||
size = 50.0
|
size = 50.0
|
||||||
size_rng = 10.0
|
size_rng = 10.0
|
||||||
angle_rng = 360
|
angle_rng = 360
|
||||||
velocity_scale_parent = 1.0
|
|
||||||
fade = 0.2
|
fade = 0.2
|
||||||
fade_rng = 0.1
|
fade_rng = 0.1
|
||||||
|
velocity.sticky = "parent"
|
||||||
|
|
||||||
|
|
||||||
[effect."blue spark"]
|
[effect."blue spark"]
|
||||||
sprite = "effect::spark::blue"
|
sprite = "effect::spark::blue"
|
||||||
lifetime = 0.5
|
lifetime = 0.5
|
||||||
lifetime_rng = 0.5
|
lifetime_rng = 0.5
|
||||||
inherit_velocity = "parent"
|
|
||||||
size = 4.0
|
size = 4.0
|
||||||
size_rng = 2.0
|
size_rng = 2.0
|
||||||
angle_rng = 360
|
angle_rng = 360
|
||||||
angvel_rng = 0.0
|
angvel_rng = 0.0
|
||||||
velocity_scale_parent = 1.0
|
|
||||||
fade = 0.2
|
fade = 0.2
|
||||||
fade_rng = 0.1
|
fade_rng = 0.1
|
||||||
|
velocity.sticky = "parent"
|
||||||
|
|
||||||
|
|
||||||
[effect."yellow spark"]
|
[effect."yellow spark"]
|
||||||
sprite = "effect::spark::yellow"
|
sprite = "effect::spark::yellow"
|
||||||
lifetime = "inherit"
|
lifetime = "inherit"
|
||||||
inherit_velocity = "parent"
|
|
||||||
size = 4.0
|
size = 4.0
|
||||||
size_rng = 2.0
|
size_rng = 2.0
|
||||||
angle_rng = 360
|
angle_rng = 360
|
||||||
angvel_rng = 0.0
|
angvel_rng = 0.0
|
||||||
velocity_scale_parent = 1.0
|
|
||||||
fade = 0.2
|
fade = 0.2
|
||||||
fade_rng = 0.1
|
fade_rng = 0.1
|
||||||
|
velocity.sticky = "parent"
|
||||||
|
|
||||||
|
|
||||||
[effect."red spark"]
|
[effect."red spark"]
|
||||||
sprite = "effect::spark::red"
|
sprite = "effect::spark::red"
|
||||||
lifetime = "inherit"
|
lifetime = "inherit"
|
||||||
inherit_velocity = "parent"
|
|
||||||
size = 4.0
|
size = 4.0
|
||||||
size_rng = 1.0
|
size_rng = 1.0
|
||||||
angle_rng = 360
|
angle_rng = 360
|
||||||
angvel_rng = 0.0
|
angvel_rng = 0.0
|
||||||
velocity_scale_parent = 1.0
|
|
||||||
fade = 0.2
|
fade = 0.2
|
||||||
fade_rng = 0.1
|
fade_rng = 0.1
|
||||||
|
velocity.sticky = "parent"
|
||||||
|
|
||||||
|
|
||||||
# Every effect has a parent, some effects have a target
|
# Every effect has a parent, some effects have a target
|
||||||
|
@ -90,12 +86,11 @@ angvel = 0.0 # Angular velocity at creation
|
||||||
|
|
||||||
|
|
||||||
# Total velocity is sum of parent + target velocities with scale applied
|
# Total velocity is sum of parent + target velocities with scale applied
|
||||||
velocity_scale_parent = 0.0 # Multiply velocity by this value
|
velocity.scale_parent = 0.0 # Multiply velocity by this value
|
||||||
velocity_scale_parent_rng = 0.0 # random variation of scale
|
velocity.scale_parent_rng = 0.0 # random variation of scale
|
||||||
velocity_scale_target = 1.0
|
velocity.scale_target = 1.0
|
||||||
velocity_scale_target_rng = 1.0
|
velocity.scale_target_rng = 1.0
|
||||||
|
velocity.direction_rng = 0.0 # Random variation of travel direction, in degrees, applied to velocity vector (/2 each side?)
|
||||||
direction_rng = 0.0 # Random variation of travel direction, in degrees, applied to velocity vector (/2 each side?)
|
|
||||||
|
|
||||||
fade = 0.2
|
fade = 0.2
|
||||||
fade_rng = 0.1
|
fade_rng = 0.1
|
||||||
|
|
|
@ -54,4 +54,4 @@ gun.projectile.impact_effect = "blaster impact"
|
||||||
gun.projectile.expire_effect.sprite = "effect::blaster"
|
gun.projectile.expire_effect.sprite = "effect::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
|
||||||
|
|
|
@ -23,13 +23,26 @@ pub(crate) mod syntax {
|
||||||
pub angle_rng: Option<f32>,
|
pub angle_rng: Option<f32>,
|
||||||
pub angvel: Option<f32>,
|
pub angvel: Option<f32>,
|
||||||
pub angvel_rng: Option<f32>,
|
pub angvel_rng: Option<f32>,
|
||||||
pub velocity_scale_parent: Option<f32>,
|
|
||||||
pub velocity_scale_parent_rng: Option<f32>,
|
|
||||||
pub velocity_scale_target: Option<f32>,
|
|
||||||
pub velocity_scale_target_rng: Option<f32>,
|
|
||||||
pub direction_rng: Option<f32>,
|
|
||||||
pub fade: Option<f32>,
|
pub fade: Option<f32>,
|
||||||
pub fade_rng: Option<f32>,
|
pub fade_rng: Option<f32>,
|
||||||
|
|
||||||
|
pub velocity: EffectVelocity,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
#[serde(untagged)]
|
||||||
|
pub enum EffectVelocity {
|
||||||
|
Sticky {
|
||||||
|
sticky: String,
|
||||||
|
},
|
||||||
|
Explicit {
|
||||||
|
scale_parent: Option<f32>,
|
||||||
|
scale_parent_rng: Option<f32>,
|
||||||
|
scale_target: Option<f32>,
|
||||||
|
scale_target_rng: Option<f32>,
|
||||||
|
direction_rng: Option<f32>,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
|
@ -69,12 +82,38 @@ pub(crate) mod syntax {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let velocity = match self.velocity {
|
||||||
|
EffectVelocity::Explicit {
|
||||||
|
scale_parent,
|
||||||
|
scale_parent_rng,
|
||||||
|
scale_target,
|
||||||
|
scale_target_rng,
|
||||||
|
direction_rng,
|
||||||
|
} => super::EffectVelocity::Explicit {
|
||||||
|
scale_parent: scale_parent.unwrap_or(0.0),
|
||||||
|
scale_parent_rng: scale_parent_rng.unwrap_or(0.0),
|
||||||
|
scale_target: scale_target.unwrap_or(0.0),
|
||||||
|
scale_target_rng: scale_target_rng.unwrap_or(0.0),
|
||||||
|
direction_rng: direction_rng.unwrap_or(0.0) / 2.0,
|
||||||
|
},
|
||||||
|
EffectVelocity::Sticky { sticky } => {
|
||||||
|
if sticky == "parent" {
|
||||||
|
super::EffectVelocity::StickyParent
|
||||||
|
} else if sticky == "target" {
|
||||||
|
super::EffectVelocity::StickyTarget
|
||||||
|
} else {
|
||||||
|
bail!("bad sticky specification `{}`", sticky);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let handle = EffectHandle {
|
let handle = EffectHandle {
|
||||||
index: content.effects.len(),
|
index: content.effects.len(),
|
||||||
};
|
};
|
||||||
content.effects.push(super::Effect {
|
content.effects.push(super::Effect {
|
||||||
handle,
|
handle,
|
||||||
sprite,
|
sprite,
|
||||||
|
velocity,
|
||||||
size: self.size,
|
size: self.size,
|
||||||
size_rng: self.size_rng.unwrap_or(0.0),
|
size_rng: self.size_rng.unwrap_or(0.0),
|
||||||
lifetime,
|
lifetime,
|
||||||
|
@ -83,11 +122,6 @@ pub(crate) mod syntax {
|
||||||
angle_rng: to_radians(self.angle_rng.unwrap_or(0.0) / 2.0),
|
angle_rng: to_radians(self.angle_rng.unwrap_or(0.0) / 2.0),
|
||||||
angvel: to_radians(self.angvel.unwrap_or(0.0)),
|
angvel: to_radians(self.angvel.unwrap_or(0.0)),
|
||||||
angvel_rng: to_radians(self.angvel_rng.unwrap_or(0.0)),
|
angvel_rng: to_radians(self.angvel_rng.unwrap_or(0.0)),
|
||||||
velocity_scale_parent: self.velocity_scale_parent.unwrap_or(0.0),
|
|
||||||
velocity_scale_parent_rng: self.velocity_scale_parent_rng.unwrap_or(0.0),
|
|
||||||
velocity_scale_target: self.velocity_scale_target.unwrap_or(0.0),
|
|
||||||
velocity_scale_target_rng: self.velocity_scale_target_rng.unwrap_or(0.0),
|
|
||||||
direction_rng: self.direction_rng.unwrap_or(0.0) / 2.0,
|
|
||||||
fade: self.fade.unwrap_or(0.0),
|
fade: self.fade.unwrap_or(0.0),
|
||||||
fade_rng: self.fade_rng.unwrap_or(0.0),
|
fade_rng: self.fade_rng.unwrap_or(0.0),
|
||||||
});
|
});
|
||||||
|
@ -157,27 +191,43 @@ pub struct Effect {
|
||||||
/// 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
|
|
||||||
pub velocity_scale_parent: f32,
|
|
||||||
|
|
||||||
/// Parent velocity random variation
|
|
||||||
pub velocity_scale_parent_rng: f32,
|
|
||||||
|
|
||||||
/// The amount of this effect's parent's target velocity to inherit.
|
|
||||||
/// If there is no target, this is zero.
|
|
||||||
pub velocity_scale_target: f32,
|
|
||||||
|
|
||||||
/// Target velocity random variation
|
|
||||||
pub velocity_scale_target_rng: f32,
|
|
||||||
|
|
||||||
/// Travel direction random variation
|
|
||||||
pub direction_rng: f32,
|
|
||||||
|
|
||||||
/// Fade this effect out over this many seconds as it ends
|
/// Fade this effect out over this many seconds as it ends
|
||||||
pub fade: f32,
|
pub fade: f32,
|
||||||
|
|
||||||
/// Random fade ariation
|
/// Random fade variation
|
||||||
pub fade_rng: f32,
|
pub fade_rng: f32,
|
||||||
|
|
||||||
|
/// How to compute this effect's velocity
|
||||||
|
pub velocity: EffectVelocity,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// How to compute an effect's velocity
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub enum EffectVelocity {
|
||||||
|
/// Stick to parent
|
||||||
|
StickyParent,
|
||||||
|
|
||||||
|
/// Stick to target.
|
||||||
|
/// Zero velocity if no target is given.
|
||||||
|
StickyTarget,
|
||||||
|
|
||||||
|
/// Compute velocity from parent and target
|
||||||
|
Explicit {
|
||||||
|
/// How much of the parent's velocity to inherit
|
||||||
|
scale_parent: f32,
|
||||||
|
|
||||||
|
/// Random variation of scale_parent
|
||||||
|
scale_parent_rng: f32,
|
||||||
|
|
||||||
|
/// How much of the target's velocity to keep
|
||||||
|
scale_target: f32,
|
||||||
|
|
||||||
|
/// Random variation of scale_target
|
||||||
|
scale_target_rng: f32,
|
||||||
|
|
||||||
|
/// Random variation of travel direction
|
||||||
|
direction_rng: f32,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
impl crate::Build for Effect {
|
impl crate::Build for Effect {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use galactica_content::{Content, EffectHandle, SpriteAutomaton};
|
use galactica_content::{Content, EffectHandle, EffectVelocity, SpriteAutomaton};
|
||||||
use nalgebra::{Rotation2, Vector2};
|
use nalgebra::{Point2, Rotation2, Vector2};
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
use rapier2d::dynamics::{RigidBodyBuilder, RigidBodyHandle, RigidBodyType};
|
use rapier2d::dynamics::{RevoluteJointBuilder, RigidBodyBuilder, RigidBodyHandle, RigidBodyType};
|
||||||
|
|
||||||
use crate::phys::{PhysStepResources, PhysWrapper};
|
use crate::phys::{PhysStepResources, PhysWrapper};
|
||||||
|
|
||||||
|
@ -35,25 +35,18 @@ impl PhysEffect {
|
||||||
ct: &Content,
|
ct: &Content,
|
||||||
wrapper: &mut PhysWrapper,
|
wrapper: &mut PhysWrapper,
|
||||||
effect: EffectHandle,
|
effect: EffectHandle,
|
||||||
|
// Where to spawn the particle, in world space.
|
||||||
pos: Vector2<f32>,
|
pos: Vector2<f32>,
|
||||||
parent_angle: f32,
|
parent: RigidBodyHandle,
|
||||||
parent_velocity: Vector2<f32>,
|
target: Option<RigidBodyHandle>,
|
||||||
target_velocity: Vector2<f32>,
|
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let effect = ct.get_effect(effect);
|
let effect = ct.get_effect(effect);
|
||||||
|
|
||||||
let mut rng = rand::thread_rng();
|
let mut rng = rand::thread_rng();
|
||||||
|
let parent_body = wrapper.get_rigid_body(parent).unwrap();
|
||||||
let velocity = {
|
let parent_angle = parent_body.rotation().angle();
|
||||||
let a =
|
let parent_pos = *parent_body.translation();
|
||||||
rng.gen_range(-effect.velocity_scale_parent_rng..=effect.velocity_scale_parent_rng);
|
let parent_velocity = parent_body.velocity_at_point(parent_body.center_of_mass());
|
||||||
let b =
|
|
||||||
rng.gen_range(-effect.velocity_scale_target_rng..=effect.velocity_scale_target_rng);
|
|
||||||
|
|
||||||
let velocity = ((effect.velocity_scale_parent + a) * parent_velocity)
|
|
||||||
+ ((effect.velocity_scale_target + b) * target_velocity);
|
|
||||||
|
|
||||||
Rotation2::new(rng.gen_range(-effect.direction_rng..=effect.direction_rng)) * velocity
|
|
||||||
};
|
|
||||||
|
|
||||||
let angvel = if effect.angvel_rng == 0.0 {
|
let angvel = if effect.angvel_rng == 0.0 {
|
||||||
effect.angvel
|
effect.angvel
|
||||||
|
@ -66,22 +59,112 @@ impl PhysEffect {
|
||||||
parent_angle + effect.angle + rng.gen_range(-effect.angle_rng..=effect.angle_rng)
|
parent_angle + effect.angle + rng.gen_range(-effect.angle_rng..=effect.angle_rng)
|
||||||
};
|
};
|
||||||
|
|
||||||
let rb = RigidBodyBuilder::new(RigidBodyType::KinematicVelocityBased)
|
let target_velocity = {
|
||||||
.position(pos.into())
|
if let Some(target) = target {
|
||||||
.rotation(angle)
|
let target_body = wrapper.get_rigid_body(target).unwrap();
|
||||||
.angvel(angvel)
|
target_body.velocity_at_point(&Point2::new(pos.x, pos.y))
|
||||||
.linvel(velocity);
|
} else {
|
||||||
|
Vector2::new(0.0, 0.0)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
PhysEffect {
|
match effect.velocity {
|
||||||
anim: SpriteAutomaton::new(ct, effect.sprite),
|
EffectVelocity::StickyTarget | EffectVelocity::StickyParent => {
|
||||||
rigid_body: wrapper.insert_rigid_body(rb.build()),
|
let rigid_body = wrapper.insert_rigid_body(
|
||||||
lifetime: 0f32
|
RigidBodyBuilder::new(RigidBodyType::Dynamic)
|
||||||
.max(effect.lifetime + rng.gen_range(-effect.lifetime_rng..=effect.lifetime_rng)),
|
.additional_mass(f32::MIN_POSITIVE)
|
||||||
|
.position(pos.into())
|
||||||
|
.rotation(angle)
|
||||||
|
.angvel(angvel)
|
||||||
|
.build(),
|
||||||
|
);
|
||||||
|
|
||||||
// Make sure size isn't negative. This check should be on EVERY rng!
|
match effect.velocity {
|
||||||
size: 0f32.max(effect.size + rng.gen_range(-effect.size_rng..=effect.size_rng)),
|
EffectVelocity::StickyParent => {
|
||||||
fade: 0f32.max(effect.fade + rng.gen_range(-effect.fade_rng..=effect.fade_rng)),
|
let d = Rotation2::new(-parent_angle) * (pos - parent_pos);
|
||||||
is_destroyed: false,
|
|
||||||
|
wrapper.add_joint(
|
||||||
|
rigid_body,
|
||||||
|
parent,
|
||||||
|
RevoluteJointBuilder::new()
|
||||||
|
.local_anchor1(Point2::new(0.0, 0.0))
|
||||||
|
.local_anchor2(Point2::new(d.x, d.y)),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
EffectVelocity::StickyTarget => {
|
||||||
|
if target.is_some() {
|
||||||
|
let target_body = wrapper.get_rigid_body(target.unwrap()).unwrap();
|
||||||
|
|
||||||
|
// Correct for rotation, since joint coordinates are relative
|
||||||
|
// and input coordinates are in world space.
|
||||||
|
let d = Rotation2::new(-target_body.rotation().angle())
|
||||||
|
* (pos - target_body.translation());
|
||||||
|
|
||||||
|
wrapper.add_joint(
|
||||||
|
rigid_body,
|
||||||
|
target.unwrap(),
|
||||||
|
RevoluteJointBuilder::new()
|
||||||
|
.local_anchor1(Point2::new(0.0, 0.0))
|
||||||
|
.local_anchor2(Point2::new(d.x, d.y)),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => unreachable!("lol what?"),
|
||||||
|
};
|
||||||
|
|
||||||
|
PhysEffect {
|
||||||
|
anim: SpriteAutomaton::new(ct, effect.sprite),
|
||||||
|
rigid_body,
|
||||||
|
lifetime: 0f32.max(
|
||||||
|
effect.lifetime + rng.gen_range(-effect.lifetime_rng..=effect.lifetime_rng),
|
||||||
|
),
|
||||||
|
|
||||||
|
// Make sure size isn't negative. This check should be on EVERY rng!
|
||||||
|
size: 0f32.max(effect.size + rng.gen_range(-effect.size_rng..=effect.size_rng)),
|
||||||
|
fade: 0f32.max(effect.fade + rng.gen_range(-effect.fade_rng..=effect.fade_rng)),
|
||||||
|
is_destroyed: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EffectVelocity::Explicit {
|
||||||
|
scale_parent,
|
||||||
|
scale_parent_rng,
|
||||||
|
scale_target,
|
||||||
|
scale_target_rng,
|
||||||
|
direction_rng,
|
||||||
|
} => {
|
||||||
|
let velocity = {
|
||||||
|
let a = rng.gen_range(-scale_parent_rng..=scale_parent_rng);
|
||||||
|
let b = rng.gen_range(-scale_target_rng..=scale_target_rng);
|
||||||
|
|
||||||
|
let velocity = ((scale_parent + a) * parent_velocity)
|
||||||
|
+ ((scale_target + b) * target_velocity);
|
||||||
|
|
||||||
|
Rotation2::new(rng.gen_range(-direction_rng..=direction_rng)) * velocity
|
||||||
|
};
|
||||||
|
|
||||||
|
let rigid_body = wrapper.insert_rigid_body(
|
||||||
|
RigidBodyBuilder::new(RigidBodyType::KinematicVelocityBased)
|
||||||
|
.position(pos.into())
|
||||||
|
.rotation(angle)
|
||||||
|
.angvel(angvel)
|
||||||
|
.linvel(velocity)
|
||||||
|
.build(),
|
||||||
|
);
|
||||||
|
|
||||||
|
PhysEffect {
|
||||||
|
anim: SpriteAutomaton::new(ct, effect.sprite),
|
||||||
|
rigid_body,
|
||||||
|
lifetime: 0f32.max(
|
||||||
|
effect.lifetime + rng.gen_range(-effect.lifetime_rng..=effect.lifetime_rng),
|
||||||
|
),
|
||||||
|
|
||||||
|
// Make sure size isn't negative. This check should be on EVERY rng!
|
||||||
|
size: 0f32.max(effect.size + rng.gen_range(-effect.size_rng..=effect.size_rng)),
|
||||||
|
fade: 0f32.max(effect.fade + rng.gen_range(-effect.fade_rng..=effect.fade_rng)),
|
||||||
|
is_destroyed: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
use galactica_content::{AnimationState, Content, FactionHandle, Projectile, SpriteAutomaton};
|
use galactica_content::{AnimationState, Content, FactionHandle, Projectile, SpriteAutomaton};
|
||||||
use nalgebra::Vector2;
|
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
use rapier2d::{dynamics::RigidBodyHandle, geometry::ColliderHandle};
|
use rapier2d::{dynamics::RigidBodyHandle, geometry::ColliderHandle};
|
||||||
|
|
||||||
|
@ -97,35 +96,18 @@ impl PhysProjectile {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let rigid_body = wrapper.remove_rigid_body(self.rigid_body).unwrap();
|
let rb = wrapper.get_rigid_body(self.rigid_body).unwrap();
|
||||||
let mut rng = rand::thread_rng();
|
|
||||||
|
|
||||||
if expire {
|
if expire {
|
||||||
match &self.content.expire_effect {
|
match &self.content.expire_effect {
|
||||||
None => {}
|
None => {}
|
||||||
Some(handle) => {
|
Some(handle) => {
|
||||||
let x = res.ct.get_effect(*handle);
|
|
||||||
let pos = *rigid_body.translation();
|
|
||||||
let vel = rigid_body.velocity_at_point(rigid_body.center_of_mass());
|
|
||||||
let angle = rigid_body.rotation().angle();
|
|
||||||
|
|
||||||
let velocity = {
|
|
||||||
let a = rng
|
|
||||||
.gen_range(-x.velocity_scale_parent_rng..=x.velocity_scale_parent_rng);
|
|
||||||
|
|
||||||
let velocity = (x.velocity_scale_parent + a) * vel;
|
|
||||||
|
|
||||||
velocity
|
|
||||||
};
|
|
||||||
|
|
||||||
new.effects.push(PhysEffect::new(
|
new.effects.push(PhysEffect::new(
|
||||||
res.ct,
|
res.ct,
|
||||||
wrapper,
|
wrapper,
|
||||||
*handle,
|
*handle,
|
||||||
pos,
|
*rb.translation(),
|
||||||
angle,
|
self.rigid_body,
|
||||||
velocity,
|
None,
|
||||||
Vector2::new(0.0, 0.0),
|
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,17 +88,13 @@ impl ShipCollapseSequence {
|
||||||
};
|
};
|
||||||
let pos = ship_pos + (ship_rot * pos);
|
let pos = ship_pos + (ship_rot * pos);
|
||||||
|
|
||||||
let velocity =
|
|
||||||
rigid_body.velocity_at_point(&Point2::new(pos.x, pos.y));
|
|
||||||
|
|
||||||
new.effects.push(PhysEffect::new(
|
new.effects.push(PhysEffect::new(
|
||||||
res.ct,
|
res.ct,
|
||||||
wrapper,
|
wrapper,
|
||||||
spawner.effect,
|
spawner.effect,
|
||||||
pos,
|
pos,
|
||||||
0.0,
|
rigid_body_handle,
|
||||||
velocity,
|
None,
|
||||||
Vector2::new(0.0, 0.0),
|
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -133,16 +129,13 @@ impl ShipCollapseSequence {
|
||||||
|
|
||||||
// Position, adjusted for ship rotation
|
// Position, adjusted for ship rotation
|
||||||
let pos = ship_pos + (ship_rot * pos);
|
let pos = ship_pos + (ship_rot * pos);
|
||||||
let vel = rigid_body.velocity_at_point(&Point2::new(pos.x, pos.y));
|
|
||||||
|
|
||||||
new.effects.push(PhysEffect::new(
|
new.effects.push(PhysEffect::new(
|
||||||
res.ct,
|
res.ct,
|
||||||
wrapper,
|
wrapper,
|
||||||
spawner.effect,
|
spawner.effect,
|
||||||
pos,
|
pos,
|
||||||
0.0,
|
rigid_body_handle,
|
||||||
vel,
|
None,
|
||||||
Vector2::new(0.0, 0.0),
|
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -453,16 +453,14 @@ impl PhysShip {
|
||||||
};
|
};
|
||||||
|
|
||||||
let pos = ship_pos + (Rotation2::new(ship_ang) * pos);
|
let pos = ship_pos + (Rotation2::new(ship_ang) * pos);
|
||||||
let velocity = rigid_body.velocity_at_point(&Point2::new(pos.x, pos.y));
|
|
||||||
|
|
||||||
new.effects.push(PhysEffect::new(
|
new.effects.push(PhysEffect::new(
|
||||||
res.ct,
|
res.ct,
|
||||||
wrapper,
|
wrapper,
|
||||||
e.effect,
|
e.effect,
|
||||||
pos.into(),
|
pos,
|
||||||
0.0,
|
self.rigid_body,
|
||||||
velocity,
|
None,
|
||||||
Vector2::new(0.0, 0.0),
|
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -126,25 +126,17 @@ impl PhysSim {
|
||||||
// Borrow again, we can only have one at a time
|
// Borrow again, we can only have one at a time
|
||||||
let pr = self.wrapper.get_rigid_body(projectile.rigid_body).unwrap();
|
let pr = self.wrapper.get_rigid_body(projectile.rigid_body).unwrap();
|
||||||
let pos = *pr.translation();
|
let pos = *pr.translation();
|
||||||
let angle = pr.rotation().angle();
|
|
||||||
|
|
||||||
match &projectile.content.impact_effect {
|
match &projectile.content.impact_effect {
|
||||||
None => {}
|
None => {}
|
||||||
Some(x) => {
|
Some(x) => {
|
||||||
let r = ship.rigid_body;
|
|
||||||
let sr = self.wrapper.get_rigid_body(r).unwrap();
|
|
||||||
let parent_velocity = pr.velocity_at_point(pr.center_of_mass());
|
|
||||||
let target_velocity =
|
|
||||||
sr.velocity_at_point(&nalgebra::Point2::new(pos.x, pos.y));
|
|
||||||
|
|
||||||
self.effects.push(PhysEffect::new(
|
self.effects.push(PhysEffect::new(
|
||||||
res.ct,
|
res.ct,
|
||||||
&mut self.wrapper,
|
&mut self.wrapper,
|
||||||
*x,
|
*x,
|
||||||
pos,
|
pos,
|
||||||
angle,
|
projectile.rigid_body,
|
||||||
parent_velocity,
|
Some(ship.rigid_body),
|
||||||
target_velocity,
|
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
use crossbeam::channel::Receiver;
|
use crossbeam::channel::Receiver;
|
||||||
use rapier2d::{
|
use rapier2d::{
|
||||||
dynamics::{
|
dynamics::{
|
||||||
CCDSolver, ImpulseJointSet, IntegrationParameters, IslandManager, MultibodyJointSet,
|
CCDSolver, GenericJoint, ImpulseJointSet, IntegrationParameters, IslandManager,
|
||||||
RigidBody, RigidBodyHandle, RigidBodySet,
|
MultibodyJointSet, RigidBody, RigidBodyHandle, RigidBodySet,
|
||||||
},
|
},
|
||||||
geometry::{BroadPhase, Collider, ColliderHandle, ColliderSet, CollisionEvent, NarrowPhase},
|
geometry::{BroadPhase, Collider, ColliderHandle, ColliderSet, CollisionEvent, NarrowPhase},
|
||||||
na::vector,
|
na::vector,
|
||||||
|
@ -16,12 +16,12 @@ pub struct PhysWrapper {
|
||||||
im: IslandManager,
|
im: IslandManager,
|
||||||
bp: BroadPhase,
|
bp: BroadPhase,
|
||||||
np: NarrowPhase,
|
np: NarrowPhase,
|
||||||
ij: ImpulseJointSet,
|
|
||||||
mj: MultibodyJointSet,
|
mj: MultibodyJointSet,
|
||||||
ccd: CCDSolver,
|
ccd: CCDSolver,
|
||||||
|
|
||||||
rigid_body_set: RigidBodySet,
|
rigid_body_set: RigidBodySet,
|
||||||
collider_set: ColliderSet,
|
collider_set: ColliderSet,
|
||||||
|
joint_set: ImpulseJointSet,
|
||||||
|
|
||||||
collision_handler: ChannelEventCollector,
|
collision_handler: ChannelEventCollector,
|
||||||
|
|
||||||
|
@ -42,7 +42,6 @@ impl PhysWrapper {
|
||||||
im: IslandManager::new(),
|
im: IslandManager::new(),
|
||||||
bp: BroadPhase::new(),
|
bp: BroadPhase::new(),
|
||||||
np: NarrowPhase::new(),
|
np: NarrowPhase::new(),
|
||||||
ij: ImpulseJointSet::new(),
|
|
||||||
mj: MultibodyJointSet::new(),
|
mj: MultibodyJointSet::new(),
|
||||||
ccd: CCDSolver::new(),
|
ccd: CCDSolver::new(),
|
||||||
collision_queue,
|
collision_queue,
|
||||||
|
@ -50,6 +49,7 @@ impl PhysWrapper {
|
||||||
|
|
||||||
rigid_body_set: RigidBodySet::new(),
|
rigid_body_set: RigidBodySet::new(),
|
||||||
collider_set: ColliderSet::new(),
|
collider_set: ColliderSet::new(),
|
||||||
|
joint_set: ImpulseJointSet::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ impl PhysWrapper {
|
||||||
&mut self.np,
|
&mut self.np,
|
||||||
&mut self.rigid_body_set,
|
&mut self.rigid_body_set,
|
||||||
&mut self.collider_set,
|
&mut self.collider_set,
|
||||||
&mut self.ij,
|
&mut self.joint_set,
|
||||||
&mut self.mj,
|
&mut self.mj,
|
||||||
&mut self.ccd,
|
&mut self.ccd,
|
||||||
None,
|
None,
|
||||||
|
@ -79,7 +79,7 @@ impl PhysWrapper {
|
||||||
body,
|
body,
|
||||||
&mut self.im,
|
&mut self.im,
|
||||||
&mut self.collider_set,
|
&mut self.collider_set,
|
||||||
&mut self.ij,
|
&mut self.joint_set,
|
||||||
&mut self.mj,
|
&mut self.mj,
|
||||||
true,
|
true,
|
||||||
);
|
);
|
||||||
|
@ -121,4 +121,14 @@ impl PhysWrapper {
|
||||||
self.collider_set
|
self.collider_set
|
||||||
.insert_with_parent(collider, parent_handle, &mut self.rigid_body_set)
|
.insert_with_parent(collider, parent_handle, &mut self.rigid_body_set)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Add an impulse joint between two bodies
|
||||||
|
pub fn add_joint(
|
||||||
|
&mut self,
|
||||||
|
body1: RigidBodyHandle,
|
||||||
|
body2: RigidBodyHandle,
|
||||||
|
joint: impl Into<GenericJoint>,
|
||||||
|
) {
|
||||||
|
self.joint_set.insert(body1, body2, joint, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue