mirror of https://github.com/AxioDL/metaforce.git
Implement CFlameWarp
This commit is contained in:
parent
149eed4b73
commit
53ec80ce72
|
@ -123,16 +123,6 @@ void CPlayerState::PutTo(CBitStreamWriter& stream)
|
|||
stream.WriteEncoded(x180_scanCompletionRate.second, CBitStreamWriter::GetBitCount(0x100));
|
||||
}
|
||||
|
||||
static const float unk[] =
|
||||
{
|
||||
0.2f, 0.1f, 0.2f, 0.2f, 1.f
|
||||
};
|
||||
|
||||
float CPlayerState::sub_80091204() const
|
||||
{
|
||||
return unk[u32(x8_currentBeam)];
|
||||
}
|
||||
|
||||
static const u32 costs[] =
|
||||
{
|
||||
5, 10, 10, 10, 1
|
||||
|
|
|
@ -128,7 +128,6 @@ private:
|
|||
CStaticInterference x188_staticIntf;
|
||||
public:
|
||||
|
||||
float sub_80091204() const;
|
||||
u32 GetMissileCostForAltAttack() const;
|
||||
float GetComboFireAmmoPeriod() const;
|
||||
static constexpr float GetMissileComboChargeFactor() { return 1.8f; }
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
#include "CParticleSwoosh.hpp"
|
||||
#include "CParticleElectric.hpp"
|
||||
#include "Graphics/CModel.hpp"
|
||||
|
||||
#include "Graphics/Shaders/CElementGenShaders.hpp"
|
||||
#include "CWarp.hpp"
|
||||
|
||||
#define MAX_GLOBAL_PARTICLES 2560
|
||||
|
||||
|
@ -24,7 +24,7 @@ int CElementGen::g_ParticleAliveCount;
|
|||
int CElementGen::g_ParticleSystemAliveCount;
|
||||
bool CElementGen::g_ParticleSystemInitialized = false;
|
||||
bool CElementGen::sMoveRedToAlphaBuffer = false;
|
||||
CElementGen::CParticle* CElementGen::g_currentParticle = nullptr;
|
||||
CParticle* CElementGen::g_currentParticle = nullptr;
|
||||
|
||||
struct SParticleInstanceTex
|
||||
{
|
||||
|
@ -533,6 +533,13 @@ void CElementGen::UpdateExistingParticles()
|
|||
AccumulateBounds(particle.x4_pos, particle.x2c_lineLengthOrSize);
|
||||
++it;
|
||||
}
|
||||
|
||||
if (x30_particles.empty())
|
||||
return;
|
||||
|
||||
for (CWarp* warp : x4_modifierList)
|
||||
if (warp->UpdateWarp())
|
||||
warp->ModifyParticles(x30_particles);
|
||||
}
|
||||
|
||||
void CElementGen::CreateNewParticles(int count)
|
||||
|
@ -566,7 +573,7 @@ void CElementGen::CreateNewParticles(int count)
|
|||
if (x2c_orientType == EModelOrientationType::One)
|
||||
x50_parentMatrices[x30_particles.size()-1] = x1d8_orientation.buildMatrix3f();
|
||||
|
||||
CElementGen::CParticle& particle = x30_particles.back();
|
||||
CParticle& particle = x30_particles.back();
|
||||
particle.x28_startFrame = x74_curFrame;
|
||||
if (CIntElement* ltme = desc->x34_x28_LTME.get())
|
||||
ltme->GetValue(0, particle.x0_endFrame);
|
||||
|
|
|
@ -58,17 +58,6 @@ public:
|
|||
CParticleListItem(s16 idx)
|
||||
: x0_partIdx(idx) {}
|
||||
};
|
||||
struct CParticle
|
||||
{
|
||||
int x0_endFrame = 0;
|
||||
zeus::CVector3f x4_pos;
|
||||
zeus::CVector3f x10_prevPos;
|
||||
zeus::CVector3f x1c_vel;
|
||||
int x28_startFrame = 0;
|
||||
float x2c_lineLengthOrSize = 0.f;
|
||||
float x30_lineWidthOrRota = 0.f;
|
||||
zeus::CColor x34_color = {0.f, 0.f, 0.f, 1.f};
|
||||
};
|
||||
static CParticle* g_currentParticle;
|
||||
private:
|
||||
friend class CElementGenShaders;
|
||||
|
|
|
@ -1,6 +1,92 @@
|
|||
#include "CFlameWarp.hpp"
|
||||
#include "CStateManager.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
|
||||
void CFlameWarp::ModifyParticles(std::vector<CParticle>& particles)
|
||||
{
|
||||
if (x9c_stateMgr == 0 || particles.size() < 9)
|
||||
return;
|
||||
|
||||
std::vector<std::pair<float, u8>> vec;
|
||||
vec.reserve(particles.size());
|
||||
|
||||
x90_minSize = FLT_MAX;
|
||||
x94_maxSize = FLT_MIN;
|
||||
float maxTransp = 0.f;
|
||||
u8 idx = 0;
|
||||
for (CParticle& particle : particles)
|
||||
{
|
||||
float transp = 1.f - particle.x34_color.a;
|
||||
if (transp > maxTransp)
|
||||
{
|
||||
float distSq = (particle.x4_pos - x74_warpPoint).magSquared();
|
||||
if (distSq > x8c_maxDistSq && distSq < x98_maxInfluenceDistSq)
|
||||
{
|
||||
x8c_maxDistSq = distSq;
|
||||
maxTransp = transp;
|
||||
x80_floatingPoint = particle.x4_pos;
|
||||
}
|
||||
}
|
||||
|
||||
if (particle.x2c_lineLengthOrSize < x90_minSize)
|
||||
x90_minSize = particle.x2c_lineLengthOrSize;
|
||||
if (particle.x2c_lineLengthOrSize > x94_maxSize)
|
||||
x94_maxSize = particle.x2c_lineLengthOrSize;
|
||||
|
||||
vec.emplace_back(transp, idx);
|
||||
|
||||
if (xa0_25_collisionWarp)
|
||||
{
|
||||
zeus::CVector3f delta = particle.x4_pos - particle.x10_prevPos;
|
||||
if (delta.magSquared() >= 0.0011920929f)
|
||||
{
|
||||
zeus::CVector3f deltaNorm = delta.normalized();
|
||||
zeus::CVector3f behindPos = particle.x10_prevPos - deltaNorm * 5.f;
|
||||
zeus::CVector3f fullDelta = particle.x4_pos - behindPos;
|
||||
CRayCastResult result =
|
||||
x9c_stateMgr->RayStaticIntersection(behindPos, deltaNorm, fullDelta.magnitude(),
|
||||
CMaterialFilter::MakeIncludeExclude({EMaterialTypes::Solid},
|
||||
{EMaterialTypes::ProjectilePassthrough}));
|
||||
if (result.IsValid())
|
||||
{
|
||||
float dist = result.GetPlane().pointToPlaneDist(particle.x4_pos);
|
||||
if (dist <= 0.f)
|
||||
{
|
||||
particle.x4_pos =- result.GetPlane().normal() * dist;
|
||||
if (result.GetPlane().normal().dot(particle.x1c_vel) < 0.f)
|
||||
{
|
||||
zeus::CVector3f prevStepPos = particle.x4_pos - particle.x1c_vel;
|
||||
particle.x4_pos += (-result.GetPlane().pointToPlaneDist(prevStepPos) /
|
||||
particle.x1c_vel.dot(result.GetPlane().normal()) - 1.f) * particle.x1c_vel;
|
||||
particle.x1c_vel -= particle.x1c_vel * 0.001f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
++idx;
|
||||
}
|
||||
|
||||
std::sort(vec.begin(), vec.end(), [](auto& a, auto& b) { return a.first < b.first; });
|
||||
|
||||
for (int i=0 ; i<9 ; ++i)
|
||||
{
|
||||
CParticle& part = particles[vec[i].second];
|
||||
x4_vecs[i] = part.x4_pos;
|
||||
if (i > 0)
|
||||
{
|
||||
zeus::CVector3f delta = x4_vecs[i] - x4_vecs[i-1];
|
||||
if (delta.magnitude() < 0.0011920929f)
|
||||
x4_vecs[i] += delta.normalized() * 0.0011920929f;
|
||||
}
|
||||
}
|
||||
|
||||
x4_vecs[0] = x74_warpPoint;
|
||||
x80_floatingPoint = x4_vecs[8];
|
||||
xa0_26_processed = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -5,33 +5,36 @@
|
|||
|
||||
namespace urde
|
||||
{
|
||||
class CStateManager;
|
||||
|
||||
class CFlameWarp : public CWarp
|
||||
{
|
||||
zeus::CVector3f x4;
|
||||
zeus::CVector3f xc;
|
||||
float x1c;
|
||||
float x20;
|
||||
int x24;
|
||||
bool x28_activated : 1;
|
||||
|
||||
rstl::reserved_vector<zeus::CVector3f, 9> x4_vecs;
|
||||
zeus::CVector3f x74_warpPoint;
|
||||
zeus::CVector3f x80_floatingPoint;
|
||||
float x8c_maxDistSq = 0.f;
|
||||
float x90_minSize = FLT_MAX;
|
||||
float x94_maxSize = FLT_MIN;
|
||||
float x98_maxInfluenceDistSq;
|
||||
CStateManager* x9c_stateMgr = nullptr;
|
||||
bool xa0_24_activated : 1;
|
||||
bool xa0_25_collisionWarp : 1;
|
||||
bool xa0_26_processed : 1;
|
||||
public:
|
||||
CFlameWarp(float a, const zeus::CVector3f& b)
|
||||
: x4(b), x1c(0.0), x20(a * a), x24(0)
|
||||
CFlameWarp(float maxInfluenceDist, const zeus::CVector3f& warpPoint, bool collisionWarp)
|
||||
: x74_warpPoint(warpPoint), x80_floatingPoint(warpPoint),
|
||||
x98_maxInfluenceDistSq(maxInfluenceDist * maxInfluenceDist)
|
||||
{
|
||||
x28_activated = false;
|
||||
x4_vecs.resize(9, warpPoint);
|
||||
xa0_24_activated = false;
|
||||
xa0_25_collisionWarp = collisionWarp;
|
||||
xa0_26_processed = false;
|
||||
}
|
||||
|
||||
~CFlameWarp() {}
|
||||
|
||||
bool UpdateWarp() { return x28_activated; }
|
||||
void ModifyParticles(int, int, int *,
|
||||
zeus::CVector3f*,
|
||||
zeus::CVector3f*,
|
||||
zeus::CVector3f*,
|
||||
zeus::CColor*,
|
||||
float*, float*) {}
|
||||
void Activate(bool val) { x28_activated = val; }
|
||||
bool IsActivated() { return x28_activated; }
|
||||
bool UpdateWarp() { return xa0_24_activated; }
|
||||
void ModifyParticles(std::vector<CParticle>& particles);
|
||||
void Activate(bool val) { xa0_24_activated = val; }
|
||||
bool IsActivated() { return xa0_24_activated; }
|
||||
FourCC Get4CharID() { return FOURCC('FWRP'); }
|
||||
};
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
|
||||
#include "RetroTypes.hpp"
|
||||
#include "Graphics/CLight.hpp"
|
||||
#include "CWarp.hpp"
|
||||
#include "zeus/CColor.hpp"
|
||||
#include "zeus/CVector3f.hpp"
|
||||
#include "zeus/CTransform.hpp"
|
||||
|
@ -12,9 +11,23 @@
|
|||
|
||||
namespace urde
|
||||
{
|
||||
class CWarp;
|
||||
|
||||
struct CParticle
|
||||
{
|
||||
int x0_endFrame = 0;
|
||||
zeus::CVector3f x4_pos;
|
||||
zeus::CVector3f x10_prevPos;
|
||||
zeus::CVector3f x1c_vel;
|
||||
int x28_startFrame = 0;
|
||||
float x2c_lineLengthOrSize = 0.f;
|
||||
float x30_lineWidthOrRota = 0.f;
|
||||
zeus::CColor x34_color = {0.f, 0.f, 0.f, 1.f};
|
||||
};
|
||||
|
||||
class CParticleGen
|
||||
{
|
||||
protected:
|
||||
std::list<CWarp*> x4_modifierList;
|
||||
public:
|
||||
virtual ~CParticleGen() = default;
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "zeus/CColor.hpp"
|
||||
#include "zeus/CVector3f.hpp"
|
||||
#include "RetroTypes.hpp"
|
||||
#include "CParticleGen.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
|
@ -11,14 +12,9 @@ namespace urde
|
|||
class CWarp
|
||||
{
|
||||
public:
|
||||
virtual ~CWarp() {}
|
||||
virtual ~CWarp() = default;
|
||||
virtual bool UpdateWarp()=0;
|
||||
virtual void ModifyParticles(int, int, int*,
|
||||
zeus::CVector3f*,
|
||||
zeus::CVector3f*,
|
||||
zeus::CVector3f*,
|
||||
zeus::CColor*,
|
||||
float*, float*)=0;
|
||||
virtual void ModifyParticles(std::vector<CParticle>& particles)=0;
|
||||
virtual void Activate(bool)=0;
|
||||
virtual bool IsActivated()=0;
|
||||
virtual FourCC Get4CharID()=0;
|
||||
|
|
Loading…
Reference in New Issue