Preliminary work on collisions
This commit is contained in:
parent
f35ff8ae46
commit
65031d57f3
@ -9,3 +9,5 @@
|
||||
- boost::asio
|
||||
- imgui
|
||||
- rlimgui
|
||||
|
||||
Note: different backend support is planned for Vulkan and whatnot. raylib's raymath component will still be necessary for physics maths.
|
3
gameenv/data/sys/collisionparams.xml
Normal file
3
gameenv/data/sys/collisionparams.xml
Normal file
@ -0,0 +1,3 @@
|
||||
<collparam>
|
||||
|
||||
</collparam>
|
@ -1,4 +1,5 @@
|
||||
math_3d_floor_collision_work false
|
||||
math_3d_collision_work false
|
||||
vid_2d_background false
|
||||
vid_3d_renderer true
|
||||
vid_3d_grid false
|
||||
|
150
mpfw/MPFW_Physics.cpp
Normal file
150
mpfw/MPFW_Physics.cpp
Normal file
@ -0,0 +1,150 @@
|
||||
#include "MPFW_Physics.h"
|
||||
#include <algorithm>
|
||||
#include <print>
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
|
||||
|
||||
// simple aabb
|
||||
bool __collides(MPFW::Physics::Box a, MPFW::Physics::Box b) {
|
||||
return
|
||||
a.min.x <= b.max.x &&
|
||||
a.max.x >= b.min.x &&
|
||||
a.min.y <= b.max.y &&
|
||||
a.max.y >= b.min.y &&
|
||||
a.min.z <= b.max.z &&
|
||||
a.max.z >= b.min.z;
|
||||
}
|
||||
|
||||
|
||||
MPFW::Physics::Box MPFW::Physics::GenerateBoundingBoxPolygon(Polygon poly)
|
||||
{
|
||||
Polygon polyCopy = poly;
|
||||
std::vector<float> x;
|
||||
std::vector<float> y;
|
||||
std::vector<float> z;
|
||||
|
||||
for (int i = 0; i < polyCopy.size(); i++) {
|
||||
x.push_back(polyCopy[i].x);
|
||||
y.push_back(polyCopy[i].y);
|
||||
z.push_back(polyCopy[i].z);
|
||||
}
|
||||
|
||||
std::sort(x.begin(), x.end());
|
||||
std::sort(y.begin(), y.end());
|
||||
std::sort(z.begin(), z.end());
|
||||
|
||||
Box retval;
|
||||
retval.min.x = x[0];
|
||||
retval.min.y = y[0];
|
||||
retval.min.z = z[0];
|
||||
|
||||
retval.max.x = x[x.size()-1];
|
||||
retval.max.y = y[y.size()-1];
|
||||
retval.max.z = z[z.size()-1];
|
||||
return retval;
|
||||
}
|
||||
|
||||
std::mutex collSetMutex;
|
||||
|
||||
void PolygonCalcThread(MPFW::Physics::CollisionSet* collSet, std::vector<MPFW::Physics::CollisionFace> pStructs, int v) {
|
||||
for (int p = 0; p < pStructs.size(); p++) {
|
||||
if (collSet->collisionFaces.size() - 1 != p) {
|
||||
collSet->collisionFaces = std::vector<MPFW::Physics::CollisionFace>(0);
|
||||
p = 0;
|
||||
}
|
||||
if (__collides(MPFW::Physics::GenerateBoundingBoxPolygon(pStructs[p].polygon), collSet->size)) {
|
||||
std::lock_guard<std::mutex> guard(collSetMutex);
|
||||
collSet->collisionFaces.push_back(pStructs[p]);
|
||||
}
|
||||
std::print("v:{},p:{}\n", v, p);
|
||||
}
|
||||
}
|
||||
|
||||
MPFW::Physics::CollisionMap MPFW::Physics::GenerateCollisionMap(std::vector<Polygon> polygons, std::vector<Vector3> totalVertices, CollisionMapGenParams cmgp)
|
||||
{
|
||||
std::vector<Polygon> polygonsCopy = polygons;
|
||||
std::vector<std::thread> polygonCalculationsThreads;
|
||||
std::vector<CollisionFace> pStructs(polygons.size());
|
||||
|
||||
for (int cFCount = 0; cFCount < polygons.size(); cFCount++) {
|
||||
CollisionFace cface;
|
||||
cface.polygon = polygonsCopy[cFCount]; // assuming polygonsCopy == polygons, because it should be.
|
||||
|
||||
|
||||
|
||||
// calculating normals (if polygon has 3 vertices or more)
|
||||
if(cface.polygon.size() >= 3){
|
||||
|
||||
// according to: https://titan.csit.rmit.edu.au/~e20068/teaching/i3dg&a/2012/normals/normals.xhtml
|
||||
|
||||
Vector3 a, b;
|
||||
|
||||
a = Vector3Subtract(cface.polygon[1], cface.polygon[0]);
|
||||
|
||||
b = Vector3Subtract(cface.polygon[2], cface.polygon[0]);
|
||||
cface.normal = Vector3Normalize(Vector3CrossProduct(a,b)); // does that actually work? I can't believe it would
|
||||
cface.normalCalculated = true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
pStructs[cFCount] = cface;
|
||||
|
||||
}
|
||||
|
||||
Box mapBoundingBox = GenerateBoundingBoxPolygon(totalVertices);
|
||||
|
||||
Vector3 sizeOfMap = mapBoundingBox.max - mapBoundingBox.min;
|
||||
Vector3 sizeOfVoxel = sizeOfMap / cmgp.voxelLateralCount;
|
||||
|
||||
CollisionMap retval;
|
||||
int vCount = 0;
|
||||
for (int z = 0; z < cmgp.voxelLateralCount; z++) {
|
||||
for (int y = 0; y < cmgp.voxelLateralCount; y++) {
|
||||
for (int x = 0; x < cmgp.voxelLateralCount; x++) {
|
||||
CollisionSet cs;
|
||||
|
||||
cs.size.min =
|
||||
{
|
||||
mapBoundingBox.min.x + sizeOfVoxel.x * x,
|
||||
mapBoundingBox.min.y + sizeOfVoxel.y * y,
|
||||
mapBoundingBox.min.z + sizeOfVoxel.z * z
|
||||
};
|
||||
|
||||
cs.size.max =
|
||||
{
|
||||
mapBoundingBox.min.x + sizeOfVoxel.x * (x + 1),
|
||||
mapBoundingBox.min.y + sizeOfVoxel.y * (y + 1),
|
||||
mapBoundingBox.min.z + sizeOfVoxel.z * (z + 1)
|
||||
};
|
||||
cs.collisionFaces = std::vector<CollisionFace>(0);
|
||||
retval.collisionSets.push_back(cs);
|
||||
// polygonCalculationsThreads.push_back(std::thread(PolygonCalcThread, &retval.collisionSets[vCount], pStructs, vCount));
|
||||
|
||||
for(int p = 0; p < pStructs.size(); p++){
|
||||
if (__collides(MPFW::Physics::GenerateBoundingBoxPolygon(pStructs[p].polygon), retval.collisionSets[vCount].size)) {
|
||||
// std::lock_guard<std::mutex> guard(collSetMutex);
|
||||
retval.collisionSets[vCount].collisionFaces.push_back(pStructs[p]);
|
||||
}
|
||||
std::print("v:{},p:{}\n", vCount, p);
|
||||
}
|
||||
vCount++;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*for (int i = 0; i < polygonCalculationsThreads.size(); i++) {
|
||||
if(polygonCalculationsThreads[i].joinable())polygonCalculationsThreads[i].join();
|
||||
}*/
|
||||
|
||||
|
||||
return retval;
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
34
mpfw/MPFW_Physics.h
Normal file
34
mpfw/MPFW_Physics.h
Normal file
@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
#include <raymath.h>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
namespace MPFW {
|
||||
namespace Physics {
|
||||
struct Box {
|
||||
Vector3 min, max;
|
||||
};
|
||||
using Polygon = std::vector<Vector3>;
|
||||
struct CollisionFace {
|
||||
Polygon polygon;
|
||||
Vector3 normal;
|
||||
bool normalCalculated = false;
|
||||
};
|
||||
|
||||
struct CollisionSet {
|
||||
Box size;
|
||||
std::vector<CollisionFace> collisionFaces;
|
||||
};
|
||||
|
||||
struct CollisionMapGenParams {
|
||||
int voxelLateralCount = 3;
|
||||
};
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
@ -389,6 +389,8 @@ void MPFW::Quake::Maps::MapFile::LoadBSPMap(std::string path)
|
||||
data.header.planes.size
|
||||
);
|
||||
|
||||
std::vector<Physics::Polygon> collPolygons;
|
||||
std::vector<Vector3> totalRlVec;
|
||||
for (int i = 0; i < data.faces.size(); i++) {
|
||||
CalculatedFace cface;
|
||||
|
||||
@ -419,6 +421,7 @@ void MPFW::Quake::Maps::MapFile::LoadBSPMap(std::string path)
|
||||
]
|
||||
));
|
||||
}
|
||||
totalRlVec.push_back(cface.vertices[cface.vertices.size() - 1]); // push back the last vertex for collision
|
||||
|
||||
}
|
||||
|
||||
@ -427,7 +430,7 @@ void MPFW::Quake::Maps::MapFile::LoadBSPMap(std::string path)
|
||||
cface.glTextureWidth = data.textures[data.texInfo[data.faces[i].texinfoId].textureId].width;
|
||||
cface.glTextureHeight = data.textures[data.texInfo[data.faces[i].texinfoId].textureId].height;
|
||||
|
||||
|
||||
collPolygons.push_back(cface.vertices);
|
||||
for (int j = 0; j < cface.vertices.size(); j++) {
|
||||
|
||||
cface.texCoords.push_back(Vector2(
|
||||
@ -528,6 +531,12 @@ void MPFW::Quake::Maps::MapFile::LoadBSPMap(std::string path)
|
||||
|
||||
|
||||
|
||||
Physics::CollisionMapGenParams cmgp;
|
||||
|
||||
*collMap = Physics::GenerateCollisionMap(collPolygons, totalRlVec, cmgp);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
ds = Debug::DONE;
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <print>
|
||||
#include "MPFW_Physics.h"
|
||||
|
||||
namespace MPFW {
|
||||
namespace Quake {
|
||||
@ -195,7 +196,7 @@ namespace MPFW {
|
||||
Debug::DebugState ds = Debug::NONE;
|
||||
MapData data;
|
||||
Palette* pal;
|
||||
|
||||
Physics::CollisionMap* collMap;
|
||||
int modelsCDBG = 0;
|
||||
int verticesCDBG = 0;
|
||||
int edgesCDBG = 0;
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "MPFW_UI.h"
|
||||
#include <algorithm>
|
||||
#include <mutex>
|
||||
#include "MPFW_Physics.h"
|
||||
|
||||
// turn quake miptex into rl texture
|
||||
Texture2D RLMT_QUAKE(MPFW::Quake::Maps::rlMipTex rlmt) {
|
||||
@ -185,6 +186,13 @@ int main() {
|
||||
|
||||
map.pal = new MPFW::Quake::Maps::Palette("data/palette.lmp");
|
||||
|
||||
|
||||
MPFW::Physics::CollisionMap collisionMap; // map of the collisions
|
||||
|
||||
map.collMap = &collisionMap;
|
||||
|
||||
|
||||
|
||||
SetConfigFlags(FLAG_WINDOW_RESIZABLE);
|
||||
|
||||
InitWindow(1280, 720, TextFormat("mpfw"));
|
||||
@ -193,6 +201,8 @@ int main() {
|
||||
DisableCursor();
|
||||
|
||||
|
||||
|
||||
|
||||
MPFW::UI::UIRenderer uiRenderer;
|
||||
MPFW::Console::CommandHandlerResources chr;
|
||||
chr.mapQuake = ↦
|
||||
@ -292,6 +302,29 @@ int main() {
|
||||
velocity.y -= 10 * GetFrameTime();
|
||||
}
|
||||
|
||||
if(chr.cvars["math_3d_floor_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 < cs.collisionFaces.size(); i++) {
|
||||
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];
|
||||
Ray r;
|
||||
r.position = camera.position;
|
||||
r.direction = { 0,-1,0 };
|
||||
RayCollision coll = GetRayCollisionTriangle(r, a, b, c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
velocity *= {GetFrameTime(), 1, GetFrameTime()};
|
||||
camera.position += velocity;
|
||||
@ -389,6 +422,12 @@ int main() {
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
for (int i = 0; i < collisionMap.collisionSets.size(); i++) {
|
||||
BoundingBox b; b.min = collisionMap.collisionSets[i].size.min;
|
||||
b.max = collisionMap.collisionSets[i].size.max;
|
||||
|
||||
DrawBoundingBox(b, RED);
|
||||
}
|
||||
EndMode3D();
|
||||
}
|
||||
|
@ -149,6 +149,7 @@
|
||||
<ClCompile Include="MPFW_Console.cpp" />
|
||||
<ClCompile Include="MPFW_HL.cpp" />
|
||||
<ClCompile Include="MPFW_Net.cpp" />
|
||||
<ClCompile Include="MPFW_Physics.cpp" />
|
||||
<ClCompile Include="MPFW_Quake.cpp" />
|
||||
<ClCompile Include="MPFW_UI.cpp" />
|
||||
<ClCompile Include="MPFW_Utils.cpp" />
|
||||
@ -160,6 +161,7 @@
|
||||
<ClInclude Include="MPFW_HL.h" />
|
||||
<ClInclude Include="MPFW_MPFWMF.h" />
|
||||
<ClInclude Include="MPFW_Net.h" />
|
||||
<ClInclude Include="MPFW_Physics.h" />
|
||||
<ClInclude Include="MPFW_Quake.h" />
|
||||
<ClInclude Include="MPFW_UI.h" />
|
||||
<ClInclude Include="MPFW_Utils.h" />
|
||||
|
@ -66,6 +66,9 @@
|
||||
<ClCompile Include="MPFW_Backend_raylib.cpp">
|
||||
<Filter>Backends</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="MPFW_Physics.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="MPFW_HL.h">
|
||||
@ -95,5 +98,8 @@
|
||||
<ClInclude Include="MPFW_Backend_raylib.h">
|
||||
<Filter>Backends</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="MPFW_Physics.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
Loading…
x
Reference in New Issue
Block a user