aboutsummaryrefslogtreecommitdiff
path: root/sp/src/public/dispcoll.h
blob: 55b6d0b34faaa6a9a08f12b258dbb934c01231e6 (plain) (blame)
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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: 
//
// $NoKeywords: $
//=============================================================================//

#ifndef DISPCOLL_H
#define DISPCOLL_H
#pragma once

#include "mathlib/vector.h"

class CCoreDispInfo;

//=============================================================================
//
// Displacement Collision Triangle Data
//
class CDispCollTri
{
public:
	
	void Init( void );
	inline void SetPoint( int index, Vector const& vert );
	inline void SetPointNormal( int index, Vector const& normal );
	void CalcPlane( void );
	
	inline void SetIntersect( bool bIntersect );
	inline bool IsIntersect( void );

	Vector	m_Points[3];		// polygon points
	Vector  m_PointNormals[3];	// polygon point normals
	Vector	m_Normal;			// plane normal
	float	m_Distance;			// plane distance
	short	m_ProjAxes[2];		// projection axes (2 minor axes)
	bool	m_bIntersect;		// intersected triangle???
};	

//=============================================================================
//
// Displacement Collision Node Data
//
class CDispCollNode
{
public:
	
	CDispCollNode();
	inline bool IsLeaf( void );
	inline void SetBounds( Vector const &bMin, Vector const &bMax );
	inline void GetBounds( Vector &bMin, Vector &bMax );
	
	Vector			m_Bounds[2];		// node minimum and maximum

	bool			m_bIsLeaf;			// is the node a leaf? ( may have to make this an int for alignment!)
	CDispCollTri	m_Tris[2];			// two triangles contained in leaf node
};


//=============================================================================
//
// Displacement Collision Data
//
class CDispCollData
{
public:

	Vector	m_StartPos;
	Vector	m_EndPos;
	Vector  m_Extents;
	float	m_Fraction;
	int		m_Contents;
	Vector	m_Normal;
	float	m_Distance;
	bool	m_bOcclude;
};



// HACKHACK: JAY: Moved this out of CDispCollTree to be thread safe in vrad
enum { TRILIST_CACHE_SIZE = 128 };

class CDispCollTreeTempData
{
public:
	//
	// temps
	//
	int					m_TriListCount;
	CDispCollTri		*m_ppTriList[TRILIST_CACHE_SIZE];

	// collision tree node cache
	float				m_AABBDistances[6];
};


//=============================================================================
//
// Displacement Collision Tree
//
class CDispCollTree
{
public:

	static const float COLLISION_EPSILON;
	static const float ONE_MINUS_COLLISION_EPSILON;

	//=========================================================================
	//
	// Creation/Destruction
	//
	CDispCollTree();
	~CDispCollTree();

	virtual bool Create( CCoreDispInfo *pDisp );

	//=========================================================================
	//
	// Collision Functions
	//
	bool RayTest( CDispCollData *pData );
	bool RayTestAllTris( CDispCollData *pData, int power );

	bool AABBIntersect( CDispCollData *pData );
	bool AABBSweep( CDispCollData *pData );

	//=========================================================================
	//
	// Attrib Functions
	//
	inline void SetPower( int power );
	inline int GetPower( void );

	inline void SetCheckCount( int count );
	inline int GetCheckCount( void );

	inline void GetBounds( Vector& boundMin, Vector& boundMax );

protected:

	int					m_Power;

	int					m_NodeCount;
	CDispCollNode		*m_pNodes;

	int					m_CheckCount;

	// collision tree node cache
	Vector				m_AABBNormals[6];
	//=========================================================================
	//
	// Creation/Destruction
	//
	void InitAABBData( void );
	void InitLeaves( CCoreDispInfo *pDisp );
	void CreateNodes( CCoreDispInfo *pDisp );
	void CreateNodes_r( CCoreDispInfo *pDisp, int nodeIndex, int termLevel );
	void CalcBounds( CDispCollNode *pNode, int nodeIndex );

	//=========================================================================
	//
	// Collision Functions
	//
	void CreatePlanesFromBounds( CDispCollTreeTempData *pTemp, Vector const &bbMin, Vector const &bbMax );

//	void RayNodeTest_r( int nodeIndex, Vector &rayStart, Vector &rayEnd );
	void RayNodeTest_r( CDispCollTreeTempData *pTemp, int nodeIndex, Vector rayStart, Vector rayEnd );
	bool RayAABBTest( CDispCollTreeTempData *pTemp, Vector &rayStart, Vector &rayEnd );
	bool RayTriListTest( CDispCollTreeTempData *pTemp, CDispCollData *pData );
	bool RayTriTest( Vector const &rayStart, Vector const &rayDir, float const rayLength, CDispCollTri const *pTri, float *fraction );

	void BuildTriList_r( CDispCollTreeTempData *pTemp, int nodeIndex, Vector &rayStart, Vector &rayEnd, Vector &extents, bool bIntersect );
	bool IntersectAABBAABBTest( CDispCollTreeTempData *pTemp, const Vector &pos, const Vector &extents );
	bool SweptAABBAABBTest( CDispCollTreeTempData *pTemp, const Vector &rayStart, const Vector &rayEnd, const Vector &extents );

	bool CullTriList( CDispCollTreeTempData *pTemp, Vector &rayStart, Vector &rayEnd, Vector &extents, bool bIntersect );
	bool SweptAABBTriTest( Vector &rayStart, Vector &rayEnd, Vector &extents, CDispCollTri const *pTri );
	bool AABBTriIntersect( CDispCollTreeTempData *pTemp, CDispCollData *pData );
	bool IntersectAABBTriTest( Vector &rayStart, Vector &extents, CDispCollTri const *pTri );
	bool SweptAABBTriIntersect( Vector &rayStart, Vector &rayEnd, Vector &extents,
						        CDispCollTri const *pTri, Vector &plNormal, float *plDist,
								float *fraction );

	//=========================================================================
	//
	// Memory Functions
	//
	bool AllocNodes( int nodeCount );
	void FreeNodes( void );

	//=========================================================================
	//
	// Utility Functions
	//
	inline int CalcNodeCount( int power );
	inline int GetParentNode( int nodeIndex );
	inline int GetChildNode( int nodeIndex, int direction );
	inline int GetNodeLevel( int nodeIndex );
	int GetNodeIndexFromComponents( int x, int y );
};


//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
inline void CDispCollTree::SetPower( int power )
{
	m_Power = power;
}

	
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
inline int CDispCollTree::GetPower( void )
{
	return m_Power;
}


//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
inline void CDispCollTree::SetCheckCount( int count )
{
	m_CheckCount = count;
}

	
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
inline int CDispCollTree::GetCheckCount( void )
{
	return m_CheckCount;
}


//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
inline void CDispCollTree::GetBounds( Vector& boundMin, Vector& boundMax )
{
	boundMin[0] = m_pNodes[0].m_Bounds[0].x;
	boundMin[1] = m_pNodes[0].m_Bounds[0].y;
	boundMin[2] = m_pNodes[0].m_Bounds[0].z;

	boundMax[0] = m_pNodes[0].m_Bounds[1].x;
	boundMax[1] = m_pNodes[0].m_Bounds[1].y;
	boundMax[2] = m_pNodes[0].m_Bounds[1].z;
}


#endif // DISPCOLL_H