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 SIZEOFOBJECT; } \
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 SIZEOFOBJECT; } \
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
);
77 class OPCODE_API AABBTreeNode
79 IMPLEMENT_TREE(AABBTreeNode
, AABB
)
82 inline_
const dTriIndex
* GetPrimitives() const { return mNodePrimitives
; }
83 inline_ udword
GetNbPrimitives() const { return mNbPrimitives
; }
86 // Tree-dependent data
87 dTriIndex
* mNodePrimitives
; //!< Node-related primitives (shortcut to a position in mIndices below)
88 udword mNbPrimitives
; //!< Number of primitives for this node
90 udword
Split(udword axis
, AABBTreeBuilder
* builder
);
91 bool Subdivide(AABBTreeBuilder
* builder
);
92 void _BuildHierarchy(AABBTreeBuilder
* builder
);
93 void _Refit(AABBTreeBuilder
* builder
);
96 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
98 * User-callback, called for each node by the walking code.
99 * \param current [in] current node
100 * \param depth [in] current node's depth
101 * \param user_data [in] user-defined data
102 * \return true to recurse through children, else false to bypass them
104 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
105 typedef bool (*WalkingCallback
) (const AABBTreeNode
* current
, udword depth
, void* user_data
);
107 class OPCODE_API AABBTree
: public AABBTreeNode
110 // Constructor / Destructor
114 bool Build(AABBTreeBuilder
* builder
);
118 inline_
const dTriIndex
* GetIndices() const { return mIndices
; } //!< Catch the indices
119 inline_ udword
GetNbNodes() const { return mTotalNbNodes
; } //!< Catch the number of nodes
122 bool IsComplete() const;
124 udword
ComputeDepth() const;
125 udword
GetUsedBytes() const;
126 udword
Walk(WalkingCallback callback
, void* user_data
) const;
128 bool Refit(AABBTreeBuilder
* builder
);
129 bool Refit2(AABBTreeBuilder
* builder
);
131 dTriIndex
* mIndices
; //!< Indices in the app list. Indices are reorganized during build (permutation).
132 AABBTreeNode
* mPool
; //!< Linear pool of nodes for complete trees. Null otherwise. [Opcode 1.3]
134 udword mTotalNbNodes
; //!< Number of nodes in the tree.
137 #endif // __OPC_AABBTREE_H__