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

其他游戏

开发平台:

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_COLLIDE2_BROAD_PHASE_H
  9. #define HK_COLLIDE2_BROAD_PHASE_H
  10. #include <Common/Base/hkBase.h>
  11. #include <Common/Base/DebugUtil/MultiThreadCheck/hkMultiThreadCheck.h>
  12. #include <Common/Base/Types/Geometry/Aabb/hkAabb.h>
  13. class hkpBroadPhase;
  14. class hkpBroadPhaseHandle;
  15. class hkpBroadPhaseHandlePair;
  16. class hkAabb;
  17. class hkPrimitiveCastCallback;
  18. class hkpBroadPhaseCastCollector;
  19. hkpBroadPhase* HK_CALL hk3AxisSweep16CreateBroadPhase( const hkVector4& worldMin, const hkVector4& worldMax, int numMarkers );
  20. hkpBroadPhase* HK_CALL hk3AxisSweep32CreateBroadPhase( const hkVector4& worldMin, const hkVector4& worldMax, int numMarkers );
  21. //
  22. typedef char hkpBroadPhaseAabbCache;
  23. /// The job of the broadphase is to quickly find pairs of AABBs that are intersecting, and thus to identify
  24. /// pairs of objects that require narrowphase collision detection. Objects that can be
  25. /// processed by the broadphase must have an hkpBroadPhaseHandle, which is used as an id for each object by the broadphase. The broadphase actually keeps
  26. /// an internal pointer to each hkpBroadPhaseHandle, so do not forget this - for instance, do not copy handles.
  27. ///
  28. /// The 16bit broadphase:
  29. ///   - Supports up to 2^14 objects (including markers)
  30. ///   - Has an internal resolution of 15 bits.
  31. ///
  32. /// The 32bit broadphase:
  33. ///   - Supports up to 2^31 objects (including markers)
  34. ///   - Has an internal resolution of 31 bits.
  35. ///   - Is twice as slow, and uses twice as much memory as the 16bit version
  36. ///
  37. /// Use the following macro to enable the 32bit broadphase. Put it *before* world construction, in the same scope as the call to hkpWorld's constructor.
  38. /// You will need to #include the hkpBroadPhase.h header:
  39. /// code
  40. /// #include <hkinternal/collide/broadphase/hkpBroadPhase.h>
  41. /// ...
  42. /// hkpBroadPhase::Enable32BitBroadphase broadphaseHelper;
  43. /// hkpWorld* myWorld = new hkpWorld(worldCinfo);
  44. /// endcode
  45. class hkpBroadPhase: public hkReferencedObject
  46. {
  47. public:
  48. hkpBroadPhase();
  49. ~hkpBroadPhase();
  50. HK_DECLARE_CLASS_ALLOCATOR(HK_MEMORY_CLASS_BROAD_PHASE);
  51. enum BroadPhaseType
  52. {
  53. BROADPHASE_16BIT,
  54. BROADPHASE_32BIT
  55. };
  56. /// Returns the type of the broadphase. This can be either 16bit or 32bit.
  57. virtual BroadPhaseType getType() const = 0;
  58. /// Adds an object to the broadphase. The new overlapping pairs are reported in pairsOut.
  59. virtual void addObject( hkpBroadPhaseHandle* object, const hkAabbUint32& aabb, hkArray<hkpBroadPhaseHandlePair>& pairsOut  ) = 0;
  60. /// Adds an object to the broadphase. The new overlapping pairs are reported in pairsOut.
  61. virtual void addObject( hkpBroadPhaseHandle* object, const hkAabb& aabb, hkArray<hkpBroadPhaseHandlePair>& pairsOut  ) = 0;
  62. /// Adds a list of objects to the broadphase. The new overlapping pairs are reported in pairsOut.
  63. /// This is faster than repeatedly calling addObject, if you have a list of objects to add
  64. virtual void addObjectBatch( hkArray<hkpBroadPhaseHandle*>& addObjectList, hkArray< hkAabb >& addAabbList, hkArray<hkpBroadPhaseHandlePair>& newPairs ) = 0;
  65. /// Removes an object from the broadphase. The removed overlapping pairs are reported in pairsOut.
  66. virtual void removeObject( hkpBroadPhaseHandle* object, hkArray<hkpBroadPhaseHandlePair>& pairsOut ) = 0;
  67. /// Removes a list of objects from the broadphase. The removed overlapping pairs are reported in pairsOut.
  68. /// This is faster than repeatedly calling removeObject, if you have a list of objects to remove
  69. virtual void removeObjectBatch( hkArray<hkpBroadPhaseHandle*>& removeObjectList, hkArray<hkpBroadPhaseHandlePair>& delPairsOut ) = 0;
  70. /// Queries the total number of objects added to the broadphase.
  71. virtual int getNumObjects() const = 0;
  72. /// Changes the position of an object and reports the changes. New overlaps are reported in addedPairs, removed pairs are reported in removedPairs.
  73. /// Note that a pair can be in both lists.
  74. virtual void updateAabbs( hkpBroadPhaseHandle* objects[], const hkAabb* aabbs, int numObjects, hkArray<hkpBroadPhaseHandlePair>& addedPairs, hkArray<hkpBroadPhaseHandlePair>& removedPairs ) = 0;
  75. // The same as updateAabbs(), only working on hkAabbUint32s.
  76. virtual void updateAabbsUint32( hkpBroadPhaseHandle* objects[], const hkAabbUint32* aabbs, int numObjects, hkArray<hkpBroadPhaseHandlePair>& addedPairs, hkArray<hkpBroadPhaseHandlePair>& removedPairs ) = 0;
  77. /// Optimizes internal memory layout. This can speed up the broadphase by up to 20%.
  78. /// This should be done after all static objects and before all dynamics objects
  79. /// are added to the scene.
  80. virtual void defragment() = 0;
  81. /// Gets all AABBs (for debug purposes).
  82. virtual void getAllAabbs( hkArray<hkAabb>& allAabbs ) const = 0;
  83. /// Gets AABB from hkpBroadPhaseHandle
  84. virtual void getAabb(const hkpBroadPhaseHandle* object, hkAabb& aabb) const = 0;
  85. /// Gets the current extents of the entire broadphase (passed in construction, but may have later been updated via shiftBroadPhase)
  86. virtual void getExtents(hkVector4& worldMinOut, hkVector4& worldMaxOut) const = 0;
  87. /// Finds all intersections between the input object and the rest.
  88. virtual void querySingleAabb( const hkAabb& aabb, hkArray<hkpBroadPhaseHandlePair>& pairs_out) const = 0;
  89. /// Finds all intersection of an existing object and the rest
  90. virtual void reQuerySingleObject( const hkpBroadPhaseHandle* object, hkArray<hkpBroadPhaseHandlePair>& pairs_out) const = 0;
  91. /// check whether 2 given broadphase handle already overlap
  92. virtual bool areAabbsOverlapping( const hkpBroadPhaseHandle* bhA, const hkpBroadPhaseHandle* bhB ) const = 0;
  93. /// If you want to shift all objects in the entire world but without altering the broadphase extents, you need to call this
  94. /// function. It will simply correct all internally stored offset information by the shiftDistance.
  95. /// Motivation for this method:
  96. ///  If your world is very large and both our graphics and physics coordinate spaces are 
  97. /// single-precision, and if you stray far enough from the origin you'll get floating point errors.
  98. /// To prevent this you have to periodically shift your coordinate spaces when you detect we have moved too far.
  99. ///  To shift the coordinate space, you have to reposition all objects in the world, which you can do by calling
  100. /// hkpRigidBody::setPosition(). However this is pretty CPU intensive and can have same bad side effects (disabling
  101.     /// tims for fixed objects).
  102. ///  A better way is to silently reposition all objects:
  103. ///   - shift all world space information of all objects silently(= avoid calling callbacks) by accessing their hkpMotion directly
  104. ///   - update the broadphase to reflect these new positions by calling this method, hkpBroadPhase::shiftAllObjects()
  105. ///
  106. /// Important Usage Notes:
  107. ///     - The broadphase cannot shift by an arbitrary floating point value, it has to round the shiftDistance up or down.
  108. ///       The actual shift distance is reported using effectiveShiftDistanceOut
  109. ///     - This function reports all new collision pairs (especially pairs between objects and the broadphase border)
  110. ///       in the array newCollisionPairs. These are objects which 'left' the broadphase during the shift.
  111. ///     - Please use the hkutilities/collide/hkpBroadPhaseBorder utility to prevent objects touching the world
  112. ///       extents before the shift.
  113. ///     - An object might appear in more than one pair.
  114. ///     - This function does not work if markers are enabled
  115. virtual void shiftAllObjects( const hkVector4& shiftDistance, hkVector4& effectiveShiftDistanceOut, hkArray<hkpBroadPhaseHandlePair>& newCollisionPairs ) = 0;
  116. /// If you want to shift the broadphase extents without changing the world position of any objects, you need to call this function.
  117. /// It will modify the extents and then update the offset information.
  118. /// Note that this changes the current extents of the broadphase (in 'world' space) returned by hkpBroadPhase::getExtents().
  119. /// Same notes as shiftAllObjects apply, since the shift may cause objects to 'leave' the broadphase.
  120. /// Motivation for this method:
  121. ///  If your world is large (but not large enough to run into floating point errors, when straying far from the
  122. /// origin), you may wish to keep a smaller broadphase active which only encompasses a subset of the full game world,
  123. /// probably those objects that are 'near' the current player or area of interaction.
  124. /// Thus your broadphase can fit more tightly than one which is large enough to encompass the whole game area.
  125. virtual void shiftBroadPhase( const hkVector4& shiftDistance, hkVector4& effectiveShiftDistanceOut, hkArray<hkpBroadPhaseHandlePair>& newCollisionPairs ) = 0;
  126. // Returns the 32bit low & high offset values.
  127. virtual void getOffsetLowHigh32bit(hkVector4& offsetLow32bit, hkVector4& offsetHigh32bit) const = 0;
  128. /// Input structure
  129. struct hkpCastRayInput
  130. {
  131. HK_DECLARE_NONVIRTUAL_CLASS_ALLOCATOR( HK_MEMORY_CLASS_BROAD_PHASE, hkpBroadPhase::hkpCastRayInput );
  132. /// The 'from' position of multiple casts
  133. hkVector4 m_from;
  134. /// The number of casts you would like to make from the same m_from start position
  135. int       m_numCasts;
  136. /// Pointer to the first 'to' position
  137. const hkVector4* m_toBase;
  138. /// the byte difference between two consecutive 'to' positions, typically sizeof(hkVector4) = 16
  139. int   m_toStriding;
  140. /// An optional cache. Note: all rays should be within the aabb which was used to build the cache
  141. const hkpBroadPhaseAabbCache* m_aabbCacheInfo;
  142. hkpCastRayInput(): m_numCasts(1), m_toStriding( hkSizeOf(hkVector4)),m_aabbCacheInfo(HK_NULL){}
  143. };
  144. /// Queries the broadphase for overlapping AABBs along the ray 'from-to'.
  145. /// For each aabb the ray cast hits the collector passed in receives a callback.
  146.     /// Basically this cast allows for doing multiple casts starting from the same position.
  147.     /// For each input ray( from, to[x] ) the collector:
  148. ///      at memory address: (collectorBase+x*collectorStriding) is called.<br>
  149. /// E.g.
  150. ///  - by setting collectorStriding to 0, always the collector collectorBase is called. You can identify
  151.     ///    the input ray by the castIndex in the hkpBroadPhaseCastCollector::addBroadPhaseHandle.
  152.     ///  - Or if you have an array of MyCollector collectors[10] you set the collectorBase to &collectors[0] and
  153.     ///    the collectorStriding = hkSizeOf(MyCollector)
  154. virtual void castRay( const hkpCastRayInput& input, hkpBroadPhaseCastCollector* collectorBase, int collectorStriding) const = 0;
  155. /// Get the size for the axis cache
  156. virtual int getAabbCacheSize() const = 0;
  157. /// Build the aabb cache. This is an optimization for broadphase raycasts.
  158. /// The idea is that the aabb cache is actually a reduced broadphase, just storing
  159. /// objects inside the aabb. Therefore using this cache can speed up rayCasts significantly<br>
  160. /// To work properly you have to:
  161. ///  - Calc an aabb which encapsulates a set of raycasts. The smaller the aabb is the better.
  162.     ///    Sometimes it might make sense to sort the rays into groups and than build one cache
  163. ///    for each group.
  164. ///  - Allocate enough space to hold your cache (use getAabbCacheSize()). The cache size can be very
  165. ///    big, it's actually 12 bytes per object in the broadphase. This is a worst case situation,
  166. ///    however the cache size cannot be calculated easily in advance, so getAabbCacheSize always returns
  167. ///    this worst case number. The best is to use hkAllocateStack to get the memory (check for overflows
  168. ///    in your allocate stack memory, which could dramatically slow down the operations).
  169. ///  - call calcAabbCache with your aabb and your cache memory.
  170. ///  - Than you can call as many calls to castRay using these cache. As long as the rays are within the
  171. ///    aabb everything works well.
  172. /// Note:
  173. ///    The cache only represents a snapshot of the engine. As soon as something changes the broadphase
  174. ///    (object moving, getting added, etc) the cache is invalid. If an invalid cache is used the engine
  175. ///    can crash !!!!.
  176. virtual void calcAabbCache( const hkAabb& aabb, hkpBroadPhaseAabbCache* aabbCacheOut) const = 0;
  177. /// Build the AABB cache from a list of collidables. This is useful for creating a cache when
  178.     /// you already have an AABB Phantom or a list of object that you know you want to raycast against.
  179.     /// This runs much faster that computing the cache from an AABB, because it doesn't have to search
  180.     /// through the broadphase.
  181. virtual void calcAabbCache( const hkArray<class hkpCollidable*>& overlappingCollidables, hkpBroadPhaseAabbCache* aabbCacheOut) const = 0;
  182. /// This structure is used as the input to hkpBroadPhase::castAabb
  183. struct hkpCastAabbInput
  184. {
  185. HK_DECLARE_NONVIRTUAL_CLASS_ALLOCATOR( HK_MEMORY_CLASS_BROAD_PHASE, hkpBroadPhase::hkpCastAabbInput );
  186. /// The start of the aabb cast (in world space)
  187. hkVector4 m_from;
  188. /// To end of the aabb cast (in world space)
  189. hkVector4 m_to;
  190. /// The half extents of the aabb
  191. hkVector4 m_halfExtents;
  192. /// An optional cache. Note: all casts should completely be within the aabb which was used to build the cache
  193. const hkpBroadPhaseAabbCache* m_aabbCacheInfo;
  194. hkpCastAabbInput(): m_aabbCacheInfo(HK_NULL){}
  195. };
  196. /// Queries the broadphase for overlapping AABBs along the aabb cast as specified in the input
  197. /// For each aabb the aabbcast hits the collector passed in receives a callback
  198. virtual void castAabb( const hkpCastAabbInput& input, hkpBroadPhaseCastCollector& collector ) const = 0;
  199. /// Set the 32bit offset and scale values for the broadphase. The broadphase will calculate some more internal values from that.
  200. virtual void set32BitOffsetAndScale(const hkVector4& offsetLow, const hkVector4& offsetHigh, const hkVector4& scale) = 0;
  201. /// Turn on locking and multithreading checks
  202. void enableMultiThreading( int spinCountForCriticalSection);
  203. inline hkMultiThreadCheck& getMultiThreadCheck();
  204. inline const hkMultiThreadCheck& getMultiThreadCheck() const;
  205. /// Mark this class and all child classes for read only access for this thread
  206. HK_FORCE_INLINE void markForRead() const;
  207. /// Mark this class and all child classes for read write access for this thread
  208. HK_FORCE_INLINE void markForWrite();
  209. /// Undo markForRead
  210. HK_FORCE_INLINE void unmarkForRead() const;
  211. /// Undo markForWrite
  212. HK_FORCE_INLINE void unmarkForWrite();
  213. /// lock the broadphase
  214. HK_FORCE_INLINE void lock();
  215. /// unlock the broadphase
  216. HK_FORCE_INLINE void unlock();
  217. typedef hkpBroadPhase* (HK_CALL *createBroadPhaseFunc)( const hkVector4& worldMin, const hkVector4& worldMax, int numMarkers );
  218. static createBroadPhaseFunc m_defaultCreationFunction;
  219. protected:
  220. void lockImplementation();
  221. void unlockImplementation();
  222. protected:
  223. mutable hkMultiThreadCheck m_multiThreadCheck;
  224. class hkCriticalSection *m_criticalSection;
  225. public:
  226. class Enable32BitBroadphase
  227. {
  228. public:
  229. Enable32BitBroadphase() 
  230. m_originalCreateBroadphaseFunc = hkpBroadPhase::m_defaultCreationFunction; 
  231. hkpBroadPhase::m_defaultCreationFunction = hk3AxisSweep32CreateBroadPhase;
  232. }
  233. ~Enable32BitBroadphase()
  234. hkpBroadPhase::m_defaultCreationFunction = m_originalCreateBroadphaseFunc; 
  235. }
  236. public:
  237. createBroadPhaseFunc m_originalCreateBroadphaseFunc;
  238. private:
  239. HK_DECLARE_NONVIRTUAL_CLASS_ALLOCATOR( HK_MEMORY_CLASS_COLLIDE, hkpBroadPhase::Enable32BitBroadphase );
  240. };
  241. };
  242. // Use this help class to enable 32 bit broadphase. Put it *before* world construction, in the same scope as the call to hkpWorld's constructor.
  243. // You will need to #include this header
  244. // Example:
  245. // #include <hkinternal/collide/broadphase/hkpBroadPhase.h>
  246. // ...
  247. // hkpBroadPhase::Enable32BitBroadphase broadphaseHelper;
  248. // hkpWorld* myWorld = new hkpWorld(worldCinfo);
  249. #include <Physics/Internal/Collide/BroadPhase/hkpBroadPhase.inl>
  250. #endif // HK_COLLIDE2_BROAD_PHASE_H
  251. /*
  252. * Havok SDK - NO SOURCE PC DOWNLOAD, BUILD(#20090216)
  253. * Confidential Information of Havok.  (C) Copyright 1999-2009
  254. * Telekinesys Research Limited t/a Havok. All Rights Reserved. The Havok
  255. * Logo, and the Havok buzzsaw logo are trademarks of Havok.  Title, ownership
  256. * rights, and intellectual property rights in the Havok software remain in
  257. * Havok and/or its suppliers.
  258. * Use of this software for evaluation purposes is subject to and indicates
  259. * acceptance of the End User licence Agreement for this product. A copy of
  260. * the license is included with this software and is also available at www.havok.com/tryhavok.
  261. */