2
0
mirror of https://github.com/AxioDL/metaforce.git synced 2025-07-07 07:25:52 +00:00

Projectile collision fix

This commit is contained in:
Jack Andersen 2018-03-14 14:27:45 -10:00
parent 017185109f
commit 08569104c2
9 changed files with 69 additions and 70 deletions

View File

@ -505,11 +505,9 @@ void CStateManager::CacheReflection()
g_Renderer->CacheReflection(ReflectionDrawer, this, true); g_Renderer->CacheReflection(ReflectionDrawer, this, true);
} }
bool CStateManager::CanCreateProjectile(TUniqueId uid, EWeaponType type, int test) const bool CStateManager::CanCreateProjectile(TUniqueId uid, EWeaponType type, int maxAllowed) const
{ {
int num = x878_weaponManager->GetNumActive(uid, type); return x878_weaponManager->GetNumActive(uid, type) < maxAllowed;
int xorv = test ^ num;
return ((xorv >> 1) - xorv & test) >> 31;
} }
void CStateManager::BuildDynamicLightListForWorld() void CStateManager::BuildDynamicLightListForWorld()

View File

@ -217,7 +217,7 @@ bool CAreaOctTree::Node::LineTestInternal(const zeus::CLine& line, const CMateri
void CAreaOctTree::Node::LineTestExInternal(const zeus::CLine& line, const CMaterialFilter& filter, void CAreaOctTree::Node::LineTestExInternal(const zeus::CLine& line, const CMaterialFilter& filter,
SRayResult& res, float lT, float hT, float maxT, SRayResult& res, float lT, float hT, float maxT,
const zeus::CVector3f& vec) const const zeus::CVector3f& dirRecip) const
{ {
float lowT = (1.f - FLT_EPSILON * 100.f) * lT; float lowT = (1.f - FLT_EPSILON * 100.f) * lT;
float highT = (1.f + FLT_EPSILON * 100.f) * hT; float highT = (1.f + FLT_EPSILON * 100.f) * hT;
@ -234,7 +234,7 @@ void CAreaOctTree::Node::LineTestExInternal(const zeus::CLine& line, const CMate
if (x20_nodeType == ETreeType::Leaf) if (x20_nodeType == ETreeType::Leaf)
{ {
TriListReference triList = GetTriangleArray(); TriListReference triList = GetTriangleArray();
float f30 = highT; float bestT = highT;
bool foundTriangle = false; bool foundTriangle = false;
SRayResult tmpRes; SRayResult tmpRes;
@ -272,7 +272,7 @@ void CAreaOctTree::Node::LineTestExInternal(const zeus::CLine& line, const CMate
// Calculate T parameter and test bound // Calculate T parameter and test bound
float t = invDet * Q.dot(e1); float t = invDet * Q.dot(e1);
if (t >= f30 || t < lowT) if (t >= bestT || t < lowT)
continue; continue;
// Calculate V parameter and test bound // Calculate V parameter and test bound
@ -282,9 +282,9 @@ void CAreaOctTree::Node::LineTestExInternal(const zeus::CLine& line, const CMate
// Do material filter // Do material filter
CMaterialList matList(triangle.GetSurfaceFlags()); CMaterialList matList(triangle.GetSurfaceFlags());
if (filter.Passes(matList) && t <= f30) if (filter.Passes(matList) && t <= bestT)
{ {
f30 = t; bestT = t;
foundTriangle = true; foundTriangle = true;
tmpRes.x10_surface.emplace(triangle); tmpRes.x10_surface.emplace(triangle);
tmpRes.x3c_t = t; tmpRes.x3c_t = t;
@ -308,7 +308,7 @@ void CAreaOctTree::Node::LineTestExInternal(const zeus::CLine& line, const CMate
float tf1 = lT; float tf1 = lT;
float tf2 = hT; float tf2 = hT;
if (BoxLineTest(child.GetBoundingBox(), line, tf1, tf2)) if (BoxLineTest(child.GetBoundingBox(), line, tf1, tf2))
child.LineTestExInternal(line, filter, tmpRes[i], tf1, tf2, maxT, vec); child.LineTestExInternal(line, filter, tmpRes[i], tf1, tf2, maxT, dirRecip);
} }
if (!tmpRes[0].x10_surface && !tmpRes[1].x10_surface) if (!tmpRes[0].x10_surface && !tmpRes[1].x10_surface)
@ -339,24 +339,25 @@ void CAreaOctTree::Node::LineTestExInternal(const zeus::CLine& line, const CMate
zeus::CVector3f center = x0_aabb.center(); // r26 zeus::CVector3f center = x0_aabb.center(); // r26
zeus::CVector3f r25 = line.origin + lT * line.dir; zeus::CVector3f lowPoint = line.origin + lT * line.dir;
zeus::CVector3f r24 = line.origin + hT * line.dir; zeus::CVector3f highPoint = line.origin + hT * line.dir;
int r19[] = {-1, -1, -1, 0}; int comps[] = {-1, -1, -1, 0};
float r20[3]; float compT[3];
int r17 = 0; int numComps = 0;
for (int i=0 ; i<3 ; ++i) for (int i=0 ; i<3 ; ++i)
{ {
if (r25[i] < center[i] || r24[i] <= center[i]) if (lowPoint[i] >= center[i] || highPoint[i] <= center[i])
if (r24[i] >= center[i] || r25[i] <= center[i]) if (highPoint[i] >= center[i] || lowPoint[i] <= center[i])
continue; continue;
if (_close_enough(line.dir[i], 0.f, 0.000099999997f)) if (_close_enough(line.dir[i], 0.f, 0.000099999997f))
continue; continue;
r19[r17++] = i; comps[numComps++] = i;
r20[i] = vec[i] * (center[i] - line.origin[i]); compT[i] = dirRecip[i] * (center[i] - line.origin[i]);
} }
switch (r17) // Sort componentT least to greatest
switch (numComps)
{ {
default: default:
return; return;
@ -364,80 +365,80 @@ void CAreaOctTree::Node::LineTestExInternal(const zeus::CLine& line, const CMate
case 1: case 1:
break; break;
case 2: case 2:
if (r20[r19[1]] < r20[r19[0]]) if (compT[comps[1]] < compT[comps[0]])
std::swap(r19[1], r19[0]); std::swap(comps[1], comps[0]);
break; break;
case 3: case 3:
if (r20[0] < r20[1]) if (compT[0] < compT[1])
{ {
if (r20[0] >= r20[2]) if (compT[0] >= compT[2])
{ {
r19[0] = 2; comps[0] = 2;
r19[1] = 0; comps[1] = 0;
r19[2] = 1; comps[2] = 1;
} }
else if (r20[1] < r20[2]) else if (compT[1] < compT[2])
{ {
r19[0] = 0; comps[0] = 0;
r19[1] = 1; comps[1] = 1;
r19[2] = 2; comps[2] = 2;
} }
else else
{ {
r19[0] = 0; comps[0] = 0;
r19[1] = 2; comps[1] = 2;
r19[2] = 1; comps[2] = 1;
} }
} }
else else
{ {
if (r20[1] >= r20[2]) if (compT[1] >= compT[2])
{ {
r19[0] = 2; comps[0] = 2;
r19[1] = 1; comps[1] = 1;
r19[2] = 0; comps[2] = 0;
} }
else if (r20[0] < r20[2]) else if (compT[0] < compT[2])
{ {
r19[0] = 1; comps[0] = 1;
r19[1] = 0; comps[1] = 0;
r19[2] = 2; comps[2] = 2;
} }
else else
{ {
r19[0] = 1; comps[0] = 1;
r19[1] = 2; comps[1] = 2;
r19[2] = 0; comps[2] = 0;
} }
} }
break; break;
} }
zeus::CVector3f lineEnd = line.origin + (lT * line.dir); zeus::CVector3f lineStart = line.origin + (lT * line.dir);
int selector = 0; int selector = 0;
if (lineEnd.x >= center.x) if (lineStart.x >= center.x)
selector = 1; selector = 1;
if (lineEnd.y >= center.y) if (lineStart.y >= center.y)
selector |= 1 << 1; selector |= 1 << 1;
if (lineEnd.z >= center.z) if (lineStart.z >= center.z)
selector |= 1 << 2; selector |= 1 << 2;
float loT = lT; float tmpLoT = lT;
for (int i=-1 ; i<r17 ; ++i) for (int i=-1 ; i<numComps ; ++i)
{ {
if (i >= 0) if (i >= 0)
selector ^= 1 << r19[i]; selector ^= 1 << comps[i];
float hiT = (i < r17-1) ? r20[r19[i+1]] : hT; float tmpHiT = (i < numComps-1) ? compT[comps[i+1]] : hT;
if (hiT > lowT && loT <= hiT) if (tmpHiT > lowT && tmpLoT <= tmpHiT)
{ {
Node child = GetChild(selector); Node child = GetChild(selector);
if (child.x20_nodeType != ETreeType::Invalid) if (child.x20_nodeType != ETreeType::Invalid)
child.LineTestExInternal(line, filter, res, loT, hiT, maxT, vec); child.LineTestExInternal(line, filter, res, tmpLoT, tmpHiT, maxT, dirRecip);
if (res.x10_surface) if (res.x10_surface)
if (res.x3c_t > highT) if (res.x3c_t > highT)
res = SRayResult(); res = SRayResult();
} }
loT = hiT; tmpLoT = tmpHiT;
} }
} }
} }
@ -462,13 +463,13 @@ void CAreaOctTree::Node::LineTestEx(const zeus::CLine& line, const CMaterialFilt
if (x20_nodeType == ETreeType::Invalid) if (x20_nodeType == ETreeType::Invalid)
return; return;
float f1 = 0.f; float lT = 0.f;
float f2 = 0.f; float hT = 0.f;
if (!BoxLineTest(x0_aabb, line, f1, f2)) if (!BoxLineTest(x0_aabb, line, lT, hT))
return; return;
zeus::CVector3f recip = 1.f / line.dir; zeus::CVector3f recip = 1.f / line.dir;
LineTestExInternal(line, filter, res, f1 - 0.000099999997f, f2 + 0.000099999997f, length, recip); LineTestExInternal(line, filter, res, lT - 0.000099999997f, hT + 0.000099999997f, length, recip);
} }
CAreaOctTree::Node CAreaOctTree::Node::GetChild(int idx) const CAreaOctTree::Node CAreaOctTree::Node::GetChild(int idx) const

View File

@ -16,12 +16,12 @@ namespace urde
{ {
CEnergyProjectile::CEnergyProjectile(bool active, const TToken<CWeaponDescription>& desc, EWeaponType type, CEnergyProjectile::CEnergyProjectile(bool active, const TToken<CWeaponDescription>& desc, EWeaponType type,
const zeus::CTransform& xf, EMaterialTypes materials, const CDamageInfo& damage, const zeus::CTransform& xf, EMaterialTypes excludeMat, const CDamageInfo& damage,
TUniqueId uid, TAreaId aid, TUniqueId owner, TUniqueId homingTarget, TUniqueId uid, TAreaId aid, TUniqueId owner, TUniqueId homingTarget,
EProjectileAttrib attribs, bool underwater, const zeus::CVector3f& scale, EProjectileAttrib attribs, bool underwater, const zeus::CVector3f& scale,
const rstl::optional_object<TLockedToken<CGenDescription>>& visorParticle, const rstl::optional_object<TLockedToken<CGenDescription>>& visorParticle,
u16 visorSfx, bool sendCollideMsg) u16 visorSfx, bool sendCollideMsg)
: CGameProjectile(active, desc, "GameProjectile", type, xf, materials, damage, uid, aid, : CGameProjectile(active, desc, "GameProjectile", type, xf, excludeMat, damage, uid, aid,
owner, homingTarget, attribs, underwater, scale, visorParticle, visorSfx, sendCollideMsg), owner, homingTarget, attribs, underwater, scale, visorParticle, visorSfx, sendCollideMsg),
x2ec_dir(xf.basis[1]), x2f8_mag(x2ec_dir.magnitude()), x2ec_dir(xf.basis[1]), x2f8_mag(x2ec_dir.magnitude()),
x2fc_camShake(CCameraShakeData::BuildProjectileCameraShake(0.5f, 0.75f)) x2fc_camShake(CCameraShakeData::BuildProjectileCameraShake(0.5f, 0.75f))

View File

@ -28,7 +28,7 @@ class CEnergyProjectile : public CGameProjectile
void StopProjectile(CStateManager& mgr); void StopProjectile(CStateManager& mgr);
public: public:
CEnergyProjectile(bool active, const TToken<CWeaponDescription>& desc, EWeaponType type, CEnergyProjectile(bool active, const TToken<CWeaponDescription>& desc, EWeaponType type,
const zeus::CTransform& xf, EMaterialTypes materials, const CDamageInfo& damage, const zeus::CTransform& xf, EMaterialTypes excludeMat, const CDamageInfo& damage,
TUniqueId uid, TAreaId aid, TUniqueId owner, TUniqueId homingTarget, TUniqueId uid, TAreaId aid, TUniqueId owner, TUniqueId homingTarget,
EProjectileAttrib attribs, bool underwater, const zeus::CVector3f& scale, EProjectileAttrib attribs, bool underwater, const zeus::CVector3f& scale,
const rstl::optional_object<TLockedToken<CGenDescription>>& visorParticle, const rstl::optional_object<TLockedToken<CGenDescription>>& visorParticle,

View File

@ -14,7 +14,7 @@
namespace urde namespace urde
{ {
CGameProjectile::CGameProjectile(bool active, const TToken<CWeaponDescription>& wDesc, std::string_view name, CGameProjectile::CGameProjectile(bool active, const TToken<CWeaponDescription>& wDesc, std::string_view name,
EWeaponType wType, const zeus::CTransform& xf, EMaterialTypes matType, EWeaponType wType, const zeus::CTransform& xf, EMaterialTypes excludeMat,
const CDamageInfo& dInfo, TUniqueId uid, TAreaId aid, TUniqueId owner, const CDamageInfo& dInfo, TUniqueId uid, TAreaId aid, TUniqueId owner,
TUniqueId homingTarget, EProjectileAttrib attribs, bool underwater, TUniqueId homingTarget, EProjectileAttrib attribs, bool underwater,
const zeus::CVector3f& scale, const zeus::CVector3f& scale,
@ -22,8 +22,8 @@ CGameProjectile::CGameProjectile(bool active, const TToken<CWeaponDescription>&
u16 visorSfx, bool sendCollideMsg) u16 visorSfx, bool sendCollideMsg)
: CWeapon(uid, aid, active, owner, wType, name, xf, : CWeapon(uid, aid, active, owner, wType, name, xf,
CMaterialFilter::MakeIncludeExclude( CMaterialFilter::MakeIncludeExclude(
{EMaterialTypes::NonSolidDamageable, matType}, {EMaterialTypes::Solid, EMaterialTypes::NonSolidDamageable},
{EMaterialTypes::Projectile, EMaterialTypes::ProjectilePassthrough, matType, EMaterialTypes::Solid}), {EMaterialTypes::Projectile, EMaterialTypes::ProjectilePassthrough, excludeMat}),
CMaterialList(), dInfo, attribs | GetBeamAttribType(wType), CModelData::CModelDataNull()), CMaterialList(), dInfo, attribs | GetBeamAttribType(wType), CModelData::CModelDataNull()),
x158_visorParticle(visorParticle), x168_visorSfx(visorSfx), x170_projectile(wDesc, xf.origin, xf.basis, scale, x158_visorParticle(visorParticle), x168_visorSfx(visorSfx), x170_projectile(wDesc, xf.origin, xf.basis, scale,
(attribs & EProjectileAttrib::ParticleOPTS) == EProjectileAttrib::ParticleOPTS), x298_lastOrigin(xf.origin), (attribs & EProjectileAttrib::ParticleOPTS) == EProjectileAttrib::ParticleOPTS), x298_lastOrigin(xf.origin),

View File

@ -59,7 +59,7 @@ protected:
}; };
public: public:
CGameProjectile(bool active, const TToken<CWeaponDescription>&, std::string_view name, CGameProjectile(bool active, const TToken<CWeaponDescription>&, std::string_view name,
EWeaponType wType, const zeus::CTransform& xf, EMaterialTypes matType, EWeaponType wType, const zeus::CTransform& xf, EMaterialTypes excludeMat,
const CDamageInfo& dInfo, TUniqueId uid, TAreaId aid, TUniqueId owner, const CDamageInfo& dInfo, TUniqueId uid, TAreaId aid, TUniqueId owner,
TUniqueId homingTarget, EProjectileAttrib attribs, bool underwater, const zeus::CVector3f& scale, TUniqueId homingTarget, EProjectileAttrib attribs, bool underwater, const zeus::CVector3f& scale,
const rstl::optional_object<TLockedToken<CGenDescription>>& visorParticle, const rstl::optional_object<TLockedToken<CGenDescription>>& visorParticle,

2
amuse

@ -1 +1 @@
Subproject commit 8f94bdd4887356f84cbe2c4eebce8f150cc1ff11 Subproject commit f5a0a46453b32aac586d69c0c51870746ef0f9c0

2
hecl

@ -1 +1 @@
Subproject commit 7e911dc13b1e8075d056f63720139fd7c6cd7496 Subproject commit 81d489a710893bee49e75447e92dd962b2849a0f

@ -1 +1 @@
Subproject commit 7488e8cbc504be018bd29e8993c39eea4cb30ff8 Subproject commit 354e9d5cca416bfc0cbc3431945ce4d32049894c