File: OPC_OptimizedTree.h

package info (click to toggle)
arkrpg 0.1.4b-6
  • links: PTS
  • area: main
  • in suites: sarge
  • size: 6,104 kB
  • ctags: 5,445
  • sloc: cpp: 28,145; sh: 9,006; ansic: 3,259; makefile: 344
file content (172 lines) | stat: -rwxr-xr-x 6,984 bytes parent folder | download | duplicates (3)
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
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/*
 *	OPCODE - Optimized Collision Detection
 *	Copyright (C) 2001 Pierre Terdiman
 *	Homepage: http://www.codercorner.com/Opcode.htm
 */
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
 *	Contains code for optimized trees.
 *	\file		OPC_OptimizedTree.h
 *	\author		Pierre Terdiman
 *	\date		March, 20, 2001
 */
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Include Guard
#ifndef __OPC_OPTIMIZEDTREE_H__
#define __OPC_OPTIMIZEDTREE_H__

	//! Common interface for a node of an implicit tree
	#define IMPLEMENT_IMPLICIT_NODE(baseclass, volume)													\
		public:																							\
		/* Constructor / Destructor */																	\
		__forceinline						baseclass() : mData(0)	{}									\
		__forceinline						~baseclass()			{}									\
		/* Leaf test */																					\
		__forceinline	BOOL				IsLeaf()		const	{ return mData&1;				}	\
		/* Data access */																				\
		__forceinline	const baseclass*	GetPos()		const	{ return (baseclass*)mData;		}	\
		__forceinline	const baseclass*	GetNeg()		const	{ return ((baseclass*)mData)+1;	}	\
		__forceinline	udword				GetPrimitive()	const	{ return (mData>>1);			}	\
		/* Stats */																						\
		__forceinline	udword				GetNodeSize()	const	{ return SIZEOFOBJECT;			}	\
																										\
						volume				mAABB;														\
						udword				mData;

	//! Common interface for a node of a no-leaf tree
	#define IMPLEMENT_NOLEAF_NODE(baseclass, volume)													\
		public:																							\
		/* Constructor / Destructor */																	\
		__forceinline						baseclass() : mData(0), mData2(0)	{}						\
		__forceinline						~baseclass()						{}						\
		/* Leaf tests */																				\
		__forceinline	BOOL				HasLeaf()		const	{ return mData&1;				}	\
		__forceinline	BOOL				HasLeaf2()		const	{ return mData2&1;				}	\
		/* Data access */																				\
		__forceinline	const baseclass*	GetPos()		const	{ return (baseclass*)mData;		}	\
		__forceinline	const baseclass*	GetNeg()		const	{ return (baseclass*)mData2;	}	\
		__forceinline	udword				GetPrimitive()	const	{ return (mData>>1);			}	\
		__forceinline	udword				GetPrimitive2()	const	{ return (mData2>>1);			}	\
		/* Stats */																						\
		__forceinline	udword				GetNodeSize()	const	{ return SIZEOFOBJECT;			}	\
																										\
						volume				mAABB;														\
						udword				mData;														\
						udword				mData2;

	class OPCODE_API AABBCollisionNode
	{
		IMPLEMENT_IMPLICIT_NODE(AABBCollisionNode, CollisionAABB)

		__forceinline	float				GetVolume()		const	{ return mAABB.mExtents.x * mAABB.mExtents.y * mAABB.mExtents.z;	}
		__forceinline	float				GetSize()		const	{ return mAABB.mExtents.SquareMagnitude();	}
		__forceinline	udword				GetRadius()		const
						{
							udword* Bits = (udword*)&mAABB.mExtents.x;
							udword Max = Bits[0];
							if(Bits[1]>Max)	Max = Bits[1];
							if(Bits[2]>Max)	Max = Bits[2];
							return Max;
						}

		// NB: using the square-magnitude or the true volume of the box, seems to yield better results
		// (assuming UNC-like informed traversal methods). I borrowed this idea from PQP. The usual "size"
		// otherwise, is the largest box extent. In SOLID that extent is computed on-the-fly each time it's
		// needed (the best approach IMHO). In RAPID the rotation matrix is permuted so that Extent[0] is
		// always the greatest, which saves looking for it at runtime. On the other hand, it yields matrices
		// whose determinant is not 1, i.e. you can't encode them anymore as unit quaternions. Not a very
		// good strategy.
	};

	class OPCODE_API AABBQuantizedNode
	{
		IMPLEMENT_IMPLICIT_NODE(AABBQuantizedNode, QuantizedAABB)

		__forceinline	uword				GetSize()		const
						{
							const uword* Bits = mAABB.mExtents;
							uword Max = Bits[0];
							if(Bits[1]>Max)	Max = Bits[1];
							if(Bits[2]>Max)	Max = Bits[2];
							return Max;
						}
		// NB: for quantized nodes I don't feel like computing a square-magnitude with integers all
		// over the place.......!
	};

	class OPCODE_API AABBNoLeafNode
	{
		IMPLEMENT_NOLEAF_NODE(AABBNoLeafNode, CollisionAABB)
	};

	class OPCODE_API AABBQuantizedNoLeafNode
	{
		IMPLEMENT_NOLEAF_NODE(AABBQuantizedNoLeafNode, QuantizedAABB)
	};

	//! Common interface for a collision tree
	#define IMPLEMENT_COLLISION_TREE(baseclass, volume)														\
		public:																								\
		/* Constructor / Destructor */																		\
											baseclass();													\
		virtual								~baseclass();													\
		/* Build from a standard tree */																	\
		virtual			bool				Build(AABBTree* tree);											\
		/* Data access */																					\
		__forceinline	const volume*		GetNodes()		const	{ return mNodes;					}	\
		/* Stats */																							\
		virtual			udword				GetUsedBytes()	const	{ return mNbNodes*sizeof(volume);	}	\
		private:																							\
						volume*				mNodes;

	class OPCODE_API AABBOptimizedTree
	{
		public:
		// Constructor / Destructor
											AABBOptimizedTree() : mNbNodes(0)		{}
		virtual								~AABBOptimizedTree()					{}

		// Data access
		__forceinline	udword				GetNbNodes()	const	{ return mNbNodes;	}

		virtual			udword				GetUsedBytes()	const	= 0;
		virtual			bool				Build(AABBTree* tree)	= 0;
		protected:
						udword				mNbNodes;
	};

	class OPCODE_API AABBCollisionTree : public AABBOptimizedTree
	{
		IMPLEMENT_COLLISION_TREE(AABBCollisionTree, AABBCollisionNode)
	};

	class OPCODE_API AABBNoLeafTree : public AABBOptimizedTree
	{
		IMPLEMENT_COLLISION_TREE(AABBNoLeafTree, AABBNoLeafNode)
	};

	class OPCODE_API AABBQuantizedTree : public AABBOptimizedTree
	{
		IMPLEMENT_COLLISION_TREE(AABBQuantizedTree, AABBQuantizedNode)

		public:
						Point				mCenterCoeff;
						Point				mExtentsCoeff;
	};

	class OPCODE_API AABBQuantizedNoLeafTree : public AABBOptimizedTree
	{
		IMPLEMENT_COLLISION_TREE(AABBQuantizedNoLeafTree, AABBQuantizedNoLeafNode)

		public:
						Point				mCenterCoeff;
						Point				mExtentsCoeff;
	};

#endif // __OPC_OPTIMIZEDTREE_H__
// END-OF-FILE\n