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;