From 9c782fc22f5361c96d5871bbe48da7e212319078 Mon Sep 17 00:00:00 2001
From: hzqst <113660872@qq.com>
Date: Wed, 9 Oct 2024 17:40:07 +0800
Subject: [PATCH] fix crash in PostSpawn
---
fallguys/engine_hook.cpp | 5 +-
fallguys/fallguys.vcxproj | 3 +-
fallguys/physics.cpp | 70 +++++++++++++-------------
fallguys/physics.h | 100 ++++++++++++++++++++++----------------
4 files changed, 95 insertions(+), 83 deletions(-)
diff --git a/fallguys/engine_hook.cpp b/fallguys/engine_hook.cpp
index b172c24..57f80b1 100644
--- a/fallguys/engine_hook.cpp
+++ b/fallguys/engine_hook.cpp
@@ -71,7 +71,8 @@ model_t* EngineFindWorldModelBySubModel(model_t* psubmodel)
for (int i = 0; i < EngineGetMaxPrecacheModel(); ++i)
{
auto mod = EngineGetPrecachedModelByIndex(i);
- if (mod->type == mod_brush && mod->name[0] && mod->name[0] != '*')
+
+ if (mod && mod->type == mod_brush && mod->name[0] && mod->name[0] != '*')
{
if (mod->needload == NL_PRESENT || mod->needload == NL_CLIENT)
{
@@ -89,7 +90,7 @@ hull_t *SV_HullForBspNew(edict_t *ent, const vec3_t mins, const vec3_t maxs, vec
hull_t *hull;
vec3_t size;
- model = (*sv_models)[(int)ent->v.modelindex];
+ model = EngineGetPrecachedModelByIndex(ent->v.modelindex);
if (!model || model->type != mod_brush)
return NULL;
diff --git a/fallguys/fallguys.vcxproj b/fallguys/fallguys.vcxproj
index eff0a74..cab1dd6 100644
--- a/fallguys/fallguys.vcxproj
+++ b/fallguys/fallguys.vcxproj
@@ -98,7 +98,8 @@
$(Bullet3LibrariesDirectory)
- $(DllPostBuildCommand)
+ $(DllPostBuildCommand)
+copy "D:\metamod-fallguys2\Debug\fallguys.dll" "D:\SteamLibrary\steamapps\common\Sven Co-op\svencoop\addons\metamod\dlls\"
$(Bullet3CheckRequirements)
diff --git a/fallguys/physics.cpp b/fallguys/physics.cpp
index a2a2723..eece60d 100644
--- a/fallguys/physics.cpp
+++ b/fallguys/physics.cpp
@@ -599,10 +599,7 @@ CPhysicsManager::CPhysicsManager()
m_ghostPairCallback = NULL;
m_overlapFilterCallback = NULL;
- //m_worldVertexArray = NULL;
-
m_gravityAcceleration = 0;
- m_numDynamicObjects = 0;
m_maxIndexGameObject = 0;
m_solidPlayerMask = 0;
@@ -750,8 +747,17 @@ std::shared_ptr CPhysicsManager::GenerateWorldVertexArray(mo
int iStartVert = iNumVerts;
brushface->start_vertex = iStartVert;
+ brushface->plane_normal = surf->plane->normal;
+ brushface->plane_dist = surf->plane->dist;
+ brushface->plane_flags = surf->flags;
- for (poly = surf->polys; poly; poly = poly->next)
+ if (surf->flags & SURF_PLANEBACK)
+ {
+ brushface->plane_normal = brushface->plane_normal * (-1);
+ brushface->plane_dist = brushface->plane_dist * (-1);
+ }
+
+ for (const auto& poly : glpolys)
{
auto v = poly->verts[0];
@@ -2498,7 +2504,7 @@ bool CPhysicsManager::CreatePhysicObjectForBrushModel(edict_t* ent)
auto staticObject = CreateStaticObject(obj, pCollisionShape, bKinematic);
- obj->AddPhysicObject(staticObject, m_dynamicsWorld, &m_numDynamicObjects);
+ obj->AddPhysicObject(staticObject, m_dynamicsWorld);
if (ent->v.flags & FL_CONVEYOR)
{
@@ -2531,7 +2537,7 @@ bool CPhysicsManager::CreateSolidPlayer(edict_t* ent)
auto playerobj = CreatePlayerObject(obj, shape, 36, 400 * m_simrate, false);
- obj->AddPhysicObject(playerobj, m_dynamicsWorld, &m_numDynamicObjects);
+ obj->AddPhysicObject(playerobj, m_dynamicsWorld);
}
if (1)
@@ -2540,7 +2546,7 @@ bool CPhysicsManager::CreateSolidPlayer(edict_t* ent)
auto playerobj = CreatePlayerObject(obj, shape, 18, 400 * m_simrate, true);
- obj->AddPhysicObject(playerobj, m_dynamicsWorld, &m_numDynamicObjects);
+ obj->AddPhysicObject(playerobj, m_dynamicsWorld);
}
return true;
@@ -3460,7 +3466,7 @@ bool CPhysicsManager::SetEntityEnvStudioAnim(edict_t* ent, int flags, float over
return false;
}
- auto mod = (*sv_models)[ent->v.modelindex];
+ auto mod = EngineGetPrecachedModelByIndex(ent->v.modelindex);
if (!mod)
{
@@ -3682,7 +3688,7 @@ bool CPhysicsManager::CreateSolidOptimizer(edict_t* ent, int boneindex, const Ve
return false;
}
- auto mod = (*sv_models)[ent->v.modelindex];
+ auto mod = EngineGetPrecachedModelByIndex(ent->v.modelindex);
if (!mod)
{
@@ -3722,7 +3728,7 @@ bool CPhysicsManager::CreateSolidOptimizer(edict_t* ent, int boneindex, const Ve
ghost->GetGhostObject()->setCollisionShape(shape);
ghost->GetGhostObject()->setCollisionFlags(ghost->GetGhostObject()->getCollisionFlags() | btCollisionObject::CF_NO_CONTACT_RESPONSE);
- obj->AddPhysicObject(ghost, m_dynamicsWorld, &m_numDynamicObjects);
+ obj->AddPhysicObject(ghost, m_dynamicsWorld);
}
if (1)
@@ -3735,7 +3741,7 @@ bool CPhysicsManager::CreateSolidOptimizer(edict_t* ent, int boneindex, const Ve
ghost->GetGhostObject()->setCollisionShape(shape);
ghost->GetGhostObject()->setCollisionFlags(ghost->GetGhostObject()->getCollisionFlags() | btCollisionObject::CF_NO_CONTACT_RESPONSE);
- obj->AddPhysicObject(ghost, m_dynamicsWorld, &m_numDynamicObjects);
+ obj->AddPhysicObject(ghost, m_dynamicsWorld);
}
obj->AddSolidOptimizer(boneindex, 0);
@@ -3752,7 +3758,7 @@ model_t *CPhysicsManager::GetBrushModelFromEntity(edict_t *ent)
return NULL;
}
- auto mod = (*sv_models)[modelindex];
+ auto mod = EngineGetPrecachedModelByIndex(modelindex);
if (!mod)
{
@@ -3790,6 +3796,9 @@ btBvhTriangleMeshShape *CPhysicsManager::CreateTriMeshShapeFromBrushEntity(edict
if (!pIndexArray)
return nullptr;
+ if (!pIndexArray->vIndexBuffer.size())
+ return nullptr;
+
auto pTriangleIndexVertexArray = new btTriangleIndexVertexArray(
pIndexArray->vIndexBuffer.size() / 3, pIndexArray->vIndexBuffer.data(), 3 * sizeof(int),
pIndexArray->pVertexArray->vVertexBuffer.size(), (float*)pIndexArray->pVertexArray->vVertexBuffer.data(), sizeof(CPhysicBrushVertex));
@@ -3836,15 +3845,13 @@ CPhysicTriggerGhostPhysicObject : public CGhostPhysicObject
return false;
}
- void AddToPhysicWorld(btDiscreteDynamicsWorld* world, int *numDynamicObjects) override
+ void AddToPhysicWorld(btDiscreteDynamicsWorld* world) override
{
- CPhysicObject::AddToPhysicWorld(world, numDynamicObjects);
+ CPhysicObject::AddToPhysicWorld(world);
if (GetGhostObject())
{
world->addCollisionObject(GetGhostObject(), btBroadphaseProxy::SensorTrigger, FallGuysCollisionFilterGroups::DynamicObjectFilter | FallGuysCollisionFilterGroups::ClippingHullFilter);
-
- (*numDynamicObjects)++;
}
}
@@ -3904,7 +3911,7 @@ bool CPhysicsManager::CreatePhysicTrigger(edict_t* ent)
ghostobj->GetGhostObject()->setCollisionShape(shape);
ghostobj->GetGhostObject()->setCollisionFlags(ghostobj->GetGhostObject()->getCollisionFlags() | btCollisionObject::CF_NO_CONTACT_RESPONSE);
- obj->AddPhysicObject(ghostobj, m_dynamicsWorld, &m_numDynamicObjects);
+ obj->AddPhysicObject(ghostobj, m_dynamicsWorld);
return true;
}
@@ -4433,7 +4440,7 @@ bool CPhysicsManager::CreatePhysicWater(edict_t* ent, float density, float linea
ghostobj->GetGhostObject()->setCollisionShape(shape);
ghostobj->GetGhostObject()->setCollisionFlags(ghostobj->GetGhostObject()->getCollisionFlags() | btCollisionObject::CF_NO_CONTACT_RESPONSE);
- obj->AddPhysicObject(ghostobj, m_dynamicsWorld, &m_numDynamicObjects);
+ obj->AddPhysicObject(ghostobj, m_dynamicsWorld);
return true;
}
@@ -4619,7 +4626,7 @@ bool CPhysicsManager::CreatePhysicObjectPost(edict_t *ent, CGameObject *obj, btC
ent->v.velocity = g_vecZero;
ent->v.avelocity = g_vecZero;
- obj->AddPhysicObject(dynamicobj, m_dynamicsWorld, &m_numDynamicObjects);
+ obj->AddPhysicObject(dynamicobj, m_dynamicsWorld);
if (objectParams->flags & PhysicObject_HasImpactImpulse)
{
@@ -4664,7 +4671,7 @@ bool CPhysicsManager::CreatePhysicObjectPost(edict_t *ent, CGameObject *obj, btC
constraint->setUserConstraintType(ConstraintType_ClippingHull);
- obj->AddPhysicObject(hullobj, m_dynamicsWorld, &m_numDynamicObjects);
+ obj->AddPhysicObject(hullobj, m_dynamicsWorld);
obj->AddConstraint(constraint, m_dynamicsWorld, true);
@@ -4775,7 +4782,7 @@ bool CPhysicsManager::CreatePhysicObject(edict_t* ent, PhysicShapeParams *shapeP
return false;
}
- auto mod = (*sv_models)[ent->v.modelindex];
+ auto mod = EngineGetPrecachedModelByIndex(ent->v.modelindex);
if (!mod)
{
@@ -4824,7 +4831,7 @@ void CPhysicsManager::PostSpawn(edict_t *ent)
{
auto mod = EngineGetPrecachedModelByIndex(i);
- if (mod->type == mod_brush && mod->name[0])
+ if (mod && mod->type == mod_brush && mod->name[0])
{
if (mod->needload == NL_PRESENT || mod->needload == NL_CLIENT)
{
@@ -5106,9 +5113,6 @@ void CPhysicsManager::StepSimulation(double frametime)
if (!m_bEnabled)
return;
- //if (!gPhysicsManager.GetNumDynamicBodies())
- // return;
-
m_dynamicsWorld->stepSimulation((btScalar)frametime, 2, m_simrate);
}
@@ -5134,11 +5138,6 @@ int CPhysicsManager::GetSolidPlayerMask()
return m_solidPlayerMask;
}
-int CPhysicsManager::GetNumDynamicBodies()
-{
- return m_numDynamicObjects;
-}
-
CGameObject *CPhysicsManager::GetGameObject(int entindex)
{
if (entindex < 0 || entindex >= (int)m_gameObjects.size())
@@ -5161,8 +5160,8 @@ void CPhysicsManager::RemoveGameObject(int entindex)
if (obj)
{
- obj->RemoveAllConstraints(m_dynamicsWorld, &m_numDynamicObjects);
- obj->RemoveAllPhysicObjects(m_dynamicsWorld, &m_numDynamicObjects);
+ obj->RemoveAllConstraints(m_dynamicsWorld);
+ obj->RemoveAllPhysicObjects(m_dynamicsWorld);
delete obj;
@@ -5235,12 +5234,9 @@ void CGameObject::EndFrame(btDiscreteDynamicsWorld* world)
ent->v.maxs = m_backup_maxs;
}
- //if (gPhysicsManager.GetNumDynamicBodies() > 0)
+ for (size_t i = 0; i < m_physics.size(); ++i)
{
- for (size_t i = 0; i < m_physics.size(); ++i)
- {
- m_physics[i]->EndFrame(world);
- }
+ m_physics[i]->EndFrame(world);
}
if (m_anim_flags & EnvStudioAnim_AnimatedStudio)
diff --git a/fallguys/physics.h b/fallguys/physics.h
index 27f43f6..17c6901 100644
--- a/fallguys/physics.h
+++ b/fallguys/physics.h
@@ -300,6 +300,7 @@ CPhysicVehicleWheelInfo : public CBulletBaseSharedUserData
m_engineIndex = 3;
m_steerIndex = 5;
m_rayCastHeight = 16;
+ m_flags = 0;
m_hitGround = false;
m_hitPointInWorld = btVector3(0, 0, 0);
@@ -313,6 +314,8 @@ CPhysicVehicleWheelInfo : public CBulletBaseSharedUserData
m_steerIndex = params->steerIndex;
m_flags = params->flags;
m_rayCastHeight = params->rayCastHeight;
+
+ m_hitGround = false;
}
//init
@@ -407,12 +410,12 @@ CPhysicObject
}
- virtual void AddToPhysicWorld(btDiscreteDynamicsWorld* world, int *numDynamicObjects)
+ virtual void AddToPhysicWorld(btDiscreteDynamicsWorld* world)
{
}
- virtual void RemoveFromPhysicWorld(btDiscreteDynamicsWorld* world, int *numDynamicObjects)
+ virtual void RemoveFromPhysicWorld(btDiscreteDynamicsWorld* world)
{
for (auto action : m_actions)
{
@@ -509,25 +512,21 @@ CGhostPhysicObject : public CPhysicObject
return false;
}
- void AddToPhysicWorld(btDiscreteDynamicsWorld* world, int *numDynamicObjects) override
+ void AddToPhysicWorld(btDiscreteDynamicsWorld* world) override
{
if (m_ghostobj)
{
world->addCollisionObject(m_ghostobj, btBroadphaseProxy::SensorTrigger, btBroadphaseProxy::DefaultFilter);
-
- (*numDynamicObjects)++;
}
}
- void RemoveFromPhysicWorld(btDiscreteDynamicsWorld* world, int *numDynamicObjects) override
+ void RemoveFromPhysicWorld(btDiscreteDynamicsWorld* world) override
{
- CPhysicObject::RemoveFromPhysicWorld(world, numDynamicObjects);
+ CPhysicObject::RemoveFromPhysicWorld(world);
if (m_ghostobj)
{
world->removeCollisionObject(m_ghostobj);
-
- (*numDynamicObjects)--;
}
}
@@ -586,13 +585,11 @@ CSolidOptimizerGhostPhysicObject : public CGhostPhysicObject
return true;
}
- void AddToPhysicWorld(btDiscreteDynamicsWorld* world, int *numDynamicObjects) override
+ void AddToPhysicWorld(btDiscreteDynamicsWorld* world) override
{
if (m_ghostobj)
{
world->addCollisionObject(m_ghostobj, btBroadphaseProxy::SensorTrigger, FallGuysCollisionFilterGroups::PlayerFilter);
-
- (*numDynamicObjects)++;
}
}
@@ -635,7 +632,7 @@ CCollisionPhysicObject : public CPhysicObject
}
}
- void AddToPhysicWorld(btDiscreteDynamicsWorld* world, int *numDynamicObjects) override
+ void AddToPhysicWorld(btDiscreteDynamicsWorld* world) override
{
if (m_rigbody)
{
@@ -643,12 +640,36 @@ CCollisionPhysicObject : public CPhysicObject
}
}
- void RemoveFromPhysicWorld(btDiscreteDynamicsWorld* world, int *numDynamicObjects) override
+ void RemoveFromPhysicWorld(btDiscreteDynamicsWorld* world) override
{
- CPhysicObject::RemoveFromPhysicWorld(world, numDynamicObjects);
+ CPhysicObject::RemoveFromPhysicWorld(world);
if (m_rigbody)
{
+ int numRefs = m_rigbody->getNumConstraintRefs();
+
+ std::vector pendingRemoves;
+
+ pendingRemoves.reserve(numRefs);
+
+ for (int i = 0; i < numRefs; ++i)
+ {
+ auto pInternalContraint = m_rigbody->getConstraintRef(i);
+
+ pendingRemoves.emplace_back(pInternalContraint);
+ }
+
+ for (size_t i = 0; i < pendingRemoves.size(); ++i)
+ {
+ auto pInternalContraint = pendingRemoves[i];
+
+ world->removeConstraint(pInternalContraint);
+
+ OnBeforeDeleteConstraint(pInternalContraint);
+
+ delete pInternalContraint;
+ }
+
world->removeRigidBody(m_rigbody);
}
}
@@ -875,18 +896,14 @@ CDynamicObject : public CCollisionPhysicObject
void SetPhysicNoCollision(bool no_collision) override;
- void AddToPhysicWorld(btDiscreteDynamicsWorld* world, int *numDynamicObjects) override
+ void AddToPhysicWorld(btDiscreteDynamicsWorld* world) override
{
- CCollisionPhysicObject::AddToPhysicWorld(world, numDynamicObjects);
-
- (*numDynamicObjects) ++ ;
+ CCollisionPhysicObject::AddToPhysicWorld(world);
}
- void RemoveFromPhysicWorld(btDiscreteDynamicsWorld* world, int *numDynamicObjects) override
+ void RemoveFromPhysicWorld(btDiscreteDynamicsWorld* world) override
{
- CCollisionPhysicObject::RemoveFromPhysicWorld(world, numDynamicObjects);
-
- (*numDynamicObjects) --;
+ CCollisionPhysicObject::RemoveFromPhysicWorld(world);
}
void StartFrame(btDiscreteDynamicsWorld* world) override;
@@ -1127,9 +1144,9 @@ CGameObject
m_solid_optimizer.emplace_back(bone, radius);
}
- void AddPhysicObject(CPhysicObject *physobj, btDiscreteDynamicsWorld* world, int *numDynamicObjects)
+ void AddPhysicObject(CPhysicObject *physobj, btDiscreteDynamicsWorld* world)
{
- physobj->AddToPhysicWorld(world, numDynamicObjects);
+ physobj->AddToPhysicWorld(world);
m_physics.emplace_back(physobj);
}
@@ -1139,46 +1156,48 @@ CGameObject
world->addConstraint(constraint, disableCollisionsBetweenLinkedBodies);
}
- void RemoveAllConstraints(btDiscreteDynamicsWorld* world, int *numDynamicObjects)
+ void RemoveAllConstraints(btDiscreteDynamicsWorld* world)
{
- std::vector defRemoves;
+ std::vector pendingRemoves;
for (int i = 0; i < world->getNumConstraints(); ++i)
{
- auto constraint = world->getConstraint(i);
+ auto pInternalConstraint = world->getConstraint(i);
for (size_t j = 0; j < m_physics.size(); ++j)
{
- auto physObj = m_physics[j];
+ auto pPhysicObject = m_physics[j];
- if (constraint->getRigidBodyA().getUserPointer() == physObj || constraint->getRigidBodyB().getUserPointer() == physObj)
+ if (pInternalConstraint->getRigidBodyA().getUserPointer() == pPhysicObject ||
+ pInternalConstraint->getRigidBodyB().getUserPointer() == pPhysicObject)
{
- defRemoves.emplace_back(constraint);
+ pendingRemoves.emplace_back(pInternalConstraint);
break;
}
}
}
- for (size_t i = 0; i < defRemoves.size(); ++i)
+ for (size_t i = 0; i < pendingRemoves.size(); ++i)
{
- auto constraint = defRemoves[i];
+ auto pInternalConstraint = pendingRemoves[i];
- world->removeConstraint(constraint);
+ world->removeConstraint(pInternalConstraint);
- OnBeforeDeleteConstraint(constraint);
+ OnBeforeDeleteConstraint(pInternalConstraint);
- delete constraint;
+ delete pInternalConstraint;
}
}
- void RemoveAllPhysicObjects(btDiscreteDynamicsWorld* world, int *numDynamicObjects)
+ void RemoveAllPhysicObjects(btDiscreteDynamicsWorld* world)
{
for (size_t i = 0; i < m_physics.size(); ++i)
{
auto physobj = m_physics[i];
+
if (physobj)
{
- physobj->RemoveFromPhysicWorld(world, numDynamicObjects);
+ physobj->RemoveFromPhysicWorld(world);
delete physobj;
}
@@ -1534,7 +1553,6 @@ class CPhysicsManager
void StepSimulation(double framerate);
int GetSolidPlayerMask();
- int GetNumDynamicBodies();
CGameObject* GetGameObject(int entindex);
CGameObject* GetGameObject(edict_t* ent);
void RemoveGameObject(int entindex);
@@ -1619,10 +1637,6 @@ class CPhysicsManager
std::vector m_gameObjects;
int m_maxIndexGameObject;
- int m_numDynamicObjects;
- //std::vector m_brushIndexArray;
- //std::vector m_brushVertexArray;
- //vertexarray_t* m_worldVertexArray;
std::unordered_map> m_indexArrayResources;
std::unordered_map> m_worldVertexResources;