1 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2 /*
3  *	OPCODE - Optimized Collision Detection
4  *	Copyright (C) 2001 Pierre Terdiman
5  *	Homepage: http://www.codercorner.com/Opcode.htm
6  */
7 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8 
9 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
10 /**
11  *	Contains code for an OBB collider.
12  *	\file		OPC_OBBCollider.h
13  *	\author		Pierre Terdiman
14  *	\date		January, 1st, 2002
15  */
16 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
17 
18 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
19 // Include Guard
20 #ifndef __OPC_OBBCOLLIDER_H__
21 #define __OPC_OBBCOLLIDER_H__
22 
23 	struct OPCODE_API OBBCache : VolumeCache
24 	{
OBBCacheOBBCache25 					OBBCache() : FatCoeff(1.1f)
26 					{
27 						FatBox.mCenter.Zero();
28 						FatBox.mExtents.Zero();
29 						FatBox.mRot.Identity();
30 					}
31 
32 		// Cached faces signature
33 		OBB				FatBox;		//!< Box used when performing the query resulting in cached faces
34 		// User settings
35 		float			FatCoeff;	//!< extents multiplier used to create a fat box
36 	};
37 
38 	class OPCODE_API OBBCollider : public VolumeCollider
39 	{
40 		public:
41 		// Constructor / Destructor
42 											OBBCollider();
43 		virtual								~OBBCollider();
44 
45 		///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
46 		/**
47 		 *	Generic collision query for generic OPCODE models. After the call, access the results:
48 		 *	- with GetContactStatus()
49 		 *	- with GetNbTouchedPrimitives()
50 		 *	- with GetTouchedPrimitives()
51 		 *
52 		 *	\param		cache			[in/out] a box cache
53 		 *	\param		box				[in] collision OBB in local space
54 		 *	\param		model			[in] Opcode model to collide with
55 		 *	\param		worldb			[in] OBB's world matrix, or null
56 		 *	\param		worldm			[in] model's world matrix, or null
57 		 *	\return		true if success
58 		 *	\warning	SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only.
59 		 */
60 		///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
61 							bool			Collide(OBBCache& cache, const OBB& box, const Model& model, const Matrix4x4* worldb=null, const Matrix4x4* worldm=null);
62 
63 		// Settings
64 
65 		///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
66 		/**
67 		 *	Settings: select between full box-box tests or "SAT-lite" tests (where Class III axes are discarded)
68 		 *	\param		flag		[in] true for full tests, false for coarse tests
69 		 */
70 		///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
SetFullBoxBoxTest(bool flag)71 		inline_				void			SetFullBoxBoxTest(bool flag)	{ mFullBoxBoxTest = flag;	}
72 
73 		// Settings
74 
75 		///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
76 		/**
77 		 *	Validates current settings. You should call this method after all the settings and callbacks have been defined for a collider.
78 		 *	\return		null if everything is ok, else a string describing the problem
79 		 */
80 		///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
81 		override(Collider)	const char*		ValidateSettings();
82 
83 		protected:
84 		// Precomputed data
85 							Matrix3x3		mAR;				//!< Absolute rotation matrix
86 							Matrix3x3		mRModelToBox;		//!< Rotation from model space to obb space
87 							Matrix3x3		mRBoxToModel;		//!< Rotation from obb space to model space
88 							Point			mTModelToBox;		//!< Translation from model space to obb space
89 							Point			mTBoxToModel;		//!< Translation from obb space to model space
90 
91 							Point			mBoxExtents;
92 							Point			mB0;				//!< - mTModelToBox + mBoxExtents
93 							Point			mB1;				//!< - mTModelToBox - mBoxExtents
94 
95 							float			mBBx1;
96 							float			mBBy1;
97 							float			mBBz1;
98 
99 							float			mBB_1;
100 							float			mBB_2;
101 							float			mBB_3;
102 							float			mBB_4;
103 							float			mBB_5;
104 							float			mBB_6;
105 							float			mBB_7;
106 							float			mBB_8;
107 							float			mBB_9;
108 
109 		// Leaf description
110 							Point			mLeafVerts[3];		//!< Triangle vertices
111 		// Settings
112 							bool			mFullBoxBoxTest;	//!< Perform full BV-BV tests (true) or SAT-lite tests (false)
113 		// Internal methods
114 							void			_Collide(const AABBCollisionNode* node);
115 							void			_Collide(const AABBNoLeafNode* node);
116 							void			_Collide(const AABBQuantizedNode* node);
117 							void			_Collide(const AABBQuantizedNoLeafNode* node);
118 							void			_CollideNoPrimitiveTest(const AABBCollisionNode* node);
119 							void			_CollideNoPrimitiveTest(const AABBNoLeafNode* node);
120 							void			_CollideNoPrimitiveTest(const AABBQuantizedNode* node);
121 							void			_CollideNoPrimitiveTest(const AABBQuantizedNoLeafNode* node);
122 			// Overlap tests
123 		inline_				BOOL			OBBContainsBox(const Point& bc, const Point& be);
124 		inline_				BOOL			BoxBoxOverlap(const Point& extents, const Point& center);
125 		inline_				BOOL			TriBoxOverlap();
126 			// Init methods
127 							BOOL			InitQuery(OBBCache& cache, const OBB& box, const Matrix4x4* worldb=null, const Matrix4x4* worldm=null);
128 	};
129 
130 	class OPCODE_API HybridOBBCollider : public OBBCollider
131 	{
132 		public:
133 		// Constructor / Destructor
134 											HybridOBBCollider();
135 		virtual								~HybridOBBCollider();
136 
137 							bool			Collide(OBBCache& cache, const OBB& box, const HybridModel& model, const Matrix4x4* worldb=null, const Matrix4x4* worldm=null);
138 		protected:
139 							Container		mTouchedBoxes;
140 	};
141 
142 #endif // __OPC_OBBCOLLIDER_H__
143