1
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3
* OPCODE - Optimized Collision Detection
4
* Copyright (C) 2001 Pierre Terdiman
5
* Homepage: http://www.codercorner.com/Opcode.htm
7
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
11
* Contains code for a versatile AABB tree.
12
* \file OPC_AABBTree.h
13
* \author Pierre Terdiman
14
* \date March, 20, 2001
16
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
18
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
20
#ifndef __OPC_AABBTREE_H__
21
#define __OPC_AABBTREE_H__
23
#ifdef OPC_NO_NEG_VANILLA_TREE
25
#define IMPLEMENT_TREE(base_class, volume) \
27
/* Constructor / Destructor */ \
31
inline_ const volume* Get##volume() const { return &mBV; } \
32
/* Clear the last bit */ \
33
inline_ const base_class* GetPos() const { return (const base_class*)(mPos&~1); } \
34
inline_ const base_class* GetNeg() const { const base_class* P = GetPos(); return P ? P+1 : null;} \
36
/* We don't need to test both nodes since we can't have one without the other */ \
37
inline_ bool IsLeaf() const { return !GetPos(); } \
40
inline_ udword GetNodeSize() const { return sizeof(*this); } \
42
/* Tree-independent data */ \
43
/* Following data always belong to the BV-tree, regardless of what the tree actually contains.*/ \
44
/* Whatever happens we need the two children and the enclosing volume.*/ \
45
volume mBV; /* Global bounding-volume enclosing all the node-related primitives */ \
46
size_t mPos; /* "Positive" & "Negative" children */
49
#define IMPLEMENT_TREE(base_class, volume) \
51
/* Constructor / Destructor */ \
55
inline_ const volume* Get##volume() const { return &mBV; } \
56
/* Clear the last bit */ \
57
inline_ const base_class* GetPos() const { return (const base_class*)(mPos&~1); } \
58
inline_ const base_class* GetNeg() const { return (const base_class*)(mNeg&~1); } \
60
/* inline_ bool IsLeaf() const { return (!GetPos() && !GetNeg()); } */ \
61
/* We don't need to test both nodes since we can't have one without the other */ \
62
inline_ bool IsLeaf() const { return !GetPos(); } \
65
inline_ udword GetNodeSize() const { return sizeof(*this); } \
67
/* Tree-independent data */ \
68
/* Following data always belong to the BV-tree, regardless of what the tree actually contains.*/ \
69
/* Whatever happens we need the two children and the enclosing volume.*/ \
70
volume mBV; /* Global bounding-volume enclosing all the node-related primitives */ \
71
size_t mPos; /* "Positive" child */ \
72
size_t mNeg; /* "Negative" child */
75
typedef void (*CullingCallback) (udword nb_primitives, udword* node_primitives, BOOL need_clipping, void* user_data);
79
// IMPLEMENT_TREE(AABBTreeNode, IceMaths::AABB)
81
/* Constructor / Destructor */
85
inline_ const IceMaths::AABB* GetAABB() const { return &mBV; }
86
/* Clear the last bit */
87
inline_ const AABBTreeNode* GetPos() const { return (const AABBTreeNode*)(mPos&~1); }
88
inline_ const AABBTreeNode* GetNeg() const { const AABBTreeNode* P = GetPos(); return P ? P+1 : null;}
90
/* We don't need to test both nodes since we can't have one without the other */
91
inline_ bool IsLeaf() const { return !GetPos(); }
94
inline_ udword GetNodeSize() const { return sizeof(*this); }
96
/* Tree-independent data */
97
/* Following data always belong to the BV-tree, regardless of what the tree actually contains.*/
98
/* Whatever happens we need the two children and the enclosing volume.*/
99
IceMaths::AABB mBV; /* Global bounding-volume enclosing all the node-related primitives */
100
size_t mPos; /* "Positive" & "Negative" children */
103
inline_ const udword* GetPrimitives() const { return mNodePrimitives; }
104
inline_ udword GetNbPrimitives() const { return mNbPrimitives; }
107
// Tree-dependent data
108
udword* mNodePrimitives; //!< Node-related primitives (shortcut to a position in mIndices below)
109
udword mNbPrimitives; //!< Number of primitives for this node
111
udword Split(udword axis, AABBTreeBuilder* builder);
112
bool Subdivide(AABBTreeBuilder* builder);
113
void _BuildHierarchy(AABBTreeBuilder* builder);
114
void _Refit(AABBTreeBuilder* builder);
117
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
119
* User-callback, called for each node by the walking code.
120
* \param current [in] current node
121
* \param depth [in] current node's depth
122
* \param user_data [in] user-defined data
123
* \return true to recurse through children, else false to bypass them
125
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
126
typedef bool (*WalkingCallback) (const AABBTreeNode* current, udword depth, void* user_data);
128
class AABBTree : public AABBTreeNode
131
// Constructor / Destructor
135
bool Build(AABBTreeBuilder* builder);
139
inline_ const udword* GetIndices() const { return mIndices; } //!< Catch the indices
140
inline_ udword GetNbNodes() const { return mTotalNbNodes; } //!< Catch the number of nodes
143
bool IsComplete() const;
145
udword ComputeDepth() const;
146
udword GetUsedBytes() const;
147
udword Walk(WalkingCallback callback, void* user_data) const;
149
bool Refit(AABBTreeBuilder* builder);
150
bool Refit2(AABBTreeBuilder* builder);
152
udword* mIndices; //!< Indices in the app list. Indices are reorganized during build (permutation).
153
AABBTreeNode* mPool; //!< Linear pool of nodes for complete trees. Null otherwise. [Opcode 1.3]
155
udword mTotalNbNodes; //!< Number of nodes in the tree.
158
#endif // __OPC_AABBTREE_H__