From 576df5ecd7368c610c5a022cd9c2ebff60cdfc78 Mon Sep 17 00:00:00 2001 From: Safariminer Date: Wed, 6 Aug 2025 00:57:00 -0400 Subject: [PATCH] working wall collisions + started work on collision map saving --- mpfw/MPFW_Physics.cpp | 136 +++++++++++++++++++++++++++++++++++++++++- mpfw/MPFW_Physics.h | 19 +++++- mpfw/MPFW_Quake.cpp | 2 +- mpfw/main.cpp | 84 +++++++++++++++++++++----- 4 files changed, 222 insertions(+), 19 deletions(-) diff --git a/mpfw/MPFW_Physics.cpp b/mpfw/MPFW_Physics.cpp index c04916a..8cdb80f 100644 --- a/mpfw/MPFW_Physics.cpp +++ b/mpfw/MPFW_Physics.cpp @@ -4,6 +4,15 @@ #include #include +#include +#include +#include +#include +#include + + +#include "MPFW_Utils.h" + // simple aabb bool __collides(MPFW::Physics::Box a, MPFW::Physics::Box b) { @@ -61,8 +70,82 @@ void PolygonCalcThread(MPFW::Physics::CollisionSet* collSet, std::vector polygons, std::vector totalVertices, CollisionMapGenParams cmgp) +MPFW::Physics::CollisionMap MPFW::Physics::GenerateCollisionMap(std::vector polygons, std::vector totalVertices, CollisionMapGenParams cmgp, std::string cacheName) { + + + if (std::filesystem::exists(std::string("data/cache/collisiondata/" + cacheName))) { + + + std::ifstream fileHandle(std::string("data/cache/collisiondata/" + cacheName), std::ios::binary); + + + if (fileHandle.good() && fileHandle.is_open()) { + std::stringstream fileStringStream; fileStringStream << fileHandle.rdbuf(); + std::string file = fileStringStream.str(); + + + if (Utils::Strings::StringIndexToInteger_4b_le(file, 0) == 0x01) { + + + + + + + CachedCollisionMap ccm; + + ccm.cachedCollisionMapVersion = Utils::Strings::StringIndexToInteger_4b_le(file, 0); + ccm.collisionSetCount = Utils::Strings::StringIndexToInteger_4b_le(file, 4); + + + + CollisionMap retval; + + ccm.collisionSets.resize(ccm.collisionSetCount); + + std::memcpy( + ccm.collisionSets.data(), + Utils::Strings::IterativeStringExcerpt(file, 8, ccm.collisionSetCount * sizeof(CachedCollisionSet)).data(), + ccm.collisionSetCount * sizeof(CachedCollisionSet)); + + for (int i = 0; i < ccm.collisionSets.size(); i++) { + CollisionSet cs; + cs.size.max.x = ccm.collisionSets[i].maxx; + cs.size.max.y = ccm.collisionSets[i].maxy; + cs.size.max.z = ccm.collisionSets[i].maxz; + cs.size.min.x = ccm.collisionSets[i].minx; + cs.size.min.y = ccm.collisionSets[i].miny; + cs.size.min.z = ccm.collisionSets[i].minz; + + + + + + // std::string subbuffer = + + + + + + + retval.collisionSets.push_back(cs); + + } + + + return retval; + + + } + + + } + + + + + } + std::vector polygonsCopy = polygons; std::vector polygonCalculationsThreads; std::vector pStructs(polygons.size()); @@ -141,10 +224,59 @@ MPFW::Physics::CollisionMap MPFW::Physics::GenerateCollisionMap(std::vector vertices; + }; + + struct CachedCollisionSet { + unsigned long fileOffset, size, polyCount; + float minx, miny, minz, maxx, maxy, maxz; + }; + + struct CachedCollisionMap { + unsigned long cachedCollisionMapVersion = 0x01; + unsigned long collisionSetCount; + std::vector collisionSets; + }; + // collision maps subdivide the maps for collisions struct CollisionMap { std::vector collisionSets; }; Box GenerateBoundingBoxPolygon(Polygon poly); - CollisionMap GenerateCollisionMap(std::vector polygons, std::vector totalVertices, CollisionMapGenParams cmgp); + CollisionMap GenerateCollisionMap(std::vector polygons, std::vector totalVertices, CollisionMapGenParams cmgp, std::string cacheName); } } \ No newline at end of file diff --git a/mpfw/MPFW_Quake.cpp b/mpfw/MPFW_Quake.cpp index cf8fbb9..a2ef230 100644 --- a/mpfw/MPFW_Quake.cpp +++ b/mpfw/MPFW_Quake.cpp @@ -533,7 +533,7 @@ void MPFW::Quake::Maps::MapFile::LoadBSPMap(std::string path) Physics::CollisionMapGenParams cmgp; - *collMap = Physics::GenerateCollisionMap(collPolygons, totalRlVec, cmgp); + *collMap = Physics::GenerateCollisionMap(collPolygons, totalRlVec, cmgp, std::format("{}", std::hash{}(path))); diff --git a/mpfw/main.cpp b/mpfw/main.cpp index 783c25a..2013fe5 100644 --- a/mpfw/main.cpp +++ b/mpfw/main.cpp @@ -1,6 +1,6 @@ #include #include - +#include #include #include #include @@ -16,6 +16,7 @@ #include "MPFW_Physics.h" #define DISTANCE_FROM_FLOOR 15 +#define DISTANCE_FROM_WALL 5 // turn quake miptex into rl texture Texture2D RLMT_QUAKE(MPFW::Quake::Maps::rlMipTex rlmt) { @@ -184,6 +185,9 @@ int main() { std::print("\nEnd of unit testing\n\n\n"); #endif + // if not already created... + std::filesystem::create_directories("data/cache/collisiondata"); + MPFW::Quake::Maps::MapFile map; map.pal = new MPFW::Quake::Maps::Palette("data/palette.lmp"); @@ -198,13 +202,10 @@ int main() { SetConfigFlags(FLAG_WINDOW_RESIZABLE); InitWindow(1280, 720, TextFormat("mpfw")); - // SetTargetFPS(60); + SetTargetFPS(60); SetExitKey(0); DisableCursor(); - - - MPFW::UI::UIRenderer uiRenderer; MPFW::Console::CommandHandlerResources chr; chr.mapQuake = ↦ @@ -220,13 +221,6 @@ int main() { uiRenderer.cmh = &cmdH; - - - // MPFW::UI::Window wndw("data/menus/test.wnd"); - - // uiRenderer.windows.push_back(wndw); - - // rlSetClipPlanes(1, INFINITY); camera.position = { 0,5,0 }; camera.target = { 1,0,0 }; camera.fovy = 120; @@ -334,10 +328,70 @@ int main() { velocity.y -= 10 * GetFrameTime(); } - - - velocity *= {GetFrameTime(), 1, GetFrameTime()}; + + if (chr.cvars["math_3d_collision_work"] == "true") { + for (int b = 0; b < collisionMap.collisionSets.size(); b++) { + BoundingBox bb; + bb.min = collisionMap.collisionSets[b].size.min; + bb.max = collisionMap.collisionSets[b].size.max; + if (CheckCollisionBoxSphere(bb, camera.position, 10)) { + MPFW::Physics::CollisionSet cs = collisionMap.collisionSets[b]; + for (int i = 0; i < collisionMap.collisionSets[b].collisionFaces.size(); i++) { + + Ray x1, x2, z1, z2; + x1.position = camera.position + velocity; + x2.position = camera.position + velocity; + z1.position = camera.position + velocity; + z2.position = camera.position + velocity; + x1.direction = { -1, 0, 0 }; + x2.direction = { 1, 0, 0 }; + z1.direction = { 0, 0, -1 }; + z2.direction = { 0, 0, 1 }; + + + for (int t = 2; t < cs.collisionFaces[i].polygon.size(); t++) { + Vector3 a = cs.collisionFaces[i].polygon[0]; + Vector3 b = cs.collisionFaces[i].polygon[t]; + Vector3 c = cs.collisionFaces[i].polygon[t - 1]; + RayCollision cx1, cx2, cz1, cz2; + + + cx1 = GetRayCollisionTriangle(x1, a, b, c); + cx2 = GetRayCollisionTriangle(x2, a, b, c); + cz1 = GetRayCollisionTriangle(z1, a, b, c); + cz2 = GetRayCollisionTriangle(z2, a, b, c); + + + if (cx1.hit) { + if (cx1.distance < DISTANCE_FROM_WALL) velocity.x += DISTANCE_FROM_WALL - cx1.distance; + } + + if (cx2.hit) { + if (cx2.distance < DISTANCE_FROM_WALL) velocity.x -= DISTANCE_FROM_WALL - cx2.distance; + } + + if (cz1.hit) { + if (cz1.distance < DISTANCE_FROM_WALL) velocity.z += DISTANCE_FROM_WALL - cz1.distance; + } + + if (cz2.hit) { + if (cz2.distance < DISTANCE_FROM_WALL) velocity.z -= DISTANCE_FROM_WALL - cz2.distance; + } + + } + + + + + + + } + } + } + } + + camera.position += velocity; camera.target = camera.position + rotation;