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

其他游戏

开发平台:

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_DYNAMICS2_COLLISION_LISTENER_H
  9. #define HK_DYNAMICS2_COLLISION_LISTENER_H
  10. #include <Common/Base/Types/Physics/ContactPoint/hkContactPoint.h>
  11. #include <Physics/Dynamics/Collide/hkpDynamicsContactMgr.h>
  12. #include <Physics/ConstraintSolver/Constraint/Contact/hkpContactPointProperties.h>
  13. #include <Physics/Collide/Agent/ContactMgr/hkpContactMgr.h>
  14. #include <Physics/Collide/Agent/hkpProcessCollisionOutput.h>
  15. #include <Physics/Dynamics/Collide/hkpSimpleConstraintContactMgr.h>
  16. class hkpCollidable;
  17. struct hkpCollisionInput;
  18. struct hkpProcessCollisionOutput;
  19. class hkpEntity;
  20. class hkpDynamicsContactMgr;
  21. /// Accept or reject contact points.
  22. enum hkpContactPointAccept
  23. {
  24. /// Accept.
  25. HK_CONTACT_POINT_ACCEPT = 0,
  26. /// Reject.
  27. HK_CONTACT_POINT_REJECT = 1
  28. };
  29. #if defined(HK_PLATFORM_PS3_SPU) 
  30. template <> struct hkSpuStorage<hkpContactPointAccept> { typedef vec_int4 StorageType; typedef int PromoteType; };
  31. //HK_COMPILE_TIME_ASSERT( sizeof(hkpContactPointAccept) == 4 );
  32. #endif
  33. struct hkpToiPointAddedEvent;
  34. struct hkpManifoldPointAddedEvent;
  35. struct hkpSimpleContactConstraintAtom;
  36. /// This collision event is passed to a hkpCollisionListener's contactPointAddedCallback() just when
  37. /// a new contact point is created by the engine
  38. struct hkpContactPointAddedEvent
  39. {
  40. HK_DECLARE_NONVIRTUAL_CLASS_ALLOCATOR( HK_MEMORY_CLASS_DYNAMICS, hkpContactPointAddedEvent );
  41. /// This is the hkpCdBody that was used (for entity A) to generate the contact point. If the entity's collision 
  42. /// detection representation is a single shape (for example one hkpConvexVerticesShape) this will actually be
  43. /// a reference to the entity's hkpCollidable. However if the entity has a more complicated shape hierarchy
  44. /// (such as a hkpMeshShape) then this will be a stack allocated hkpCdBody object, which may also reference a
  45. /// stack allocated hkpShape. Do not store a pointer to this hkpCdBody, or the shape it references for this
  46. /// reason, as the objects may be temporary. You can call getRootCollidable() on the hkpCdBody, which will
  47. /// return a reference to the (permanent) heap created hkpCollidable owned by the entity.
  48. /// The shape this points to is always the "leaf" shape, e.g. the actual triangle
  49. /// that created the contact point.
  50. HK_PAD_ON_SPU(const hkpCdBody*) m_bodyA;
  51. /// This is the hkpCdBody that was used (for entity B) to generate the contact point. See the comments for m_bodyA
  52. /// for further details.
  53. HK_PAD_ON_SPU(const hkpCdBody*) m_bodyB;
  54. enum Type { TYPE_TOI, TYPE_MANIFOLD };
  55. const hkEnum<Type, hkInt32> m_type;
  56. /// The entity this collision listener was added to
  57. /// (or HK_NULL if the collision listener was added to the world)
  58. HK_PAD_ON_SPU(hkpEntity*) m_callbackFiredFrom;
  59. /// The contact point. This cannot be changed by the user - it needs to be done in process callback.
  60. HK_PAD_ON_SPU(const hkContactPoint*) m_contactPoint;
  61. /// Optional information about the feature type of that contact.
  62. /// This provides detailed information about the type of contact, e.g.
  63. /// point-point, point-edge .., edge-edge or point-triangle.
  64. /// Only valid if the gsk algorithm is used. However if hkpShapeCollection::m_disableWelding
  65. /// is set to false (default), this pointer might be HK_NULL.
  66. HK_PAD_ON_SPU(const hkpGskCache*) m_gskCache;
  67. /// The contact point properties, including friction and restitution. 
  68. /// This is changeable (and is the best place to change it).
  69. /// This is set to HK_NULL if you're using hkpReportContactMgr.
  70. HK_PAD_ON_SPU(hkpContactPointProperties*)  m_contactPointProperties; 
  71. /// gets the body index to be used by getNumExtendedUserDatas and getExtendedUserData
  72. inline int getEntityIndex( const hkpEntity* entity ) const;
  73. /// gets the contact atom.
  74. inline const hkpSimpleContactConstraintAtom* getAtom() const;
  75. /// Gets number of extended user datas for that entity.
  76. inline int getNumExtendedUserDatas(const hkpEntity* entity) const;
  77. /// Gets all user datas into the 'datasOut' buffer. The buffer's size must match the size of extended datas.
  78. inline void getExtendedUserDatas(const hkpEntity* entity, hkpContactPointProperties::UserData* datasOut, int numDatas) const;
  79. /// Writes all data from 'datasIn' buffer into the extended user data block. The buffer's size must match the size of extended datas.
  80. inline void setExtendedUserDatas(const hkpEntity* entity, hkpContactPointProperties::UserData* datasIn, int numDatas) const;
  81. /// The relative velocity of the objects at the point of contact projected onto the collision normal.<br>
  82. /// Note: this value is negative
  83. /// You can change its value, but it only has an effect for toi contact points
  84. HK_PAD_ON_SPU(hkReal) m_projectedVelocity;        
  85. /// Whether the contact point will actually be added to the constraint solver or not. 
  86. /// By default this is HK_CONTACT_POINT_ACCEPT. If you set this to HK_CONTACT_POINT_REJECT
  87. /// the contact point will be removed and a remove callback will be triggered immediately.
  88. HK_PAD_ON_SPU(hkpContactPointAccept) m_status;
  89. inline hkBool isToi() const;
  90. /// if the underlying contact point is a toi contact point, this will give you a safe access
  91. /// to the additional properties
  92. inline hkpToiPointAddedEvent& asToiEvent();
  93. /// if the underlying contact point is a normal collision point, this will give you a safe access
  94. /// to the additional properties
  95. inline hkpManifoldPointAddedEvent& asManifoldEvent();
  96. //
  97. // internal section
  98. //
  99. // The contact manager.
  100. HK_PAD_ON_SPU(hkpDynamicsContactMgr*) m_internalContactMgr;
  101. HK_PAD_ON_SPU(const struct hkpProcessCollisionInput*) m_collisionInput;
  102. HK_PAD_ON_SPU(struct hkpProcessCollisionOutput*) m_collisionOutput;
  103. // Creates a new hkpContactPointAddedEvent.
  104. inline hkpContactPointAddedEvent( hkpDynamicsContactMgr* contactMgr,
  105. const hkpProcessCollisionInput* m_collisionInput,
  106. hkpProcessCollisionOutput* m_collisionOutput,
  107. const hkpCdBody* a,    const hkpCdBody* b, 
  108. hkContactPoint* cp,   const hkpGskCache* gskCache, hkpContactPointProperties* cpp, 
  109. hkReal projectedVelocity, Type pointType );
  110. };
  111. /// additional properties, in case hkpContactPointAddedEvent is a toi event
  112. struct hkpToiPointAddedEvent: public hkpContactPointAddedEvent
  113. {
  114. HK_DECLARE_NONVIRTUAL_CLASS_ALLOCATOR( HK_MEMORY_CLASS_DYNAMICS, hkpToiPointAddedEvent );
  115. /// The time of impact, you can modify this value
  116. HK_PAD_ON_SPU(hkTime) m_toi;
  117. // Creates a new hkpContactPointAddedEvent.
  118. inline hkpToiPointAddedEvent( hkpDynamicsContactMgr* contactMgr,
  119. const hkpProcessCollisionInput* collisionInput,
  120. hkpProcessCollisionOutput* collisionOutput,
  121. const hkpCdBody* a,    const hkpCdBody* b, 
  122. hkContactPoint* cp,   const hkpGskCache* gskCache, hkpContactPointProperties* cpp, 
  123. hkTime toi, hkReal projectedVelocity );
  124. };
  125. /// Additional properties if the added event was fired by the normal discrete collision detection
  126. struct hkpManifoldPointAddedEvent : public hkpContactPointAddedEvent
  127. {
  128. HK_DECLARE_NONVIRTUAL_CLASS_ALLOCATOR( HK_MEMORY_CLASS_DYNAMICS, hkpManifoldPointAddedEvent );
  129. /// Identifies the contact point in the contact mgr
  130. HK_PAD_ON_SPU(hkContactPointId) m_contactPointId;
  131. /// This lets you specify the delay to the next process callback.
  132. /// This is by default initialized with 0
  133. mutable HK_PAD_ON_SPU(hkUint16) m_nextProcessCallbackDelay;
  134. inline hkpManifoldPointAddedEvent( hkContactPointId contactPointId, 
  135. hkpDynamicsContactMgr* contactMgr,
  136. const hkpProcessCollisionInput* collisionInput,
  137. hkpProcessCollisionOutput* collisionOutput,
  138. const hkpCdBody* a,    const hkpCdBody* b, 
  139. hkContactPoint* cp,   const hkpGskCache* gskCache, hkpContactPointProperties* cpp, 
  140. hkReal projectedVelocity);
  141. };
  142. /// This event is fired once for every new contact point exactly when
  143. /// its information is used for the very first time.
  144. /// You should use this:
  145. ///   - to trigger high quality game events
  146. /// Warning: Due to the way this function is implemented, you cannot use it to
  147. /// apply forces or impulses at rigid bodies. The reason is that
  148. /// this callback is fired by the solver and at this stage the rigid
  149. /// body velocities are copied to internal solver data already.
  150. struct hkpContactPointConfirmedEvent
  151. {
  152. HK_DECLARE_NONVIRTUAL_CLASS_ALLOCATOR( HK_MEMORY_CLASS_DYNAMICS, hkpContactPointConfirmedEvent );
  153. /// The first entity's hkpCollidable. Note that this is not the "leaf" hkpCdBody (as is the case for the hkpContactPointAddedEvent).
  154. /// This is because these events are fired after collision detection has been performed, and the hkpCdBody objects needed
  155. /// to create the contact points may no longer exist.
  156. const hkpCollidable* m_collidableA;
  157. /// The second entity's hkpCollidable. Note that this is not the "leaf" hkpCdBody (as is the case for the hkpContactPointAddedEvent).
  158. /// This is because these events are fired after collision detection has been performed, and the hkpCdBody objects needed
  159. /// to create the contact points may no longer exist.
  160. const hkpCollidable* m_collidableB;
  161. /// The entity this collision listener was added to
  162. /// (or HK_NULL if the collision listener was added to the world)
  163. hkpEntity* m_callbackFiredFrom; 
  164. /// returns true if the contact point is a toi contact point
  165. inline hkBool isToi() const;
  166. //
  167. // Changeable attributes:
  168. //
  169. /// The contact point. 
  170. hkContactPoint* m_contactPoint;
  171. /// The contact point properties, including friction and restitution.
  172. /// This is set to HK_NULL if you're using hkpReportContactMgr.
  173. hkpContactPointProperties*  m_contactPointProperties;
  174. /// gets the body index to be used by getNumExtendedUserDatas and getExtendedUserData
  175. inline int getEntityIndex( const hkpEntity* entity ) const;
  176. /// gets the contact atom.
  177. inline const hkpSimpleContactConstraintAtom* getAtom() const;
  178. /// Gets number of extended user datas for that entity.
  179. inline int getNumExtendedUserDatas(const hkpEntity* entity) const;
  180. /// Gets all user datas into the 'datasOut' buffer. The buffer's size must match the size of extended datas.
  181. inline void getExtendedUserDatas(const hkpEntity* entity, hkpContactPointProperties::UserData* datasOut, int numDatas) const;
  182. /// Writes all data from 'datasIn' buffer into the extended user data block. The buffer's size must match the size of extended datas.
  183. inline void setExtendedUserDatas(const hkpEntity* entity, hkpContactPointProperties::UserData* datasIn, int numDatas) const;
  184. /// Specifies how much the contact normal should be rotated in toi events. This is only relevant for Toi points.
  185. /// When set to non-zero value, this parameter reduces number of toi collisions, artificially adding separating velocity to colliding bodies.
  186. /// The higher the relative velocity of the bodies in the contact's tangent plane, the higher the extra impulse. 
  187. /// Note: This causes serious artifacts for collisions of e.g. a car riding along a wall and then crashing/sliding into the wall. Similarly,
  188. ///       it may cause artifacts, when a car's chassis collides with landscape. It is advised to zero this parameter in a callback in such cases.
  189. hkReal m_rotateNormal;
  190. /// The relative velocity of the objects at the point of contact projected onto the collision normal.
  191. /// Changing this value influences the restitution. If this event is a toi event, you should
  192. /// only decrease its value, otherwise objects can sink in at the expense of tons of extra CPU.
  193. hkReal m_projectedVelocity;     
  194. const hkEnum<hkpContactPointAddedEvent::Type, hkInt32> m_type;
  195. /// Gets the contact point id of this point (or -1 for TOIs)
  196. hkContactPointId getContactPointId() const;
  197. /// Gets the DynamicsContactMgr: Warning: This function only works if you are not implementing your own
  198. /// hkpDynamicsContactMgr
  199. // 
  200. const class hkpDynamicsContactMgr* getContactMgr() const;
  201. // Internal section
  202. // 
  203. /// Pointer to the contact constraint data that triggered the callback. This can be used to access the contact manager and 
  204. /// extract the id of the contact point. This is only valid for in-manifold contact points, and is set to null for Toi contact points.
  205. const class hkpSimpleContactConstraintData* m_contactData;
  206. // Creates a new hkpContactPointAddedEvent.
  207. inline hkpContactPointConfirmedEvent( hkpContactPointAddedEvent::Type type,
  208. const hkpCollidable* a, const hkpCollidable* b, 
  209. const hkpSimpleContactConstraintData* data,
  210. hkContactPoint* cp, hkpContactPointProperties* cpp, 
  211. hkReal rotateNormal,
  212. hkReal projectedVelocity);
  213. };
  214. /// This collision event is passed to a hkpCollisionListener's contactPointRemovedCallback() before a contact point is removed.
  215. struct hkpContactPointRemovedEvent
  216. {
  217. HK_DECLARE_NONVIRTUAL_CLASS_ALLOCATOR( HK_MEMORY_CLASS_DYNAMICS, hkpContactPointRemovedEvent );
  218. /// gets the body index to be used by getNumExtendedUserDatas and getExtendedUserData
  219. inline int getEntityIndex( const hkpEntity* entity ) const;
  220. /// gets the contact atom.
  221. inline const hkpSimpleContactConstraintAtom* getAtom() const;
  222. /// Gets number of extended user datas for that entity.
  223. inline int getNumExtendedUserDatas(const hkpEntity* entity) const;
  224. /// Gets all user datas into the 'datasOut' buffer. The buffer's size must match the size of extended datas.
  225. inline void getExtendedUserDatas(const hkpEntity* entity, hkpContactPointProperties::UserData* datasOut, int numDatas) const;
  226. /// Writes all data from 'datasIn' buffer into the extended user data block. The buffer's size must match the size of extended datas.
  227. inline void setExtendedUserDatas(const hkpEntity* entity, hkpContactPointProperties::UserData* datasIn, int numDatas) const;
  228. /// Identifies the contact point. Is set to HK_INVALID_CONTACT_POINT if this contact point was a toi
  229. HK_PAD_ON_SPU(hkContactPointId) m_contactPointId;
  230. /// The properties of the contact point. 
  231. HK_PAD_ON_SPU(hkpContactPointProperties*) m_contactPointProperties;
  232. /// The first entity.
  233. HK_PAD_ON_SPU(hkpEntity*) m_entityA;
  234. /// The second entity.
  235. HK_PAD_ON_SPU(hkpEntity*) m_entityB;
  236. /// The entity this collision listener was added to
  237. /// (or HK_NULL if the collision listener was added to the world)
  238. HK_PAD_ON_SPU(hkpEntity*) m_callbackFiredFrom;
  239. /// returns true if the contact point is a toi contact point
  240. inline hkBool isToi();
  241. //
  242. // Internal section
  243. //
  244. // Creates a new hkpContactPointRemovedEvent.
  245. inline hkpContactPointRemovedEvent(  hkContactPointId contactPointId, hkpDynamicsContactMgr* contactMgr, class hkpConstraintOwner* constraintOwner, hkpContactPointProperties* prop, hkpEntity* a, hkpEntity* b);
  246. // The contact manager.
  247. HK_PAD_ON_SPU(hkpDynamicsContactMgr*) m_internalContactMgr;
  248. HK_PAD_ON_SPU(hkpConstraintOwner*) m_constraintOwner;
  249. };
  250. /// This collision event is passed to a hkpCollisionListener's contactProcessCallback() just after
  251. /// all collision agents between a pair of bodies have been executed.
  252. struct hkpContactProcessEvent
  253. {
  254. HK_DECLARE_NONVIRTUAL_CLASS_ALLOCATOR( HK_MEMORY_CLASS_DYNAMICS, hkpContactProcessEvent );
  255. const hkpContactProcessEvent& operator=(const hkpContactProcessEvent&);
  256. /// gets the body index to be used by getNumExtendedUserDatas and getExtendedUserData
  257. inline int getEntityIndex( const hkpEntity* entity ) const;
  258. /// gets the contact atom.
  259. inline const hkpSimpleContactConstraintAtom* getAtom() const;
  260. /// Gets number of extended user datas for that entity.
  261. inline int getNumExtendedUserDatas(const hkpEntity* entity) const;
  262. /// Gets all user datas into the 'datasOut' buffer. The buffer's size must match the size of extended datas.
  263. inline void getExtendedUserDatas(int contactPointIndex, const hkpEntity* entity, hkpContactPointProperties::UserData* datasOut, int numDatas) const;
  264. /// Writes all data from 'datasIn' buffer into the extended user data block. The buffer's size must match the size of extended datas.
  265. inline void setExtendedUserDatas(int contactPointIndex, const hkpEntity* entity, hkpContactPointProperties::UserData* datasIn, int numDatas) const;
  266. /// Gets all user datas into the 'datasOut' buffer. The buffer's size must match the size of extended datas.
  267. inline void getToiExtendedUserDatas(const hkpEntity* entity, hkpContactPointProperties::UserData* datasOut, int numDatas) const;
  268. /// Writes all data from 'datasIn' buffer into the extended user data block. The buffer's size must match the size of extended datas.
  269. inline void setToiExtendedUserDatas(const hkpEntity* entity, hkpContactPointProperties::UserData* datasIn, int numDatas) const;
  270. /// The first entity's hkpCollidable. Note that this is not the "leaf" hkpCdBody (as is the case for the hkpContactPointAddedEvent).
  271. /// This is because these events are fired after collision detection has been performed, and the hkpCdBody objects needed
  272. /// to create the contact points may no longer exist.
  273. HK_PAD_ON_SPU(const hkpCollidable*) m_collidableA;
  274. /// The second entity's hkpCollidable. Note that this is not the "leaf" hkpCdBody (as is the case for the hkpContactPointAddedEvent).
  275. /// This is because these events are fired after collision detection has been performed, and the hkpCdBody objects needed
  276. /// to create the contact points may no longer exist.
  277. HK_PAD_ON_SPU(const hkpCollidable*) m_collidableB;
  278. /// The entity this collision listener was added to
  279. /// (or HK_NULL if the collision listener was added to the world)
  280. HK_PAD_ON_SPU(hkpEntity*) m_callbackFiredFrom;
  281. /// All contact points including the toi contact point
  282. HK_PAD_ON_SPU(hkpProcessCollisionData*) m_collisionData;
  283.     
  284. /// An array of additional properties, like friction, one pointer for each contact point in
  285. /// the m_collisionData->m_contactPoints array
  286. /// This is only available on ppu. On Spu use m_internalContactMgr->getContactPointProperty().
  287. hkpContactPointProperties* m_contactPointProperties[ HK_MAX_CONTACT_POINT ];
  288. //
  289. // Internal section
  290. //
  291. // Access to the contact manager
  292. HK_PAD_ON_SPU(hkpDynamicsContactMgr*) m_internalContactMgr;
  293. /// Creates a new hkpContactProcessEvent.
  294. inline hkpContactProcessEvent(  hkpDynamicsContactMgr* contactMgr, const hkpCollidable* a, const hkpCollidable* b, hkpProcessCollisionData* cr);
  295. };
  296. /// The base interface for listeners that respond to collision events.
  297. /// There are two types of contacts:
  298. ///   - Normal contacts, which are persistent between two objects and are part of the contact manifold
  299. ///   - Toi contacts, which are just created if two objects hit with high velocity and the interaction
  300. ///     of both objects is flagged as continuous.
  301. class hkpCollisionListener
  302. {
  303. public:
  304. ///  Called after a contact point is created. This contact point is still a potential one.
  305. ///  You can use this callback to:
  306. ///  - Override the friction and restitution values in the contact point's hkContactPointMaterial.
  307. ///  - Reject the contact point.
  308. /// In this call you get access to the full information of the new contact point.
  309. virtual void contactPointAddedCallback( hkpContactPointAddedEvent& event) = 0;
  310. /// Called when a new contact point is used for the very first time.
  311. /// At this stage the contact point no longer is a potential one.
  312. /// So this callback can be used to trigger high quality game events.
  313. /// This callback is fired:
  314. ///    - If it is a normal (manifold) contact: by the constraint solver
  315. ///    - If it is a toi contact: by the toi handler in hkpContinuousSimulation
  316. virtual void contactPointConfirmedCallback( hkpContactPointConfirmedEvent& event) = 0;
  317. /// Called before a contact point gets removed.
  318. virtual void contactPointRemovedCallback( hkpContactPointRemovedEvent& event ) = 0;
  319. /// Called just after all collision detection between 2 rigid bodies has been executed.
  320. /// NB: Callback frequency is related to hkpEntity::m_processContactCallbackDelay. 
  321. /// This callback allows you to change any information in the result. 
  322. /// You can and should use this callback to:
  323. ///    - do custom welding
  324. ///    - trigger sound effects, especially scratching and rolling
  325. virtual void contactProcessCallback( hkpContactProcessEvent& event ) {}
  326. /// Virtual destructor for derived objects
  327. virtual ~hkpCollisionListener() {}
  328. };
  329. #include <Physics/Dynamics/Collide/hkpCollisionListener.inl>
  330. #endif // HK_DYNAMICS2_COLLISION_LISTENER_H
  331. /*
  332. * Havok SDK - NO SOURCE PC DOWNLOAD, BUILD(#20090216)
  333. * Confidential Information of Havok.  (C) Copyright 1999-2009
  334. * Telekinesys Research Limited t/a Havok. All Rights Reserved. The Havok
  335. * Logo, and the Havok buzzsaw logo are trademarks of Havok.  Title, ownership
  336. * rights, and intellectual property rights in the Havok software remain in
  337. * Havok and/or its suppliers.
  338. * Use of this software for evaluation purposes is subject to and indicates
  339. * acceptance of the End User licence Agreement for this product. A copy of
  340. * the license is included with this software and is also available at www.havok.com/tryhavok.
  341. */