Files
BMagnu fcaa9dd998 Allow trail particles to be parented to their spawner (#7528)
* Adapt particle at runtime

* Refactor EffectHosts

* fix issues

* cleanup

* Remove live transitive particles

* paticle hosts now do local correctly

* Fix effecthostparticle local mode

* again

* Set particle host orientation

* I don't like mixed local and global vectors

* agaiiin

* Fix validity check

* parent foo

* Fix bugs, hopefully finally

* refactor

* Flip new table option for intuitiveness

* Fix support for GCC9 due to issues with LWG3052

* Address feedback
2026-07-15 15:10:15 +09:00

87 lines
2.7 KiB
C++

#pragma once
#include "object/object.h"
#include "globalincs/pstypes.h"
#include "globalincs/utility.h"
#include "math/vecmat.h"
#include <optional>
#include <variant>
namespace particle {
struct particle;
typedef std::weak_ptr<particle> WeakParticlePtr;
}
namespace effects {
struct attachment_object {
int objnum = -1;
int sig = -1;
};
struct attachment_particle {
particle::WeakParticlePtr particle = particle::WeakParticlePtr();
};
struct EffectAttachment {
private:
using underlying_type = std::variant<std::monostate, attachment_object, attachment_particle>;
underlying_type m_variant;
public:
vec3d local_pos_to_global(const vec3d& local_pos, float interp = 0.0f) const;
vec3d global_pos_to_local(const vec3d& global_pos) const ;
vec3d local_vel_to_global(const vec3d& local_vel) const;
vec3d global_vel_to_local(const vec3d& global_vel) const;
vec3d local_last_pos_to_global(const vec3d& last_pos) const;
bool is_valid() const;
bool is_not_attached() const;
//Note, a particle attachment's frame of reference is only an offset since particles DO NOT have an orientation.
//In rare circumstances, their global velocity is used to compute an orientation, but for all purposes of local
//frames of references, that is not the case.
std::pair<vec3d, matrix> get_frame(float interp = 0.0f) const;
std::optional<attachment_object> extract_object() const;
EffectAttachment resolve_true_parent() const;
constexpr EffectAttachment() : m_variant(std::monostate()) {};
EffectAttachment(const underlying_type& variant) : m_variant(variant) {};
EffectAttachment(underlying_type&& variant) : m_variant(std::move(variant)) {};
};
}
class EffectHost {
protected:
matrix m_orientationOverride;
bool m_orientationOverrideRelative;
EffectHost(matrix orientationOverride, bool orientationOverrideRelative) : m_orientationOverride(orientationOverride), m_orientationOverrideRelative(orientationOverrideRelative) {}
public:
virtual ~EffectHost() = default;
virtual std::pair<vec3d, matrix> getPositionAndOrientation(bool relativeToParent, float interp, const std::optional<vec3d>& tabled_offset) const = 0;
virtual vec3d getVelocity() const = 0;
virtual float getVelocityMagnitude() const {
vec3d velocity = getVelocity();
return vm_vec_mag_quick(&velocity);
}
virtual effects::EffectAttachment getParentAttachment() const { return {}; }
virtual int getParentSubmodel() const { return -1; }
virtual float getLifetime() const { return -1.f; }
virtual float getScale() const { return 1.f; }
virtual float getParticleMultiplier() const { return 1.f; }
virtual float getHostRadius() const { return 0.f; }
virtual bool isValid() const { return true; }
virtual void setupProcessing() {}
};