mirror of https://github.com/AxioDL/metaforce.git
Fixes in ANIM cooking
This commit is contained in:
parent
37307e1cf6
commit
87023b432e
|
@ -283,28 +283,32 @@ std::unique_ptr<atUint8[]> BitstreamWriter::write(const std::vector<std::vector<
|
|||
float quantRangeF = float(quantRange);
|
||||
|
||||
/* Pre-pass to calculate translation multiplier */
|
||||
float maxTransVal = 0.0f;
|
||||
float maxScaleVal = 0.0f;
|
||||
float maxTransDelta = 0.0f;
|
||||
float maxScaleDelta = 0.0f;
|
||||
auto kit = chanKeys.begin();
|
||||
for (Channel& chan : channels) {
|
||||
switch (chan.type) {
|
||||
case Channel::Type::Translation: {
|
||||
zeus::simd<float> lastVal = {};
|
||||
for (auto it = kit->begin(); it != kit->end(); ++it) {
|
||||
const Value* key = &*it;
|
||||
zeus::simd_floats f(key->simd);
|
||||
maxTransVal = std::max(maxTransVal, std::fabs(f[0]));
|
||||
maxTransVal = std::max(maxTransVal, std::fabs(f[1]));
|
||||
maxTransVal = std::max(maxTransVal, std::fabs(f[2]));
|
||||
zeus::simd_floats f(key->simd - lastVal);
|
||||
lastVal = key->simd;
|
||||
maxTransDelta = std::max(maxTransDelta, std::fabs(f[0]));
|
||||
maxTransDelta = std::max(maxTransDelta, std::fabs(f[1]));
|
||||
maxTransDelta = std::max(maxTransDelta, std::fabs(f[2]));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Channel::Type::Scale: {
|
||||
zeus::simd<float> lastVal = {};
|
||||
for (auto it = kit->begin(); it != kit->end(); ++it) {
|
||||
const Value* key = &*it;
|
||||
zeus::simd_floats f(key->simd);
|
||||
maxScaleVal = std::max(maxScaleVal, std::fabs(f[0]));
|
||||
maxScaleVal = std::max(maxScaleVal, std::fabs(f[1]));
|
||||
maxScaleVal = std::max(maxScaleVal, std::fabs(f[2]));
|
||||
zeus::simd_floats f(key->simd - lastVal);
|
||||
lastVal = key->simd;
|
||||
maxScaleDelta = std::max(maxScaleDelta, std::fabs(f[0]));
|
||||
maxScaleDelta = std::max(maxScaleDelta, std::fabs(f[1]));
|
||||
maxScaleDelta = std::max(maxScaleDelta, std::fabs(f[2]));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -313,8 +317,8 @@ std::unique_ptr<atUint8[]> BitstreamWriter::write(const std::vector<std::vector<
|
|||
}
|
||||
++kit;
|
||||
}
|
||||
transMultOut = maxTransVal / quantRangeF;
|
||||
scaleMultOut = maxScaleVal / quantRangeF;
|
||||
transMultOut = std::max(maxTransDelta / quantRangeF, FLT_EPSILON);
|
||||
scaleMultOut = std::max(maxScaleDelta / quantRangeF, FLT_EPSILON);
|
||||
|
||||
/* Output channel inits */
|
||||
std::vector<QuantizedValue> initVals;
|
||||
|
|
|
@ -20,7 +20,7 @@ class CAABoxShader {
|
|||
public:
|
||||
static void Initialize();
|
||||
static void Shutdown();
|
||||
CAABoxShader(bool zOnly);
|
||||
CAABoxShader(bool zOnly = false);
|
||||
void setAABB(const zeus::CAABox& aabb);
|
||||
void draw(const zeus::CColor& color);
|
||||
};
|
||||
|
|
|
@ -63,24 +63,25 @@ void CFlameWarp::ModifyParticles(std::vector<CParticle>& particles) {
|
|||
|
||||
std::sort(vec.begin(), vec.end(), [](auto& a, auto& b) { return a.first < b.first; });
|
||||
|
||||
int pitch = particles.size() / 9;
|
||||
for (int i = 0; i < 9; ++i) {
|
||||
CParticle& part = particles[vec[i].second];
|
||||
x4_points[i] = part.x4_pos;
|
||||
CParticle& part = particles[vec[i * pitch].second];
|
||||
x4_collisionPoints[i] = part.x4_pos;
|
||||
if (i > 0) {
|
||||
zeus::CVector3f delta = x4_points[i] - x4_points[i - 1];
|
||||
zeus::CVector3f delta = x4_collisionPoints[i] - x4_collisionPoints[i - 1];
|
||||
if (delta.magnitude() < 0.0011920929f)
|
||||
x4_points[i] += delta.normalized() * 0.0011920929f;
|
||||
x4_collisionPoints[i] += delta.normalized() * 0.0011920929f;
|
||||
}
|
||||
}
|
||||
|
||||
x4_points[0] = x74_warpPoint;
|
||||
x80_floatingPoint = x4_points[8];
|
||||
x4_collisionPoints[0] = x74_warpPoint;
|
||||
x80_floatingPoint = x4_collisionPoints[8];
|
||||
xa0_26_processed = true;
|
||||
}
|
||||
|
||||
zeus::CAABox CFlameWarp::CalculateBounds() const {
|
||||
zeus::CAABox ret;
|
||||
for (const auto& v : x4_points)
|
||||
for (const auto& v : x4_collisionPoints)
|
||||
ret.accumulateBounds(v);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ namespace urde {
|
|||
class CStateManager;
|
||||
|
||||
class CFlameWarp : public CWarp {
|
||||
rstl::reserved_vector<zeus::CVector3f, 9> x4_points;
|
||||
rstl::reserved_vector<zeus::CVector3f, 9> x4_collisionPoints;
|
||||
zeus::CVector3f x74_warpPoint;
|
||||
zeus::CVector3f x80_floatingPoint;
|
||||
float x8c_maxDistSq = 0.f;
|
||||
|
@ -23,13 +23,13 @@ public:
|
|||
: x74_warpPoint(warpPoint)
|
||||
, x80_floatingPoint(warpPoint)
|
||||
, x98_maxInfluenceDistSq(maxInfluenceDist * maxInfluenceDist) {
|
||||
x4_points.resize(9, warpPoint);
|
||||
x4_collisionPoints.resize(9, warpPoint);
|
||||
xa0_24_activated = false;
|
||||
xa0_25_collisionWarp = collisionWarp;
|
||||
xa0_26_processed = false;
|
||||
}
|
||||
|
||||
const rstl::reserved_vector<zeus::CVector3f, 9>& GetPoints() const { return x4_points; }
|
||||
const rstl::reserved_vector<zeus::CVector3f, 9>& GetCollisionPoints() const { return x4_collisionPoints; }
|
||||
float GetMinSize() const { return x90_minSize; }
|
||||
float GetMaxSize() const { return x94_maxSize; }
|
||||
void SetWarpPoint(const zeus::CVector3f& p) { x74_warpPoint = p; }
|
||||
|
@ -44,7 +44,7 @@ public:
|
|||
bool IsProcessed() const { return xa0_26_processed; }
|
||||
FourCC Get4CharID() { return FOURCC('FWRP'); }
|
||||
void ResetPosition(const zeus::CVector3f& pos) {
|
||||
for (auto& vec : x4_points) {
|
||||
for (auto& vec : x4_collisionPoints) {
|
||||
vec = pos;
|
||||
}
|
||||
xa0_26_processed = false;
|
||||
|
|
|
@ -31,7 +31,7 @@ CFlameThrower::CFlameThrower(const TToken<CWeaponDescription>& wDesc, std::strin
|
|||
, x400_24_active(false)
|
||||
, x400_25_particlesActive(false)
|
||||
, x400_26_(!(flameInfo.GetAttributes() & 1))
|
||||
, x400_27_detailedParticles((flameInfo.GetAttributes() & 0x2) != 0) {
|
||||
, x400_27_coneCollision((flameInfo.GetAttributes() & 0x2) != 0) {
|
||||
|
||||
}
|
||||
|
||||
|
@ -81,7 +81,7 @@ void CFlameThrower::CreateFlameParticles(CStateManager& mgr) {
|
|||
DeleteProjectileLight(mgr);
|
||||
x348_flameGen.reset(new CElementGen(x33c_flameDesc));
|
||||
x348_flameGen->SetParticleEmission(true);
|
||||
x348_flameGen->SetZTest(x400_27_detailedParticles);
|
||||
x348_flameGen->SetZTest(x400_27_coneCollision);
|
||||
x348_flameGen->AddModifier(&x34c_flameWarp);
|
||||
if (x348_flameGen->SystemHasLight() && x2c8_projectileLight == kInvalidUniqueId)
|
||||
CreateProjectileLight("FlameThrower_Light"sv, x348_flameGen->GetLight(), mgr);
|
||||
|
@ -129,15 +129,16 @@ CRayCastResult CFlameThrower::DoCollisionCheck(TUniqueId& idOut, const zeus::CAA
|
|||
CRayCastResult ret;
|
||||
rstl::reserved_vector<TUniqueId, 1024> nearList;
|
||||
mgr.BuildNearList(nearList, aabb, CMaterialFilter::skPassEverything, this);
|
||||
if (x400_27_detailedParticles && x34c_flameWarp.GetPoints().size() > 0) {
|
||||
float pitch = (x34c_flameWarp.GetMaxSize() - x34c_flameWarp.GetMinSize()) /
|
||||
float(x34c_flameWarp.GetPoints().size()) * 0.5f;
|
||||
float curOffset = pitch;
|
||||
for (int i = 1; i < x34c_flameWarp.GetPoints().size(); ++i) {
|
||||
zeus::CVector3f delta = x34c_flameWarp.GetPoints()[i] - x34c_flameWarp.GetPoints()[i - 1];
|
||||
zeus::CTransform lookXf = zeus::lookAt(x34c_flameWarp.GetPoints()[i - 1], x34c_flameWarp.GetPoints()[i]);
|
||||
lookXf.origin = delta * 0.5f + x34c_flameWarp.GetPoints()[i - 1];
|
||||
zeus::COBBox obb(lookXf, {curOffset, delta.magnitude() * 0.5f, curOffset});
|
||||
const auto& colPoints = x34c_flameWarp.GetCollisionPoints();
|
||||
if (x400_27_coneCollision && colPoints.size() > 0) {
|
||||
float radiusPitch = (x34c_flameWarp.GetMaxSize() - x34c_flameWarp.GetMinSize()) /
|
||||
float(colPoints.size()) * 0.5f;
|
||||
float curRadius = radiusPitch;
|
||||
for (int i = 1; i < colPoints.size(); ++i) {
|
||||
zeus::CVector3f delta = colPoints[i] - colPoints[i - 1];
|
||||
zeus::CTransform lookXf = zeus::lookAt(colPoints[i - 1], colPoints[i]);
|
||||
lookXf.origin = delta * 0.5f + colPoints[i - 1];
|
||||
zeus::COBBox obb(lookXf, {curRadius, delta.magnitude() * 0.5f, curRadius});
|
||||
for (TUniqueId id : nearList) {
|
||||
if (CActor* act = static_cast<CActor*>(mgr.ObjectById(id))) {
|
||||
CProjectileTouchResult tres = CanCollideWith(*act, mgr);
|
||||
|
@ -159,16 +160,15 @@ CRayCastResult CFlameThrower::DoCollisionCheck(TUniqueId& idOut, const zeus::CAA
|
|||
}
|
||||
}
|
||||
}
|
||||
curOffset += pitch;
|
||||
curRadius += radiusPitch;
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < x34c_flameWarp.GetPoints().size() - 1; ++i) {
|
||||
zeus::CVector3f delta = x34c_flameWarp.GetPoints()[i + 1] - x34c_flameWarp.GetPoints()[i];
|
||||
for (int i = 0; i < colPoints.size() - 1; ++i) {
|
||||
zeus::CVector3f delta = colPoints[i + 1] - colPoints[i];
|
||||
float deltaMag = delta.magnitude();
|
||||
if (deltaMag <= 0.f)
|
||||
break;
|
||||
CRayCastResult cres = RayCollisionCheckWithWorld(idOut, x34c_flameWarp.GetPoints()[i],
|
||||
x34c_flameWarp.GetPoints()[i + 1], deltaMag, nearList, mgr);
|
||||
CRayCastResult cres = RayCollisionCheckWithWorld(idOut, colPoints[i], colPoints[i + 1], deltaMag, nearList, mgr);
|
||||
if (cres.IsValid())
|
||||
return cres;
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include "Weapon/CGameProjectile.hpp"
|
||||
#include "Particle/CFlameWarp.hpp"
|
||||
#include "Graphics/Shaders/CAABoxShader.hpp"
|
||||
|
||||
namespace urde {
|
||||
class CFlameInfo;
|
||||
|
@ -35,7 +36,7 @@ private:
|
|||
bool x400_24_active : 1;
|
||||
bool x400_25_particlesActive : 1;
|
||||
bool x400_26_ : 1;
|
||||
bool x400_27_detailedParticles : 1; /* Z-sort and finer collision detection */
|
||||
bool x400_27_coneCollision : 1; /* Z-sort and finer collision detection */
|
||||
};
|
||||
u32 _dummy = 0;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue