29#ifndef EXT_INERTIA_TENSOR_H
30#define EXT_INERTIA_TENSOR_H
32#include "foundation/PxMat33.h"
33#include "foundation/PxMathUtils.h"
49 void translate(
const PxVec3& t);
51 PX_INLINE void scaleDensity(PxReal densityScale);
55 void setBox(
const PxVec3& halfWidths);
58 void setSphere(PxReal radius);
61 void setCylinder(
int dir, PxReal r, PxReal l);
64 void setCapsule(
int dir, PxReal r, PxReal l);
67 void setEllipsoid(PxReal rx, PxReal ry, PxReal rz);
71 PX_INLINE PxReal getMass()
const {
return mMass; }
90 if(extents.x != 0.0f) v*=extents.x;
91 if(extents.y != 0.0f) v*=extents.y;
92 if(extents.z != 0.0f) v*=extents.z;
97 PX_INLINE PxReal computeSphereRatio(PxReal radius) {
return (4.0f/3.0f) * PxPi * radius * radius * radius; }
98 PxReal computeSphereMass(PxReal radius, PxReal density) {
return density * computeSphereRatio(radius); }
99 PxReal computeSphereDensity(PxReal radius, PxReal mass) {
return mass / computeSphereRatio(radius); }
102 PX_INLINE PxReal computeBoxRatio(
const PxVec3& extents) {
return volume(extents); }
103 PxReal computeBoxMass(
const PxVec3& extents, PxReal density) {
return density * computeBoxRatio(extents); }
104 PxReal computeBoxDensity(
const PxVec3& extents, PxReal mass) {
return mass / computeBoxRatio(extents); }
107 PX_INLINE PxReal computeEllipsoidRatio(
const PxVec3& extents) {
return (4.0f/3.0f) * PxPi * volume(extents); }
108 PxReal computeEllipsoidMass(
const PxVec3& extents, PxReal density) {
return density * computeEllipsoidRatio(extents); }
109 PxReal computeEllipsoidDensity(
const PxVec3& extents, PxReal mass) {
return mass / computeEllipsoidRatio(extents); }
112 PX_INLINE PxReal computeCylinderRatio(PxReal r, PxReal l) {
return PxPi * r * r * (2.0f*l); }
113 PxReal computeCylinderMass(PxReal r, PxReal l, PxReal density) {
return density * computeCylinderRatio(r, l); }
114 PxReal computeCylinderDensity(PxReal r, PxReal l, PxReal mass) {
return mass / computeCylinderRatio(r, l); }
117 PX_INLINE PxReal computeCapsuleRatio(PxReal r, PxReal l) {
return computeSphereRatio(r) + computeCylinderRatio(r, l);}
118 PxReal computeCapsuleMass(PxReal r, PxReal l, PxReal density) {
return density * computeCapsuleRatio(r, l); }
119 PxReal computeCapsuleDensity(PxReal r, PxReal l, PxReal mass) {
return mass / computeCapsuleRatio(r, l); }
122 PX_INLINE PxReal computeConeRatio(PxReal r, PxReal l) {
return PxPi * r * r *
PxAbs(l)/3.0f; }
123 PxReal computeConeMass(PxReal r, PxReal l, PxReal density) {
return density * computeConeRatio(r, l); }
124 PxReal computeConeDensity(PxReal r, PxReal l, PxReal mass) {
return mass / computeConeRatio(r, l); }
126 void computeBoxInertiaTensor(PxVec3& inertia, PxReal mass, PxReal xlength, PxReal ylength, PxReal zlength);
127 void computeSphereInertiaTensor(PxVec3& inertia, PxReal mass, PxReal radius,
bool hollow);
128 bool jacobiTransform(PxI32 n, PxF64 a[], PxF64 w[]);
129 bool diagonalizeInertiaTensor(
const PxMat33& denseInertia, PxVec3& diagonalInertia, PxMat33& rotation);
133void Ext::computeBoxInertiaTensor(PxVec3& inertia, PxReal mass, PxReal xlength, PxReal ylength, PxReal zlength)
136 const PxReal coeff = mass/12;
137 inertia.x = coeff * (ylength*ylength + zlength*zlength);
138 inertia.y = coeff * (xlength*xlength + zlength*zlength);
139 inertia.z = coeff * (xlength*xlength + ylength*ylength);
141 PX_ASSERT(inertia.x != 0.0f);
142 PX_ASSERT(inertia.y != 0.0f);
143 PX_ASSERT(inertia.z != 0.0f);
144 PX_ASSERT(inertia.isFinite());
147void Ext::computeSphereInertiaTensor(PxVec3& inertia, PxReal mass, PxReal radius,
bool hollow)
149 inertia.x = mass * radius * radius;
151 inertia.x *= PxReal(2 / 3.0);
153 inertia.x *= PxReal(2 / 5.0);
155 inertia.z = inertia.y = inertia.x;
156 PX_ASSERT(inertia.isFinite());
165Ext::InertiaTensorComputer::InertiaTensorComputer(
bool initTozero)
171Ext::InertiaTensorComputer::InertiaTensorComputer(
const PxMat33& inertia,
const PxVec3& com, PxReal mass) :
179Ext::InertiaTensorComputer::~InertiaTensorComputer()
183PX_INLINE void Ext::InertiaTensorComputer::zero()
186 mI = PxMat33(PxZero);
190PX_INLINE void Ext::InertiaTensorComputer::setDiagonal(PxReal mass,
const PxVec3& diag)
195 PX_ASSERT(mI.column0.isFinite() && mI.column1.isFinite() && mI.column2.isFinite());
199void Ext::InertiaTensorComputer::setBox(
const PxVec3& halfWidths)
202 const PxReal mass = 8.0f * computeBoxRatio(halfWidths);
203 const PxReal s =(1.0f/3.0f) * mass;
205 const PxReal x = halfWidths.x*halfWidths.x;
206 const PxReal y = halfWidths.y*halfWidths.y;
207 const PxReal z = halfWidths.z*halfWidths.z;
209 setDiagonal(mass, PxVec3(y+z, z+x, x+y) * s);
212PX_INLINE void Ext::InertiaTensorComputer::rotate(
const PxMat33& rot)
215 mI = rot * mI * rot.getTranspose();
216 PX_ASSERT(mI.column0.isFinite() && mI.column1.isFinite() && mI.column2.isFinite());
219 PX_ASSERT(mG.isFinite());
222void Ext::InertiaTensorComputer::translate(
const PxVec3& t)
228 t1.column0 = PxVec3(0, mG.z, -mG.y);
229 t1.column1 = PxVec3(-mG.z, 0, mG.x);
230 t1.column2 = PxVec3(mG.y, -mG.x, 0);
235 mI += (t1 * t1)*mMass;
239 t2.column0 = PxVec3(0, sum.z, -sum.y);
240 t2.column1 = PxVec3(-sum.z, 0, sum.x);
241 t2.column2 = PxVec3(sum.y, -sum.x, 0);
242 mI += (t1 * t1 - t2 * t2)*mMass;
248 PX_ASSERT(mI.column0.isFinite() && mI.column1.isFinite() && mI.column2.isFinite());
249 PX_ASSERT(mG.isFinite());
253PX_INLINE void Ext::InertiaTensorComputer::transform(
const PxTransform& transform)
259PX_INLINE void Ext::InertiaTensorComputer::setBox(
const PxVec3& halfWidths,
const PxTransform* pose)
266PX_INLINE void Ext::InertiaTensorComputer::scaleDensity(PxReal densityScale)
269 mMass *= densityScale;
270 PX_ASSERT(mI.column0.isFinite() && mI.column1.isFinite() && mI.column2.isFinite());
274PX_INLINE void Ext::InertiaTensorComputer::add(
const InertiaTensorComputer& it)
276 const PxReal TotalMass = mMass + it.mMass;
277 mG = (mG * mMass + it.mG * it.mMass) / TotalMass;
281 PX_ASSERT(mI.column0.isFinite() && mI.column1.isFinite() && mI.column2.isFinite());
282 PX_ASSERT(mG.isFinite());
286PX_INLINE void Ext::InertiaTensorComputer::center()
292void Ext::InertiaTensorComputer::setSphere(PxReal radius)
295 const PxReal m = computeSphereRatio(radius);
297 const PxReal s = m * radius * radius * (2.0f/5.0f);
298 setDiagonal(m,PxVec3(s,s,s));
301PX_INLINE void Ext::InertiaTensorComputer::setSphere(PxReal radius,
const PxTransform* pose)
308void Ext::InertiaTensorComputer::setCylinder(
int dir, PxReal r, PxReal l)
311 const PxReal m = computeCylinderRatio(r, l);
313 const PxReal i1 = r*r*m/2.0f;
314 const PxReal i2 = (3.0f*r*r+4.0f*l*l)*m/12.0f;
318 case 0: setDiagonal(m,PxVec3(i1,i2,i2));
break;
319 case 1: setDiagonal(m,PxVec3(i2,i1,i2));
break;
320 default: setDiagonal(m,PxVec3(i2,i2,i1));
break;
324PX_INLINE void Ext::InertiaTensorComputer::setCylinder(
int dir, PxReal r, PxReal l,
const PxTransform* pose)
326 setCylinder(dir, r, l);
331void Ext::InertiaTensorComputer::setCapsule(
int dir, PxReal r, PxReal l)
334 const PxReal m = computeCapsuleRatio(r, l);
336 const PxReal t = PxPi * r * r;
337 const PxReal i1 = t * ((r*r*r * 8.0f/15.0f) + (l*r*r));
338 const PxReal i2 = t * ((r*r*r * 8.0f/15.0f) + (l*r*r * 3.0f/2.0f) + (l*l*r * 4.0f/3.0f) + (l*l*l * 2.0f/3.0f));
342 case 0: setDiagonal(m,PxVec3(i1,i2,i2));
break;
343 case 1: setDiagonal(m,PxVec3(i2,i1,i2));
break;
344 default: setDiagonal(m,PxVec3(i2,i2,i1));
break;
348PX_INLINE void Ext::InertiaTensorComputer::setCapsule(
int dir, PxReal r, PxReal l,
const PxTransform* pose)
350 setCapsule(dir, r, l);
355void Ext::InertiaTensorComputer::setEllipsoid(PxReal rx, PxReal ry, PxReal rz)
358 const PxReal m = computeEllipsoidRatio(PxVec3(rx, ry, rz));
361 const PxReal s = m * (2.0f/5.0f);
364 setDiagonal(m,PxVec3(ry*rz,rz*rx,rx*ry)*s);
367PX_INLINE void Ext::InertiaTensorComputer::setEllipsoid(PxReal rx, PxReal ry, PxReal rz,
const PxTransform* pose)
369 setEllipsoid(rx,ry,rz);
Definition ExtInertiaTensor.h:40
PX_CUDA_CALLABLE static PX_INLINE const PxMat33T createDiagonal(const PxVec3T< float > &d)
Construct from diagonal, off-diagonals are zero.
Definition PxMat33.h:186
3x3 matrix class
Definition PxMat33.h:91
3 Element vector class.
Definition PxVec3.h:50
#define PX_INLINE
Definition PxPreprocessor.h:320
transform(pattern)
Definition docopt.py:72
Sorts an array of objects in ascending order, assuming that the predicate implements the < operator:
Definition PxBoxController.h:39
PX_INLINE void rotate(const Gu::Box &src, const PxMat34 &mtx, Gu::Box &obb)
recomputes the OBB after an arbitrary transform by a 4x4 matrix.
Definition GuBoxConversion.h:100
PX_CUDA_CALLABLE PX_FORCE_INLINE float PxAbs(float a)
abs returns the absolute value of its argument.
Definition PxMath.h:109
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:326