#pragma once #include "object/object.h" #include "globalincs/pstypes.h" #include "globalincs/utility.h" #include "math/vecmat.h" #include #include namespace particle { struct particle; typedef std::weak_ptr 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; 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 get_frame(float interp = 0.0f) const; std::optional 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 getPositionAndOrientation(bool relativeToParent, float interp, const std::optional& 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() {} };