hkKdTree.h
上传用户:yisoukefu
上传日期:2020-08-09
资源大小:39506k
文件大小:8k
源码类别:

其他游戏

开发平台:

Visual C++

  1. /* 
  2.  * 
  3.  * Confidential Information of Telekinesys Research Limited (t/a Havok). Not for disclosure or distribution without Havok's
  4.  * prior written consent. This software contains code, techniques and know-how which is confidential and proprietary to Havok.
  5.  * Level 2 and Level 3 source code contains trade secrets of Havok. Havok Software (C) Copyright 1999-2009 Telekinesys Research Limited t/a Havok. All Rights Reserved. Use of this software is subject to the terms of an end user license agreement.
  6.  * 
  7.  */
  8. #ifndef HK_KDTREE_H
  9. #define HK_KDTREE_H
  10. #include <Common/Base/hkBase.h>
  11. #include <Common/Base/Types/Geometry/Aabb/hkAabb.h>
  12. typedef hkUlong hkPrimitiveId;
  13. typedef hkUint16 hkSplitType;
  14. #if HK_POINTER_SIZE == 8
  15. typedef hkUint32 hkHalfPointer;
  16. #else
  17. typedef hkUint16 hkHalfPointer;
  18. #endif
  19. const hkSplitType HK_KD_NODE_MIN_SPLIT = hkSplitType(0);
  20. const hkSplitType HK_KD_NODE_MAX_SPLIT = hkSplitType(-1);
  21. class hkKdTreeNode
  22. {
  23. public:
  24. HK_DECLARE_NONVIRTUAL_CLASS_ALLOCATOR( HK_MEMORY_CLASS_DEMO, hkKdTreeNode );
  25. HK_FORCE_INLINE hkKdTreeNode( );
  26. HK_FORCE_INLINE ~hkKdTreeNode() {}
  27. /*
  28.  *  Split Data
  29.  */
  30. HK_FORCE_INLINE int getSplitAxis() const;
  31. HK_FORCE_INLINE hkSplitType getSplitMin() const;
  32. HK_FORCE_INLINE hkSplitType getSplitMax() const;
  33. HK_FORCE_INLINE void setSplit(int axis, hkSplitType splitMin, hkSplitType splitMax);
  34. /*
  35.  *  Leaf Data
  36.  */
  37. HK_FORCE_INLINE hkPrimitiveId getPrimitiveId() const;
  38. HK_FORCE_INLINE void setPrimitiveId(hkPrimitiveId id);
  39. HK_FORCE_INLINE hkBool isLeaf() const;
  40. HK_FORCE_INLINE hkBool isEmptyLeaf() const;
  41. HK_FORCE_INLINE hkBool32 isLeaf32() const;
  42. HK_FORCE_INLINE hkBool32 isEmptyLeaf32() const;
  43. HK_FORCE_INLINE void setEmpty(); 
  44. /*
  45.  *  Traversal
  46.  */
  47. HK_FORCE_INLINE hkKdTreeNode* getLeft() const;
  48. HK_FORCE_INLINE hkKdTreeNode* getRight() const;
  49. HK_FORCE_INLINE hkUint32 getLeftOffset() const;
  50. HK_FORCE_INLINE hkUint32 getRightOffset() const;
  51. HK_FORCE_INLINE hkBool isLeft() const;
  52. HK_FORCE_INLINE hkBool isRight() const;
  53. HK_FORCE_INLINE hkKdTreeNode* getSibling() const;
  54. HK_FORCE_INLINE void setLeftAndRightByteOffset( hkUlong offset );
  55. HK_FORCE_INLINE void adjustLeftAndRightByteOffset( int offsetDelta );
  56. /*
  57.  * Bound data
  58.  */
  59. HK_FORCE_INLINE void setNumPrimitivesInLeaf( hkUint32 offset );
  60. HK_FORCE_INLINE hkUint32 getNumPrimitivesInLeaf() const;
  61. HK_FORCE_INLINE void setAabbBound(const hkSplitType bound[4]);  
  62. private:
  63. struct Leaf
  64. {
  65. // Type    Bit 31
  66. // PrimIdx Bit 0..30
  67. HK_ALIGN(hkInt32 m_type_primId, 8);
  68. hkUint32 m_numPrimitives;
  69. };
  70. struct Node
  71. {
  72. // Type   Bit 31
  73. // Offset Bit 30..3 
  74. // Unused Bit 2
  75. // Split Axis Bit 1..0
  76. hkInt32 m_type_left_axis;
  77. hkSplitType m_splitMin;
  78. hkSplitType m_splitMax;
  79. };
  80. union {
  81. Leaf m_leaf;
  82. Node m_node;
  83. hkSplitType m_bound[4]; // The min or max of an embedded AABB
  84. } m_data; // 8 Bytes per node 
  85. };
  86. // <ce.todo> Move ProjectedEntry out of BuildInput namespace
  87. namespace hkKdTreeBuildInput
  88. {
  89. union PointerHalfUnion
  90. {
  91. hkUlong m_ulong;
  92. hkHalfPointer m_halfPointer[2];
  93. };
  94. struct ProjectedEntry
  95. {
  96. HK_ALIGN16(hkSplitType m_min[3]);
  97. hkHalfPointer m_primIdHigh;
  98. hkSplitType m_max[3];
  99. hkHalfPointer m_primIdLow;
  100. #if (HK_POINTER_SIZE == 4)
  101. void operator=(const ProjectedEntry& other)
  102. {
  103. *(hkQuadReal*)this = *(const hkQuadReal*)&other;
  104. }
  105. #endif
  106. HK_FORCE_INLINE hkPrimitiveId getPrimitiveId() const
  107. {
  108. PointerHalfUnion u;
  109. u.m_halfPointer[0] = m_primIdHigh;
  110. u.m_halfPointer[1] = m_primIdLow;
  111. return u.m_ulong;
  112. }
  113. HK_FORCE_INLINE void setPrimitiveId(hkPrimitiveId primId)
  114. {
  115. PointerHalfUnion u;
  116. u.m_ulong = primId;
  117. m_primIdHigh = u.m_halfPointer[0];
  118. m_primIdLow  = u.m_halfPointer[1];
  119. }
  120. HK_FORCE_INLINE void invalidate()
  121. {
  122. m_min[0] = m_min[1] = m_min[2] = HK_KD_NODE_MAX_SPLIT;
  123. m_max[0] = m_max[1] = m_max[2] = HK_KD_NODE_MIN_SPLIT;
  124. }
  125. HK_FORCE_INLINE void reset()
  126. {
  127. m_min[0] = m_min[1] = m_min[2] = HK_KD_NODE_MIN_SPLIT;
  128. m_max[0] = m_max[1] = m_max[2] = HK_KD_NODE_MAX_SPLIT;
  129. }
  130. };
  131. }
  132. struct hkKdTreeCinfo
  133. {
  134. enum EmptyNodeAllocation
  135. {
  136. NO_EMPTY_NODES = 0,
  137. FEW_EMTPY_NODES = 8,
  138. STANDARD_EMPTY_NODES = 2,
  139. LOTS_OF_EMPTY_NODES = 1
  140. };
  141. int m_numPrimitives;
  142. hkEnum<EmptyNodeAllocation, hkUint8> m_emptyNodeAllocation;
  143. hkBool m_isDistributedBuild;
  144. hkAabb m_aabb;
  145. hkKdTreeCinfo();
  146. };
  147. class hkKdTree
  148. {
  149. public:
  150. HK_DECLARE_NONVIRTUAL_CLASS_ALLOCATOR(HK_MEMORY_CLASS_DEMO, hkKdTree);
  151. hkKdTree(int prealloc); // deprecated
  152. hkKdTree(const hkKdTreeCinfo& cinfo);
  153. ~hkKdTree();
  154. hkArray<hkKdTreeNode>& getNodes() { return m_nodes; }
  155. const hkArray<hkKdTreeNode>& getNodes() const { return m_nodes; }
  156. hkKdTreeNode* getRoot() { return m_nodes.begin(); }
  157. const hkKdTreeNode* getRoot() const { return m_nodes.begin(); }
  158. HK_FORCE_INLINE int getNumPrimitives() const { return m_numPrimitives; }
  159. HK_FORCE_INLINE int getNumReservedEmptyNodes() const { return m_numReservedEmptyNodes; }
  160. HK_FORCE_INLINE int getTotalNumNodes() const { return m_numReservedEmptyNodes + m_numRegularNodes; }
  161. HK_FORCE_INLINE hkAabb& getAabb() { return m_aabb; }
  162. HK_FORCE_INLINE const hkAabb& getAabb() const { return m_aabb; }
  163. HK_FORCE_INLINE hkKdTreeBuildInput::ProjectedEntry* getProjectedEntries() { return m_projectedEntries.begin(); }
  164. HK_FORCE_INLINE const hkKdTreeBuildInput::ProjectedEntry* getProjectedEntries() const { return m_projectedEntries.begin(); }
  165. enum
  166. {
  167. DISTRIBUTED_BUILD_SUBTREE_OFFSET = 8,
  168. };
  169. // Summary of memory constraints and assumptions
  170. // Fast builds:
  171. // 1) The smallest tree (1 primitive) needs 2 nodes - 1 root, and one for 1 padding
  172. // 2) For larger trees, for N primitives, we have N leaf nodes, N-1 tree nodes, and 1 extra node at the root.
  173. // This doesn't count reserved empty nodes, and the actual count can be less because of writing multiple primitives per leaf.
  174. static HK_FORCE_INLINE int HK_CALL getSizeForFastBuild(int numPrimitives) { return 2 * numPrimitives; }
  175. // Summary of memory constraints and assumptions
  176. // Distributed builds:
  177. // 1) We set up 4 sub-trees, so need to be able to handle the worst-case distribution
  178. // 2) The size of each subtree is hkKdTree::getSizeForFastBuild(numPrimsInSubTree)
  179. // 3) The single-threaded version of tree building starts the subtrees at node 8 (since it needs to reassemble the tree later
  180. static HK_FORCE_INLINE int HK_CALL getSizeForDistributedBuild(int numPrimitives);
  181. static HK_FORCE_INLINE int HK_CALL getNumExtraNodesForFastBuild(int numPrimitives, hkKdTreeCinfo::EmptyNodeAllocation ena);
  182. /// Prevent a node from being "hit" by raycasts
  183. void invalidatePrimitive(hkPrimitiveId id);
  184. HK_ALIGN16(hkArray<hkKdTreeNode> m_nodes);
  185. int m_maxDepth;
  186. protected:
  187. void initNodeArray(int numNodes);
  188. int m_numPrimitives;
  189. int m_numRegularNodes;
  190. int m_numReservedEmptyNodes;
  191. hkArray<struct hkKdTreeBuildInput::ProjectedEntry> m_projectedEntries;
  192. hkAabb m_aabb;
  193. HK_FORCE_INLINE void setNumPrimitives(int n);
  194. };
  195. #include <Common/Internal/KdTree/hkKdTree.inl>
  196. #endif // HK_KDTREE_H
  197. /*
  198. * Havok SDK - NO SOURCE PC DOWNLOAD, BUILD(#20090216)
  199. * Confidential Information of Havok.  (C) Copyright 1999-2009
  200. * Telekinesys Research Limited t/a Havok. All Rights Reserved. The Havok
  201. * Logo, and the Havok buzzsaw logo are trademarks of Havok.  Title, ownership
  202. * rights, and intellectual property rights in the Havok software remain in
  203. * Havok and/or its suppliers.
  204. * Use of this software for evaluation purposes is subject to and indicates
  205. * acceptance of the End User licence Agreement for this product. A copy of
  206. * the license is included with this software and is also available at www.havok.com/tryhavok.
  207. */