Fixed the goddamn fences.

Colliding with and/or brushing against the metal chain-linked fences in
the game caused severe performance degredation as the SH4 struggled to
keep up with the physics.

The PSVita REGTA3 port also struggled, somehow, with its bazillion times
faster CPU. The PS2 version has no fences. The Xbox version implemented
an interesting compromise, where fences could be collided with and
knocked over, but individual links did not interact with one-another,
only with the car.

So that's what I've essentially done here. Intersection testing is still
happening between all of the previous CPhysical entities in question
(player vs fences vs fences); however, the contact resolution for fence vs
fence collisions is now being essentially canceled.

Apparently that's all that was needed, as you can now mow down long-ass
fences with no performance impact and a response that looks like what
the Xbox does.
This commit is contained in:
Falco Girgis 2025-01-12 00:29:42 -06:00
parent 2065c9a93f
commit e86fb27a48
3 changed files with 13 additions and 3 deletions

View File

@ -83,6 +83,11 @@ CEntity::~CEntity(void)
ResolveReferences();
}
bool
CEntity::IsFence(void) {
return IsObject() && ::IsFence(static_cast<CObject *>(this)->GetModelIndex());
}
void
CEntity::SetModelIndex(uint32 id)
{

View File

@ -131,6 +131,7 @@ public:
bool IsPed(void) { return m_type == ENTITY_TYPE_PED; }
bool IsObject(void) { return m_type == ENTITY_TYPE_OBJECT; }
bool IsDummy(void) { return m_type == ENTITY_TYPE_DUMMY; }
bool IsFence(void);
RpAtomic *GetAtomic(void) {
assert(RwObjectGetType(m_rwObject) == rpATOMIC);

View File

@ -59,7 +59,7 @@ CPhysical::CPhysical(void)
bInfiniteMass = false;
bIsInWater = false;
bHitByTrain = false;
bSkipLineCol = false;
bSkipLineCol = IsFence();
m_fDistanceTravelled = 0.0f;
m_treadable[PATH_CAR] = nil;
@ -1461,6 +1461,10 @@ CPhysical::ProcessCollisionSectorList(CPtrList *lists)
skipCollision = false;
altcollision = false;
if(A->IsFence() && B->IsFence()) {
skipCollision = true;
A->bSkipLineCol = true;
}
if(B->IsBuilding())
skipCollision = false;
else if(IsStreetLight(A->GetModelIndex()) &&
@ -1922,12 +1926,12 @@ CPhysical::ProcessCollision(void)
n = NUMSTEPS(0.09f);
step = savedTimeStep / n;
}
}else if(responsecase == COLLRESPONSE_SMALLBOX || responsecase == COLLRESPONSE_FENCEPART){
}else if(responsecase == COLLRESPONSE_SMALLBOX){
if(distSq >= sq(0.15f)){
n = NUMSTEPS(0.15f);
step = savedTimeStep / n;
}
}else{
}else if(responsecase != COLLRESPONSE_FENCEPART){
if(distSq >= sq(0.3f)){
n = NUMSTEPS(0.3f);
step = savedTimeStep / n;