summaryrefslogtreecommitdiffhomepage
path: root/third-party/Opcode/OPC_PlanesCollider.h
blob: fd31e1aaab25fe2a9e3bb8e415dc6d0b211e104d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/*
 *	OPCODE - Optimized Collision Detection
 *	Copyright (C) 2001 Pierre Terdiman
 *	Homepage: http://www.codercorner.com/Opcode.htm
 */
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
 *	Contains code for a planes collider.
 *	\file		OPC_PlanesCollider.h
 *	\author		Pierre Terdiman
 *	\date		January, 1st, 2002
 */
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Include Guard
#ifndef __OPC_PLANESCOLLIDER_H__
#define __OPC_PLANESCOLLIDER_H__

	struct OPCODE_API PlanesCache : VolumeCache
	{
					PlanesCache()
					{
					}
	};

	class OPCODE_API PlanesCollider : public VolumeCollider
	{
		public:
		// Constructor / Destructor
											PlanesCollider();
		virtual								~PlanesCollider();

		///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/**
		 *	Generic collision query for generic OPCODE models. After the call, access the results:
		 *	- with GetContactStatus()
		 *	- with GetNbTouchedPrimitives()
		 *	- with GetTouchedPrimitives()
		 *
		 *	\param		cache			[in/out] a planes cache
		 *	\param		planes			[in] list of planes in world space
		 *	\param		nb_planes		[in] number of planes
		 *	\param		model			[in] Opcode model to collide with
		 *	\param		worldm			[in] model's world matrix, or null
		 *	\return		true if success
		 *	\warning	SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only.
		 */
		///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
							bool			Collide(PlanesCache& cache, const IcePlane* planes, udword nb_planes, const Model& model, const Matrix4x4* worldm=null);

		// Mutant box-with-planes collision queries
		inline_				bool			Collide(PlanesCache& cache, const OBB& box, const Model& model, const Matrix4x4* worldb=null, const Matrix4x4* worldm=null)
											{
												IcePlane PL[6];

												if(worldb)
												{
													// Create a new OBB in world space
													OBB WorldBox;
													box.Rotate(*worldb, WorldBox);
													// Compute planes from the sides of the box
													WorldBox.ComputePlanes(PL);
												}
												else
												{
													// Compute planes from the sides of the box
													box.ComputePlanes(PL);
												}

												// Collide with box planes
												return Collide(cache, PL, 6, model, worldm);
											}
		// Settings

		///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/**
		 *	Validates current settings. You should call this method after all the settings and callbacks have been defined for a collider.
		 *	\return		null if everything is ok, else a string describing the problem
		 */
		///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		override(Collider)	const char*		ValidateSettings();

		protected:
		// Planes in model space
							udword			mNbPlanes;
							IcePlane*			mPlanes;
		// Leaf description
							VertexPointers	mVP;
		// Internal methods
							void			_Collide(const AABBCollisionNode* node, udword clip_mask);
							void			_Collide(const AABBNoLeafNode* node, udword clip_mask);
							void			_Collide(const AABBQuantizedNode* node, udword clip_mask);
							void			_Collide(const AABBQuantizedNoLeafNode* node, udword clip_mask);
							void			_CollideNoPrimitiveTest(const AABBCollisionNode* node, udword clip_mask);
							void			_CollideNoPrimitiveTest(const AABBNoLeafNode* node, udword clip_mask);
							void			_CollideNoPrimitiveTest(const AABBQuantizedNode* node, udword clip_mask);
							void			_CollideNoPrimitiveTest(const AABBQuantizedNoLeafNode* node, udword clip_mask);
			// Overlap tests
		inline_				BOOL			PlanesAABBOverlap(const IcePoint& center, const IcePoint& extents, udword& out_clip_mask, udword in_clip_mask);
		inline_				BOOL			PlanesTriOverlap(udword in_clip_mask);
			// Init methods
							BOOL			InitQuery(PlanesCache& cache, const IcePlane* planes, udword nb_planes, const Matrix4x4* worldm=null);
	};

	class OPCODE_API HybridPlanesCollider : public PlanesCollider
	{
		public:
		// Constructor / Destructor
											HybridPlanesCollider();
		virtual								~HybridPlanesCollider();

							bool			Collide(PlanesCache& cache, const IcePlane* planes, udword nb_planes, const HybridModel& model, const Matrix4x4* worldm=null);
		protected:
							Container		mTouchedBoxes;
	};

#endif // __OPC_PLANESCOLLIDER_H__