Skip to content

Commit a243052

Browse files
authored
Fix Particles Hosted on Particles Which Themselves Are Parented (#7085)
* Allow particles serving as particles hosts to provide their own parent to their children * Fix parent particles with parents
1 parent 05bf43b commit a243052

File tree

2 files changed

+34
-3
lines changed

2 files changed

+34
-3
lines changed

code/particle/hosts/EffectHostParticle.cpp

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,11 @@ EffectHostParticle::EffectHostParticle(particle::WeakParticlePtr particle, matri
1313
EffectHost(orientationOverride, orientationOverrideRelative), m_particle(std::move(particle)) {}
1414

1515
//Particle hosts can never have a parent, so it'll always return global space
16-
std::pair<vec3d, matrix> EffectHostParticle::getPositionAndOrientation(bool /*relativeToParent*/, float interp, const std::optional<vec3d>& tabled_offset) const {
16+
std::pair<vec3d, matrix> EffectHostParticle::getPositionAndOrientation(bool relativeToParent, float interp, const std::optional<vec3d>& tabled_offset) const {
1717
const auto& particle = m_particle.lock();
1818

19+
relativeToParent &= particle->attached_objnum >= 0;
20+
1921
vec3d pos;
2022
if (interp != 0.0f) {
2123
float vel_scalar = particle->parent_effect.getParticleEffect().m_lifetime_curves.get_output(particle::ParticleEffect::ParticleLifetimeCurvesOutput::VELOCITY_MULT, std::forward_as_tuple(*particle, vm_vec_mag_quick(&particle->velocity)));
@@ -25,6 +27,15 @@ std::pair<vec3d, matrix> EffectHostParticle::getPositionAndOrientation(bool /*re
2527
pos = particle->pos;
2628
}
2729

30+
//We might need to convert the position to global space if the parent particle has a parent
31+
if (particle->attached_objnum >= 0) {
32+
vec3d global_pos;
33+
vm_vec_linear_interpolate(&global_pos, &Objects[particle->attached_objnum].pos, &Objects[particle->attached_objnum].last_pos, interp);
34+
35+
vm_vec_unrotate(&pos, &pos, &Objects[particle->attached_objnum].orient);
36+
pos += global_pos;
37+
}
38+
2839
// find the particle direction (normalized vector)
2940
// note: this can't be computed for particles with 0 velocity, so use the safe version
3041
vec3d particle_dir;
@@ -34,8 +45,20 @@ std::pair<vec3d, matrix> EffectHostParticle::getPositionAndOrientation(bool /*re
3445
pos += particle_dir * tabled_offset->xyz.z;
3546

3647
matrix orientation;
37-
//As there's no sensible uvec in this particle orientation, relative override orientation is not that sensible. Nonetheless, allow it for compatibility, or future orientation-aware particles
38-
orientation = m_orientationOverrideRelative ? m_orientationOverride * *vm_vector_2_matrix_norm(&orientation, &particle_dir) : m_orientationOverride;
48+
49+
if (!relativeToParent) {
50+
//As there's no sensible uvec in this particle orientation, relative override orientation is not that sensible. Nonetheless, allow it for compatibility, or future orientation-aware particles
51+
orientation = m_orientationOverrideRelative ? m_orientationOverride * *vm_vector_2_matrix_norm(&orientation, &particle_dir) : m_orientationOverride;
52+
}
53+
else {
54+
//The position data here is in world space
55+
//Since we're operating in local space, we can take the orientation override at face value if it's relative, but we need to convert it from global to local otherwise.
56+
matrix global_orient_transpose;
57+
orientation = m_orientationOverrideRelative ? m_orientationOverride : m_orientationOverride * *vm_copy_transpose(&global_orient_transpose, &Objects[particle->attached_objnum].orient);
58+
59+
vm_vec_sub2(&pos, &Objects[particle->attached_objnum].pos);
60+
vm_vec_rotate(&pos, &pos, &Objects[particle->attached_objnum].orient);
61+
}
3962

4063
return { pos, orientation };
4164
}
@@ -44,6 +67,11 @@ vec3d EffectHostParticle::getVelocity() const {
4467
return m_particle.lock()->velocity;
4568
}
4669

70+
std::pair<int, int> EffectHostParticle::getParentObjAndSig() const {
71+
const auto& particle = m_particle.lock();
72+
return {particle->attached_objnum, particle->attached_sig};
73+
}
74+
4775
float EffectHostParticle::getLifetime() const {
4876
const auto& particle = m_particle.lock();
4977
return particle->max_life - particle->age;

code/particle/hosts/EffectHostParticle.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ class EffectHostParticle : public EffectHost {
1414

1515
vec3d getVelocity() const override;
1616

17+
//Particles can inherit parent particle's parents, but cannot actually be parented to another particle
18+
std::pair<int, int> getParentObjAndSig() const override;
19+
1720
float getLifetime() const override;
1821

1922
float getScale() const override;

0 commit comments

Comments
 (0)