PxMassProperties.h
Go to the documentation of this file.
1 //
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions
4 // are met:
5 // * Redistributions of source code must retain the above copyright
6 // notice, this list of conditions and the following disclaimer.
7 // * Redistributions in binary form must reproduce the above copyright
8 // notice, this list of conditions and the following disclaimer in the
9 // documentation and/or other materials provided with the distribution.
10 // * Neither the name of NVIDIA CORPORATION nor the names of its
11 // contributors may be used to endorse or promote products derived
12 // from this software without specific prior written permission.
13 //
14 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
15 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
18 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22 // OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 //
26 // Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
27 // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
28 // Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
29 
30 
31 #ifndef PX_PHYSICS_EXTENSIONS_MASS_PROPERTIES_H
32 #define PX_PHYSICS_EXTENSIONS_MASS_PROPERTIES_H
33 
37 #include "PxPhysXConfig.h"
38 #include "foundation/PxMath.h"
39 #include "foundation/PxMathUtils.h"
40 #include "foundation/PxVec3.h"
41 #include "foundation/PxMat33.h"
42 #include "foundation/PxQuat.h"
43 #include "foundation/PxTransform.h"
44 #include "geometry/PxGeometry.h"
45 #include "geometry/PxBoxGeometry.h"
49 #include "geometry/PxConvexMesh.h"
50 
51 #if !PX_DOXYGEN
52 namespace physx
53 {
54 #endif
55 
64 {
65 public:
69  PX_FORCE_INLINE PxMassProperties() : inertiaTensor(PxIdentity), centerOfMass(0.0f), mass(1.0f) {}
70 
74  PX_FORCE_INLINE PxMassProperties(const PxReal m, const PxMat33& inertiaT, const PxVec3& com) : inertiaTensor(inertiaT), centerOfMass(com), mass(m) {}
75 
84  {
85  switch (geometry.getType())
86  {
88  {
89  const PxSphereGeometry& s = static_cast<const PxSphereGeometry&>(geometry);
90  mass = (4.0f / 3.0f) * PxPi * s.radius * s.radius * s.radius;
91  inertiaTensor = PxMat33::createDiagonal(PxVec3(2.0f / 5.0f * mass * s.radius * s.radius));
92  centerOfMass = PxVec3(0.0f);
93  }
94  break;
95 
97  {
98  const PxBoxGeometry& b = static_cast<const PxBoxGeometry&>(geometry);
99  mass = b.halfExtents.x * b.halfExtents.y * b.halfExtents.z * 8.0f;
101  inertiaTensor = PxMat33::createDiagonal(PxVec3(d2.y + d2.z, d2.x + d2.z, d2.x + d2.y)) * (mass * 1.0f / 3.0f);
102  centerOfMass = PxVec3(0.0f);
103  }
104  break;
105 
107  {
108  const PxCapsuleGeometry& c = static_cast<const PxCapsuleGeometry&>(geometry);
109  PxReal r = c.radius, h = c.halfHeight;
110  mass = ((4.0f / 3.0f) * r + 2 * c.halfHeight) * PxPi * r * r;
111 
112  PxReal a = r*r*r * (8.0f / 15.0f) + h*r*r * (3.0f / 2.0f) + h*h*r * (4.0f / 3.0f) + h*h*h * (2.0f / 3.0f);
113  PxReal b = r*r*r * (8.0f / 15.0f) + h*r*r;
114  inertiaTensor = PxMat33::createDiagonal(PxVec3(b, a, a) * PxPi * r * r);
115  centerOfMass = PxVec3(0.0f);
116  }
117  break;
118 
120  {
121  const PxConvexMeshGeometry& c = static_cast<const PxConvexMeshGeometry&>(geometry);
122  PxVec3 unscaledCoM;
123  PxMat33 unscaledInertiaTensorNonCOM; // inertia tensor of convex mesh in mesh local space
124  PxMat33 unscaledInertiaTensorCOM;
125  PxReal unscaledMass;
126  c.convexMesh->getMassInformation(unscaledMass, unscaledInertiaTensorNonCOM, unscaledCoM);
127 
128  // inertia tensor relative to center of mass
129  unscaledInertiaTensorCOM[0][0] = unscaledInertiaTensorNonCOM[0][0] - unscaledMass*PxReal((unscaledCoM.y*unscaledCoM.y+unscaledCoM.z*unscaledCoM.z));
130  unscaledInertiaTensorCOM[1][1] = unscaledInertiaTensorNonCOM[1][1] - unscaledMass*PxReal((unscaledCoM.z*unscaledCoM.z+unscaledCoM.x*unscaledCoM.x));
131  unscaledInertiaTensorCOM[2][2] = unscaledInertiaTensorNonCOM[2][2] - unscaledMass*PxReal((unscaledCoM.x*unscaledCoM.x+unscaledCoM.y*unscaledCoM.y));
132  unscaledInertiaTensorCOM[0][1] = unscaledInertiaTensorCOM[1][0] = (unscaledInertiaTensorNonCOM[0][1] + unscaledMass*PxReal(unscaledCoM.x*unscaledCoM.y));
133  unscaledInertiaTensorCOM[1][2] = unscaledInertiaTensorCOM[2][1] = (unscaledInertiaTensorNonCOM[1][2] + unscaledMass*PxReal(unscaledCoM.y*unscaledCoM.z));
134  unscaledInertiaTensorCOM[0][2] = unscaledInertiaTensorCOM[2][0] = (unscaledInertiaTensorNonCOM[0][2] + unscaledMass*PxReal(unscaledCoM.z*unscaledCoM.x));
135 
136  const PxMeshScale& s = c.scale;
137  mass = unscaledMass * s.scale.x * s.scale.y * s.scale.z;
138  centerOfMass = s.rotation.rotate(s.scale.multiply(s.rotation.rotateInv(unscaledCoM)));
139  inertiaTensor = scaleInertia(unscaledInertiaTensorCOM, s.rotation, s.scale);
140  }
141  break;
142 
148  {
149  *this = PxMassProperties();
150  }
151  break;
152  }
153 
154  PX_ASSERT(inertiaTensor.column0.isFinite() && inertiaTensor.column1.isFinite() && inertiaTensor.column2.isFinite());
155  PX_ASSERT(centerOfMass.isFinite());
156  PX_ASSERT(PxIsFinite(mass));
157  }
158 
166  {
167  PX_ASSERT(PxIsFinite(scale));
168 
169  return PxMassProperties(mass * scale, inertiaTensor * scale, centerOfMass);
170  }
171 
178  {
179  PX_ASSERT(t.isFinite());
180 
181  inertiaTensor = translateInertia(inertiaTensor, mass, t);
182  centerOfMass += t;
183 
184  PX_ASSERT(inertiaTensor.column0.isFinite() && inertiaTensor.column1.isFinite() && inertiaTensor.column2.isFinite());
185  PX_ASSERT(centerOfMass.isFinite());
186  }
187 
195  PX_FORCE_INLINE static PxVec3 getMassSpaceInertia(const PxMat33& inertia, PxQuat& massFrame)
196  {
197  PX_ASSERT(inertia.column0.isFinite() && inertia.column1.isFinite() && inertia.column2.isFinite());
198 
199  PxVec3 diagT = PxDiagonalize(inertia, massFrame);
200  PX_ASSERT(diagT.isFinite());
201  PX_ASSERT(massFrame.isFinite());
202  return diagT;
203  }
204 
213  PX_FORCE_INLINE static PxMat33 translateInertia(const PxMat33& inertia, const PxReal mass, const PxVec3& t)
214  {
215  PX_ASSERT(inertia.column0.isFinite() && inertia.column1.isFinite() && inertia.column2.isFinite());
216  PX_ASSERT(PxIsFinite(mass));
217  PX_ASSERT(t.isFinite());
218 
219  PxMat33 s( PxVec3(0,t.z,-t.y),
220  PxVec3(-t.z,0,t.x),
221  PxVec3(t.y,-t.x,0) );
222 
223  PxMat33 translatedIT = s.getTranspose() * s * mass + inertia;
224  PX_ASSERT(translatedIT.column0.isFinite() && translatedIT.column1.isFinite() && translatedIT.column2.isFinite());
225  return translatedIT;
226  }
227 
235  PX_FORCE_INLINE static PxMat33 rotateInertia(const PxMat33& inertia, const PxQuat& q)
236  {
237  PX_ASSERT(inertia.column0.isFinite() && inertia.column1.isFinite() && inertia.column2.isFinite());
238  PX_ASSERT(q.isUnit());
239 
240  PxMat33 m(q);
241  PxMat33 rotatedIT = m * inertia * m.getTranspose();
242  PX_ASSERT(rotatedIT.column0.isFinite() && rotatedIT.column1.isFinite() && rotatedIT.column2.isFinite());
243  return rotatedIT;
244  }
245 
254  static PxMat33 scaleInertia(const PxMat33& inertia, const PxQuat& scaleRotation, const PxVec3& scale)
255  {
256  PX_ASSERT(inertia.column0.isFinite() && inertia.column1.isFinite() && inertia.column2.isFinite());
257  PX_ASSERT(scaleRotation.isUnit());
258  PX_ASSERT(scale.isFinite());
259 
260  PxMat33 localInertiaT = rotateInertia(inertia, scaleRotation); // rotate inertia into scaling frame
261  PxVec3 diagonal(localInertiaT[0][0], localInertiaT[1][1], localInertiaT[2][2]);
262 
263  PxVec3 xyz2 = PxVec3(diagonal.dot(PxVec3(0.5f))) - diagonal; // original x^2, y^2, z^2
264  PxVec3 scaledxyz2 = xyz2.multiply(scale).multiply(scale);
265 
266  PxReal xx = scaledxyz2.y + scaledxyz2.z,
267  yy = scaledxyz2.z + scaledxyz2.x,
268  zz = scaledxyz2.x + scaledxyz2.y;
269 
270  PxReal xy = localInertiaT[0][1] * scale.x * scale.y,
271  xz = localInertiaT[0][2] * scale.x * scale.z,
272  yz = localInertiaT[1][2] * scale.y * scale.z;
273 
274  PxMat33 scaledInertia( PxVec3(xx, xy, xz),
275  PxVec3(xy, yy, yz),
276  PxVec3(xz, yz, zz));
277 
278  PxMat33 scaledIT = rotateInertia(scaledInertia * (scale.x * scale.y * scale.z), scaleRotation.getConjugate());
279  PX_ASSERT(scaledIT.column0.isFinite() && scaledIT.column1.isFinite() && scaledIT.column2.isFinite());
280  return scaledIT;
281  }
282 
291  static PxMassProperties sum(const PxMassProperties* props, const PxTransform* transforms, const PxU32 count)
292  {
293  PxReal combinedMass = 0.0f;
294  PxVec3 combinedCoM(0.0f);
295  PxMat33 combinedInertiaT = PxMat33(PxZero);
296 
297  for(PxU32 i = 0; i < count; i++)
298  {
299  PX_ASSERT(props[i].inertiaTensor.column0.isFinite() && props[i].inertiaTensor.column1.isFinite() && props[i].inertiaTensor.column2.isFinite());
300  PX_ASSERT(props[i].centerOfMass.isFinite());
301  PX_ASSERT(PxIsFinite(props[i].mass));
302 
303  combinedMass += props[i].mass;
304  const PxVec3 comTm = transforms[i].transform(props[i].centerOfMass);
305  combinedCoM += comTm * props[i].mass;
306  }
307 
308  if(combinedMass > 0.f)
309  combinedCoM /= combinedMass;
310 
311  for(PxU32 i = 0; i < count; i++)
312  {
313  const PxVec3 comTm = transforms[i].transform(props[i].centerOfMass);
314  combinedInertiaT += translateInertia(rotateInertia(props[i].inertiaTensor, transforms[i].q), props[i].mass, combinedCoM - comTm);
315  }
316 
317  PX_ASSERT(combinedInertiaT.column0.isFinite() && combinedInertiaT.column1.isFinite() && combinedInertiaT.column2.isFinite());
318  PX_ASSERT(combinedCoM.isFinite());
319  PX_ASSERT(PxIsFinite(combinedMass));
320 
321  return PxMassProperties(combinedMass, combinedInertiaT, combinedCoM);
322  }
323 
324 
328 };
329 
330 #if !PX_DOXYGEN
331 } // namespace physx
332 #endif
333 
335 #endif
Definition: GuContactBuffer.h:37
PX_CUDA_CALLABLE PX_INLINE PxQuat getConjugate() const
Definition: PxQuat.h:247
PxMassProperties(const PxGeometry &geometry)
Compute mass properties based on a provided geometry structure.
Definition: PxMassProperties.h:83
Definition: Px.h:84
PxConvexMesh * convexMesh
A reference to the convex mesh object.
Definition: PxConvexMeshGeometry.h:126
PX_CUDA_CALLABLE PX_INLINE bool isFinite() const
returns true if all 3 elems of the vector are finite (not NAN or INF, etc.)
Definition: PxVec3.h:156
virtual PX_PHYSX_COMMON_API void getMassInformation(PxReal &mass, PxMat33 &localInertia, PxVec3 &localCenterOfMass) const =0
Returns the mass properties of the mesh assuming unit density.
PxMeshScale scale
The scaling transformation (from vertex space to shape space).
Definition: PxConvexMeshGeometry.h:125
PX_FORCE_INLINE void translate(const PxVec3 &t)
Translate the center of mass by a given vector and adjust the inertia tensor accordingly.
Definition: PxMassProperties.h:177
Class representing the geometry of a capsule.
Definition: PxCapsuleGeometry.h:55
A class expressing a nonuniform scaling transformation.
Definition: PxMeshScale.h:68
PxVec3 halfExtents
Half of the width, height, and depth of the box.
Definition: PxBoxGeometry.h:88
static const float PxPi
Definition: PxMath.h:58
PX_CUDA_CALLABLE PX_FORCE_INLINE float dot(const PxVec3 &v) const
returns the scalar product of this and other.
Definition: PxVec3.h:276
#define PX_FORCE_INLINE
Definition: PxPreprocessor.h:351
This is a quaternion class. For more information on quaternion mathematics consult a mathematics sour...
Definition: PxQuat.h:49
float PxReal
Definition: PxSimpleTypes.h:78
A class representing the geometry of a sphere.
Definition: PxSphereGeometry.h:49
static PxMat33 scaleInertia(const PxMat33 &inertia, const PxQuat &scaleRotation, const PxVec3 &scale)
Non-uniform scaling of the inertia tensor.
Definition: PxMassProperties.h:254
PX_FORCE_INLINE PxMassProperties()
Default constructor.
Definition: PxMassProperties.h:69
Definition: PxGeometry.h:57
PxReal radius
The radius of the sphere.
Definition: PxSphereGeometry.h:72
Definition: PxGeometry.h:61
PxQuat rotation
The orientation of the scaling axes.
Definition: PxMeshScale.h:165
A geometry object.
Definition: PxGeometry.h:75
Definition: PxGeometry.h:55
internal use only!
Definition: PxGeometry.h:62
Definition: Px.h:78
static PX_FORCE_INLINE PxMat33 rotateInertia(const PxMat33 &inertia, const PxQuat &q)
Rotate an inertia tensor around the center of mass.
Definition: PxMassProperties.h:235
PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3 transform(const PxVec3 &input) const
Definition: PxTransform.h:111
PX_CUDA_CALLABLE static PX_INLINE const PxMat33 createDiagonal(const PxVec3 &d)
Construct from diagonal, off-diagonals are zero.
Definition: PxMat33.h:176
float y
Definition: PxVec3.h:381
Utility class to compute and manipulate mass and inertia tensor properties.
Definition: PxMassProperties.h:63
PxVec3 scale
A nonuniform scaling.
Definition: PxMeshScale.h:164
PxReal mass
The mass of the object.
Definition: PxMassProperties.h:327
PxU8 geometry[sizeof(PxGeometry)]
Definition: PxGeometryHelpers.h:215
internal use only!
Definition: PxGeometry.h:63
PX_FOUNDATION_API PxVec3 PxDiagonalize(const PxMat33 &m, PxQuat &axes)
class representing a rigid euclidean transform as a quaternion and a vector
Definition: PxTransform.h:48
PX_CUDA_CALLABLE bool isUnit() const
returns true if finite and magnitude is close to unit
Definition: PxQuat.h:132
PxVec3 column2
Definition: PxMat33.h:353
3x3 matrix class
Definition: PxMat33.h:90
static PX_FORCE_INLINE PxVec3 getMassSpaceInertia(const PxMat33 &inertia, PxQuat &massFrame)
Get the entries of the diagonalized inertia tensor and the corresponding reference rotation...
Definition: PxMassProperties.h:195
static PX_FORCE_INLINE PxMat33 translateInertia(const PxMat33 &inertia, const PxReal mass, const PxVec3 &t)
Translate an inertia tensor using the parallel axis theorem.
Definition: PxMassProperties.h:213
static PxMassProperties sum(const PxMassProperties *props, const PxTransform *transforms, const PxU32 count)
Sum up individual mass properties.
Definition: PxMassProperties.h:291
PxReal radius
The radius of the capsule.
Definition: PxCapsuleGeometry.h:84
PxVec3 column0
Definition: PxMat33.h:353
PX_CUDA_CALLABLE PX_FORCE_INLINE bool PxIsFinite(float f)
returns true if the passed number is a finite floating point number as opposed to INF...
Definition: PxMath.h:292
PxReal halfHeight
half of the capsule&#39;s height, measured between the centers of the hemispherical ends.
Definition: PxCapsuleGeometry.h:89
Definition: PxGeometry.h:59
PX_CUDA_CALLABLE PX_FORCE_INLINE const PxVec3 rotate(const PxVec3 &v) const
Definition: PxQuat.h:287
Definition: PxGeometry.h:58
#define PX_ASSERT(exp)
Definition: PxAssert.h:59
Definition: PxGeometry.h:60
PX_CUDA_CALLABLE bool isFinite() const
returns true if all elements are finite (not NAN or INF, etc.)
Definition: PxQuat.h:124
PX_CUDA_CALLABLE PX_FORCE_INLINE const PxMat33 getTranspose() const
Get transposed matrix.
Definition: PxMat33.h:190
uint32_t PxU32
Definition: Px.h:48
PX_CUDA_CALLABLE PX_FORCE_INLINE const PxVec3 rotateInv(const PxVec3 &v) const
Definition: PxQuat.h:301
PX_FORCE_INLINE PxMassProperties(const PxReal m, const PxMat33 &inertiaT, const PxVec3 &com)
Construct from individual elements.
Definition: PxMassProperties.h:74
Definition: PxGeometry.h:56
PxMat33 inertiaTensor
The inertia tensor of the object.
Definition: PxMassProperties.h:325
float z
Definition: PxVec3.h:381
PX_FORCE_INLINE PxMassProperties operator*(const PxReal scale) const
Scale mass properties.
Definition: PxMassProperties.h:165
PxVec3 column1
Definition: PxMat33.h:353
Convex mesh geometry class.
Definition: PxConvexMeshGeometry.h:80
Class representing the geometry of a box.
Definition: PxBoxGeometry.h:50
PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3 multiply(const PxVec3 &a) const
a[i] * b[i], for all i.
Definition: PxVec3.h:336
3 Element vector class.
Definition: PxVec3.h:49
PxVec3 centerOfMass
The center of mass of the object.
Definition: PxMassProperties.h:326
float x
Definition: PxVec3.h:381