Files
2026-08-09 01:29:43 -07:00

310 lines
13 KiB
C++

#pragma once
#include "cm/collisiontypes.h"
#include "cm/jobs/collisionquery.h"
#include "idlib/math/mat3x4.h"
#include "idlib/math/pluecker.h"
#include <cstddef>
#include <cstdint>
class idTraceModel;
struct cm_sideCache_t {
std::uint32_t side;
};
struct cm_trmVertex_t {
idBoundsShort bounds;
int pad;
};
struct cm_trmEdge_t {
idBoundsShort bounds;
std::uint16_t vertexNum[2];
};
struct cm_trmPolygon_t {
idPlane plane;
idBoundsShort bounds;
std::uint32_t numEdges;
std::uint8_t edges[16];
std::uint32_t vertexSideMask;
std::uint32_t vertexSideBits;
std::uint32_t pad[2];
};
struct idModelCheckCounts {
std::uint8_t baseCheckCounts[928];
std::uint8_t checkCount;
std::uint8_t* vertexCheckCounts;
std::uint8_t* edgeCheckCounts;
std::uint8_t* polygonCheckCounts;
std::uint8_t* polytopeCheckCounts;
void SetupForSubModel(const cm_subModelData_t* subModelData);
};
struct idTraceWork {
cm_trmVertex_t verts[32];
cm_trmEdge_t edges[32];
cm_trmPolygon_t polys[16];
idVec4 vertexPosition[32];
idVec4 vertexEndPosition[32];
idPluecker vertexPluecker[32];
idPluecker edgePluecker[32];
idPluecker edgeZAxisPluecker[32];
idVec4 edgeNormal[32];
std::uint8_t vertIsUsed[32];
std::uint8_t edgeIsUsed[32];
std::uint8_t polyIsUsed[16];
std::uint32_t numVerts;
std::uint32_t numEdges;
std::uint32_t numPolys;
int contents;
idVec4 start;
idVec4 end;
idVec4 dir;
idVec4 negDir;
idMat3x4 trmTransform;
idVec4 trmBoundsMin;
idVec4 trmBoundsMax;
idVec4 trmExtents;
idVec4 traceBoundsMin;
idVec4 traceBoundsMax;
idBoundsShort traceBoundsShort;
int pad;
idPlane heartPlane1;
idPlane heartPlane2;
float maxDistFromHeartPlane1;
float maxDistFromHeartPlane2;
float fraction;
int subModelNum;
float angle;
float negAngle;
float maxTan;
float initialTan;
idVec4 origin;
idVec4 axis;
idMat3x4 ZAxisTransform;
idMat3x4 endTransform;
float contactDepth;
traceType_t traceType;
bool isConvex;
bool quickExit;
cm_sideCache_t polygonSideCache;
cm_sideCache_t polygonEdgeSideCache[20];
cm_sideCache_t polygonVertexSideCache[20];
idPluecker polygonEdgePlueckerCache[16];
idPluecker polygonVertexPlueckerCache[16];
std::uint8_t subModelDataForBounds[768];
idModelCheckCounts modelCheckCounts;
cm_subModelPtrs_t subModelPtrs;
trace_t* traceResult;
contactsResult_t* contactsResult;
clipResult_t* clipResult;
trace_t tempTraceResult;
int profile[5];
void Init();
};
class idPolygonModelCollisionDetection {
public:
static void SetupSubModelPtrsFromData(cm_subModelPtrs_t& pointers,
const cm_subModelData_t* data);
static idTraceWork* AllocTraceWork();
static int GetTraceWorkSPUSize();
static cm_subModelData_t* SetupSubModelForBounds(cm_subModelData_t* data,
int size, const idBounds& bounds);
static bool TestStuckInSubModelBounds(idTraceWork* tw,
const idBounds& subModelBounds);
static idVec3 LocalExtentsFromUnTransformedBounds(
const idBounds& globalBounds, const idVec3& globalStart,
const idVec3& globalEnd, const idMat3& modelAxis);
static void TraceThroughSubModelTree(idTraceWork* tw);
static void TraceThroughSubModel(idTraceWork* tw,
const cm_subModelData_t* subModelData, int subModelNum);
static unsigned int GetSubModelsForTrace(const cm_polygonModel_t& model,
const idVec3& start, const idVec3& end, const idVec3& extents,
int* subModelNums);
static void TraceThroughModel(idTraceWork* tw,
const cm_polygonModel_t& model);
static bool TestTrmVertsInPolytope(idTraceWork* tw, int polytopeNum);
static bool TestTrmInPolygon(idTraceWork* tw, int polygonNum);
static void StartContents(idTraceWork* tw, trace_t* result,
const idVec3& start, const idTraceModel* trm,
const idMat3& trmAxis, int contentMask,
const idVec3& modelOrigin, const idMat3& modelAxis);
static void StartContentsPoint(idTraceWork* tw, trace_t* result,
const idVec3& start, int contentMask,
const idVec3& modelOrigin, const idMat3& modelAxis);
static void FinishContents(idTraceWork* tw, const idVec3& modelOrigin,
const idMat3& modelAxis, int modelEntityNum, int modelPhysicsId,
int modelBodyId, int selfId, int modelContentsOverride);
static void TranslationSetup(idTraceWork* tw, const idVec3& start,
const idVec3& end, const idVec3& offset, const idMat3& trmAxis,
const idVec3& modelOrigin, const idMat3& modelAxis);
static void TranslationUsedPrimitives(idTraceWork* tw,
const idVec3& start, const idVec3& end, const idTraceModel& trm,
const idMat3& trmAxis);
static void TranslationHeartPlanes(idTraceWork* tw);
static void TranslationVerts(idTraceWork* tw, const idTraceModel& trm);
static void TranslationEdges(idTraceWork* tw, const idTraceModel& trm);
static void TranslationPolys(idTraceWork* tw, const idTraceModel& trm);
static void TranslationBounds(idTraceWork* tw);
static void TranslationUpdateBounds(idTraceWork* tw);
static void TranslationPlueckerCache(idTraceWork* tw,
const cm_polygon_t& polygon);
static void TranslationEdgePlueckerCache(idTraceWork* tw,
const cm_polygon_t& polygon);
static void TranslationSideCache(const idPluecker* pluecker,
const std::uint8_t* used, unsigned int count,
const idPluecker* plueckerCache, cm_sideCache_t* sideCache,
unsigned int cacheSize);
static void TranslationPolygonSideCache(idTraceWork* tw,
const cm_polygon_t& polygon);
static void AddContact(idTraceWork* tw);
static float TranslateEdgeThroughEdge(const idPluecker& first,
const idPluecker& second, const idVec3& direction);
static int TranslateTrmEdgesThroughPolygon(idTraceWork* tw,
const cm_polygon_t& polygon);
static float TranslatePointThroughPlane(const idPlane& plane,
const idVec3& start, const idVec3& end);
static int TranslateTrmVertsThroughPolygon(idTraceWork* tw,
const cm_polygon_t& polygon, const idPlane& polygonPlane);
static int TranslatePolygonVertsThroughTrm(idTraceWork* tw,
const cm_polygon_t& polygon);
static int TranslateTrmThroughPolygon(idTraceWork* tw, int polygonNum);
static int TranslatePointThroughPolygon(idTraceWork* tw, int polygonNum);
static int StartTranslation(idTraceWork* tw, trace_t* result,
contactsResult_t* contacts, const idVec3& start, const idVec3& end,
const idTraceModel* trm, const idMat3& trmAxis, int contentMask,
const idVec3& modelOrigin, const idMat3& modelAxis);
static int StartTranslationPoint(idTraceWork* tw, trace_t* result,
const idVec3& start, const idVec3& end, int contentMask,
const idVec3& modelOrigin, const idMat3& modelAxis);
static void FinishTranslation(idTraceWork* tw, const idVec3& start,
const idVec3& end, const idVec3& modelOrigin,
const idMat3& modelAxis, int modelEntityNum, int modelPhysicsId,
int modelBodyId, int selfId, int modelContentsOverride);
static int ClipInPlace(idVec5* points, int numPoints,
const idPlane& plane, float epsilon, bool keepOn);
static bool ClipPolygonWithTrm(idTraceWork* tw, int polygonNum);
static void StartClip(idTraceWork* tw, clipResult_t* result,
const idVec3& start, const idTraceModel& trm,
const idMat3& trmAxis, int contentMask,
const idVec3& modelOrigin, const idMat3& modelAxis);
static void FinishClip(idTraceWork* tw, int firstClipVert,
const idVec3& modelOrigin, const idMat3& modelAxis);
static void TestTrmEdgeInContactWithPolygon(idTraceWork* tw,
const cm_polygon_t& polygon, int trmEdgeNum);
static void TestTrmVertexInContactWithPolygon(idTraceWork* tw,
const cm_polygon_t& polygon, const idPlane& polygonPlane,
int trmVertNum);
static void TestVertexInContactWithTrmPolygon(idTraceWork* tw,
const cm_trmPolygon_t& trmPolygon, const cm_polygon_t& polygon,
const cm_vertex_t& vertex);
static bool TestTrmInContactWithPolygon(idTraceWork* tw,
int polygonNum);
static void StartContacts(idTraceWork* tw, contactsResult_t* result,
const idVec3& start, const idVec3& direction, float depth,
const idTraceModel& trm, const idMat3& trmAxis, int contentMask,
const idVec3& modelOrigin, const idMat3& modelAxis);
static void FinishContacts(idTraceWork* tw, int firstContact,
const idVec3& modelOrigin, const idMat3& modelAxis,
int modelEntityNum, int modelPhysicsId, int modelBodyId, int selfId,
int modelContentsOverride);
static bool EdgeIntersectsBoundsShort(const idBoundsShort& bounds,
const idVec3& start, const idVec3& end);
static void RotationSetup(idTraceWork* tw, const idVec3& rotationOrigin,
const idVec3& rotationAxis, float angle, const idVec3& start,
const idVec3& offset, const idMat3& trmAxis,
const idVec3& modelOrigin, const idMat3& modelAxis);
static void TransformFromOriginAxisAngle(idMat3x4& transform,
const idVec3& origin, const idVec3& axis, float angle);
static void TransformAxisToZAxis(idMat3x4& transform,
const idVec3& origin, const idVec3& axis);
static void RotationVerts(idTraceWork* tw, const idTraceModel& trm,
idVec4* zverts);
static void RotationEdges(idTraceWork* tw, const idTraceModel& trm,
const idVec4* zverts);
static void RotationPolys(idTraceWork* tw, const idTraceModel& trm);
static void RotationBounds(idTraceWork* tw);
static void RotationEdgePlueckerCache(idTraceWork* tw,
const cm_polygon_t& polygon);
static void RotationCullPolygonEdges(idTraceWork* tw,
const cm_polygon_t& polygon);
static int CollisionBetweenEdgeBounds(const idTraceWork& tw,
const idVec3& firstStart, const idVec3& firstEnd,
const idVec3& secondStart, const idVec3& secondEnd,
float tanHalfAngle, idVec3& collisionPoint,
idVec3& collisionNormal);
static int RotateEdgeThroughEdge(const idPluecker& first,
const idPluecker& second, float angle, float minTan, float maxTan,
float& tanHalfAngle);
static int EdgeFurthestFromEdge(const idPluecker& first,
const idPluecker& second, float angle, float& tanHalfAngle,
float& direction);
static int RotateTrmEdgesThroughPolygon(idTraceWork* tw,
const cm_polygon_t& polygon);
static int RotatePointThroughPlane(const idVec3& point,
const idPlane& plane, float angle, float minTan, float maxTan,
float& tanHalfAngle);
static int PointFurthestFromPlane(const idVec3& point,
const idPlane& plane, float angle, float& tanHalfAngle,
float& direction);
static int RotatePointThroughEpsilonPlane(const idTraceWork& tw,
const idVec3& point, const idVec3& endPoint, const idPlane& plane,
float angle, const idVec3& rotationOrigin, float& tanHalfAngle,
idVec3& collisionPoint, idVec3& endDirection);
static int RotateTrmVertsThroughPolygon(idTraceWork* tw,
const cm_polygon_t& polygon, const idPlane& polygonPlane);
static int RotatePolygonVertsThroughTrm(idTraceWork* tw,
const cm_polygon_t& polygon);
static bool RotateTrmThroughPolygon(idTraceWork* tw, int polygonNum);
static int StartRotation(idTraceWork* tw, trace_t* result,
const idVec3& rotationOrigin, const idVec3& rotationAxis,
float angle, const idVec3& start, const idTraceModel* trm,
const idMat3& trmAxis, int contentMask,
const idVec3& modelOrigin, const idMat3& modelAxis);
static int StartRotationPoint(idTraceWork* tw, trace_t* result,
const idVec3& rotationOrigin, const idVec3& rotationAxis,
float angle, const idVec3& start, int contentMask,
const idVec3& modelOrigin, const idMat3& modelAxis);
static void FinishRotation(idTraceWork* tw,
const idVec3& rotationOrigin, const idVec3& rotationAxis,
float angle, const idVec3& start, const idMat3& trmAxis,
const idVec3& modelOrigin, const idMat3& modelAxis,
int modelEntityNum, int modelPhysicsId, int modelBodyId, int selfId,
int modelContentsOverride);
};
float CM_TanZeroHalfPI(float angle);
float CM_ArcTanPositive(float value);
void CM_PointRotationBounds(const idVec3& origin, const idVec3& axis,
const idVec3& start, const idVec3& end,
idVec4& boundsMin, idVec4& boundsMax);
static_assert(sizeof(cm_sideCache_t) == 4,
"Recovered cm_sideCache_t ABI changed");
static_assert(sizeof(cm_trmVertex_t) == 16,
"Recovered cm_trmVertex_t ABI changed");
static_assert(sizeof(cm_trmEdge_t) == 16,
"Recovered cm_trmEdge_t ABI changed");
static_assert(sizeof(cm_trmPolygon_t) == 64,
"Recovered cm_trmPolygon_t ABI changed");
#if INTPTR_MAX == INT32_MAX
static_assert(sizeof(idModelCheckCounts) == 948,
"Recovered idModelCheckCounts ABI changed");
static_assert(sizeof(idTraceWork) == 9244,
"Recovered idTraceWork ABI changed");
#endif