| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312 |
- /*
- ** Command & Conquer Renegade(tm)
- ** Copyright 2025 Electronic Arts Inc.
- **
- ** This program is free software: you can redistribute it and/or modify
- ** it under the terms of the GNU General Public License as published by
- ** the Free Software Foundation, either version 3 of the License, or
- ** (at your option) any later version.
- **
- ** This program is distributed in the hope that it will be useful,
- ** but WITHOUT ANY WARRANTY; without even the implied warranty of
- ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ** GNU General Public License for more details.
- **
- ** You should have received a copy of the GNU General Public License
- ** along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- /***********************************************************************************************
- *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
- ***********************************************************************************************
- * *
- * Project Name : WWMath *
- * *
- * $Archive:: /Commando/Code/wwmath/colmath.h $*
- * *
- * Author:: Greg Hjelstrom *
- * *
- * $Modtime:: 5/04/01 8:25p $*
- * *
- * $Revision:: 19 $*
- * *
- *---------------------------------------------------------------------------------------------*
- * Functions: *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- #if defined(_MSC_VER)
- #pragma once
- #endif
- #ifndef COLMATH_H
- #define COLMATH_H
- #ifndef ALWAYS_H
- #include "always.h"
- #endif
- #ifndef VECTOR3_H
- #include "vector3.h"
- #endif
- #ifndef CASTRES_H
- #include "castres.h"
- #endif
- class AAPlaneClass;
- class PlaneClass;
- class LineSegClass;
- class TriClass;
- class SphereClass;
- class AABoxClass;
- class OBBoxClass;
- class FrustumClass;
- const float COLLISION_EPSILON = 0.001f;
- /*
- ** #define COLMATH_STAT_TRACKING to enable stat tracking for the collision math functions
- */
- #ifdef WWDEBUG
- #define COLMATH_STAT_TRACKING
- #endif
- /**
- ** CollisionMath
- ** This is a collection of the low-level math functions for collision detection.
- */
- class CollisionMath
- {
- public:
- ////////////////////////////////////////////////////////////////////////////////////////
- // Intersect Functions.
- // These functions simply return a bool indicating whether the two operands intersect.
- ////////////////////////////////////////////////////////////////////////////////////////
- static bool Intersection_Test(const AABoxClass & box,const TriClass & tri);
- static bool Intersection_Test(const AABoxClass & box,const AABoxClass & box2);
- static bool Intersection_Test(const AABoxClass & box,const OBBoxClass & box2);
- static bool Intersection_Test(const OBBoxClass & box,const TriClass & tri);
- static bool Intersection_Test(const OBBoxClass & box,const AABoxClass & box2);
- static bool Intersection_Test(const OBBoxClass & box,const OBBoxClass & box2);
- static bool Intersection_Test(const SphereClass & sphere,const AABoxClass & box);
- static bool Intersection_Test(const SphereClass & sphere,const OBBoxClass & box);
- ////////////////////////////////////////////////////////////////////////////////////////
- // Overlap Functions.
- // Classify the second operand with respect to the first operand.
- // For example Overlap_Test(plane,point) tests whether 'point' is in front of or
- // behind 'plane'.
- // OverlapType: This enumeration is the result of an overlap test.
- // It indicates whether the the object is in the positive (front/outside) space
- // of the volume, the negative (back/inside) space of the volume, or both (overlapping)
- ////////////////////////////////////////////////////////////////////////////////////////
- enum OverlapType
- {
- POS = 0x01,
- NEG = 0x02,
- ON = 0x04,
- BOTH = 0x08,
- OUTSIDE = POS,
- INSIDE = NEG,
- OVERLAPPED = BOTH,
- FRONT = POS,
- BACK = NEG
- };
- // AAPlane functions. Where is operand B with respect to this AAPlane
- static OverlapType Overlap_Test(const AAPlaneClass & plane,const Vector3 & point);
- static OverlapType Overlap_Test(const AAPlaneClass & plane,const LineSegClass & line);
- static OverlapType Overlap_Test(const AAPlaneClass & plane,const TriClass & tri);
- static OverlapType Overlap_Test(const AAPlaneClass & plane,const SphereClass & sphere);
- static OverlapType Overlap_Test(const AAPlaneClass & plane,const AABoxClass & box);
- static OverlapType Overlap_Test(const AAPlaneClass & plane,const OBBoxClass & box);
- // Plane functions. Where is operand B with respect to the plane
- static OverlapType Overlap_Test(const PlaneClass & plane,const Vector3 & point);
- static OverlapType Overlap_Test(const PlaneClass & plane,const LineSegClass & line);
- static OverlapType Overlap_Test(const PlaneClass & plane,const TriClass & tri);
- static OverlapType Overlap_Test(const PlaneClass & plane,const SphereClass & sphere);
- static OverlapType Overlap_Test(const PlaneClass & plane,const Vector3 & center,const Vector3 & extent);
- inline static OverlapType Overlap_Test(const PlaneClass & plane,const AABoxClass & box);
- static OverlapType Overlap_Test(const PlaneClass & plane,const OBBoxClass & box);
- // Sphere functions. Where is operand B with respect to the sphere
- static OverlapType Overlap_Test(const SphereClass & sphere,const Vector3 & point);
- static OverlapType Overlap_Test(const SphereClass & sphere,const LineSegClass & line);
- static OverlapType Overlap_Test(const SphereClass & sphere,const TriClass & tri);
- static OverlapType Overlap_Test(const SphereClass & sphere,const SphereClass & sphere2);
- static OverlapType Overlap_Test(const SphereClass & sphere,const AABoxClass & aabox);
- static OverlapType Overlap_Test(const SphereClass & sphere,const OBBoxClass & obbox);
- // AABox functions. Where is operand B with respect to the AABox
- static OverlapType Overlap_Test(const AABoxClass & box,const Vector3 & point);
- static OverlapType Overlap_Test(const AABoxClass & box,const LineSegClass & line);
- static OverlapType Overlap_Test(const AABoxClass & box,const TriClass & tri);
- static OverlapType Overlap_Test(const AABoxClass & box,const AABoxClass & box2);
- static OverlapType Overlap_Test(const AABoxClass & box,const OBBoxClass & obbox);
- static OverlapType Overlap_Test(const AABoxClass & box,const SphereClass & sphere);
- // OBBox functions, where is operand B with respect to the OBBox
- static OverlapType Overlap_Test(const OBBoxClass & box,const Vector3 & point);
- static OverlapType Overlap_Test(const OBBoxClass & box,const LineSegClass & line);
- static OverlapType Overlap_Test(const OBBoxClass & box,const TriClass & tri);
- static OverlapType Overlap_Test(const OBBoxClass & box,const AABoxClass & box2);
- static OverlapType Overlap_Test(const OBBoxClass & box,const OBBoxClass & box2);
- // Frustum functions
- static OverlapType Overlap_Test(const FrustumClass & frustum,const Vector3 & point);
- static OverlapType Overlap_Test(const FrustumClass & frustum,const TriClass & tri);
- static OverlapType Overlap_Test(const FrustumClass & frustum,const SphereClass & sphere);
- static OverlapType Overlap_Test(const FrustumClass & frustum,const AABoxClass & box);
- static OverlapType Overlap_Test(const FrustumClass & frustum,const OBBoxClass & box);
- // Frustum functions for hierachical culling systems.
- // At your root node, just pass in planes_passed = 0, then the variable will be modified to
- // indicate which planes that volume was inside. You can then pass that value in for the
- // test of all child nodes and optimize away some of the tests. See AABTreeCullSystemClass
- // for an example usage.
- static OverlapType Overlap_Test(const FrustumClass & frustum,const AABoxClass & box,int & planes_passed);
- static OverlapType Overlap_Test(const FrustumClass & frustum,const OBBoxClass & box,int & planes_passed);
- // Miscellaneous other Overlap tests
- static OverlapType Overlap_Test(const Vector3 & min,const Vector3 & max,const LineSegClass & line);
- ////////////////////////////////////////////////////////////////////////////////////////
- // Collision Functions.
- // Collide the first operand into the last operand.
- // For example Collide(box,move,tri) tests for collision between a box moving into
- // a triangle.
- ////////////////////////////////////////////////////////////////////////////////////////
- // Line segment functions. Intersect this line segment with the given object
- static bool Collide(const LineSegClass & line,const AAPlaneClass & plane,CastResultStruct * result);
- static bool Collide(const LineSegClass & line,const PlaneClass & plane,CastResultStruct * result);
- static bool Collide(const LineSegClass & line,const TriClass & tri,CastResultStruct * result);
- static bool Collide(const LineSegClass & line,const SphereClass & sphere,CastResultStruct * result);
- static bool Collide(const LineSegClass & line,const AABoxClass & box,CastResultStruct * result);
- static bool Collide(const LineSegClass & line,const OBBoxClass & box,CastResultStruct * result);
- // AABox functions
- static bool Collide(const AABoxClass & box,const Vector3 & move,const PlaneClass & plane,CastResultStruct * result);
- static bool Collide(const AABoxClass & box,const Vector3 & move,const TriClass & tri,CastResultStruct * result);
- static bool Collide(const AABoxClass & box,const Vector3 & move,const AABoxClass & box2,CastResultStruct * result);
- static bool Collide(const AABoxClass & box,const Vector3 & move,const OBBoxClass & box2,const Vector3 & move2,CastResultStruct * result);
- // OBBox functions
- static bool Collide(const OBBoxClass & box,const Vector3 & move,const PlaneClass & plane,CastResultStruct * result);
- static bool Collide(const OBBoxClass & box,const Vector3 & move,const TriClass & tri,const Vector3 & move2,CastResultStruct * result);
- static bool Collide(const OBBoxClass & box,const Vector3 & move,const AABoxClass & box2,const Vector3 & move2,CastResultStruct * result);
- static bool Collide(const OBBoxClass & box,const Vector3 & move,const OBBoxClass & box2,const Vector3 & move2,CastResultStruct * result);
- ////////////////////////////////////////////////////////////////////////////////////////
- // Stats
- // Note that these functions will only work if you have stat tracking enabled
- ////////////////////////////////////////////////////////////////////////////////////////
- struct ColmathStatsStruct
- {
- ColmathStatsStruct(void);
- void Reset(void);
- int TotalCollisionCount;
- int TotalCollisionHitCount;
- int CollisionRayTriCount;
- int CollisionRayTriHitCount;
- int CollisionAABoxTriCount;
- int CollisionAABoxTriHitCount;
- int CollisionAABoxAABoxCount;
- int CollisionAABoxAABoxHitCount;
- int CollisionOBBoxTriCount;
- int CollisionOBBoxTriHitCount;
- int CollisionOBBoxAABoxCount;
- int CollisionOBBoxAABoxHitCount;
- int CollisionOBBoxOBBoxCount;
- int CollisionOBBoxOBBoxHitCount;
- };
-
- static void Reset_Stats(void) { Stats.Reset(); }
- static const ColmathStatsStruct & Get_Current_Stats(void) { return Stats; }
- private:
- static OverlapType eval_overlap_mask(int mask);
- static OverlapType eval_overlap_collision(const CastResultStruct & res);
- static const float COINCIDENCE_EPSILON;
- static ColmathStatsStruct Stats;
- };
- inline CollisionMath::OverlapType CollisionMath::eval_overlap_mask(int mask)
- {
- // check if all verts are "ON"
- if (mask == ON) {
- return ON;
- }
- // check if all verts are either "ON" or "POS"
- if ((mask & ~(POS | ON)) == 0) {
- return POS;
- }
- // check if all verts are either "ON" or "BACK"
- if ((mask & ~(NEG | ON)) == 0) {
- return NEG;
- }
- // otherwise, poly spans the plane.
- return BOTH;
- }
- inline CollisionMath::OverlapType CollisionMath::eval_overlap_collision(const CastResultStruct & res)
- {
- if (res.Fraction < 1.0f) {
- return BOTH;
- } else {
- if (res.StartBad) {
- return NEG;
- } else {
- return POS;
- }
- }
- }
- /*
- ** Stat tracking Macros
- */
- #ifdef COLMATH_STAT_TRACKING
- #define TRACK_COLLISION_RAY_TRI Stats.CollisionRayTriCount++; Stats.TotalCollisionCount++;
- #define TRACK_COLLISION_RAY_TRI_HIT Stats.CollisionRayTriHitCount++; Stats.TotalCollisionHitCount;
- #define TRACK_COLLISION_AABOX_TRI Stats.CollisionAABoxTriCount++; Stats.TotalCollisionCount++;
- #define TRACK_COLLISION_AABOX_TRI_HIT Stats.CollisionAABoxTriHitCount++; Stats.TotalCollisionHitCount++;
- #define TRACK_COLLISION_AABOX_AABOX Stats.CollisionAABoxAABoxCount++; Stats.TotalCollisionCount++;
- #define TRACK_COLLISION_AABOX_AABOX_HIT Stats.CollisionAABoxAABoxHitCount++; Stats.TotalCollisionHitCount++;
- #define TRACK_COLLISION_OBBOX_TRI Stats.CollisionOBBoxTriCount++; Stats.TotalCollisionCount++;
- #define TRACK_COLLISION_OBBOX_TRI_HIT Stats.CollisionOBBoxTriHitCount++; Stats.TotalCollisionHitCount++;
- #define TRACK_COLLISION_OBBOX_AABOX Stats.CollisionOBBoxAABoxCount++; Stats.TotalCollisionCount++;
- #define TRACK_COLLISION_OBBOX_AABOX_HIT Stats.CollisionOBBoxAABoxHitCount++; Stats.TotalCollisionHitCount++;
- #define TRACK_COLLISION_OBBOX_OBBOX Stats.CollisionOBBoxOBBoxCount++; Stats.TotalCollisionCount++;
- #define TRACK_COLLISION_OBBOX_OBBOX_HIT Stats.CollisionOBBoxOBBoxHitCount++; Stats.TotalCollisionHitCount++;
- #else
- #define TRACK_COLLISION_RAY_TRI
- #define TRACK_COLLISION_RAY_TRI_HIT
- #define TRACK_COLLISION_AABOX_TRI
- #define TRACK_COLLISION_AABOX_TRI_HIT
- #define TRACK_COLLISION_AABOX_AABOX
- #define TRACK_COLLISION_AABOX_AABOX_HIT
- #define TRACK_COLLISION_OBBOX_TRI
- #define TRACK_COLLISION_OBBOX_TRI_HIT
- #define TRACK_COLLISION_OBBOX_AABOX
- #define TRACK_COLLISION_OBBOX_AABOX_HIT
- #define TRACK_COLLISION_OBBOX_OBBOX
- #define TRACK_COLLISION_OBBOX_OBBOX_HIT
- #endif
- #endif // COLMATH_H
|