Fixes in ANIM cooking

This commit is contained in:
Jack Andersen 2019-06-15 16:22:23 -10:00
parent 37307e1cf6
commit 87023b432e
6 changed files with 47 additions and 41 deletions

View File

@ -283,28 +283,32 @@ std::unique_ptr<atUint8[]> BitstreamWriter::write(const std::vector<std::vector<
float quantRangeF = float(quantRange); float quantRangeF = float(quantRange);
/* Pre-pass to calculate translation multiplier */ /* Pre-pass to calculate translation multiplier */
float maxTransVal = 0.0f; float maxTransDelta = 0.0f;
float maxScaleVal = 0.0f; float maxScaleDelta = 0.0f;
auto kit = chanKeys.begin(); auto kit = chanKeys.begin();
for (Channel& chan : channels) { for (Channel& chan : channels) {
switch (chan.type) { switch (chan.type) {
case Channel::Type::Translation: { case Channel::Type::Translation: {
zeus::simd<float> lastVal = {};
for (auto it = kit->begin(); it != kit->end(); ++it) { for (auto it = kit->begin(); it != kit->end(); ++it) {
const Value* key = &*it; const Value* key = &*it;
zeus::simd_floats f(key->simd); zeus::simd_floats f(key->simd - lastVal);
maxTransVal = std::max(maxTransVal, std::fabs(f[0])); lastVal = key->simd;
maxTransVal = std::max(maxTransVal, std::fabs(f[1])); maxTransDelta = std::max(maxTransDelta, std::fabs(f[0]));
maxTransVal = std::max(maxTransVal, std::fabs(f[2])); maxTransDelta = std::max(maxTransDelta, std::fabs(f[1]));
maxTransDelta = std::max(maxTransDelta, std::fabs(f[2]));
} }
break; break;
} }
case Channel::Type::Scale: { case Channel::Type::Scale: {
zeus::simd<float> lastVal = {};
for (auto it = kit->begin(); it != kit->end(); ++it) { for (auto it = kit->begin(); it != kit->end(); ++it) {
const Value* key = &*it; const Value* key = &*it;
zeus::simd_floats f(key->simd); zeus::simd_floats f(key->simd - lastVal);
maxScaleVal = std::max(maxScaleVal, std::fabs(f[0])); lastVal = key->simd;
maxScaleVal = std::max(maxScaleVal, std::fabs(f[1])); maxScaleDelta = std::max(maxScaleDelta, std::fabs(f[0]));
maxScaleVal = std::max(maxScaleVal, std::fabs(f[2])); maxScaleDelta = std::max(maxScaleDelta, std::fabs(f[1]));
maxScaleDelta = std::max(maxScaleDelta, std::fabs(f[2]));
} }
break; break;
} }
@ -313,8 +317,8 @@ std::unique_ptr<atUint8[]> BitstreamWriter::write(const std::vector<std::vector<
} }
++kit; ++kit;
} }
transMultOut = maxTransVal / quantRangeF; transMultOut = std::max(maxTransDelta / quantRangeF, FLT_EPSILON);
scaleMultOut = maxScaleVal / quantRangeF; scaleMultOut = std::max(maxScaleDelta / quantRangeF, FLT_EPSILON);
/* Output channel inits */ /* Output channel inits */
std::vector<QuantizedValue> initVals; std::vector<QuantizedValue> initVals;

View File

@ -20,7 +20,7 @@ class CAABoxShader {
public: public:
static void Initialize(); static void Initialize();
static void Shutdown(); static void Shutdown();
CAABoxShader(bool zOnly); CAABoxShader(bool zOnly = false);
void setAABB(const zeus::CAABox& aabb); void setAABB(const zeus::CAABox& aabb);
void draw(const zeus::CColor& color); void draw(const zeus::CColor& color);
}; };

View File

@ -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; }); 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) { for (int i = 0; i < 9; ++i) {
CParticle& part = particles[vec[i].second]; CParticle& part = particles[vec[i * pitch].second];
x4_points[i] = part.x4_pos; x4_collisionPoints[i] = part.x4_pos;
if (i > 0) { 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) if (delta.magnitude() < 0.0011920929f)
x4_points[i] += delta.normalized() * 0.0011920929f; x4_collisionPoints[i] += delta.normalized() * 0.0011920929f;
} }
} }
x4_points[0] = x74_warpPoint; x4_collisionPoints[0] = x74_warpPoint;
x80_floatingPoint = x4_points[8]; x80_floatingPoint = x4_collisionPoints[8];
xa0_26_processed = true; xa0_26_processed = true;
} }
zeus::CAABox CFlameWarp::CalculateBounds() const { zeus::CAABox CFlameWarp::CalculateBounds() const {
zeus::CAABox ret; zeus::CAABox ret;
for (const auto& v : x4_points) for (const auto& v : x4_collisionPoints)
ret.accumulateBounds(v); ret.accumulateBounds(v);
return ret; return ret;
} }

View File

@ -6,7 +6,7 @@ namespace urde {
class CStateManager; class CStateManager;
class CFlameWarp : public CWarp { 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 x74_warpPoint;
zeus::CVector3f x80_floatingPoint; zeus::CVector3f x80_floatingPoint;
float x8c_maxDistSq = 0.f; float x8c_maxDistSq = 0.f;
@ -23,13 +23,13 @@ public:
: x74_warpPoint(warpPoint) : x74_warpPoint(warpPoint)
, x80_floatingPoint(warpPoint) , x80_floatingPoint(warpPoint)
, x98_maxInfluenceDistSq(maxInfluenceDist * maxInfluenceDist) { , x98_maxInfluenceDistSq(maxInfluenceDist * maxInfluenceDist) {
x4_points.resize(9, warpPoint); x4_collisionPoints.resize(9, warpPoint);
xa0_24_activated = false; xa0_24_activated = false;
xa0_25_collisionWarp = collisionWarp; xa0_25_collisionWarp = collisionWarp;
xa0_26_processed = false; 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 GetMinSize() const { return x90_minSize; }
float GetMaxSize() const { return x94_maxSize; } float GetMaxSize() const { return x94_maxSize; }
void SetWarpPoint(const zeus::CVector3f& p) { x74_warpPoint = p; } void SetWarpPoint(const zeus::CVector3f& p) { x74_warpPoint = p; }
@ -44,7 +44,7 @@ public:
bool IsProcessed() const { return xa0_26_processed; } bool IsProcessed() const { return xa0_26_processed; }
FourCC Get4CharID() { return FOURCC('FWRP'); } FourCC Get4CharID() { return FOURCC('FWRP'); }
void ResetPosition(const zeus::CVector3f& pos) { void ResetPosition(const zeus::CVector3f& pos) {
for (auto& vec : x4_points) { for (auto& vec : x4_collisionPoints) {
vec = pos; vec = pos;
} }
xa0_26_processed = false; xa0_26_processed = false;

View File

@ -31,7 +31,7 @@ CFlameThrower::CFlameThrower(const TToken<CWeaponDescription>& wDesc, std::strin
, x400_24_active(false) , x400_24_active(false)
, x400_25_particlesActive(false) , x400_25_particlesActive(false)
, x400_26_(!(flameInfo.GetAttributes() & 1)) , 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); DeleteProjectileLight(mgr);
x348_flameGen.reset(new CElementGen(x33c_flameDesc)); x348_flameGen.reset(new CElementGen(x33c_flameDesc));
x348_flameGen->SetParticleEmission(true); x348_flameGen->SetParticleEmission(true);
x348_flameGen->SetZTest(x400_27_detailedParticles); x348_flameGen->SetZTest(x400_27_coneCollision);
x348_flameGen->AddModifier(&x34c_flameWarp); x348_flameGen->AddModifier(&x34c_flameWarp);
if (x348_flameGen->SystemHasLight() && x2c8_projectileLight == kInvalidUniqueId) if (x348_flameGen->SystemHasLight() && x2c8_projectileLight == kInvalidUniqueId)
CreateProjectileLight("FlameThrower_Light"sv, x348_flameGen->GetLight(), mgr); CreateProjectileLight("FlameThrower_Light"sv, x348_flameGen->GetLight(), mgr);
@ -129,15 +129,16 @@ CRayCastResult CFlameThrower::DoCollisionCheck(TUniqueId& idOut, const zeus::CAA
CRayCastResult ret; CRayCastResult ret;
rstl::reserved_vector<TUniqueId, 1024> nearList; rstl::reserved_vector<TUniqueId, 1024> nearList;
mgr.BuildNearList(nearList, aabb, CMaterialFilter::skPassEverything, this); mgr.BuildNearList(nearList, aabb, CMaterialFilter::skPassEverything, this);
if (x400_27_detailedParticles && x34c_flameWarp.GetPoints().size() > 0) { const auto& colPoints = x34c_flameWarp.GetCollisionPoints();
float pitch = (x34c_flameWarp.GetMaxSize() - x34c_flameWarp.GetMinSize()) / if (x400_27_coneCollision && colPoints.size() > 0) {
float(x34c_flameWarp.GetPoints().size()) * 0.5f; float radiusPitch = (x34c_flameWarp.GetMaxSize() - x34c_flameWarp.GetMinSize()) /
float curOffset = pitch; float(colPoints.size()) * 0.5f;
for (int i = 1; i < x34c_flameWarp.GetPoints().size(); ++i) { float curRadius = radiusPitch;
zeus::CVector3f delta = x34c_flameWarp.GetPoints()[i] - x34c_flameWarp.GetPoints()[i - 1]; for (int i = 1; i < colPoints.size(); ++i) {
zeus::CTransform lookXf = zeus::lookAt(x34c_flameWarp.GetPoints()[i - 1], x34c_flameWarp.GetPoints()[i]); zeus::CVector3f delta = colPoints[i] - colPoints[i - 1];
lookXf.origin = delta * 0.5f + x34c_flameWarp.GetPoints()[i - 1]; zeus::CTransform lookXf = zeus::lookAt(colPoints[i - 1], colPoints[i]);
zeus::COBBox obb(lookXf, {curOffset, delta.magnitude() * 0.5f, curOffset}); lookXf.origin = delta * 0.5f + colPoints[i - 1];
zeus::COBBox obb(lookXf, {curRadius, delta.magnitude() * 0.5f, curRadius});
for (TUniqueId id : nearList) { for (TUniqueId id : nearList) {
if (CActor* act = static_cast<CActor*>(mgr.ObjectById(id))) { if (CActor* act = static_cast<CActor*>(mgr.ObjectById(id))) {
CProjectileTouchResult tres = CanCollideWith(*act, mgr); CProjectileTouchResult tres = CanCollideWith(*act, mgr);
@ -159,16 +160,15 @@ CRayCastResult CFlameThrower::DoCollisionCheck(TUniqueId& idOut, const zeus::CAA
} }
} }
} }
curOffset += pitch; curRadius += radiusPitch;
} }
} else { } else {
for (int i = 0; i < x34c_flameWarp.GetPoints().size() - 1; ++i) { for (int i = 0; i < colPoints.size() - 1; ++i) {
zeus::CVector3f delta = x34c_flameWarp.GetPoints()[i + 1] - x34c_flameWarp.GetPoints()[i]; zeus::CVector3f delta = colPoints[i + 1] - colPoints[i];
float deltaMag = delta.magnitude(); float deltaMag = delta.magnitude();
if (deltaMag <= 0.f) if (deltaMag <= 0.f)
break; break;
CRayCastResult cres = RayCollisionCheckWithWorld(idOut, x34c_flameWarp.GetPoints()[i], CRayCastResult cres = RayCollisionCheckWithWorld(idOut, colPoints[i], colPoints[i + 1], deltaMag, nearList, mgr);
x34c_flameWarp.GetPoints()[i + 1], deltaMag, nearList, mgr);
if (cres.IsValid()) if (cres.IsValid())
return cres; return cres;
} }

View File

@ -2,6 +2,7 @@
#include "Weapon/CGameProjectile.hpp" #include "Weapon/CGameProjectile.hpp"
#include "Particle/CFlameWarp.hpp" #include "Particle/CFlameWarp.hpp"
#include "Graphics/Shaders/CAABoxShader.hpp"
namespace urde { namespace urde {
class CFlameInfo; class CFlameInfo;
@ -35,7 +36,7 @@ private:
bool x400_24_active : 1; bool x400_24_active : 1;
bool x400_25_particlesActive : 1; bool x400_25_particlesActive : 1;
bool x400_26_ : 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; u32 _dummy = 0;
}; };