2
0

OPC_AABBTree.h 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2. /*
  3. * OPCODE - Optimized Collision Detection
  4. * Copyright (C) 2001 Pierre Terdiman
  5. * Homepage: http://www.codercorner.com/Opcode.htm
  6. */
  7. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  8. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  9. /**
  10. * Contains code for a versatile AABB tree.
  11. * \file OPC_AABBTree.h
  12. * \author Pierre Terdiman
  13. * \date March, 20, 2001
  14. */
  15. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  16. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  17. // Include Guard
  18. #ifndef __OPC_AABBTREE_H__
  19. #define __OPC_AABBTREE_H__
  20. #ifdef OPC_NO_NEG_VANILLA_TREE
  21. //! TO BE DOCUMENTED
  22. #define IMPLEMENT_TREE(base_class, volume) \
  23. public: \
  24. /* Constructor / Destructor */ \
  25. base_class(); \
  26. ~base_class(); \
  27. /* Data access */ \
  28. inline_ const volume* Get##volume() const { return &mBV; } \
  29. /* Clear the last bit */ \
  30. inline_ const base_class* GetPos() const { return (const base_class*)(mPos&~1); } \
  31. inline_ const base_class* GetNeg() const { const base_class* P = GetPos(); return P ? P+1 : null;} \
  32. \
  33. /* We don't need to test both nodes since we can't have one without the other */ \
  34. inline_ bool IsLeaf() const { return !GetPos(); } \
  35. \
  36. /* Stats */ \
  37. inline_ udword GetNodeSize() const { return SIZEOFOBJECT; } \
  38. protected: \
  39. /* Tree-independent data */ \
  40. /* Following data always belong to the BV-tree, regardless of what the tree actually contains.*/ \
  41. /* Whatever happens we need the two children and the enclosing volume.*/ \
  42. volume mBV; /* Global bounding-volume enclosing all the node-related primitives */ \
  43. size_t mPos; /* "Positive" & "Negative" children */
  44. #else
  45. //! TO BE DOCUMENTED
  46. #define IMPLEMENT_TREE(base_class, volume) \
  47. public: \
  48. /* Constructor / Destructor */ \
  49. base_class(); \
  50. ~base_class(); \
  51. /* Data access */ \
  52. inline_ const volume* Get##volume() const { return &mBV; } \
  53. /* Clear the last bit */ \
  54. inline_ const base_class* GetPos() const { return (const base_class*)(mPos&~1); } \
  55. inline_ const base_class* GetNeg() const { return (const base_class*)(mNeg&~1); } \
  56. \
  57. /* inline_ bool IsLeaf() const { return (!GetPos() && !GetNeg()); } */ \
  58. /* We don't need to test both nodes since we can't have one without the other */ \
  59. inline_ bool IsLeaf() const { return !GetPos(); } \
  60. \
  61. /* Stats */ \
  62. inline_ udword GetNodeSize() const { return SIZEOFOBJECT; } \
  63. protected: \
  64. /* Tree-independent data */ \
  65. /* Following data always belong to the BV-tree, regardless of what the tree actually contains.*/ \
  66. /* Whatever happens we need the two children and the enclosing volume.*/ \
  67. volume mBV; /* Global bounding-volume enclosing all the node-related primitives */ \
  68. size_t mPos; /* "Positive" child */ \
  69. size_t mNeg; /* "Negative" child */
  70. #endif
  71. typedef void (*CullingCallback) (udword nb_primitives, udword* node_primitives, BOOL need_clipping, void* user_data);
  72. class OPCODE_API AABBTreeNode
  73. {
  74. IMPLEMENT_TREE(AABBTreeNode, AABB)
  75. public:
  76. // Data access
  77. inline_ const udword* GetPrimitives() const { return mNodePrimitives; }
  78. inline_ udword GetNbPrimitives() const { return mNbPrimitives; }
  79. protected:
  80. // Tree-dependent data
  81. udword* mNodePrimitives; //!< Node-related primitives (shortcut to a position in mIndices below)
  82. udword mNbPrimitives; //!< Number of primitives for this node
  83. // Internal methods
  84. udword Split(udword axis, AABBTreeBuilder* builder);
  85. bool Subdivide(AABBTreeBuilder* builder);
  86. void _BuildHierarchy(AABBTreeBuilder* builder);
  87. void _Refit(AABBTreeBuilder* builder);
  88. };
  89. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  90. /**
  91. * User-callback, called for each node by the walking code.
  92. * \param current [in] current node
  93. * \param depth [in] current node's depth
  94. * \param user_data [in] user-defined data
  95. * \return true to recurse through children, else false to bypass them
  96. */
  97. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  98. typedef bool (*WalkingCallback) (const AABBTreeNode* current, udword depth, void* user_data);
  99. class OPCODE_API AABBTree : public AABBTreeNode
  100. {
  101. public:
  102. // Constructor / Destructor
  103. AABBTree();
  104. ~AABBTree();
  105. // Build
  106. bool Build(AABBTreeBuilder* builder);
  107. void Release();
  108. // Data access
  109. inline_ const udword* GetIndices() const { return mIndices; } //!< Catch the indices
  110. inline_ udword GetNbNodes() const { return mTotalNbNodes; } //!< Catch the number of nodes
  111. // Infos
  112. bool IsComplete() const;
  113. // Stats
  114. udword ComputeDepth() const;
  115. udword GetUsedBytes() const;
  116. udword Walk(WalkingCallback callback, void* user_data) const;
  117. bool Refit(AABBTreeBuilder* builder);
  118. bool Refit2(AABBTreeBuilder* builder);
  119. private:
  120. udword* mIndices; //!< Indices in the app list. Indices are reorganized during build (permutation).
  121. AABBTreeNode* mPool; //!< Linear pool of nodes for complete trees. Null otherwise. [Opcode 1.3]
  122. // Stats
  123. udword mTotalNbNodes; //!< Number of nodes in the tree.
  124. };
  125. #endif // __OPC_AABBTREE_H__