HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
massProperties.h
Go to the documentation of this file.
1 //
2 // Copyright 2021 Pixar
3 //
4 // Licensed under the Apache License, Version 2.0 (the "Apache License")
5 // with the following modification; you may not use this file except in
6 // compliance with the Apache License and the following modification to it:
7 // Section 6. Trademarks. is deleted and replaced with:
8 //
9 // 6. Trademarks. This License does not grant permission to use the trade
10 // names, trademarks, service marks, or product names of the Licensor
11 // and its affiliates, except as required to comply with Section 4(c) of
12 // the License and to reproduce the content of the NOTICE file.
13 //
14 // You may obtain a copy of the Apache License at
15 //
16 // http://www.apache.org/licenses/LICENSE-2.0
17 //
18 // Unless required by applicable law or agreed to in writing, software
19 // distributed under the Apache License with the above modification is
20 // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21 // KIND, either express or implied. See the Apache License for the specific
22 // language governing permissions and limitations under the Apache License.
23 //
24 #ifndef PXR_USD_USD_MASS_PROPERTIES_H
25 #define PXR_USD_USD_MASS_PROPERTIES_H
26 
27 #include "pxr/pxr.h"
28 #include "pxr/usd/usdPhysics/api.h"
29 #include "pxr/usd/usd/common.h"
30 
31 #include "pxr/base/gf/vec3f.h"
32 #include "pxr/base/gf/quatf.h"
33 #include "pxr/base/gf/rotation.h"
34 #include "pxr/base/gf/matrix3f.h"
35 #include "pxr/base/gf/matrix4f.h"
36 
38 
39 GfQuatf UsdPhysicsIndexedRotation(uint32_t axis, float s, float c)
40 {
41  float v[3] = { 0, 0, 0 };
42  v[axis] = s;
43  return GfQuatf(c, v[0], v[1], v[2]);
44 }
45 
46 uint32_t UsdPhysicsGetNextIndex3(uint32_t i)
47 {
48  return (i + 1 + (i >> 1)) & 3;
49 }
50 
51 
53 {
54  const uint32_t MAX_ITERS = 24;
55 
56  GfQuatf q = GfQuatf(1.0);
57 
58  GfMatrix3f d;
59  for (uint32_t i = 0; i < MAX_ITERS; i++)
60  {
61  GfMatrix3f axes(q);
62  d = axes * m * axes.GetTranspose();
63 
64  float d0 = fabs(d[1][2]), d1 = fabs(d[0][2]), d2 = fabs(d[0][1]);
65  uint32_t a = uint32_t(d0 > d1 && d0 > d2 ? 0 : d1 > d2 ? 1 : 2); // rotation axis index, from largest
66  // off-diagonal
67  // element
68 
69  uint32_t a1 = UsdPhysicsGetNextIndex3(a), a2 = UsdPhysicsGetNextIndex3(a1);
70  if (d[a1][a2] == 0.0f || fabs(d[a1][a1] - d[a2][a2]) > 2e6 * fabs(2.0 * d[a1][a2]))
71  break;
72 
73  float w = (d[a1][a1] - d[a2][a2]) / (2.0f * d[a1][a2]); // cot(2 * phi), where phi is the rotation angle
74  float absw = fabs(w);
75 
76  GfQuatf r;
77  if (absw > 1000)
78  r = UsdPhysicsIndexedRotation(a, 1 / (4 * w), 1.0f); // h will be very close to 1, so use small angle approx instead
79  else
80  {
81  float t = 1 / (absw + sqrt(w * w + 1)); // absolute value of tan phi
82  float h = 1 / sqrt(t * t + 1); // absolute value of cos phi
83 
84  r = UsdPhysicsIndexedRotation(a, sqrt((1 - h) / 2) * ((w >= 0.0f) ? 1.0f : -1.0f), sqrt((1 + h) / 2));
85  }
86 
87  q = (q * r).GetNormalized();
88  }
89 
90  massFrame = q;
91  return GfVec3f(d.GetColumn(0)[0], d.GetColumn(1)[1], d.GetColumn(2)[2]);
92 }
93 
94 // -------------------------------------------------------------------------- //
95 // MASSPROPERTIES //
96 // -------------------------------------------------------------------------- //
97 
98 /// \class UsdPhysicsMassProperties
99 ///
100 /// Mass properties computation class. Used to combine together individual mass
101 /// properties and produce final one.
102 ///
104 {
105 public:
106 
107  /// Construct a MassProperties
108  USDPHYSICS_API UsdPhysicsMassProperties() : _inertiaTensor(0.0f), _centerOfMass(0.0f), _mass(1.0f)
109  {
110  _inertiaTensor[0][0] = 1.0;
111  _inertiaTensor[1][1] = 1.0;
112  _inertiaTensor[2][2] = 1.0;
113  }
114 
115  /// Construct from individual elements.
116  USDPHYSICS_API UsdPhysicsMassProperties(const float m, const GfMatrix3f& inertiaT, const GfVec3f& com)
117  : _inertiaTensor(inertiaT), _centerOfMass(com), _mass(m)
118  {
119  }
120 
121  /// Scale mass properties.
122  /// \p scale The linear scaling factor to apply to the mass properties.
123  /// \return The scaled mass properties.
125  {
126  return UsdPhysicsMassProperties(_mass * scale, _inertiaTensor * scale, _centerOfMass);
127  }
128 
129  /// Translate the center of mass by a given vector and adjust the inertia tensor accordingly.
130  /// \p t The translation vector for the center of mass.
132  {
133  _inertiaTensor = TranslateInertia(_inertiaTensor, _mass, t);
134  _centerOfMass += t;
135  }
136 
137  /// Get the entries of the diagonalized inertia tensor and the corresponding reference rotation.
138  /// \p inertia The inertia tensor to diagonalize.
139  /// \p massFrame The frame the diagonalized tensor refers to.
140  /// \return The entries of the diagonalized inertia tensor.
141  USDPHYSICS_API static GfVec3f GetMassSpaceInertia(const GfMatrix3f& inertia, GfQuatf& massFrame)
142  {
143 
144  GfVec3f diagT = UsdPhysicsDiagonalize(inertia, massFrame);
145  return diagT;
146  }
147 
148  /// Translate an inertia tensor using the parallel axis theorem
149  /// \p inertia The inertia tensor to translate.
150  /// \p mass The mass of the object.
151  /// \p t The relative frame to translate the inertia tensor to.
152  /// \return The translated inertia tensor.
153  USDPHYSICS_API static GfMatrix3f TranslateInertia(const GfMatrix3f& inertia, const float mass, const GfVec3f& t)
154  {
155  GfMatrix3f s;
156  s.SetColumn(0, GfVec3f(0, t[2], -t[1]));
157  s.SetColumn(1, GfVec3f(-t[2], 0, t[0]));
158  s.SetColumn(2, GfVec3f(t[1], -t[0], 0));
159 
160  GfMatrix3f translatedIT = s * s.GetTranspose() * mass + inertia;
161  return translatedIT;
162  }
163 
164 
165  /// Rotate an inertia tensor around the center of mass
166  /// \p inertia The inertia tensor to rotate.
167  /// \p q The rotation to apply to the inertia tensor.
168  /// \return The rotated inertia tensor.
170  {
171  GfMatrix3f m(q);
172  GfMatrix3f rotatedIT = m.GetTranspose() * inertia * m;
173  return rotatedIT;
174  }
175 
176  /// Sum up individual mass properties.
177  /// \p props Array of mass properties to sum up.
178  /// \p transforms Reference transforms for each mass properties entry.
179  /// \p count The number of mass properties to sum up.
180  /// \return The summed up mass properties.
182  {
183  float combinedMass = 0.0f;
184  GfVec3f combinedCoM(0.0f);
185  GfMatrix3f combinedInertiaT = GfMatrix3f(0.0f);
186 
187  for (uint32_t i = 0; i < count; i++)
188  {
189  combinedMass += props[i]._mass;
190  const GfVec3f comTm = transforms[i].Transform(props[i]._centerOfMass);
191  combinedCoM += comTm * props[i]._mass;
192  }
193 
194  if (combinedMass > 0.f)
195  combinedCoM /= combinedMass;
196 
197  for (uint32_t i = 0; i < count; i++)
198  {
199  const GfVec3f comTm = transforms[i].Transform(props[i]._centerOfMass);
200  combinedInertiaT += TranslateInertia(
201  RotateInertia(props[i]._inertiaTensor, GfQuatf(transforms[i].ExtractRotation().GetQuat())),
202  props[i]._mass, combinedCoM - comTm);
203  }
204 
205  return UsdPhysicsMassProperties(combinedMass, combinedInertiaT, combinedCoM);
206  }
207 
208  /// Get inertia tensor
209  /// \return Inertia tensor
211  {
212  return _inertiaTensor;
213  }
214 
215  /// Set inertia tensor
216  /// \p inTensor New inertia tensor.
217  void SetInertiaTensor(const GfMatrix3f& inTensor)
218  {
219  _inertiaTensor = inTensor;
220  }
221 
222  /// Get center of mass
223  /// \return Center of mass
224  const GfVec3f& GetCenterOfMass() const
225  {
226  return _centerOfMass;
227  }
228 
229  /// Get mass
230  /// \return Mass
231  float GetMass() const
232  {
233  return _mass;
234  }
235 
236  /// Set mass
237  /// \p inMass New mass.
238  void SetMass(float inMass)
239  {
240  _mass = inMass;
241  }
242 
243 private:
244  GfMatrix3f _inertiaTensor; //!< The inertia tensor of the object.
245  GfVec3f _centerOfMass; //!< The center of mass of the object.
246  float _mass; //!< The mass of the object.
247 };
248 
250 
251 #endif
PXR_NAMESPACE_OPEN_SCOPE GfQuatf UsdPhysicsIndexedRotation(uint32_t axis, float s, float c)
const GLdouble * v
Definition: glcorearb.h:837
static USDPHYSICS_API UsdPhysicsMassProperties Sum(const UsdPhysicsMassProperties *props, const GfMatrix4f *transforms, const uint32_t count)
vfloat4 sqrt(const vfloat4 &a)
Definition: simd.h:7481
static USDPHYSICS_API GfMatrix3f RotateInertia(const GfMatrix3f &inertia, const GfQuatf &q)
Definition: vec3f.h:62
GLboolean GLboolean GLboolean GLboolean a
Definition: glcorearb.h:1222
GLdouble s
Definition: glad.h:3009
static USDPHYSICS_API GfVec3f GetMassSpaceInertia(const GfMatrix3f &inertia, GfQuatf &massFrame)
GA_API const UT_StringHolder com
GF_API GfMatrix3f GetTranspose() const
Returns the transpose of the matrix.
GLdouble GLdouble GLdouble q
Definition: glad.h:2445
GfVec3f UsdPhysicsDiagonalize(const GfMatrix3f &m, GfQuatf &massFrame)
Definition: quatf.h:59
GA_API const UT_StringHolder scale
GLfloat f
Definition: glcorearb.h:1926
void SetMass(float inMass)
const GfVec3f & GetCenterOfMass() const
USDPHYSICS_API void Translate(const GfVec3f &t)
GfVec3d Transform(const GfVec3d &vec) const
Definition: matrix4f.h:659
uint32_t UsdPhysicsGetNextIndex3(uint32_t i)
GfVec3f GetColumn(int i) const
Gets a column of the matrix as a Vec3.
Definition: matrix3f.h:177
USDPHYSICS_API UsdPhysicsMassProperties operator*(const float scale) const
GLdouble t
Definition: glad.h:2397
#define USDPHYSICS_API
Definition: api.h:40
USDPHYSICS_API UsdPhysicsMassProperties(const float m, const GfMatrix3f &inertiaT, const GfVec3f &com)
Construct from individual elements.
GA_API const UT_StringHolder mass
GLfloat GLfloat GLfloat GLfloat h
Definition: glcorearb.h:2002
void SetInertiaTensor(const GfMatrix3f &inTensor)
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Definition: path.h:1441
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:91
const GfMatrix3f & GetInertiaTensor() const
GLubyte GLubyte GLubyte GLubyte w
Definition: glcorearb.h:857
static USDPHYSICS_API GfMatrix3f TranslateInertia(const GfMatrix3f &inertia, const float mass, const GfVec3f &t)
void SetColumn(int i, const GfVec3f &v)
Sets a column of the matrix from a Vec3.
Definition: matrix3f.h:165
GLboolean r
Definition: glcorearb.h:1222
USDPHYSICS_API UsdPhysicsMassProperties()
Construct a MassProperties.
GLint GLsizei count
Definition: glcorearb.h:405
GLenum GLuint GLsizei const GLenum * props
Definition: glcorearb.h:2525