hkpGroupFilter.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_DYNAMICS2_GROUP_FILTER_H
  9. #define HK_DYNAMICS2_GROUP_FILTER_H
  10. #include <Physics/Collide/Filter/hkpCollisionFilter.h>
  11. extern const hkClass hkpGroupFilterClass;
  12. /// This is an example collision filter. It is open source and can be modified to produce a 
  13. /// filter which exactly matches your requirements.  However, the implementation of the collision
  14. /// filter can be a significant factor in performance of your physics. This filter is designed to
  15. /// allow custom filtering between bones in different ragdolls or other constrained systems in your world,
  16. /// by doing simple operations on two 32 bit numbers.  The collision detection pipeline is setup to produce
  17. /// these 32 bit numbers, called collision filter infos.  Using this filter (or one very like it) for all
  18. /// your filtering will give optimal cache performance, and we strongly recommend using this if possible.
  19. ///
  20. /// It inherits from hkpCollisionFilter, and so implements each of the 4 hkpCollisionFilter::isCollisionEnabled
  21. /// methods. For each method, it extracts two 32 bit values from the inputs (one representing each object to be 
  22. /// tested), and passes these values to a common filtering mechanism.
  23. ///
  24. /// We split the 32 bit value into a layer (5 bits), a system group (16 bits), a subsystem id (5 bits),
  25. /// and the id of another subsystem that we do not want to collide with (5 bits).  The filter allows the user
  26. /// to specify whether collisions are enabled or disabled between every pair of layers.
  27. ///
  28. /// The exact logic of the filter is as follows:
  29. ///
  30. /// If two entities share the same system group (except group 0) then:
  31. /// they collide if A.subSystemId != B.subSystemDontCollideWith and B.subSystemId != A.subSystemDontCollideWith.
  32. /// Otherwise:
  33. /// they collide if collisions between their layers are enabled (based on a 32*32 bitfield).
  34. ///
  35. /// Some things to keep in mind:
  36. ///
  37. ///     - Collisions between layer 0 and any other layer should not be disabled (by default all layers 
  38. ///       collide with all other layers, including themselves).  This is a policy decision for shape collection filtering. 
  39. ///   All shape collections are required to implement hkpShapeCollection::getCollisionFilterInfo for each child shape. 
  40. ///   By default this returns 0 (i.e. if no special child shape filter information is set).  
  41. ///   So if you disable layer 0 in the group filter and use this filter as a shape collection filter,
  42. ///   it will disable collisions with children of all default shape collections.
  43. /// - System group 0 is special in that if two objects of system group 0 are under consideration, their subystem id 
  44. ///       will not be considered.  Instead, only the layer information will be used.
  45. ///
  46. /// <br>
  47. /// The class provides helper methods for getting and setting these values. <br>
  48. /// <br>
  49. ///
  50. /// Examples:
  51. ///     -   Keyframed objects should not collide with static geometry. Therefore 
  52. ///         we can put all static geometry into one layer and all the keyframed object into
  53. ///         another layer. Then we disable the collision between these layers.
  54. /// -   All elements of a ragdoll should collide with each other, except those that are connected by 
  55. ///         a constraint. In this case we assign all bodies of the ragdoll to the same system group. Also we assign
  56. /// a unique subSystemId for each body in the ragdoll. Then we set subSystemDontCollideWith
  57. /// to the id of the parent rigidbody (assuming you see the ragdoll as a hierarchy of bodies
  58. ///         and constraints, see the hkaRagdollUtils for details)
  59. /// <br>
  60. /// Note:<br>
  61. ///     If two shape collections A and B collide, the following will happen
  62. ///        - the collidable of A and B will be checked
  63. ///        - then, one of the collections will be expanded, say in our case A will be replaced by 
  64. ///          its children A# = { A0, A1, ... An }
  65. ///        - Each collisionInfo of child A# (see hkpShapeCollection::getCollisionFilterInfo()) will
  66. ///          be tested against hkpCollidable::getCollisionFilterInfo() of B
  67. ///        - then for each A# B will be expanded into its children B# = {B0, B1, ...Bn}
  68. ///        - Each collisionInfo of child A# (see hkpShapeCollection::getCollisionFilterInfo()) will be tested
  69. ///          against collisionInfo of child B# 
  70. ///    Interestingly, B was never tested against A#. That means if you have a complex shape collection hierarchy,
  71. ///          you think about your filters very carefully.
  72. ///  
  73. class hkpGroupFilter : public hkpCollisionFilter
  74. {
  75. // we make the size of this class 256 bytes, so that the spu simulator always finds a valid allocated memory piece
  76. public:
  77.     /// A collision filter info value which tells the group filter to take the collision filter info from the root collidable.
  78.     /// Usually this will be used for the hkpExtendedMeshShape::m_defaultCollisionFilterInfo.
  79. enum { USE_COLLIDABLE_FILTER_INFO = 0xffffffff };
  80. public:
  81. HK_DECLARE_REFLECTION();
  82. /// Constructor, by default enables all collisions between all layers
  83. hkpGroupFilter();
  84. ~hkpGroupFilter();
  85. /// Enable the collision between layer layerA and layerB
  86. void enableCollisionsBetween(int layerA, int layerB);
  87. /// Disables collisions between the layers A and B
  88. void disableCollisionsBetween(int layerA, int layerB);
  89. /// Enables collisions between the specified layers
  90. /// layerBitsA and layerBitsB are bitfields, one bit for every layer.
  91. /// e.g. to enable collisions between one layer and all other layers,
  92. /// call enableCollisionsUsingBitfield( 1<< myLayer, 0xfffffffe)
  93. void enableCollisionsUsingBitfield(hkUint32 layerBitsA, hkUint32 layerBitsB);
  94. /// Disables collisions between the specified collision layers. 
  95. /// See enableCollisionsUsingBitfield for how to use bitfields
  96. void disableCollisionsUsingBitfield(hkUint32 layerBitsA, hkUint32 layerBitsB);
  97. /// Combine the layer and systemGroup information into one 32 bit integer.
  98. /// This resulting collision filter info can be used in entities and hkEntityCinfo
  99. static inline hkUint32 HK_CALL calcFilterInfo( int layer, int systemGroup = 0, int subSystemId = 0, int subSystemDontCollideWith = 0);
  100. /// Extract the layer from a given filterInfo
  101. static inline int HK_CALL getLayerFromFilterInfo( hkUint32 filterInfo );
  102. /// Returns the filter info provided with the layer replaced by newLayer
  103. static inline int HK_CALL setLayer( hkUint32 filterInfo, int newLayer );
  104. /// Extract the system group from a given filterInfo
  105. static inline int HK_CALL getSystemGroupFromFilterInfo( hkUint32 filterInfo );
  106. /// Extract the subsystem id from a given filterInfo
  107. static inline int HK_CALL getSubSystemIdFromFilterInfo( hkUint32 filterInfo );
  108. /// Extract the subSystemDontCollideWith from a given filterInfo
  109. static inline int HK_CALL getSubSystemDontCollideWithFromFilterInfo( hkUint32 filterInfo );
  110. /// Creates a new unique identifier for system groups (maximum 65k)
  111. inline int getNewSystemGroup();
  112. /// Checks two collidables. This is the implementation of the hkpCollidableCollidableFilter::isCollisionEnabled method.
  113. /// This extracts a 32 bit value from each hkpCollidable, using the getCollisionFilterInfo() method.
  114. virtual hkBool isCollisionEnabled( const hkpCollidable& a, const hkpCollidable& b ) const;
  115. /// This is an implementation of hkpShapeCollectionFilter::isCollisionEnabled()
  116. /// This gets the 32 bit collision info for hkpCdBody "b" by calling hkpShapeContainer::getCollisionFilterInfo( bKey ).
  117. /// For body "a" we do one of two things, depending on whether a has a parent or not.
  118. /// 1. If "a" does not have a parent, we know that it is not a child shape of a shape collection, and so we simply call
  119. /// hkpCollidable::getCollisionFilterInfo() on its root collidable (hkpCdBody::getRootCollidable).
  120. /// 2. If "a" does have a parent, we know that it _may_ have a hkpShapeCollection in an ancestor hkpCdBody. We then travel up the hkpCdBody
  121. /// hierarchy until we reach the first hkpCdBody being a child of a hkpShapeCollection or hkpBvTreeShape (or we reach the root collidable and act as in point 1.). We then call
  122. /// hkpShapeCollection::getCollisionFilterInfo() using the found shape collection and the found child hkpCdBody.
  123. virtual hkBool isCollisionEnabled( const hkpCollisionInput& input, const hkpCdBody& a, const hkpCdBody& b, const HK_SHAPE_CONTAINER& bContainer, hkpShapeKey bKey  ) const;
  124. // hkpShapeCollectionFilter interface forwarding
  125. virtual hkBool isCollisionEnabled( const hkpCollisionInput& input, const hkpCdBody& collectionBodyA, const hkpCdBody& collectionBodyB, const HK_SHAPE_CONTAINER& containerShapeA, const HK_SHAPE_CONTAINER& containerShapeB, hkpShapeKey keyA, hkpShapeKey keyB ) const;
  126. /// This is an implementation of hkpRayShapeCollectionFilter::isCollisionEnabled()
  127. /// This gets the 32 bit collision info for the ray by getting hkpShapeRayCastInput::m_filterInfo (for aInput)
  128. /// To get the 32 bit collision info for the shape, we call hkpShapeCollection::getCollisionFilterInfo() for bCollection, using bKey.
  129. virtual hkBool isCollisionEnabled( const hkpShapeRayCastInput& aInput, const hkpShape& bShape, const HK_SHAPE_CONTAINER& bContainer, hkpShapeKey bKey ) const;
  130. /// This is an implementation of hkpRayCollidableFilter::isCollisionEnabled()
  131. /// This gets the 32 bit collision info for the ray by getting hkpWorldRayCastInput::m_filterInfo (for inputA)
  132. /// To get the 32 bit collision info for the collidableB, we simply call hkpCollidable::getCollisionFilterInfo() collidableB
  133. virtual hkBool isCollisionEnabled( const hkpWorldRayCastInput& inputA, const hkpCollidable& collidableB ) const;
  134. /// The actual filter implementation between two hkUint32 values. All the other isCollisionEnabled functions call this method.
  135. /// Returns true if the objects are enabled to collide, based on their collision groups.
  136. hkBool isCollisionEnabled(hkUint32 infoA, hkUint32 infoB) const;
  137. public:
  138. int m_nextFreeSystemGroup;
  139. hkUint32 m_collisionLookupTable[32];
  140. hkVector4 m_pad256[4];
  141. public:
  142. hkpGroupFilter( class hkFinishLoadedObjectFlag flag ) : hkpCollisionFilter(flag)
  143. {
  144. if( flag.m_finishing )
  145. {
  146. m_type = HK_FILTER_GROUP;
  147. }
  148. }
  149. virtual int dummyUnused() { return 0; }
  150. };
  151. #include <Physics/Collide/Filter/Group/hkpGroupFilter.inl>
  152. #endif // HK_DYNAMICS2_GROUP_FILTER_H
  153. /*
  154. * Havok SDK - NO SOURCE PC DOWNLOAD, BUILD(#20090216)
  155. * Confidential Information of Havok.  (C) Copyright 1999-2009
  156. * Telekinesys Research Limited t/a Havok. All Rights Reserved. The Havok
  157. * Logo, and the Havok buzzsaw logo are trademarks of Havok.  Title, ownership
  158. * rights, and intellectual property rights in the Havok software remain in
  159. * Havok and/or its suppliers.
  160. * Use of this software for evaluation purposes is subject to and indicates
  161. * acceptance of the End User licence Agreement for this product. A copy of
  162. * the license is included with this software and is also available at www.havok.com/tryhavok.
  163. */