diff --git a/Plugins/BulletPhysics/BasePhysicManager.cpp b/Plugins/BulletPhysics/BasePhysicManager.cpp index 1f444440..ebd99e82 100644 --- a/Plugins/BulletPhysics/BasePhysicManager.cpp +++ b/Plugins/BulletPhysics/BasePhysicManager.cpp @@ -3,7 +3,19 @@ #include "exportfuncs.h" #include "privatehook.h" #include "enginedef.h" +#include "plugins.h" #include "BasePhysicManager.h" +#include "mathlib2.h" + +CBasePhysicManager::CBasePhysicManager() +{ + m_worldVertexArray = NULL; + m_barnacleIndexArray = NULL; + m_barnacleVertexArray = NULL; + m_gargantuaIndexArray = NULL; + m_gargantuaVertexArray = NULL; + m_gravity = 0; +} void CBasePhysicManager::Init(void) { @@ -17,7 +29,10 @@ void CBasePhysicManager::Shutdown() void CBasePhysicManager::NewMap(void) { - + GenerateWorldIndexVertexArray(); + GenerateBarnacleIndexVertexArray(); + GenerateGargantuaIndexVertexArray(); + CreateBrushModel(r_worldentity); } void CBasePhysicManager::DebugDraw(void) @@ -27,7 +42,7 @@ void CBasePhysicManager::DebugDraw(void) void CBasePhysicManager::SetGravity(float velocity) { - + m_gravity = -velocity; } void CBasePhysicManager::StepSimulation(double framerate) @@ -60,24 +75,46 @@ bool CBasePhysicManager::ChangeRagdollEntityIndex(int old_entindex, int new_enti return false; } -IRagdollObject* CBasePhysicManager::FindRagdollObject(int entindex) +IPhysicObject* CBasePhysicManager::GetPhysicObject(int entindex) { - return NULL; -} + auto itor = m_physicObjects.find(entindex); -IRagdollObject* CBasePhysicManager::CreateRagdollObject(model_t* mod, int entindex, const CRagdollConfig* config) -{ - return NULL; + if (itor == m_physicObjects.end()) + { + return NULL; + } + + return itor->second; } -IStaticObject* CBasePhysicManager::CreateStaticObject(model_t* mod, int entindex) +IRagdollObject* CBasePhysicManager::CreateRagdollObject(model_t* mod, int entindex, const CRagdollConfig& config) { return NULL; } void CBasePhysicManager::CreateBrushModel(cl_entity_t* ent) { + auto PhysicObject = GetPhysicObject(ent->index); + if (PhysicObject) + return; + + auto IndexArray = GetIndexArrayFromBrushModel(ent->model); + + if (!IndexArray) + return; + + CPhysicStaticObjectCreationParameter CreationParameter; + CreationParameter.VertexArray = m_worldVertexArray; + CreationParameter.IndexArray = IndexArray; + CreationParameter.IsKinematic = false; + + if ((ent != r_worldentity) && (ent->curstate.movetype == MOVETYPE_PUSH || ent->curstate.movetype == MOVETYPE_PUSHSTEP)) + { + CreationParameter.IsKinematic = true; + } + + CreateStaticObject(ent, CreationParameter); } void CBasePhysicManager::CreateBarnacle(cl_entity_t* ent) @@ -98,4 +135,505 @@ void CBasePhysicManager::RemovePhysicObject(int entindex) void CBasePhysicManager::UpdateTempEntity(TEMPENTITY** ppTempEntFree, TEMPENTITY** ppTempEntActive, double frame_time, double client_time) { +} + +class CSavedPolyFlag +{ +public: + CSavedPolyFlag(glpoly_t* p, int flags) : m_poly(p), m_flags(flags) + { + + } + + glpoly_t* m_poly; + int m_flags; +}; + +void CBasePhysicManager::GenerateWorldIndexVertexArray() +{ + FreeWorldVertexArray(); + + m_worldVertexArray = new CPhysicVertexArray; + + std::vector SavedPolyFlags; + + CPhysicBrushVertex Vertexes[3]; + + int iNumFaces = 0; + int iNumVerts = 0; + + m_worldVertexArray->vFaceBuffer.resize(r_worldmodel->numsurfaces); + + for (int i = 0; i < r_worldmodel->numsurfaces; i++) + { + msurface_t* surf; + + if (g_iEngineType == ENGINE_GOLDSRC_HL25) + { + surf = (((msurface_hl25_t*)r_worldmodel->surfaces) + i); + } + else + { + surf = r_worldmodel->surfaces + i; + } + + if ((surf->flags & (SURF_DRAWTURB | SURF_UNDERWATER | SURF_DRAWSKY))) + continue; + + auto poly = surf->polys; + + SavedPolyFlags.emplace_back(poly, poly->flags); + + poly->flags = i; + + CPhysicBrushFace* brushface = &m_worldVertexArray->vFaceBuffer[i]; + + int iStartVert = iNumVerts; + + brushface->start_vertex = iStartVert; + + for (poly = surf->polys; poly; poly = poly->next) + { + auto v = poly->verts[0]; + + for (int j = 0; j < 3; j++, v += VERTEXSIZE) + { + Vertexes[j].pos[0] = v[0]; + Vertexes[j].pos[1] = v[1]; + Vertexes[j].pos[2] = v[2]; + } + + m_worldVertexArray->vVertexBuffer.emplace_back(Vertexes[0]); + m_worldVertexArray->vVertexBuffer.emplace_back(Vertexes[1]); + m_worldVertexArray->vVertexBuffer.emplace_back(Vertexes[2]); + + iNumVerts += 3; + + for (int j = 0; j < (poly->numverts - 3); j++, v += VERTEXSIZE) + { + Vertexes[1] = Vertexes[2]; + + Vertexes[2].pos[0] = v[0]; + Vertexes[2].pos[1] = v[1]; + Vertexes[2].pos[2] = v[2]; + + m_worldVertexArray->vVertexBuffer.emplace_back(Vertexes[0]); + m_worldVertexArray->vVertexBuffer.emplace_back(Vertexes[1]); + m_worldVertexArray->vVertexBuffer.emplace_back(Vertexes[2]); + + iNumVerts += 3; + } + } + + brushface->num_vertexes = iNumVerts - iStartVert; + } + + GenerateBrushIndexArray(); + + for (auto& p : SavedPolyFlags) + { + p.m_poly->flags = p.m_flags; + } +} + +void CBasePhysicManager::FreeWorldVertexArray() +{ + if (m_worldVertexArray) { + delete m_worldVertexArray; + m_worldVertexArray = NULL; + } +} + +/* + Purpose : Generate IndexArray for world and all brush models +*/ + +void CBasePhysicManager::GenerateBrushIndexArray() +{ + FreeAllBrushIndexArray(); + + int maxNum = EngineGetMaxKnownModel(); + + if ((int)m_brushIndexArray.size() < maxNum) + m_brushIndexArray.resize(maxNum); + + for (int i = 0; i < EngineGetNumKnownModel(); ++i) + { + auto mod = EngineGetModelByIndex(i); + if (mod->type == mod_brush && mod->name[0]) + { + if (mod->needload == NL_PRESENT || mod->needload == NL_CLIENT) + { + m_brushIndexArray[i] = new CPhysicIndexArray; + GenerateIndexArrayForBrushModel(mod, m_worldVertexArray, m_brushIndexArray[i]); + } + } + } +} + +void CBasePhysicManager::FreeAllBrushIndexArray() +{ + for (size_t i = 0; i < m_brushIndexArray.size(); ++i) + { + if (m_brushIndexArray[i]) + { + delete m_brushIndexArray[i]; + m_brushIndexArray[i] = NULL; + } + } + m_brushIndexArray.clear(); +} + +void CBasePhysicManager::GenerateIndexArrayForBrushModel(model_t* mod, CPhysicVertexArray* vertexArray, CPhysicIndexArray* indexArray) +{ + if (mod == r_worldmodel) + { + GenerateIndexArrayRecursiveWorldNode(mod->nodes, vertexArray, indexArray); + } + else + { + for (int i = 0; i < mod->nummodelsurfaces; i++) + { + msurface_t* surf; + + if (g_iEngineType == ENGINE_GOLDSRC_HL25) + { + surf = (((msurface_hl25_t*)mod->surfaces) + mod->firstmodelsurface + i); + } + else + { + surf = mod->surfaces + mod->firstmodelsurface + i; + } + + GenerateIndexArrayForSurface(surf, vertexArray, indexArray); + } + } +} + +void CBasePhysicManager::GenerateIndexArrayForSurface(msurface_t* psurf, CPhysicVertexArray* vertexarray, CPhysicIndexArray* indexarray) +{ + if (psurf->flags & SURF_DRAWTURB) + { + return; + } + + if (psurf->flags & SURF_DRAWSKY) + { + return; + } + + if (psurf->flags & SURF_UNDERWATER) + { + return; + } + + GenerateIndexArrayForBrushface(&vertexarray->vFaceBuffer[psurf->polys->flags], indexarray); +} + +void CBasePhysicManager::GenerateIndexArrayRecursiveWorldNode(mnode_t* node, CPhysicVertexArray* vertexArray, CPhysicIndexArray* indexArray) +{ + if (node->contents == CONTENTS_SOLID) + return; + + if (node->contents < 0) + return; + + GenerateIndexArrayRecursiveWorldNode(node->children[0], vertexArray, indexArray); + + for (int i = 0; i < node->numsurfaces; ++i) + { + msurface_t* surf; + + if (g_iEngineType == ENGINE_GOLDSRC_HL25) + { + surf = (((msurface_hl25_t*)r_worldmodel->surfaces) + node->firstsurface + i); + } + else + { + surf = r_worldmodel->surfaces + node->firstsurface + i; + } + + GenerateIndexArrayForSurface(surf, vertexArray, indexArray); + } + + GenerateIndexArrayRecursiveWorldNode(node->children[1], vertexArray, indexArray); +} + +void CBasePhysicManager::GenerateIndexArrayForBrushface(CPhysicBrushFace* brushface, CPhysicIndexArray* indexArray) +{ + int first = -1; + int prv0 = -1; + int prv1 = -1; + int prv2 = -1; + + for (int i = 0; i < brushface->num_vertexes; i++) + { + if (prv0 != -1 && prv1 != -1 && prv2 != -1) + { + indexArray->vIndexBuffer.emplace_back(brushface->start_vertex + first); + indexArray->vIndexBuffer.emplace_back(brushface->start_vertex + prv2); + } + + indexArray->vIndexBuffer.emplace_back(brushface->start_vertex + i); + + if (first == -1) + first = i; + + prv0 = prv1; + prv1 = prv2; + prv2 = i; + } +} + +void CBasePhysicManager::GenerateBarnacleIndexVertexArray() +{ + const int BARNACLE_SEGMENTS = 12; + + const float BARNACLE_RADIUS1 = 22; + const float BARNACLE_RADIUS2 = 16; + const float BARNACLE_RADIUS3 = 10; + + const float BARNACLE_HEIGHT1 = 0; + const float BARNACLE_HEIGHT2 = -10; + const float BARNACLE_HEIGHT3 = -36; + + FreeBarnacleIndexVertexArray(); + + m_barnacleVertexArray = new CPhysicVertexArray; + m_barnacleVertexArray->vVertexBuffer.resize(BARNACLE_SEGMENTS * 8); + m_barnacleVertexArray->vFaceBuffer.resize(BARNACLE_SEGMENTS * 2); + + int iStartVertex = 0; + int iNumVerts = 0; + int iNumFace = 0; + + for (int x = 0; x < BARNACLE_SEGMENTS; x++) + { + float xSegment = (float)x / (float)BARNACLE_SEGMENTS; + float xSegment2 = (float)(x + 1) / (float)BARNACLE_SEGMENTS; + + //layer 1 + + m_barnacleVertexArray->vVertexBuffer[iNumVerts].pos[0] = std::sin(xSegment * 2 * M_PI) * BARNACLE_RADIUS1; + m_barnacleVertexArray->vVertexBuffer[iNumVerts].pos[1] = std::cos(xSegment * 2 * M_PI) * BARNACLE_RADIUS1; + m_barnacleVertexArray->vVertexBuffer[iNumVerts].pos[2] = BARNACLE_HEIGHT1; + + iNumVerts++; + + m_barnacleVertexArray->vVertexBuffer[iNumVerts].pos[0] = std::sin(xSegment * 2 * M_PI) * BARNACLE_RADIUS2; + m_barnacleVertexArray->vVertexBuffer[iNumVerts].pos[1] = std::cos(xSegment * 2 * M_PI) * BARNACLE_RADIUS2; + m_barnacleVertexArray->vVertexBuffer[iNumVerts].pos[2] = BARNACLE_HEIGHT2; + + iNumVerts++; + + m_barnacleVertexArray->vVertexBuffer[iNumVerts].pos[0] = std::sin(xSegment2 * 2 * M_PI) * BARNACLE_RADIUS2; + m_barnacleVertexArray->vVertexBuffer[iNumVerts].pos[1] = std::cos(xSegment2 * 2 * M_PI) * BARNACLE_RADIUS2; + m_barnacleVertexArray->vVertexBuffer[iNumVerts].pos[2] = BARNACLE_HEIGHT2; + + iNumVerts++; + + m_barnacleVertexArray->vVertexBuffer[iNumVerts].pos[0] = std::sin(xSegment2 * 2 * M_PI) * BARNACLE_RADIUS1; + m_barnacleVertexArray->vVertexBuffer[iNumVerts].pos[1] = std::cos(xSegment2 * 2 * M_PI) * BARNACLE_RADIUS1; + m_barnacleVertexArray->vVertexBuffer[iNumVerts].pos[2] = BARNACLE_HEIGHT1; + + iNumVerts++; + + m_barnacleVertexArray->vFaceBuffer[iNumFace].start_vertex = iStartVertex; + m_barnacleVertexArray->vFaceBuffer[iNumFace].num_vertexes = 4; + iNumFace++; + + iStartVertex = iNumVerts; + + // layer 2 + + m_barnacleVertexArray->vVertexBuffer[iNumVerts].pos[0] = std::sin(xSegment * 2 * M_PI) * BARNACLE_RADIUS2; + m_barnacleVertexArray->vVertexBuffer[iNumVerts].pos[1] = std::cos(xSegment * 2 * M_PI) * BARNACLE_RADIUS2; + m_barnacleVertexArray->vVertexBuffer[iNumVerts].pos[2] = BARNACLE_HEIGHT2; + + iNumVerts++; + + m_barnacleVertexArray->vVertexBuffer[iNumVerts].pos[0] = std::sin(xSegment * 2 * M_PI) * BARNACLE_RADIUS3; + m_barnacleVertexArray->vVertexBuffer[iNumVerts].pos[1] = std::cos(xSegment * 2 * M_PI) * BARNACLE_RADIUS3; + m_barnacleVertexArray->vVertexBuffer[iNumVerts].pos[2] = BARNACLE_HEIGHT3; + + iNumVerts++; + + m_barnacleVertexArray->vVertexBuffer[iNumVerts].pos[0] = std::sin(xSegment2 * 2 * M_PI) * BARNACLE_RADIUS3; + m_barnacleVertexArray->vVertexBuffer[iNumVerts].pos[1] = std::cos(xSegment2 * 2 * M_PI) * BARNACLE_RADIUS3; + m_barnacleVertexArray->vVertexBuffer[iNumVerts].pos[2] = BARNACLE_HEIGHT3; + + iNumVerts++; + + m_barnacleVertexArray->vVertexBuffer[iNumVerts].pos[0] = std::sin(xSegment2 * 2 * M_PI) * BARNACLE_RADIUS2; + m_barnacleVertexArray->vVertexBuffer[iNumVerts].pos[1] = std::cos(xSegment2 * 2 * M_PI) * BARNACLE_RADIUS2; + m_barnacleVertexArray->vVertexBuffer[iNumVerts].pos[2] = BARNACLE_HEIGHT2; + + iNumVerts++; + + m_barnacleVertexArray->vFaceBuffer[iNumFace].start_vertex = iStartVertex; + m_barnacleVertexArray->vFaceBuffer[iNumFace].num_vertexes = 4; + iNumFace++; + + iStartVertex = iNumVerts; + } + + m_barnacleIndexArray = new CPhysicIndexArray; + + for (int i = 0; i < (int)m_barnacleVertexArray->vFaceBuffer.size(); i++) + { + GenerateIndexArrayForBrushface(&m_barnacleVertexArray->vFaceBuffer[i], m_barnacleIndexArray); + } +} + +void CBasePhysicManager::FreeBarnacleIndexVertexArray() +{ + if (m_barnacleVertexArray) + { + delete m_barnacleVertexArray; + m_barnacleVertexArray = NULL; + } + + if (m_barnacleIndexArray) + { + delete m_barnacleIndexArray; + m_barnacleIndexArray = NULL; + } +} + +void CBasePhysicManager::GenerateGargantuaIndexVertexArray() +{ + const int GARGANTUA_SEGMENTS = 12; + + const float GARGANTUA_RADIUS1 = 16; + const float GARGANTUA_RADIUS2 = 14; + const float GARGANTUA_RADIUS3 = 12; + + const float GARGANTUA_HEIGHT1 = 8; + const float GARGANTUA_HEIGHT2 = -8; + const float GARGANTUA_HEIGHT3 = -24; + + FreeGargantuaIndexVertexArray(); + + m_gargantuaVertexArray = new CPhysicVertexArray; + m_gargantuaVertexArray->vVertexBuffer.resize(GARGANTUA_SEGMENTS * (4 + 4));// + 3 + m_gargantuaVertexArray->vFaceBuffer.resize(GARGANTUA_SEGMENTS * 2); + + int iStartVertex = 0; + int iNumVerts = 0; + int iNumFace = 0; + + for (int x = 0; x < GARGANTUA_SEGMENTS; x++) + { + float xSegment = (float)x / (float)GARGANTUA_SEGMENTS; + float xSegment2 = (float)(x + 1) / (float)GARGANTUA_SEGMENTS; + + //layer 1 + + m_gargantuaVertexArray->vVertexBuffer[iNumVerts].pos[0] = std::sin(xSegment * 2 * M_PI) * GARGANTUA_RADIUS1; + m_gargantuaVertexArray->vVertexBuffer[iNumVerts].pos[1] = std::cos(xSegment * 2 * M_PI) * GARGANTUA_RADIUS1; + m_gargantuaVertexArray->vVertexBuffer[iNumVerts].pos[2] = GARGANTUA_HEIGHT1; + iNumVerts++; + + m_gargantuaVertexArray->vVertexBuffer[iNumVerts].pos[0] = std::sin(xSegment * 2 * M_PI) * GARGANTUA_RADIUS2; + m_gargantuaVertexArray->vVertexBuffer[iNumVerts].pos[1] = std::cos(xSegment * 2 * M_PI) * GARGANTUA_RADIUS2; + m_gargantuaVertexArray->vVertexBuffer[iNumVerts].pos[2] = GARGANTUA_HEIGHT2; + iNumVerts++; + + m_gargantuaVertexArray->vVertexBuffer[iNumVerts].pos[0] = std::sin(xSegment2 * 2 * M_PI) * GARGANTUA_RADIUS2; + m_gargantuaVertexArray->vVertexBuffer[iNumVerts].pos[1] = std::cos(xSegment2 * 2 * M_PI) * GARGANTUA_RADIUS2; + m_gargantuaVertexArray->vVertexBuffer[iNumVerts].pos[2] = GARGANTUA_HEIGHT2; + iNumVerts++; + + m_gargantuaVertexArray->vVertexBuffer[iNumVerts].pos[0] = std::sin(xSegment2 * 2 * M_PI) * GARGANTUA_RADIUS1; + m_gargantuaVertexArray->vVertexBuffer[iNumVerts].pos[1] = std::cos(xSegment2 * 2 * M_PI) * GARGANTUA_RADIUS1; + m_gargantuaVertexArray->vVertexBuffer[iNumVerts].pos[2] = GARGANTUA_HEIGHT1; + iNumVerts++; + + m_gargantuaVertexArray->vFaceBuffer[iNumFace].start_vertex = iStartVertex; + m_gargantuaVertexArray->vFaceBuffer[iNumFace].num_vertexes = 4; + iNumFace++; + + iStartVertex = iNumVerts; + + // layer 2 + + m_gargantuaVertexArray->vVertexBuffer[iNumVerts].pos[0] = std::sin(xSegment * 2 * M_PI) * GARGANTUA_RADIUS2; + m_gargantuaVertexArray->vVertexBuffer[iNumVerts].pos[1] = std::cos(xSegment * 2 * M_PI) * GARGANTUA_RADIUS2; + m_gargantuaVertexArray->vVertexBuffer[iNumVerts].pos[2] = GARGANTUA_HEIGHT2; + + iNumVerts++; + + m_gargantuaVertexArray->vVertexBuffer[iNumVerts].pos[0] = std::sin(xSegment * 2 * M_PI) * GARGANTUA_RADIUS3; + m_gargantuaVertexArray->vVertexBuffer[iNumVerts].pos[1] = std::cos(xSegment * 2 * M_PI) * GARGANTUA_RADIUS3; + m_gargantuaVertexArray->vVertexBuffer[iNumVerts].pos[2] = GARGANTUA_HEIGHT3; + + iNumVerts++; + + m_gargantuaVertexArray->vVertexBuffer[iNumVerts].pos[0] = std::sin(xSegment2 * 2 * M_PI) * GARGANTUA_RADIUS3; + m_gargantuaVertexArray->vVertexBuffer[iNumVerts].pos[1] = std::cos(xSegment2 * 2 * M_PI) * GARGANTUA_RADIUS3; + m_gargantuaVertexArray->vVertexBuffer[iNumVerts].pos[2] = GARGANTUA_HEIGHT3; + + iNumVerts++; + + m_gargantuaVertexArray->vVertexBuffer[iNumVerts].pos[0] = std::sin(xSegment2 * 2 * M_PI) * GARGANTUA_RADIUS2; + m_gargantuaVertexArray->vVertexBuffer[iNumVerts].pos[1] = std::cos(xSegment2 * 2 * M_PI) * GARGANTUA_RADIUS2; + m_gargantuaVertexArray->vVertexBuffer[iNumVerts].pos[2] = GARGANTUA_HEIGHT2; + + iNumVerts++; + + m_gargantuaVertexArray->vFaceBuffer[iNumFace].start_vertex = iStartVertex; + m_gargantuaVertexArray->vFaceBuffer[iNumFace].num_vertexes = 4; + iNumFace++; + + iStartVertex = iNumVerts; + } + + m_gargantuaIndexArray = new CPhysicIndexArray; + + for (int i = 0; i < (int)m_gargantuaVertexArray->vFaceBuffer.size(); i++) + { + if (i >= 3 * 2 && i < 8 * 2) + continue; + + GenerateIndexArrayForBrushface(&m_gargantuaVertexArray->vFaceBuffer[i], m_gargantuaIndexArray); + } +} + +void CBasePhysicManager::FreeGargantuaIndexVertexArray() +{ + if (m_gargantuaVertexArray) + { + delete m_gargantuaVertexArray; + m_gargantuaVertexArray = NULL; + } + + if (m_gargantuaIndexArray) + { + delete m_gargantuaIndexArray; + m_gargantuaIndexArray = NULL; + } +} + +CRagdollConfig *CBasePhysicManager::GetRagdollConfigFromModel(model_t* mod) +{ + int modelindex = EngineGetModelIndex(mod); + + if (modelindex < 0 || modelindex >(int)m_ragdollConfigs.size()) + { + return NULL; + } + + return m_ragdollConfigs[modelindex]; +} + +CPhysicIndexArray * CBasePhysicManager::GetIndexArrayFromBrushModel(model_t *mod) +{ + int modelindex = EngineGetModelIndex(mod); + + if (modelindex < 0 || modelindex > (int)m_brushIndexArray.size()) + { + return NULL; + } + + return m_brushIndexArray[modelindex]; } \ No newline at end of file diff --git a/Plugins/BulletPhysics/BasePhysicManager.h b/Plugins/BulletPhysics/BasePhysicManager.h index 23323670..acd24006 100644 --- a/Plugins/BulletPhysics/BasePhysicManager.h +++ b/Plugins/BulletPhysics/BasePhysicManager.h @@ -1,10 +1,88 @@ #pragma once +#include +#include + #include "PhysicManager.h" +class CPhysicBrushVertex +{ +public: + CPhysicBrushVertex() + { + pos[0] = 0; + pos[1] = 0; + pos[2] = 0; + } + + vec3_t pos; +}; + +class CPhysicBrushFace +{ +public: + CPhysicBrushFace() + { + start_vertex = 0; + num_vertexes = 0; + } + + int start_vertex; + int num_vertexes; +}; + +class CPhysicVertexArray +{ +public: + CPhysicVertexArray() + { + bIsDynamic = false; + } + std::vector vVertexBuffer; + std::vector vFaceBuffer; + bool bIsDynamic; +}; + +class CPhysicIndexArray +{ +public: + CPhysicIndexArray() + { + bIsDynamic = false; + } + std::vector vIndexBuffer; + bool bIsDynamic; +}; + +class CPhysicObjectCreationParameter +{ +public: + CPhysicVertexArray* VertexArray; + CPhysicIndexArray* IndexArray; +}; + +class CPhysicStaticObjectCreationParameter : public CPhysicObjectCreationParameter +{ +public: + bool IsKinematic; +}; + class CBasePhysicManager : public IPhysicManager { +protected: + CPhysicVertexArray* m_worldVertexArray; + CPhysicIndexArray* m_barnacleIndexArray; + CPhysicVertexArray* m_barnacleVertexArray; + CPhysicIndexArray* m_gargantuaIndexArray; + CPhysicVertexArray* m_gargantuaVertexArray; + float m_gravity; + + std::unordered_map m_physicObjects; + std::vector m_ragdollConfigs; + std::vector m_brushIndexArray; public: + CBasePhysicManager(); + void Init(void) override; void Shutdown() override; void NewMap(void) override; @@ -16,12 +94,38 @@ class CBasePhysicManager : public IPhysicManager bool SetupJiggleBones(studiohdr_t* hdr, int entindex) override; void MergeBarnacleBones(studiohdr_t* hdr, int entindex) override; bool ChangeRagdollEntityIndex(int old_entindex, int new_entindex) override; - IRagdollObject* FindRagdollObject(int entindex) override; - IRagdollObject* CreateRagdollObject(model_t* mod, int entindex, const CRagdollConfig* config) override; - IStaticObject* CreateStaticObject(model_t* mod, int entindex) override; + IPhysicObject* GetPhysicObject(int entindex) override; + IRagdollObject* CreateRagdollObject(model_t* mod, int entindex, const CRagdollConfig& config) override; void CreateBrushModel(cl_entity_t* ent) override; void CreateBarnacle(cl_entity_t* ent) override; void CreateGargantua(cl_entity_t* ent) override; void RemovePhysicObject(int entindex) override; void UpdateTempEntity(TEMPENTITY** ppTempEntFree, TEMPENTITY** ppTempEntActive, double frame_time, double client_time) override; + +public: + + virtual IStaticObject* CreateStaticObject(cl_entity_t* ent, const CPhysicStaticObjectCreationParameter& CreationParameter) = 0; + +private: + //WorldVertexArray and WorldIndexArray + void GenerateWorldIndexVertexArray(); + void FreeWorldVertexArray(); + void GenerateBrushIndexArray(); + void FreeAllBrushIndexArray(); + void GenerateIndexArrayForBrushModel(model_t* mod, CPhysicVertexArray* vertexArray, CPhysicIndexArray* indexArray); + void GenerateIndexArrayRecursiveWorldNode(mnode_t* node, CPhysicVertexArray* vertexArray, CPhysicIndexArray* indexArray); + void GenerateIndexArrayForSurface(msurface_t* psurf, CPhysicVertexArray* vertexarray, CPhysicIndexArray* indexarray); + void GenerateIndexArrayForBrushface(CPhysicBrushFace* brushface, CPhysicIndexArray* indexArray); + + CPhysicIndexArray* GetIndexArrayFromBrushModel(model_t* mod); + + //Barnacle's VertexArray and IndexArray + void GenerateBarnacleIndexVertexArray(); + void FreeBarnacleIndexVertexArray(); + + //Gargantua's VertexArray and IndexArray + void GenerateGargantuaIndexVertexArray(); + void FreeGargantuaIndexVertexArray(); + + CRagdollConfig* GetRagdollConfigFromModel(model_t* mod); }; \ No newline at end of file diff --git a/Plugins/BulletPhysics/BulletPhysicManager.h b/Plugins/BulletPhysics/BulletPhysicManager.h index fc507f39..df085857 100644 --- a/Plugins/BulletPhysics/BulletPhysicManager.h +++ b/Plugins/BulletPhysics/BulletPhysicManager.h @@ -25,17 +25,8 @@ class CBulletPhysicManager : public CBasePhysicManager void DebugDraw(void) override; void SetGravity(float velocity) override; void StepSimulation(double framerate) override; - void ReloadConfig(void) override; - bool SetupBones(studiohdr_t* hdr, int entindex) override; - bool SetupJiggleBones(studiohdr_t* hdr, int entindex) override; - void MergeBarnacleBones(studiohdr_t* hdr, int entindex) override; - bool ChangeRagdollEntityIndex(int old_entindex, int new_entindex) override; - IRagdollObject* FindRagdollObject(int entindex) override; - IRagdollObject* CreateRagdollObject(model_t* mod, int entindex, const CRagdollConfig* config) override; - IStaticObject* CreateStaticObject(model_t* mod, int entindex) override; - void CreateBrushModel(cl_entity_t* ent) override; - void CreateBarnacle(cl_entity_t* ent) override; - void CreateGargantua(cl_entity_t* ent) override; - void RemovePhysicObject(int entindex) override; - void UpdateTempEntity(TEMPENTITY** ppTempEntFree, TEMPENTITY** ppTempEntActive, double frame_time, double client_time) override; + +public: + IStaticObject* CreateStaticObject(cl_entity_t* ent, const CPhysicStaticObjectCreationParameter& CreationParameter) override; + }; \ No newline at end of file diff --git a/Plugins/BulletPhysics/BulletPhysicMnager.cpp b/Plugins/BulletPhysics/BulletPhysicMnager.cpp index f32c7108..f8ee5c0b 100644 --- a/Plugins/BulletPhysics/BulletPhysicMnager.cpp +++ b/Plugins/BulletPhysics/BulletPhysicMnager.cpp @@ -16,94 +16,122 @@ CBulletPhysicManager::CBulletPhysicManager() : CBasePhysicManager() m_debugDraw = NULL; } -void CBulletPhysicManager::Init(void) +ATTRIBUTE_ALIGNED16(class) +CBulletPhysicsDebugDraw : public btIDebugDraw { - CBasePhysicManager::Init(); -} +private: + int m_debugMode; + DefaultColors m_ourColors; -void CBulletPhysicManager::Shutdown() -{ - CBasePhysicManager::Shutdown(); +public: + BT_DECLARE_ALIGNED_ALLOCATOR(); -} + CBulletPhysicsDebugDraw() : m_debugMode(btIDebugDraw::DBG_DrawWireframe | btIDebugDraw::DBG_DrawConstraints | btIDebugDraw::DBG_DrawConstraintLimits) + { -void CBulletPhysicManager::NewMap(void) -{ - CBasePhysicManager::NewMap(); + } -} + ~CBulletPhysicsDebugDraw() override + { + } -void CBulletPhysicManager::DebugDraw(void) -{ + DefaultColors getDefaultColors() const override + { + return m_ourColors; + } + ///the default implementation for setDefaultColors has no effect. A derived class can implement it and store the colors. + void setDefaultColors(const DefaultColors& colors) override + { + m_ourColors = colors; + } -} -void CBulletPhysicManager::SetGravity(float velocity) -{ + void drawLine(const btVector3& from1, const btVector3& to1, const btVector3& color1) override + { -} -void CBulletPhysicManager::StepSimulation(double framerate) -{ + } -} -void CBulletPhysicManager::ReloadConfig(void) -{ + void drawContactPoint(const btVector3& PointOnB, const btVector3& normalOnB, btScalar distance, int lifeTime, const btVector3& color) override + { + drawLine(PointOnB, PointOnB + normalOnB * distance, color); + btVector3 nColor(0, 0, 0); + drawLine(PointOnB, PointOnB + normalOnB * 0.01, nColor); + } -} + void reportErrorWarning(const char* warningString) override + { -bool CBulletPhysicManager::SetupBones(studiohdr_t* hdr, int entindex) -{ - return false; -} + } -bool CBulletPhysicManager::SetupJiggleBones(studiohdr_t* hdr, int entindex) -{ - return false; -} + void draw3dText(const btVector3& location, const char* textString) override + { -void CBulletPhysicManager::MergeBarnacleBones(studiohdr_t* hdr, int entindex) -{ + } -} + void setDebugMode(int debugMode) override + { + m_debugMode = debugMode; + } -bool CBulletPhysicManager::ChangeRagdollEntityIndex(int old_entindex, int new_entindex) -{ - return false; -} + int getDebugMode() const override + { + return m_debugMode; + } +}; -IRagdollObject* CBulletPhysicManager::FindRagdollObject(int entindex) -{ - return NULL; -} -IRagdollObject* CBulletPhysicManager::CreateRagdollObject(model_t* mod, int entindex, const CRagdollConfig* config) +void CBulletPhysicManager::Init(void) { - return NULL; + CBasePhysicManager::Init(); + + m_collisionConfiguration = new btDefaultCollisionConfiguration(); + m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); + m_overlappingPairCache = new btDbvtBroadphase(); + m_solver = new btSequentialImpulseConstraintSolver; + m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher, m_overlappingPairCache, m_solver, m_collisionConfiguration); + + m_debugDraw = new CBulletPhysicsDebugDraw; + m_dynamicsWorld->setDebugDrawer(m_debugDraw); + + //m_overlapFilterCallback = new GameFilterCallback(); + m_dynamicsWorld->getPairCache()->setOverlapFilterCallback(m_overlapFilterCallback); + + m_dynamicsWorld->setGravity(btVector3(0, 0, 0)); } -IStaticObject* CBulletPhysicManager::CreateStaticObject(model_t* mod, int entindex) +void CBulletPhysicManager::Shutdown() { - return NULL; + CBasePhysicManager::Shutdown(); + } -void CBulletPhysicManager::CreateBrushModel(cl_entity_t* ent) +void CBulletPhysicManager::NewMap(void) { + CBasePhysicManager::NewMap(); } -void CBulletPhysicManager::CreateBarnacle(cl_entity_t* ent) + +void CBulletPhysicManager::DebugDraw(void) { } -void CBulletPhysicManager::CreateGargantua(cl_entity_t* ent) + +void CBulletPhysicManager::SetGravity(float velocity) { + CBasePhysicManager::SetGravity(velocity); + m_dynamicsWorld->setGravity(btVector3(0, 0, m_gravity)); } -void CBulletPhysicManager::RemovePhysicObject(int entindex) + +void CBulletPhysicManager::StepSimulation(double framerate) { } -void CBulletPhysicManager::UpdateTempEntity(TEMPENTITY** ppTempEntFree, TEMPENTITY** ppTempEntActive, double frame_time, double client_time) + +IStaticObject* CBulletPhysicManager::CreateStaticObject(cl_entity_t* ent, const CPhysicStaticObjectCreationParameter& CreationParameter) { + + return NULL; } static CBulletPhysicManager g_BulletPhysicManager; diff --git a/Plugins/BulletPhysics/ClientEntityManager.cpp b/Plugins/BulletPhysics/ClientEntityManager.cpp index 9d3a55e5..3cb44175 100644 --- a/Plugins/BulletPhysics/ClientEntityManager.cpp +++ b/Plugins/BulletPhysics/ClientEntityManager.cpp @@ -17,8 +17,8 @@ class CClientEntityManager : public IClientEntityManager { private: - std::unordered_map m_barnacleMap; - std::unordered_map m_gargantuaMap; + std::unordered_map m_BarnacleMap; + std::unordered_map m_GargantuaMap; CPlayerDeathState m_PlayerDeathState[33]; bool m_bIsPlayerEmitted[33]; @@ -289,7 +289,7 @@ class CClientEntityManager : public IClientEntityManager void FreePlayerForBarnacle(int entindex) override { - for (auto itor = m_barnacleMap.begin(); itor != m_barnacleMap.end(); ) + for (auto itor = m_BarnacleMap.begin(); itor != m_BarnacleMap.end(); ) { if (itor->second == entindex) { @@ -304,20 +304,20 @@ class CClientEntityManager : public IClientEntityManager void NewMap(void) override { m_BarnacleModel = NULL; - m_barnacleMap.clear(); + m_BarnacleMap.clear(); m_GargantuaModel = NULL; - m_gargantuaMap.clear(); + m_GargantuaMap.clear(); ClearAllPlayerDeathState(); } void AddBarnacle(int entindex, int playerindex) override { - auto itor = m_barnacleMap.find(entindex); - if (itor == m_barnacleMap.end()) + auto itor = m_BarnacleMap.find(entindex); + if (itor == m_BarnacleMap.end()) { - m_barnacleMap[entindex] = playerindex; + m_BarnacleMap[entindex] = playerindex; } else if (itor->second == 0 && playerindex != 0) { @@ -327,10 +327,10 @@ class CClientEntityManager : public IClientEntityManager void AddGargantua(int entindex, int playerindex) { - auto itor = m_gargantuaMap.find(entindex); - if (itor == m_gargantuaMap.end()) + auto itor = m_GargantuaMap.find(entindex); + if (itor == m_GargantuaMap.end()) { - m_gargantuaMap[entindex] = playerindex; + m_GargantuaMap[entindex] = playerindex; } else if (itor->second == 0 && playerindex != 0) { @@ -343,8 +343,8 @@ class CClientEntityManager : public IClientEntityManager */ cl_entity_t* FindPlayerForBarnacle(int entindex) { - auto itor = m_barnacleMap.find(entindex); - if (itor != m_barnacleMap.end()) + auto itor = m_BarnacleMap.find(entindex); + if (itor != m_BarnacleMap.end()) { if (itor->second != 0) { @@ -366,8 +366,8 @@ class CClientEntityManager : public IClientEntityManager */ cl_entity_t* FindPlayerForGargantua(int entindex) { - auto itor = m_gargantuaMap.find(entindex); - if (itor != m_gargantuaMap.end()) + auto itor = m_GargantuaMap.find(entindex); + if (itor != m_GargantuaMap.end()) { if (itor->second != 0) { @@ -389,7 +389,7 @@ class CClientEntityManager : public IClientEntityManager */ cl_entity_t* FindBarnacleForPlayer(entity_state_t* player) { - for (auto itor = m_barnacleMap.begin(); itor != m_barnacleMap.end(); itor++) + for (auto itor = m_BarnacleMap.begin(); itor != m_BarnacleMap.end(); itor++) { auto ent = gEngfuncs.GetEntityByIndex(itor->first); if (IsEntityBarnacle(ent)) @@ -412,7 +412,7 @@ class CClientEntityManager : public IClientEntityManager */ cl_entity_t* FindGargantuaForPlayer(entity_state_t* player) { - for (auto itor = m_gargantuaMap.begin(); itor != m_gargantuaMap.end(); itor++) + for (auto itor = m_GargantuaMap.begin(); itor != m_GargantuaMap.end(); itor++) { auto ent = gEngfuncs.GetEntityByIndex(itor->first); if (IsEntityGargantua(ent) && ent->curstate.sequence == 15) diff --git a/Plugins/BulletPhysics/exportfuncs.cpp b/Plugins/BulletPhysics/exportfuncs.cpp index afbe4686..6b5d75f2 100644 --- a/Plugins/BulletPhysics/exportfuncs.cpp +++ b/Plugins/BulletPhysics/exportfuncs.cpp @@ -50,30 +50,10 @@ bool g_bIsCounterStrike = false; int g_iRagdollRenderState = 0; int g_iRagdollRenderEntIndex = 0; -model_t* r_worldmodel = NULL; -cl_entity_t* r_worldentity = NULL; - ref_params_t r_params = { 0 }; -studiohdr_t **pstudiohdr = NULL; -model_t **r_model = NULL; -void *g_pGameStudioRenderer = NULL; -int* r_framecount = NULL; -int *r_visframecount = NULL; -int *cl_parsecount = NULL; -void *cl_frames = NULL; -int size_of_frame = 0; -int *cl_viewentity = NULL; -cl_entity_t **currententity = NULL; -void *mod_known = NULL; -int *mod_numknown = NULL; -TEMPENTITY *gTempEnts = NULL; - -int *g_iUser1 = NULL; -int *g_iUser2 = NULL; - -float(*pbonetransform)[MAXSTUDIOBONES][3][4] = NULL; -float(*plighttransform)[MAXSTUDIOBONES][3][4] = NULL; +model_t* r_worldmodel = NULL; +cl_entity_t* r_worldentity = NULL; model_t* CounterStrike_RedirectPlayerModel(model_t* original_model, int PlayerNumber, int* modelindex); @@ -221,12 +201,12 @@ bool CL_IsFirstPersonMode(cl_entity_t *player) return (!gExportfuncs.CL_IsThirdPerson() && (*cl_viewentity) == player->index && !(chase_active && chase_active->value)) ? true : false; } -int EngineGetNumKnownModel(void) +int EngineGetNumKnownModel() { return (*mod_numknown); } -int EngineGetMaxKnownModel(void) +int EngineGetMaxKnownModel() { if (g_iEngineType == ENGINE_SVENGINE) return 16384; diff --git a/Plugins/BulletPhysics/physics.cpp b/Plugins/BulletPhysics/physics.cpp index 28483700..1621ec9f 100644 --- a/Plugins/BulletPhysics/physics.cpp +++ b/Plugins/BulletPhysics/physics.cpp @@ -17,10 +17,6 @@ extern cvar_t *bv_ragdoll_sleepaftertime; extern cvar_t *bv_ragdoll_sleeplinearvel; extern cvar_t *bv_ragdoll_sleepangularvel; -int EngineGetNumKnownModel(void); -int EngineGetMaxKnownModel(void); -int EngineGetModelIndex(model_t *mod); -model_t *EngineGetModelByIndex(int index); int StudioGetSequenceActivityType(model_t *mod, entity_state_t* entstate); void RagdollDestroyCallback(int entindex); @@ -185,6 +181,7 @@ CPhysicsManager::CPhysicsManager() m_solver = NULL; m_dynamicsWorld = NULL; m_debugDraw = NULL; + m_worldVertexArray = NULL; m_barnacleIndexArray = NULL; m_barnacleVertexArray = NULL; @@ -503,17 +500,10 @@ void CPhysicsManager::CreateBrushModel(cl_entity_t *ent) void CPhysicsManager::NewMap(void) { - //G2BScale = bv_scale->value; - //B2GScale = 1 / bv_scale->value; - ReloadConfig(); RemoveAllRagdolls(); RemoveAllStatics(); - r_worldentity = gEngfuncs.GetEntityByIndex(0); - - r_worldmodel = r_worldentity->model; - GenerateWorldVerticeArray(); GenerateBrushIndiceArray(); GenerateBarnacleIndiceVerticeArray(); diff --git a/Plugins/BulletPhysics/plugins.cpp b/Plugins/BulletPhysics/plugins.cpp index 8e33f03d..7c38fde2 100644 --- a/Plugins/BulletPhysics/plugins.cpp +++ b/Plugins/BulletPhysics/plugins.cpp @@ -40,6 +40,7 @@ void IPluginsV4::Init(metahook_api_t *pAPI, mh_interface_t *pInterface, mh_engin void IPluginsV4::Shutdown(void) { + } void IPluginsV4::LoadEngine(cl_enginefunc_t *pEngfuncs) diff --git a/Plugins/BulletPhysics/privatehook.cpp b/Plugins/BulletPhysics/privatehook.cpp index 6dec96f9..4bf3dc36 100644 --- a/Plugins/BulletPhysics/privatehook.cpp +++ b/Plugins/BulletPhysics/privatehook.cpp @@ -4,6 +4,7 @@ #include "enginedef.h" #include "plugins.h" #include "privatehook.h" +#include "exportfuncs.h" #include "message.h" #include "physics.h" #include "ClientEntityManager.h" @@ -26,9 +27,30 @@ #define R_DRAWTENTITIESONLIST_SIG_HL25 "\x55\x8B\xEC\x81\xEC\x2A\x00\x00\x00\xA1\x2A\x2A\x2A\x2A\x33\xC5\x89\x45\xFC\xF3\x0F\x2A\x2A\x2A\x2A\x2A\x2A\x0F\x2E" #define R_DRAWTENTITIESONLIST_SIG_SVENGINE "\x55\x8B\xEC\x83\xE4\x2A\x81\xEC\x2A\x00\x00\x00\xA1\x2A\x2A\x2A\x2A\x33\xC4\x89\x84\x24\x2A\x00\x00\x00\xD9\x05\x2A\x2A\x2A\x2A\xD9\xEE" -private_funcs_t gPrivateFuncs; +private_funcs_t gPrivateFuncs = {0}; -hook_t* g_phook_R_NewMap = NULL; +studiohdr_t** pstudiohdr = NULL; +model_t** r_model = NULL; +void* g_pGameStudioRenderer = NULL; +int* r_framecount = NULL; +int* r_visframecount = NULL; +int* cl_parsecount = NULL; +void* cl_frames = NULL; +int size_of_frame = 0; +int* cl_viewentity = NULL; +cl_entity_t** currententity = NULL; +void* mod_known = NULL; +int* mod_numknown = NULL; +TEMPENTITY* gTempEnts = NULL; + +int* g_iUser1 = NULL; +int* g_iUser2 = NULL; + +float(*pbonetransform)[MAXSTUDIOBONES][3][4] = NULL; +float(*plighttransform)[MAXSTUDIOBONES][3][4] = NULL; + +static hook_t* g_phook_R_NewMap = NULL; +static hook_t* g_phook_Mod_LoadStudioModel = NULL; void Engine_FillAddreess(void) { @@ -317,6 +339,47 @@ void Engine_FillAddreess(void) mod_known = *(void **)(addr + 7); } + if (1) + { + const char sigs1[] = "bogus\0"; + auto Bogus_String = Search_Pattern_Data(sigs1); + if (!Bogus_String) + Bogus_String = Search_Pattern_Rdata(sigs1); + Sig_VarNotFound(Bogus_String); + char pattern[] = "\x68\x2A\x2A\x2A\x2A\x2A\xE8"; + *(DWORD*)(pattern + 1) = (DWORD)Bogus_String; + auto Bogus_Call = Search_Pattern(pattern); + Sig_VarNotFound(Bogus_Call); + + gPrivateFuncs.Mod_LoadStudioModel = (decltype(gPrivateFuncs.Mod_LoadStudioModel))g_pMetaHookAPI->ReverseSearchFunctionBeginEx(Bogus_Call, 0x50, [](PUCHAR Candidate) { + + // .text : 01D71630 81 EC 10 01 00 00 sub esp, 110h + if (Candidate[0] == 0x81 && + Candidate[1] == 0xEC && + Candidate[4] == 0x00 && + Candidate[5] == 0x00) + { + return TRUE; + } + // .text : 01D61AD0 55 push ebp + // .text : 01D61AD1 8B EC mov ebp, esp + // .text : 01D61AD3 81 EC 0C 01 00 00 sub esp, 10Ch + if (Candidate[0] == 0x55 && + Candidate[1] == 0x8B && + Candidate[2] == 0xEC && + Candidate[3] == 0x81 && + Candidate[4] == 0xEC && + Candidate[7] == 0x00 && + Candidate[8] == 0x00) + { + return TRUE; + } + + return FALSE; + }); + Sig_FuncNotFound(Mod_LoadStudioModel); + } + if (1) { const char sigs1[] = "Cached models:\n"; @@ -532,6 +595,9 @@ void Client_FillAddress(void) void R_NewMap(void) { + r_worldentity = gEngfuncs.GetEntityByIndex(0); + r_worldmodel = r_worldentity->model; + gPrivateFuncs.R_NewMap(); gPhysicsManager.NewMap(); ClientEntityManager()->NewMap(); @@ -540,6 +606,7 @@ void R_NewMap(void) TEMPENTITY *efxapi_R_TempModel(float *pos, float *dir, float *angles, float life, int modelIndex, int soundtype) { auto r = gPrivateFuncs.efxapi_R_TempModel(pos, dir, angles, life, modelIndex, soundtype); + if (r && g_bIsCreatingClCorpse && g_iCreatingClCorpsePlayerIndex > 0) { int tentindex = r - gTempEnts; @@ -554,12 +621,21 @@ TEMPENTITY *efxapi_R_TempModel(float *pos, float *dir, float *angles, float life return r; } +void Mod_LoadStudioModel(model_t* mod, void* buffer) +{ + gPrivateFuncs.Mod_LoadStudioModel(mod, buffer); + + +} + void Engine_InstallHook(void) { Install_InlineHook(R_NewMap); + Install_InlineHook(Mod_LoadStudioModel); } void Engine_UninstallHook(void) { Uninstall_Hook(R_NewMap); + Uninstall_Hook(Mod_LoadStudioModel); } \ No newline at end of file diff --git a/Plugins/BulletPhysics/privatehook.h b/Plugins/BulletPhysics/privatehook.h index f9922a49..2b792e95 100644 --- a/Plugins/BulletPhysics/privatehook.h +++ b/Plugins/BulletPhysics/privatehook.h @@ -19,7 +19,6 @@ typedef struct void(*R_NewMap)(void); void(*R_RecursiveWorldNode)(void *node); void(*R_DrawTEntitiesOnList)(int onlyClientDraw); - //int(*ClientDLL_AddEntity)(int type, struct cl_entity_s *ent); //Client GameStudioRenderer void(__fastcall* GameStudioRenderer_StudioSetupBones)(void* pthis, int); @@ -48,6 +47,9 @@ typedef struct void (*FirstPerson_f)(void); void (*ThreadPerson_f)(void); + //Engine model managment + void (*Mod_LoadStudioModel)(model_t* mod, void* buffer); + //efxapi TEMPENTITY *(*efxapi_R_TempModel) (float *pos, float *dir, float *angles, float life, int modelIndex, int soundtype); }private_funcs_t; @@ -62,6 +64,7 @@ void Engine_UninstallHook(void); extern studiohdr_t** pstudiohdr; extern model_t** r_model; +extern void* g_pGameStudioRenderer; extern float(*pbonetransform)[128][3][4]; extern float(*plighttransform)[128][3][4]; @@ -116,4 +119,9 @@ static_assert(sizeof(extra_player_info_t) == 0x74, "Size check"); extern cvar_t *cl_minmodels; extern cvar_t *cl_min_t; extern cvar_t *cl_min_ct; -extern extra_player_info_t(*g_PlayerExtraInfo)[65]; \ No newline at end of file +extern extra_player_info_t(*g_PlayerExtraInfo)[65]; + +int EngineGetMaxKnownModel(); +int EngineGetNumKnownModel(); +int EngineGetModelIndex(model_t* mod); +model_t* EngineGetModelByIndex(int index); \ No newline at end of file diff --git a/Plugins/Renderer/gl_hooks.cpp b/Plugins/Renderer/gl_hooks.cpp index 7e636c84..363b34c2 100644 --- a/Plugins/Renderer/gl_hooks.cpp +++ b/Plugins/Renderer/gl_hooks.cpp @@ -6119,6 +6119,7 @@ void R_FillAddress(void) Sig_FuncNotFound(Mod_LoadStudioModel); } + if(1) { const char sigs1[] = "Mod_LoadBrushModel: %s has wrong version number"; auto Bogus_String = Search_Pattern_Data(sigs1);