OPC_TreeBuilders.h 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  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. udword mLimit; //!< Limit number of primitives / node. If limit is 1, build a complete tree (2*N-1 nodes)
  39. udword mRules; //!< Building/Splitting rules (a combination of SplittingRules flags)
  40. };
  41. class OPCODE_API AABBTreeBuilder
  42. {
  43. public:
  44. //! Constructor
  45. AABBTreeBuilder() :
  46. mNbPrimitives(0),
  47. mNodeBase(null),
  48. mCount(0),
  49. mNbInvalidSplits(0) {}
  50. //! Destructor
  51. virtual ~AABBTreeBuilder() {}
  52. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  53. /**
  54. * Computes the AABB of a set of primitives.
  55. * \param primitives [in] list of indices of primitives
  56. * \param nb_prims [in] number of indices
  57. * \param global_box [out] global AABB enclosing the set of input primitives
  58. * \return true if success
  59. */
  60. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  61. virtual bool ComputeGlobalBox(const udword* primitives, udword nb_prims, AABB& global_box) const = 0;
  62. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  63. /**
  64. * Computes the splitting value along a given axis for a given primitive.
  65. * \param index [in] index of the primitive to split
  66. * \param axis [in] axis index (0,1,2)
  67. * \return splitting value
  68. */
  69. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  70. virtual float GetSplittingValue(udword index, udword axis) const = 0;
  71. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  72. /**
  73. * Computes the splitting value along a given axis for a given node.
  74. * \param primitives [in] list of indices of primitives
  75. * \param nb_prims [in] number of indices
  76. * \param global_box [in] global AABB enclosing the set of input primitives
  77. * \param axis [in] axis index (0,1,2)
  78. * \return splitting value
  79. */
  80. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  81. virtual float GetSplittingValue(const udword* primitives, udword nb_prims, const AABB& global_box, udword axis) const
  82. {
  83. // Default split value = middle of the axis (using only the box)
  84. return global_box.GetCenter(axis);
  85. }
  86. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  87. /**
  88. * Validates node subdivision. This is called each time a node is considered for subdivision, during tree building.
  89. * \param primitives [in] list of indices of primitives
  90. * \param nb_prims [in] number of indices
  91. * \param global_box [in] global AABB enclosing the set of input primitives
  92. * \return TRUE if the node should be subdivised
  93. */
  94. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  95. virtual BOOL ValidateSubdivision(const udword* primitives, udword nb_prims, const AABB& global_box)
  96. {
  97. // Check the user-defined limit
  98. if(nb_prims<=mSettings.mLimit) return FALSE;
  99. return TRUE;
  100. }
  101. BuildSettings mSettings; //!< Splitting rules & split limit [Opcode 1.3]
  102. udword mNbPrimitives; //!< Total number of primitives.
  103. void* mNodeBase; //!< Address of node pool [Opcode 1.3]
  104. // Stats
  105. inline_ void SetCount(udword nb) { mCount=nb; }
  106. inline_ void IncreaseCount(udword nb) { mCount+=nb; }
  107. inline_ udword GetCount() const { return mCount; }
  108. inline_ void SetNbInvalidSplits(udword nb) { mNbInvalidSplits=nb; }
  109. inline_ void IncreaseNbInvalidSplits() { mNbInvalidSplits++; }
  110. inline_ udword GetNbInvalidSplits() const { return mNbInvalidSplits; }
  111. private:
  112. udword mCount; //!< Stats: number of nodes created
  113. udword mNbInvalidSplits; //!< Stats: number of invalid splits
  114. };
  115. class OPCODE_API AABBTreeOfVerticesBuilder : public AABBTreeBuilder
  116. {
  117. public:
  118. //! Constructor
  119. AABBTreeOfVerticesBuilder() : mVertexArray(null) {}
  120. //! Destructor
  121. virtual ~AABBTreeOfVerticesBuilder() {}
  122. override(AABBTreeBuilder) bool ComputeGlobalBox(const udword* primitives, udword nb_prims, AABB& global_box) const;
  123. override(AABBTreeBuilder) float GetSplittingValue(udword index, udword axis) const;
  124. override(AABBTreeBuilder) float GetSplittingValue(const udword* primitives, udword nb_prims, const AABB& global_box, udword axis) const;
  125. const Point* mVertexArray; //!< Shortcut to an app-controlled array of vertices.
  126. };
  127. class OPCODE_API AABBTreeOfAABBsBuilder : public AABBTreeBuilder
  128. {
  129. public:
  130. //! Constructor
  131. AABBTreeOfAABBsBuilder() : mAABBArray(null) {}
  132. //! Destructor
  133. virtual ~AABBTreeOfAABBsBuilder() {}
  134. override(AABBTreeBuilder) bool ComputeGlobalBox(const udword* primitives, udword nb_prims, AABB& global_box) const;
  135. override(AABBTreeBuilder) float GetSplittingValue(udword index, udword axis) const;
  136. const AABB* mAABBArray; //!< Shortcut to an app-controlled array of AABBs.
  137. };
  138. class OPCODE_API AABBTreeOfTrianglesBuilder : public AABBTreeBuilder
  139. {
  140. public:
  141. //! Constructor
  142. AABBTreeOfTrianglesBuilder() : mIMesh(null) {}
  143. //! Destructor
  144. virtual ~AABBTreeOfTrianglesBuilder() {}
  145. override(AABBTreeBuilder) bool ComputeGlobalBox(const udword* primitives, udword nb_prims, AABB& global_box) const;
  146. override(AABBTreeBuilder) float GetSplittingValue(udword index, udword axis) const;
  147. override(AABBTreeBuilder) float GetSplittingValue(const udword* primitives, udword nb_prims, const AABB& global_box, udword axis) const;
  148. const MeshInterface* mIMesh; //!< Shortcut to an app-controlled mesh interface
  149. };
  150. #endif // __OPC_TREEBUILDERS_H__