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

其他游戏

开发平台:

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_INERTIA_TENSOR_COMPUTER_H
  9. #define HK_DYNAMICS2_INERTIA_TENSOR_COMPUTER_H
  10. #include <Common/Base/hkBase.h>
  11. struct hkGeometry;
  12. class hkpShape;
  13. class hkpRigidBodyCinfo;
  14. class hkpRigidBody;
  15. class hkpConstraintInstance;
  16. /// This structure holds the "mass and volume" properties of an object, and is filled in by each of the
  17. /// hkpInertiaTensorComputer methods.
  18. /// Volume is not strictly a mass property, but may be useful to help determine the mass required
  19. /// to achieve a given density for an object.
  20. struct hkpMassProperties
  21. {
  22. HK_DECLARE_NONVIRTUAL_CLASS_ALLOCATOR(HK_MEMORY_CLASS_INERTIA, hkpMassProperties);
  23. HK_DECLARE_REFLECTION();
  24. /// Initialize (to zero data).
  25. hkpMassProperties() : m_volume(0.0f), m_mass(0.0f) { m_centerOfMass.setZero4(); m_inertiaTensor.setZero(); }
  26. hkpMassProperties(class hkFinishLoadedObjectFlag flag) {}
  27. void scaleToDensity( hkReal density );
  28. void scaleToMass( hkReal newMass );
  29. /// The volume of an object 
  30. hkReal m_volume;
  31. /// The mass of an object.
  32. hkReal m_mass;
  33. /// The center of mass.
  34. hkVector4 m_centerOfMass;
  35. /// The inertia tensor.
  36. hkMatrix3 m_inertiaTensor;
  37. };
  38. /// This structure is used by the hkpInertiaTensorComputer to help construct mass properties of "compound" objects.
  39. struct hkpMassElement
  40. {
  41. HK_DECLARE_NONVIRTUAL_CLASS_ALLOCATOR(HK_MEMORY_CLASS_INERTIA, hkpMassElement);
  42. /// Initialize (to zero data).
  43. HK_FORCE_INLINE hkpMassElement(){ m_transform.setIdentity(); }
  44. /// Initialize given properties and transform.
  45. HK_FORCE_INLINE hkpMassElement(const hkpMassProperties& properties,const hkTransform& transform) :
  46. m_properties(properties), m_transform(transform)
  47. {
  48. }
  49. /// All mass properties for this element.
  50. hkpMassProperties m_properties;
  51. /// A transform for this element (usually with respect to body Local space)
  52. /// ie an ElementToLocal transform.
  53. hkTransform m_transform;
  54. };
  55. /// A class to compute the inertia tensor, center of mass and volume of various classes of objects.
  56. class hkpInertiaTensorComputer
  57. {
  58. public:
  59. ///////////////////////////////////////
  60. // Explicit surface types calculations
  61. ///////////////////////////////////////
  62. /// Creates mass properties given a sphere, considered as a volume of uniform density.
  63. /// Returns HK_FAILURE on failure (radius, mass invalid), otherwise returns HK_SUCCESS.
  64. static hkResult HK_CALL computeSphereVolumeMassProperties( hkReal radius, hkReal mass, hkpMassProperties& result);
  65. /// Creates mass properties given box halfextents, considered as a volume of uniform density.
  66. /// Returns HK_FAILURE on failure (halfExtents, mass invalid), otherwise returns HK_SUCCESS.
  67. static hkResult HK_CALL computeBoxVolumeMassProperties(const hkVector4& halfExtents, hkReal mass, hkpMassProperties& result);
  68. /// Creates mass properties given a capsule considered as a volume of uniform density.
  69. /// The capsule is specified by the start and end points of its axis (excluding radius), and a radius.
  70. /// The radius MUST be greater than zero. The height (length of axis) may be zero. 
  71. /// Returns HK_FAILURE on failure (radius, mass invalid), otherwise returns HK_SUCCESS.
  72. static hkResult HK_CALL computeCapsuleVolumeMassProperties( const hkVector4& startAxis, const hkVector4& endAxis, hkReal radius, hkReal mass, hkpMassProperties& result);
  73. /// Creates mass properties given a sphere hull, assumed to have a given thickness (measured "inwards") of uniform density.
  74. /// The thickness MUST be greater than zero and less than radius.
  75. /// Returns HK_FAILURE on failure (radius, surfaceThickness, mass invalid), otherwise returns HK_SUCCESS.
  76. static hkResult HK_CALL computeSphereSurfaceMassProperties( hkReal radius, hkReal mass, hkReal surfaceThickness, hkpMassProperties& result);
  77. /// Creates mass properties given box hull halfextents, assumed to have a given thickness (measured "inwards") of uniform density
  78. /// The thickness MUST be greater than zero and less than min of half-extents.
  79. /// Returns HK_FAILURE on failure (halfExtents, surfaceThickness, mass invalid), otherwise returns HK_SUCCESS.
  80. static hkResult HK_CALL computeBoxSurfaceMassProperties(const hkVector4& halfExtents, hkReal mass, hkReal surfaceThickness, hkpMassProperties& result);
  81. /// Creates mass properties given triangle vertices, assumed to have a given thickness, of uniform density
  82. /// The thickness MUST be greater than or EQUAL to zero. It can be zero, in which case the mass properties calculated are those
  83. /// of a triangular lamina. Otherwise it generates a triangular prism with center equal to the triangle center.
  84. /// Returns HK_FAILURE on failure (surfaceThickness, mass invalid), otherwise returns HK_SUCCESS.
  85. static hkResult HK_CALL computeTriangleSurfaceMassProperties(const hkVector4& v0, const hkVector4& v1, const hkVector4& v2, hkReal mass, hkReal surfaceThickness, hkpMassProperties& result);
  86. /// Creates mass properties given a cylinder, considered as a volume of uniform density.
  87. /// Returns HK_FAILURE on failure (startAxis, endAxis, radius, mass invalid), otherwise returns HK_SUCCESS.
  88. static hkResult HK_CALL computeCylinderVolumeMassProperties(const hkVector4& startAxis, const hkVector4& endAxis, hkReal radius, hkReal mass, hkpMassProperties& result);
  89. ///////////////////////////////////////
  90. // Geometric/vertex-based calculations
  91. ///////////////////////////////////////
  92. /// Creates mass properties given a point cloud, using the convex hull of the cloud, considered as a volume of uniform density.
  93. /// Returns HK_FAILURE on failure (vertices coplanar, mass invalid), otherwise returns HK_SUCCESS.
  94. static hkResult HK_CALL computeVertexHullVolumeMassProperties(const hkReal* vertexIn, int striding, int numVertices, hkReal mass, hkpMassProperties &result);
  95. /// Creates mass properties given a point cloud, using vertices as point masses, with uniform mass distribution.
  96. /// Returns HK_FAILURE on failure (vertices, mass invalid), otherwise returns HK_SUCCESS.
  97. /// No volume is assumed/calculated.
  98. static hkResult HK_CALL computeVertexCloudMassProperties(const hkReal* vertexIn, int striding, int numVertices, hkReal mass, hkpMassProperties &result);
  99. /// Creates mass properties for the given (possibly open/disconnected) geometry using triangles assumed to have a given thickness to provide volume.
  100. /// If distributeUniformly == true, the mass is distributed proportional to the area of each triangle. 
  101. /// If distributeUniformly == false, the same mass is given to each triangle, independent of its area. This means that "highly tessellated"
  102. /// areas will have more mass, usually undesirable, but perhaps useful in some instances.
  103. /// The thickness MUST be greater than zero.
  104. /// Returns HK_FAILURE on failure (geometry, surfaceThickness, mass invalid), otherwise returns HK_SUCCESS.
  105. static hkResult HK_CALL computeGeometrySurfaceMassProperties(const hkGeometry* geom, hkReal surfaceThickness, hkBool distributeUniformly, hkReal mass, hkpMassProperties &result);
  106. /// Computes the inertia tensor and the center of mass given a total mass for the provided geometry.
  107. /// Asserts on failure (geometry, surfaceThickness, mass invalid), otherwise returns.
  108. /// WARNING: This function assumes the geometry is properly closed.
  109. static void HK_CALL computeGeometryVolumeMassProperties(const hkGeometry* geom, hkReal mass, hkpMassProperties &result);
  110. /// Computes the inertia tensor and the center of mass given a total mass for the provided geometry.
  111. /// returns HK_FAILURE on failure (geometry, surfaceThickness, mass invalid), otherwise returns.
  112. /// WARNING: This function assumes the geometry is properly closed.
  113. static hkResult HK_CALL computeGeometryVolumeMassPropertiesChecked(const hkGeometry* geom, hkReal mass, hkpMassProperties &result);
  114. ///////////////////////////////////////
  115. // Compound calculation
  116. ///////////////////////////////////////
  117. /// Creates mass properties given a group of mass properties/transforms in a common space.
  118. /// For example, to compute mass properties for an hkpListShape-based compound body with children of different
  119. /// masses, use computeShapeVolumeMassProperties() to compute each child's mass element.
  120. /// (with m_transform left as identity), and then combine them using this method. 
  121. /// Returns HK_FAILURE on failure (mass invalid), otherwise returns HK_SUCCESS.
  122. static hkResult HK_CALL combineMassProperties(const hkArray<hkpMassElement>& elements, hkpMassProperties& result );
  123. ///////////////////////////////////////
  124. // "Shape" calculation 
  125. ///////////////////////////////////////
  126. /// Computes the inertia tensor and the center of mass given a total mass for a hkpShape (using "volume" methods).
  127. /// N.B. Every child shape of the shape passed in MUST have a volume. Triangles are automatically given a thickness of 0.01f
  128. static void HK_CALL computeShapeVolumeMassProperties(const hkpShape* shape, hkReal mass, hkpMassProperties &result);
  129. /// "Shape" calculation and assignment to a hkpRigidBodyCinfo (using "volume" methods).
  130. /// Useful for 1-line RigidBody mass property calculation.
  131. /// N.B. Every child shape of the shape passed in MUST have a volume. Triangles are automatically given a thickness of 0.01f
  132. static void HK_CALL setShapeVolumeMassProperties(const hkpShape* shape, hkReal mass, hkpRigidBodyCinfo& bodyInfo);
  133. /// assignment to a hkpRigidBodyCinfo (using "volume" methods).
  134. static void HK_CALL setMassProperties(const hkpMassProperties& props, hkpRigidBodyCinfo& bodyInfo);
  135. /// assignment to a hkpRigidBodyCinfo (using "volume" methods).
  136. static void HK_CALL setAndScaleToDensity(const hkpMassProperties& props, hkReal density, hkpRigidBodyCinfo& bodyInfo);
  137. /// assignment to a hkpRigidBodyCinfo (using "volume" methods).
  138. static void HK_CALL setAndScaleToMass(const hkpMassProperties& props, hkReal mass, hkpRigidBodyCinfo& bodyInfo);
  139. /// Increase the inertia of all axes to be at least (max(inertia of all axes)/maxInertiaRatio)
  140. static void HK_CALL clipInertia(hkReal maxInertiaRatio, hkpRigidBodyCinfo& bodyInfo);
  141. ///////////////////////////////////////
  142. // Inertia Tensor Simplification  
  143. ///////////////////////////////////////
  144. /// Computes a "best" approximation of a full inertia tensor as an oriented particle inertia tensor, which
  145. /// is constant along the diagonal, and zero on the off-diagonals, ie. = I * k for some k. The matrix passed in
  146. /// is set to this approximation.
  147. static void HK_CALL simplifyInertiaTensorToOrientedParticle(hkMatrix3 &inertia);
  148. /// Converts a full inertia tensor to a space, where the inertia is just a diagonal
  149. /// matrix. principleAxisOut is a matrix converting from the new principle axis space
  150. /// to the old inertia tensor space.
  151. static void HK_CALL convertInertiaTensorToPrincipleAxis( hkMatrix3& inertia, hkRotation& principleAxisOut );
  152. /// Recompute the inertia tensors of a constraint tree.
  153. /// The idea is that bodies up in the hierarchy should not get an inertia tensor smaller than the inertia
  154. /// of its children.
  155. /// The overall inertia of the constraint tree should not change significantly, however the individual inertias
  156. /// can change a lot.
  157. /// The purpose of the function is to make motors and constraint limits of a ragdoll
  158. /// much stiffer, without changing the "normal" behavior of the ragdoll visibly.
  159. /// Set inertiaFactorHint to 1 if you want the minimal amount of inertia increase,
  160. /// set inertiaFactorHint to > 1 (e.g. 5) if you allow for higher inertia increase
  161. static void HK_CALL optimizeInertiasOfConstraintTree( hkpConstraintInstance*const* constraints, int numConstraints, hkpRigidBody* rootBody, hkReal inertiaFactorHint = 1.5f );
  162. ///////////////////////////////////////
  163. // Helper functions
  164. ///////////////////////////////////////
  165. /// Given an inertia tensor calculated in a space, and the center of mass in this space
  166. /// this function calculates the inertia around the center of mass. The physics simulation
  167. /// expects all inertia tensors to be expressed around the center of mass.
  168. static void HK_CALL shiftInertiaToCom(hkVector4& shift, hkReal mass, hkMatrix3& inertia);
  169. /// Given an inertia tensor calculated around the center of mass, and the center of mass itself
  170. /// this function calculates the inertia around a point shifted away from the
  171. /// center of mass. This allows you to move inertia tensors to a common space so they can be combined.
  172. static void HK_CALL shiftInertiaFromCom(hkVector4& shift, hkReal mass, hkMatrix3& inertia);
  173. /// Calculates the principal axes of the shape. Returns the axis with greatest extent in a majorAxis, and the next
  174. /// most significant axis in a minorAxis.
  175. static void HK_CALL calculatePrincipalAxis(const hkpShape* pShape, const hkMatrix3& inertiaTensor, hkVector4& majorAxis, hkVector4& minorAxis);
  176. };
  177. #endif // HK_DYNAMICS2_INERTIA_TENSOR_COMPUTER_H
  178. /*
  179. * Havok SDK - NO SOURCE PC DOWNLOAD, BUILD(#20090216)
  180. * Confidential Information of Havok.  (C) Copyright 1999-2009
  181. * Telekinesys Research Limited t/a Havok. All Rights Reserved. The Havok
  182. * Logo, and the Havok buzzsaw logo are trademarks of Havok.  Title, ownership
  183. * rights, and intellectual property rights in the Havok software remain in
  184. * Havok and/or its suppliers.
  185. * Use of this software for evaluation purposes is subject to and indicates
  186. * acceptance of the End User licence Agreement for this product. A copy of
  187. * the license is included with this software and is also available at www.havok.com/tryhavok.
  188. */