working wall collisions + started work on collision map saving

This commit is contained in:
Safariminer 2025-08-06 00:57:00 -04:00
parent 89f31a7184
commit 576df5ecd7
4 changed files with 222 additions and 19 deletions

View File

@ -4,6 +4,15 @@
#include <thread>
#include <mutex>
#include <filesystem>
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#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<MPFW::P
}
}
MPFW::Physics::CollisionMap MPFW::Physics::GenerateCollisionMap(std::vector<Polygon> polygons, std::vector<Vector3> totalVertices, CollisionMapGenParams cmgp)
MPFW::Physics::CollisionMap MPFW::Physics::GenerateCollisionMap(std::vector<Polygon> polygons, std::vector<Vector3> 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<Polygon> polygonsCopy = polygons;
std::vector<std::thread> polygonCalculationsThreads;
std::vector<CollisionFace> pStructs(polygons.size());
@ -141,10 +224,59 @@ MPFW::Physics::CollisionMap MPFW::Physics::GenerateCollisionMap(std::vector<Poly
if(polygonCalculationsThreads[i].joinable())polygonCalculationsThreads[i].join();
}*/
/*
std::ofstream cacheFile(std::string("data/cache/collisiondata/" + cacheName), std::ios::binary);
CachedCollisionMap cache;
cache.cachedCollisionMapVersion = 0x01;
cache.collisionSetCount = retval.collisionSets.size();
cacheFile.write((char*)&cache.cachedCollisionMapVersion, 4);
cacheFile.write((char*)&cache.collisionSetCount, 4);
int headerSize = retval.collisionSets.size() * 36 + 8;
int currentFileSize = 0;
std::string subfile = "";
for (int i = 0; i < retval.collisionSets.size(); i++) {
std::string collsetsubfile = "";
for (int j = 0; j < retval.collisionSets[i].collisionFaces.size(); j++) {
using namespace std::string_literals;
collsetsubfile += retval.collisionSets[i].collisionFaces[j].
}
unsigned long fileOffset = headerSize + currentFileSize;
unsigned long size = retval.
cacheFile.write((char*)& n, 4);
cacheFile.write((char*)& n, 4);
int collsize = retval.collisionSets[i].collisionFaces.size();
cacheFile.write((char*)&collsize, 4);
cacheFile.write((char*)&retval.collisionSets[i].size.min.x, 4);
cacheFile.write((char*)&retval.collisionSets[i].size.min.y, 4);
cacheFile.write((char*)&retval.collisionSets[i].size.min.z, 4);
cacheFile.write((char*)&retval.collisionSets[i].size.max.x, 4);
cacheFile.write((char*)&retval.collisionSets[i].size.max.y, 4);
cacheFile.write((char*)&retval.collisionSets[i].size.max.z, 4);
}
cacheFile.close();
*/
return retval;
}

View File

@ -24,11 +24,28 @@ namespace MPFW {
int voxelLateralCount = 3;
};
struct CachedPolygon {
unsigned long length;
Vector3 normal;
std::vector<Vector3> 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<CachedCollisionSet> collisionSets;
};
// collision maps subdivide the maps for collisions
struct CollisionMap {
std::vector<CollisionSet> collisionSets;
};
Box GenerateBoundingBoxPolygon(Polygon poly);
CollisionMap GenerateCollisionMap(std::vector<Polygon> polygons, std::vector<Vector3> totalVertices, CollisionMapGenParams cmgp);
CollisionMap GenerateCollisionMap(std::vector<Polygon> polygons, std::vector<Vector3> totalVertices, CollisionMapGenParams cmgp, std::string cacheName);
}
}

View File

@ -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<std::string>{}(path)));

View File

@ -1,6 +1,6 @@
#include <iostream>
#include <raylib.h>
#include <filesystem>
#include <raymath.h>
#include <fstream>
#include <sstream>
@ -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 = &map;
@ -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;