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

其他游戏

开发平台:

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_SPU_COLLISION_CALLBACK_UTIL_H
  9. #define HK_SPU_COLLISION_CALLBACK_UTIL_H
  10. #include <Common/Base/Spu/Dma/Utils/hkSpuDmaUtils.h>
  11. #include <Physics/Dynamics/Collide/hkpCollisionListener.h>
  12. class hkpBvTreeShape;
  13. /// This is an utility class, which helps to export callback information from the spu to the ppu. This is just an example how to do this.
  14. /// Please copy the files for ppu and spu and create your own version. 
  15. /// For future Havok physics versions this class is subject to change.
  16. ///
  17. /// The SPU is severely memory-limited, so to be able to properly handle collision events (without any restrictions) as soon as the collision
  18. /// detection is running on the SPU we need to forward those events to the PPU. This utility handles the forwarding of the events. Simply
  19. /// create an instance of this utility using the static createSpuCollisionCallbackUtil() function. Pass in the total amount of memory you want
  20. /// the utility to have. Note that this includes the buffer for the events, so don't make it too small. You then have to attach this utility
  21. /// to each entity you want the events forwarded for. During collision detection this utility will now collect all 3 types of collision events
  22. /// (added, processed and removed), repack them, add them to the utility's event queue and write this event data back to the PPU. On the PPU
  23. /// you now only have to call fireCallbacks() with a pointer to your user-implemented callback functions. This will fire the appropriate
  24. /// callback function for each collision event and pass in the corresponding event data. Make sure to reset the event queue on your last call
  25. /// to fireCallbacks() (in case you should call it several times) or otherwise the queue will fill up pretty fast, preventing any further events
  26. /// to be forwarded from SPU to PPU.
  27. HK_CLASSALIGN16(class) hkSpuCollisionCallbackUtil : public hkReferencedObject
  28. {
  29. public:
  30. /// register its spu functions
  31. static void HK_CALL registerSpuFunctions();
  32. public:
  33. /// Event base class.
  34. ///
  35. /// This is the base class for all 3 collision events. It has a type that can be used
  36. /// to identify the actual event. It also holds the total size for the event (used for
  37. /// advancing to the next event in the queue) and PPU pointers to the colliding entities.
  38. HK_ALIGN16(struct) Event
  39. {
  40. HK_DECLARE_NONVIRTUAL_CLASS_ALLOCATOR( HK_MEMORY_CLASS_DYNAMICS, hkSpuCollisionCallbackUtil::Event );
  41. public:
  42. enum EventType
  43. {
  44. CONTACT_POINT_ADDED,
  45. CONTACT_POINT_PROCESS,
  46. CONTACT_POINT_REMOVED
  47. };
  48. public:
  49. /// Safely get the contact mgr, returns zero if the collision agent has been removed in the meantime
  50. hkpDynamicsContactMgr* getContactManager();
  51. /// Gets the next event in the list
  52. /// If there isn't an entry after this one, will return rubbish
  53. /// Use the getTerminator method to give you the first invalid entry
  54. Event* getNext() { return hkAddByteOffset(this, m_size); }
  55. hkUint16 m_size;
  56. hkEnum<EventType, hkUint16> m_type;
  57. hkpEntity* m_entityA;
  58. hkpEntity* m_entityB;
  59. hkpDynamicsContactMgr* m_contactMgr;
  60. };
  61. /// This callback event is fired whenever a new contact point is added.
  62. ///
  63. /// It stores the contact point information.
  64. struct ContactPointAddedEvent : public hkSpuCollisionCallbackUtil::Event
  65. {
  66. HK_DECLARE_NONVIRTUAL_CLASS_ALLOCATOR( HK_MEMORY_CLASS_DYNAMICS, hkSpuCollisionCallbackUtil::ContactPointAddedEvent );
  67. hkpShapeKey m_shapeKeyA;
  68. hkpShapeKey m_shapeKeyB;
  69. hkContactPointId m_contactId;
  70. hkReal m_projectedVelocity;
  71. hkContactPoint m_contactPoint;
  72. };
  73. /// This callback event is fired for a colliding pair of entities during collision detection.
  74. ///
  75. /// It holds all existing contact points between the two entities. This array of contact points
  76. /// is dynamically expanded and the total number of contact points is stored separately.
  77. /// Note: if you want to add custom members to this event make sure to only add them BEFORE
  78. ///       m_contactPoints or otherwise you risk them to be overwritten!
  79. struct ContactPointProcessEvent : public hkSpuCollisionCallbackUtil::Event
  80. {
  81. HK_DECLARE_NONVIRTUAL_CLASS_ALLOCATOR( HK_MEMORY_CLASS_DYNAMICS, hkSpuCollisionCallbackUtil::ContactPointProcessEvent );
  82. struct ContactPoint: public hkContactPoint
  83. {
  84. HK_DECLARE_NONVIRTUAL_CLASS_ALLOCATOR( HK_MEMORY_CLASS_MATH, hkSpuCollisionCallbackUtil::ContactPointProcessEvent::ContactPoint );
  85. HK_FORCE_INLINE hkUint32 getContactPointId() { return m_position.getInt24W(); }
  86. };
  87. public:
  88. int m_numContactPoints;
  89. //
  90. // Add any additional custom members here... 
  91. // Note: never append them after m_contactPoints!
  92. // Keep in mind that m_contactPoints is 16byte aligned!
  93. //
  94. // this array is dynamically allocated when creating the utility
  95. ContactPoint m_contactPoints[1];
  96. };
  97. /// This callback event is fired whenever an existing contact point is removed.
  98. ///
  99. /// It stores the contact point's id.
  100. struct ContactPointRemovedEvent : public hkSpuCollisionCallbackUtil::Event
  101. {
  102. HK_DECLARE_NONVIRTUAL_CLASS_ALLOCATOR( HK_MEMORY_CLASS_DYNAMICS, hkSpuCollisionCallbackUtil::ContactPointRemovedEvent );
  103. hkContactPointId m_contactPointId;
  104. };
  105. /// This structure serves as a kind of interface to user-implemented callback functions.
  106. ///
  107. /// Create a dedicated object of this type (or derive an existing one from it) and implement
  108. /// the callback functions to your likings. Each function is passed its individual event
  109. /// structure holding all relevant data.
  110. struct Callbacks
  111. {
  112. public:
  113. virtual ~Callbacks() {}
  114. virtual void contactPointAddedCallbackFromSpu  (ContactPointAddedEvent*   event) {}
  115. virtual void contactPointProcessCallbackFromSpu(ContactPointProcessEvent* event) {}
  116. virtual void contactPointRemovedCallbackFromSpu(ContactPointRemovedEvent* event) {}
  117. };
  118. /// Use these flags to decide whether a call to fireCallbacks() should reset the event queue or not.
  119. ///
  120. /// Resetting the event queue will delete all existing events. So if you want to process these events a second time
  121. /// (e.g. first for some visualization, then for actual processing) you can call fireCallbacks() twice, once without
  122. /// resetting the queue, the second time with resetting the queue.
  123. /// Note: you should make sure to reset the queue once you are done with it or otherwise it will fill up pretty fast
  124. ///       and no further events will be able to be forwarded from SPU to PPU
  125. enum ResetEventQueue
  126. {
  127. RESET_EVENT_QUEUE,
  128. DO_NOT_RESET_EVENT_QUEUE,
  129. };
  130. /// Empties out the list, resetting it
  131. void reset() { m_nextFreeEvent = m_events; }
  132. /// Get the first in the list
  133. Event* getFirst() { return m_events; }
  134. /// Get one past the end element in the list. An event pointer must be less then this to be valid
  135. Event* getTerminator();
  136. public:
  137. /// Call this function to create a new collision callback utility.
  138. ///
  139. /// The totalSizeOfUtil parameter specifies the total(!) size of the utility, not the event buffer size. The event
  140. /// buffer size is 16 bytes less.
  141. // This is done to have more control over the amount of memory that might be wasted when allocating a buffer size that
  142. // is exactly the same size as one pool memory page. In such a case the whole utility would be just 16 bytes too large
  143. // and would allocate one whole additional memory page just for 16 bytes.
  144. static hkSpuCollisionCallbackUtil* HK_CALL createSpuCollisionCallbackUtil(int totalSizeOfUtil);
  145. /// Call this function to fire your user-implemented event callback functions.
  146. ///
  147. /// See ResetEventQueue for some information on the resetFlag parameter.
  148. /// See Callbacks fr some information on the user-implemented callback functions.
  149. void fireCallbacks(hkpWorld* world, Callbacks* m_callbacks, ResetEventQueue resetFlag = RESET_EVENT_QUEUE);
  150. // internal functions
  151. static void contactPointAddedEvent  (hkpEntity* entityA, hkpEntity* entityB, hkpContactPointAddedEvent&   event);
  152. static void contactPointProcessEvent(hkpEntity* entityA, hkpEntity* entityB, hkpContactProcessEvent&      event);
  153. static void contactPointRemovedEvent(hkpEntity* entityA, hkpEntity* entityB, hkpContactPointRemovedEvent& event);
  154. static hkBool shapeContainerIsCollisionEnabled(const hkpProcessCollisionInput* input, const hkpCdBody* bodyA, const hkpCdBody* bodyB, const HK_SHAPE_CONTAINER* shapeCollectionB, hkpShapeKey shapeKeyB);
  155. static hkBool shapeContainer2IsCollisionEnabled(const hkpProcessCollisionInput* input, const hkpCdBody* bodyA, const hkpCdBody* bodyB, const HK_SHAPE_CONTAINER* shapeCollectionA, const HK_SHAPE_CONTAINER* shapeCollectionB, hkpShapeKey shapeKeyA, hkpShapeKey shapeKeyB);
  156. static int numShapeKeyHitsLimitBrached( const hkpProcessCollisionInput* input, 
  157. const hkpCdBody* bodyA, const hkpCdBody* bodyB, 
  158. const hkpBvTreeShape* bvTreeShapeB, hkAabb& aabb,
  159. hkpShapeKey* shapeKeysInOut,
  160. int shapeKeysCapacity);
  161. protected:
  162. static void writeBackEvent(hkpEntity* entity, const Event& event);
  163. public:
  164. // sizeof(hkReferencedObject) : 8 bytes
  165. hkUint32 m_capacity; // number of 16byte blocks, i.e. actual size in bytes = m_capacity * 16
  166. void* m_nextFreeEvent;
  167. // this array is dynamically allocated when creating the utility
  168. Event m_events[1];
  169. };
  170. #endif // HK_SPU_COLLISION_CALLBACK_UTIL_H
  171. /*
  172. * Havok SDK - NO SOURCE PC DOWNLOAD, BUILD(#20090216)
  173. * Confidential Information of Havok.  (C) Copyright 1999-2009
  174. * Telekinesys Research Limited t/a Havok. All Rights Reserved. The Havok
  175. * Logo, and the Havok buzzsaw logo are trademarks of Havok.  Title, ownership
  176. * rights, and intellectual property rights in the Havok software remain in
  177. * Havok and/or its suppliers.
  178. * Use of this software for evaluation purposes is subject to and indicates
  179. * acceptance of the End User licence Agreement for this product. A copy of
  180. * the license is included with this software and is also available at www.havok.com/tryhavok.
  181. */