OPC_TreeBuilders.h 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  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 tree builders.
  11. * \file OPC_TreeBuilders.h
  12. * \author Pierre Terdiman
  13. * \date March, 20, 2001
  14. */
  15. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  16. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  17. // Include Guard
  18. #ifndef __OPC_TREEBUILDERS_H__
  19. #define __OPC_TREEBUILDERS_H__
  20. //! Tree splitting rules
  21. enum SplittingRules
  22. {
  23. // Primitive split
  24. SPLIT_LARGEST_AXIS = (1<<0), //!< Split along the largest axis
  25. SPLIT_SPLATTER_POINTS = (1<<1), //!< Splatter primitive centers (QuickCD-style)
  26. SPLIT_BEST_AXIS = (1<<2), //!< Try largest axis, then second, then last
  27. SPLIT_BALANCED = (1<<3), //!< Try to keep a well-balanced tree
  28. SPLIT_FIFTY = (1<<4), //!< Arbitrary 50-50 split
  29. // Node split
  30. SPLIT_GEOM_CENTER = (1<<5), //!< Split at geometric center (else split in the middle)
  31. //
  32. SPLIT_FORCE_DWORD = 0x7fffffff
  33. };
  34. //! Simple wrapper around build-related settings [Opcode 1.3]
  35. struct OPCODE_API BuildSettings
  36. {
  37. inline_ BuildSettings() : mLimit(1), mRules(SPLIT_FORCE_DWORD) {}
  38. inline_ explicit BuildSettings(udword Rules) : mLimit(1), mRules(Rules) {}
  39. udword mLimit; //!< Limit number of primitives / node. If limit is 1, build a complete tree (2*N-1 nodes)
  40. udword mRules; //!< Building/Splitting rules (a combination of SplittingRules flags)
  41. };
  42. class OPCODE_API AABBTreeBuilder
  43. {
  44. public:
  45. //! Constructor
  46. AABBTreeBuilder() :
  47. mNbPrimitives(0),
  48. mNodeBase(null),
  49. mCount(0),
  50. mNbInvalidSplits(0) {}
  51. //! Destructor
  52. virtual ~AABBTreeBuilder() {}
  53. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  54. /**
  55. * Computes the AABB of a set of primitives.
  56. * \param primitives [in] list of indices of primitives
  57. * \param nb_prims [in] number of indices
  58. * \param global_box [out] global AABB enclosing the set of input primitives
  59. * \return true if success
  60. */
  61. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  62. virtual bool ComputeGlobalBox(const dTriIndex* primitives, udword nb_prims, AABB& global_box) const = 0;
  63. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  64. /**
  65. * Computes the splitting value along a given axis for a given primitive.
  66. * \param index [in] index of the primitive to split
  67. * \param axis [in] axis index (0,1,2)
  68. * \return splitting value
  69. */
  70. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  71. virtual float GetSplittingValue(udword index, udword axis) const = 0;
  72. virtual Point GetSplittingValues(udword index) const = 0;
  73. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  74. /**
  75. * Computes the splitting value along a given axis for a given node.
  76. * \param primitives [in] list of indices of primitives
  77. * \param nb_prims [in] number of indices
  78. * \param global_box [in] global AABB enclosing the set of input primitives
  79. * \param axis [in] axis index (0,1,2)
  80. * \return splitting value
  81. */
  82. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  83. virtual float GetSplittingValue(const dTriIndex* /*primitives*/, udword /*nb_prims*/, const AABB& global_box, udword axis) const
  84. {
  85. // Default split value = middle of the axis (using only the box)
  86. return global_box.GetCenter(axis);
  87. }
  88. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  89. /**
  90. * Validates node subdivision. This is called each time a node is considered for subdivision, during tree building.
  91. * \param primitives [in] list of indices of primitives
  92. * \param nb_prims [in] number of indices
  93. * \param global_box [in] global AABB enclosing the set of input primitives
  94. * \return TRUE if the node should be subdivised
  95. */
  96. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  97. virtual BOOL ValidateSubdivision(const dTriIndex* /*primitives*/, udword nb_prims, const AABB& /*global_box*/)
  98. {
  99. // Check the user-defined limit
  100. if(nb_prims<=mSettings.mLimit) return FALSE;
  101. return TRUE;
  102. }
  103. BuildSettings mSettings; //!< Splitting rules & split limit [Opcode 1.3]
  104. udword mNbPrimitives; //!< Total number of primitives.
  105. void* mNodeBase; //!< Address of node pool [Opcode 1.3]
  106. // Stats
  107. inline_ void SetCount(udword nb) { mCount=nb; }
  108. inline_ void IncreaseCount(udword nb) { mCount+=nb; }
  109. inline_ udword GetCount() const { return mCount; }
  110. inline_ void SetNbInvalidSplits(udword nb) { mNbInvalidSplits=nb; }
  111. inline_ void IncreaseNbInvalidSplits() { mNbInvalidSplits++; }
  112. inline_ udword GetNbInvalidSplits() const { return mNbInvalidSplits; }
  113. private:
  114. udword mCount; //!< Stats: number of nodes created
  115. udword mNbInvalidSplits; //!< Stats: number of invalid splits
  116. };
  117. class OPCODE_API AABBTreeOfVerticesBuilder : public AABBTreeBuilder
  118. {
  119. public:
  120. //! Constructor
  121. AABBTreeOfVerticesBuilder() : mVertexArray(null) {}
  122. //! Destructor
  123. virtual ~AABBTreeOfVerticesBuilder() {}
  124. override(AABBTreeBuilder) bool ComputeGlobalBox(const dTriIndex* primitives, udword nb_prims, AABB& global_box) const;
  125. override(AABBTreeBuilder) float GetSplittingValue(udword index, udword axis) const;
  126. override(AABBTreeBuilder) Point GetSplittingValues(udword index) const;
  127. override(AABBTreeBuilder) float GetSplittingValue(const dTriIndex* primitives, udword nb_prims, const AABB& global_box, udword axis) const;
  128. const Point* mVertexArray; //!< Shortcut to an app-controlled array of vertices.
  129. };
  130. class OPCODE_API AABBTreeOfAABBsBuilder : public AABBTreeBuilder
  131. {
  132. public:
  133. //! Constructor
  134. AABBTreeOfAABBsBuilder() : mAABBArray(null) {}
  135. //! Destructor
  136. virtual ~AABBTreeOfAABBsBuilder() {}
  137. override(AABBTreeBuilder) bool ComputeGlobalBox(const dTriIndex* primitives, udword nb_prims, AABB& global_box) const;
  138. override(AABBTreeBuilder) float GetSplittingValue(udword index, udword axis) const;
  139. override(AABBTreeBuilder) Point GetSplittingValues(udword index) const;
  140. const AABB* mAABBArray; //!< Shortcut to an app-controlled array of AABBs.
  141. };
  142. class OPCODE_API AABBTreeOfTrianglesBuilder : public AABBTreeBuilder
  143. {
  144. public:
  145. //! Constructor
  146. AABBTreeOfTrianglesBuilder() : mIMesh(null) {}
  147. //! Destructor
  148. virtual ~AABBTreeOfTrianglesBuilder() {}
  149. override(AABBTreeBuilder) bool ComputeGlobalBox(const dTriIndex* primitives, udword nb_prims, AABB& global_box) const;
  150. override(AABBTreeBuilder) float GetSplittingValue(udword index, udword axis) const;
  151. override(AABBTreeBuilder) float GetSplittingValue(const dTriIndex* primitives, udword nb_prims, const AABB& global_box, udword axis) const;
  152. override(AABBTreeBuilder) Point GetSplittingValues(udword index) const;
  153. const MeshInterface* mIMesh; //!< Shortcut to an app-controlled mesh interface
  154. };
  155. #endif // __OPC_TREEBUILDERS_H__