metaforce/Runtime/Particle/CFlameWarp.cpp

90 lines
3.0 KiB
C++
Raw Normal View History

2016-02-16 03:25:06 +00:00
#include "CFlameWarp.hpp"
2017-09-10 09:04:51 +00:00
#include "CStateManager.hpp"
2016-02-16 03:25:06 +00:00
2018-12-08 05:30:43 +00:00
namespace urde {
2016-02-16 03:25:06 +00:00
2018-12-08 05:30:43 +00:00
void CFlameWarp::ModifyParticles(std::vector<CParticle>& particles) {
if (x9c_stateMgr == 0 || particles.size() < 9)
return;
2017-09-10 09:04:51 +00:00
2018-12-08 05:30:43 +00:00
std::vector<std::pair<float, u8>> vec;
vec.reserve(particles.size());
2017-09-10 09:04:51 +00:00
2018-12-08 05:30:43 +00:00
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;
}
}
2017-09-10 09:04:51 +00:00
2018-12-08 05:30:43 +00:00
if (particle.x2c_lineLengthOrSize < x90_minSize)
x90_minSize = particle.x2c_lineLengthOrSize;
if (particle.x2c_lineLengthOrSize > x94_maxSize)
x94_maxSize = particle.x2c_lineLengthOrSize;
2017-09-10 09:04:51 +00:00
2018-12-08 05:30:43 +00:00
vec.emplace_back(transp, idx);
2017-09-10 09:04:51 +00:00
2018-12-08 05:30:43 +00:00
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) {
2019-07-01 06:14:42 +00:00
particle.x4_pos -= result.GetPlane().normal() * dist;
2018-12-08 05:30:43 +00:00
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;
2017-09-10 09:04:51 +00:00
}
2018-12-08 05:30:43 +00:00
}
2017-09-10 09:04:51 +00:00
}
2018-12-08 05:30:43 +00:00
}
2017-09-10 09:04:51 +00:00
}
2018-12-08 05:30:43 +00:00
++idx;
}
2017-09-10 09:04:51 +00:00
2018-12-08 05:30:43 +00:00
std::sort(vec.begin(), vec.end(), [](auto& a, auto& b) { return a.first < b.first; });
2019-06-16 02:22:23 +00:00
int pitch = particles.size() / 9;
2018-12-08 05:30:43 +00:00
for (int i = 0; i < 9; ++i) {
2019-06-16 02:22:23 +00:00
CParticle& part = particles[vec[i * pitch].second];
x4_collisionPoints[i] = part.x4_pos;
2018-12-08 05:30:43 +00:00
if (i > 0) {
2019-06-16 02:22:23 +00:00
zeus::CVector3f delta = x4_collisionPoints[i] - x4_collisionPoints[i - 1];
2018-12-08 05:30:43 +00:00
if (delta.magnitude() < 0.0011920929f)
2019-06-16 02:22:23 +00:00
x4_collisionPoints[i] += delta.normalized() * 0.0011920929f;
2017-09-10 09:04:51 +00:00
}
2018-12-08 05:30:43 +00:00
}
2017-09-10 09:04:51 +00:00
2019-06-16 02:22:23 +00:00
x4_collisionPoints[0] = x74_warpPoint;
x80_floatingPoint = x4_collisionPoints[8];
2018-12-08 05:30:43 +00:00
xa0_26_processed = true;
2017-09-10 09:04:51 +00:00
}
zeus::CAABox CFlameWarp::CalculateBounds() const {
zeus::CAABox ret;
2019-06-16 02:22:23 +00:00
for (const auto& v : x4_collisionPoints)
ret.accumulateBounds(v);
return ret;
}
2018-12-08 05:30:43 +00:00
} // namespace urde