RavEngine
Loading...
Searching...
No Matches
DyFeatherstoneArticulationUtils.h
1// Redistribution and use in source and binary forms, with or without
2// modification, are permitted provided that the following conditions
3// are met:
4// * Redistributions of source code must retain the above copyright
5// notice, this list of conditions and the following disclaimer.
6// * Redistributions in binary form must reproduce the above copyright
7// notice, this list of conditions and the following disclaimer in the
8// documentation and/or other materials provided with the distribution.
9// * Neither the name of NVIDIA CORPORATION nor the names of its
10// contributors may be used to endorse or promote products derived
11// from this software without specific prior written permission.
12//
13// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
14// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
17// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24//
25// Copyright (c) 2008-2022 NVIDIA Corporation. All rights reserved.
26// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
27// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
28
29#ifndef DY_FEATHERSTONE_ARTICULATION_UTIL_H
30#define DY_FEATHERSTONE_ARTICULATION_UTIL_H
31
32#include "foundation/PxVecMath.h"
33#include "CmSpatialVector.h"
34#include "foundation/PxBitUtils.h"
35#include "foundation/PxMemory.h"
36
37namespace physx
38{
39
40namespace Dy
41{
42 static const size_t DY_MAX_DOF = 6;
43
45 {
46 static const PxU32 MaxColumns = 3;
47 public:
48
49#ifndef __CUDACC__
50 PX_CUDA_CALLABLE PX_FORCE_INLINE SpatialSubspaceMatrix() :numColumns(0)
51 {
52 //PxMemZero(columns, sizeof(Cm::SpatialVectorF) * 6);
53 PxMemSet(columns, 0, sizeof(Cm::UnAlignedSpatialVector) * MaxColumns);
54 }
55#endif
56
57 PX_CUDA_CALLABLE PX_FORCE_INLINE void setNumColumns(const PxU32 nc)
58 {
59 numColumns = nc;
60 }
61
62 PX_CUDA_CALLABLE PX_FORCE_INLINE PxU32 getNumColumns() const
63 {
64 return numColumns;
65 }
66
67 PX_CUDA_CALLABLE PX_FORCE_INLINE Cm::SpatialVectorF transposeMultiply(Cm::SpatialVectorF& v) const
68 {
69 PxReal result[6];
70 for (PxU32 i = 0; i < numColumns; ++i)
71 {
72 const Cm::UnAlignedSpatialVector& row = columns[i];
73 result[i] = row.dot(v);
74 }
75
77 res.top.x = result[0]; res.top.y = result[1]; res.top.z = result[2];
78 res.bottom.x = result[3]; res.bottom.y = result[4]; res.bottom.z = result[5];
79
80 return res;
81
82 }
83
84 PX_CUDA_CALLABLE PX_FORCE_INLINE void setColumn(const PxU32 index, const PxVec3& top, const PxVec3& bottom)
85 {
86 PX_ASSERT(index < MaxColumns);
87 columns[index] = Cm::SpatialVectorF(top, bottom);
88 }
89
90 PX_CUDA_CALLABLE PX_FORCE_INLINE Cm::UnAlignedSpatialVector& operator[](unsigned int num)
91 {
92 PX_ASSERT(num < MaxColumns);
93 return columns[num];
94 }
95
96 PX_CUDA_CALLABLE PX_FORCE_INLINE const Cm::UnAlignedSpatialVector& operator[](unsigned int num) const
97 {
98 PX_ASSERT(num < MaxColumns);
99 return columns[num];
100 }
101
102 PX_CUDA_CALLABLE PX_FORCE_INLINE const Cm::UnAlignedSpatialVector* getColumns() const
103 {
104 return columns;
105 }
106
107
108 //private:
109 Cm::UnAlignedSpatialVector columns[MaxColumns]; //3x24 = 72
110 PxU32 numColumns; //76
111 PxU32 padding; //80
112
113 };
114
115 //this should be 6x6 matrix
116 //|R, 0|
117 //|-R*rX, R|
119 {
120 PxMat33 R;
121 PxQuat q;
122 PxMat33 T;
123
124 public:
125 PX_CUDA_CALLABLE PX_FORCE_INLINE SpatialTransform() : R(PxZero), T(PxZero)
126 {
127 }
128
129 PX_CUDA_CALLABLE PX_FORCE_INLINE SpatialTransform(const PxMat33& R_, const PxMat33& T_) : R(R_), T(T_)
130 {
131 q = PxQuat(R_);
132 }
133
134 PX_CUDA_CALLABLE PX_FORCE_INLINE SpatialTransform(const PxQuat& q_, const PxMat33& T_) : q(q_), T(T_)
135 {
136 R = PxMat33(q_);
137 }
138
139 //This assume angular is the top vector and linear is the bottom vector
140 /*PX_CUDA_CALLABLE PX_FORCE_INLINE Cm::SpatialVector operator *(const Cm::SpatialVector& s) const
141 {
142 const PxVec3 angular = R * s.angular;
143 const PxVec3 linear = T * s.angular + R * s.linear;
144 return Cm::SpatialVector(linear, angular);
145 }*/
146
147
149 //PX_FORCE_INLINE Cm::SpatialVectorF operator *(Cm::SpatialVectorF& s) const
150 //{
151 // const PxVec3 top = R * s.top;
152 // const PxVec3 bottom = T * s.top + R * s.bottom;
153
154 // const PxVec3 top1 = q.rotate(s.top);
155 // const PxVec3 bottom1 = T * s.top + q.rotate(s.bottom);
156
158 // const PxVec3 bDif = (bottom - bottom1).abs();
159 // const PxReal eps = 0.001f;
160 // PX_ASSERT(tDif.x < eps && tDif.y < eps && tDif.z < eps);
161 // PX_ASSERT(bDif.x < eps && bDif.y < eps && bDif.z < eps);*/
162 // return Cm::SpatialVectorF(top1, bottom1);
163 //}
164
165 //This assume angular is the top vector and linear is the bottom vector
167 {
168 //const PxVec3 top = R * s.top;
169 //const PxVec3 bottom = T * s.top + R * s.bottom;
170
171 const PxVec3 top1 = q.rotate(s.top);
172 const PxVec3 bottom1 = T * s.top + q.rotate(s.bottom);
173
174 return Cm::SpatialVectorF(top1, bottom1);
175 }
176
178 {
179 //const PxVec3 top = R * s.top;
180 //const PxVec3 bottom = T * s.top + R * s.bottom;
181
182 const PxVec3 top1 = q.rotate(s.top);
183 const PxVec3 bottom1 = T * s.top + q.rotate(s.bottom);
184
185 return Cm::UnAlignedSpatialVector(top1, bottom1);
186 }
187
188 //transpose is the same as inverse, R(inverse) = R(transpose)
189 //|R(t), 0 |
190 //|rXR(t), R(t)|
191 PX_CUDA_CALLABLE PX_FORCE_INLINE SpatialTransform getTranspose() const
192 {
193 SpatialTransform ret;
194 ret.q = q.getConjugate();
195 ret.R = R.getTranspose();
196 ret.T = T.getTranspose();
197 return ret;
198
199 }
200
201 PX_CUDA_CALLABLE PX_FORCE_INLINE Cm::SpatialVectorF transposeTransform(const Cm::SpatialVectorF& s) const
202 {
203 const PxVec3 top1 = q.rotateInv(s.top);
204 const PxVec3 bottom1 = T.transformTranspose(s.top) + q.rotateInv(s.bottom);
205
206 return Cm::SpatialVectorF(top1, bottom1);
207 }
208
209 PX_CUDA_CALLABLE PX_FORCE_INLINE Cm::UnAlignedSpatialVector transposeTransform(const Cm::UnAlignedSpatialVector& s) const
210 {
211 const PxVec3 top1 = q.rotateInv(s.top);
212 const PxVec3 bottom1 = T.transformTranspose(s.top) + q.rotateInv(s.bottom);
213
214 return Cm::UnAlignedSpatialVector(top1, bottom1);
215 }
216
217 PX_CUDA_CALLABLE PX_FORCE_INLINE void operator =(SpatialTransform& other)
218 {
219 R = other.R;
220 q = other.q;
221 T = other.T;
222 }
223
224 };
225
226 struct InvStIs
227 {
228 PxReal invStIs[3][3];
229 };
230
231 //this should be 6x6 matrix and initialize to
232 //|0, M|
233 //|I, 0|
234 //this should be 6x6 matrix but bottomRight is the transpose of topLeft
235 //so we can get rid of bottomRight
237 {
238 PxMat33 topLeft; // intialize to 0
239 PxMat33 topRight; // initialize to mass matrix
240 PxMat33 bottomLeft; // initialize to inertia
241 PxU32 padding; //4 112
242
243 public:
244
245 PX_CUDA_CALLABLE PX_FORCE_INLINE SpatialMatrix()
246 {
247 }
248
249 PX_CUDA_CALLABLE PX_FORCE_INLINE SpatialMatrix(PxZERO r) : topLeft(PxZero), topRight(PxZero),
250 bottomLeft(PxZero)
251 {
252 PX_UNUSED(r);
253 }
254
255 PX_CUDA_CALLABLE PX_FORCE_INLINE SpatialMatrix(const PxMat33& topLeft_, const PxMat33& topRight_, const PxMat33& bottomLeft_)
256 {
257 topLeft = topLeft_;
258 topRight = topRight_;
259 bottomLeft = bottomLeft_;
260 }
261
262 PX_CUDA_CALLABLE PX_FORCE_INLINE PxMat33 getBottomRight() const
263 {
264 return topLeft.getTranspose();
265 }
266
267 PX_FORCE_INLINE PX_CUDA_CALLABLE void setZero()
268 {
269 topLeft = PxMat33(0.f);
270 topRight = PxMat33(0.f);
271 bottomLeft = PxMat33(0.f);
272 }
273
274
275 //This assume angular is the top vector and linear is the bottom vector
276 PX_CUDA_CALLABLE PX_FORCE_INLINE Cm::SpatialVector operator *(const Cm::SpatialVector& s) const
277 {
278 const PxVec3 angular = topLeft * s.angular + topRight * s.linear;
279 const PxVec3 linear = bottomLeft * s.angular + topLeft.transformTranspose(s.linear);
280 return Cm::SpatialVector(linear, angular);
281 }
282
283 //This assume angular is the top vector and linear is the bottom vector
284 PX_CUDA_CALLABLE PX_FORCE_INLINE Cm::SpatialVectorF operator *(const Cm::SpatialVectorF& s) const
285 {
286 const PxVec3 top = topLeft * s.top + topRight * s.bottom;
287 const PxVec3 bottom = bottomLeft * s.top + topLeft.transformTranspose(s.bottom);
288
289 return Cm::SpatialVectorF(top, bottom);
290 }
291
292 PX_CUDA_CALLABLE PX_FORCE_INLINE Cm::UnAlignedSpatialVector operator *(const Cm::UnAlignedSpatialVector& s) const
293 {
294 const PxVec3 top = topLeft * s.top + topRight * s.bottom;
295 const PxVec3 bottom = bottomLeft * s.top + topLeft.transformTranspose(s.bottom);
296
297 return Cm::UnAlignedSpatialVector(top, bottom);
298 }
299
300
301 PX_CUDA_CALLABLE PX_FORCE_INLINE SpatialMatrix operator *(const PxReal& s) const
302 {
303 const PxMat33 newTopLeft = topLeft * s;
304 const PxMat33 newTopRight = topRight * s;
305 const PxMat33 newBottomLeft = bottomLeft * s;
306
307 return SpatialMatrix(newTopLeft, newTopRight, newBottomLeft);
308 }
309
310 PX_CUDA_CALLABLE PX_FORCE_INLINE SpatialMatrix operator -(const SpatialMatrix& s) const
311 {
312 const PxMat33 newTopLeft = topLeft - s.topLeft;
313 const PxMat33 newTopRight = topRight - s.topRight;
314 const PxMat33 newBottomLeft = bottomLeft - s.bottomLeft;
315
316 return SpatialMatrix(newTopLeft, newTopRight, newBottomLeft);
317 }
318
319 PX_CUDA_CALLABLE PX_FORCE_INLINE SpatialMatrix operator +(const SpatialMatrix& s) const
320 {
321 const PxMat33 newTopLeft = topLeft + s.topLeft;
322 const PxMat33 newTopRight = topRight + s.topRight;
323 const PxMat33 newBottomLeft = bottomLeft + s.bottomLeft;
324
325 return SpatialMatrix(newTopLeft, newTopRight, newBottomLeft);
326 }
327
328 PX_CUDA_CALLABLE PX_FORCE_INLINE SpatialMatrix operator-()
329 {
330 const PxMat33 newTopLeft = -topLeft;
331 const PxMat33 newTopRight = -topRight;
332 const PxMat33 newBottomLeft = -bottomLeft;
333
334 return SpatialMatrix(newTopLeft, newTopRight, newBottomLeft);
335 }
336
337 PX_CUDA_CALLABLE PX_FORCE_INLINE void operator +=(const SpatialMatrix& s)
338 {
339 topLeft += s.topLeft;
340 topRight += s.topRight;
341 bottomLeft += s.bottomLeft;
342 }
343
344 PX_CUDA_CALLABLE PX_FORCE_INLINE SpatialMatrix operator *(const SpatialMatrix& s)
345 {
346 const PxMat33 sBottomRight = s.topLeft.getTranspose();
347 const PxMat33 bottomRight = topLeft.getTranspose();
348
349 const PxMat33 newTopLeft = topLeft * s.topLeft + topRight * s.bottomLeft;
350 const PxMat33 newTopRight = topLeft * s.topRight + topRight * sBottomRight;
351 const PxMat33 newBottomLeft = bottomLeft * s.topLeft + bottomRight * s.bottomLeft;
352
353 return SpatialMatrix(newTopLeft, newTopRight, newBottomLeft);
354 }
355
356 static SpatialMatrix constructSpatialMatrix(const Cm::SpatialVector& Is, const Cm::SpatialVector& stI)
357 {
358 //construct top left
359 const PxVec3 tLeftC0 = Is.angular * stI.angular.x;
360 const PxVec3 tLeftC1 = Is.angular * stI.angular.y;
361 const PxVec3 tLeftC2 = Is.angular * stI.angular.z;
362
363 const PxMat33 topLeft(tLeftC0, tLeftC1, tLeftC2);
364
365 //construct top right
366 const PxVec3 tRightC0 = Is.angular * stI.linear.x;
367 const PxVec3 tRightC1 = Is.angular * stI.linear.y;
368 const PxVec3 tRightC2 = Is.angular * stI.linear.z;
369 const PxMat33 topRight(tRightC0, tRightC1, tRightC2);
370
371 //construct bottom left
372 const PxVec3 bLeftC0 = Is.linear * stI.angular.x;
373 const PxVec3 bLeftC1 = Is.linear * stI.angular.y;
374 const PxVec3 bLeftC2 = Is.linear * stI.angular.z;
375 const PxMat33 bottomLeft(bLeftC0, bLeftC1, bLeftC2);
376
377 return SpatialMatrix(topLeft, topRight, bottomLeft);
378 }
379
380 static PX_CUDA_CALLABLE SpatialMatrix constructSpatialMatrix(const Cm::SpatialVectorF& Is, const Cm::SpatialVectorF& stI)
381 {
382 //construct top left
383 const PxVec3 tLeftC0 = Is.top * stI.top.x;
384 const PxVec3 tLeftC1 = Is.top * stI.top.y;
385 const PxVec3 tLeftC2 = Is.top * stI.top.z;
386
387 const PxMat33 topLeft(tLeftC0, tLeftC1, tLeftC2);
388
389 //construct top right
390 const PxVec3 tRightC0 = Is.top * stI.bottom.x;
391 const PxVec3 tRightC1 = Is.top * stI.bottom.y;
392 const PxVec3 tRightC2 = Is.top * stI.bottom.z;
393 const PxMat33 topRight(tRightC0, tRightC1, tRightC2);
394
395 //construct bottom left
396 const PxVec3 bLeftC0 = Is.bottom * stI.top.x;
397 const PxVec3 bLeftC1 = Is.bottom * stI.top.y;
398 const PxVec3 bLeftC2 = Is.bottom * stI.top.z;
399 const PxMat33 bottomLeft(bLeftC0, bLeftC1, bLeftC2);
400
401 return SpatialMatrix(topLeft, topRight, bottomLeft);
402 }
403
404 template <typename SpatialVector>
405 static PX_CUDA_CALLABLE SpatialMatrix constructSpatialMatrix(const SpatialVector* columns)
406 {
407 const PxMat33 topLeft(columns[0].top, columns[1].top, columns[2].top);
408 const PxMat33 bottomLeft(columns[0].bottom, columns[1].bottom, columns[2].bottom);
409 const PxMat33 topRight(columns[3].top, columns[4].top, columns[5].top);
410
411 return SpatialMatrix(topLeft, topRight, bottomLeft);
412 }
413
414 PX_CUDA_CALLABLE PX_FORCE_INLINE SpatialMatrix getTranspose()
415 {
416 const PxMat33 newTopLeft = topLeft.getTranspose();
417 const PxMat33 newTopRight = bottomLeft.getTranspose();
418 const PxMat33 newBottomLeft = topRight.getTranspose();
419 //const PxMat33 newBottomRight = bottomRight.getTranspose();
420
421 return SpatialMatrix(newTopLeft, newTopRight, newBottomLeft);// , newBottomRight);
422 }
423
424 //static bool isTranspose(const PxMat33& a, const PxMat33& b)
425 //{
426 // PxReal eps = 0.01f;
427 // //test bottomRight is the transpose of topLeft
428 // for (PxU32 i = 0; i <3; ++i)
429 // {
430 // for (PxU32 j = 0; j <3; ++j)
431 // {
432 // if (PxAbs(a[i][j] - b[j][i]) > eps)
433 // return false;
434 // }
435 // }
436
437 // return true;
438 //}
439
440 PX_FORCE_INLINE bool isIdentity(const PxMat33& matrix)
441 {
442 const PxReal eps = 0.00001f;
443 const float x = PxAbs(1.f - matrix.column0.x);
444 const float y = PxAbs(1.f - matrix.column1.y);
445 const float z = PxAbs(1.f - matrix.column2.z);
446 const bool identity = ((x < eps) && PxAbs(matrix.column0.y - 0.f) < eps && PxAbs(matrix.column0.z - 0.f) < eps) &&
447 (PxAbs(matrix.column1.x - 0.f) < eps && (y < eps) && PxAbs(matrix.column1.z - 0.f) < eps) &&
448 (PxAbs(matrix.column2.x - 0.f) < eps && PxAbs(matrix.column2.y - 0.f) < eps && (z < eps));
449
450 return identity;
451 }
452
453 PX_FORCE_INLINE bool isZero(const PxMat33& matrix)
454 {
455 const PxReal eps = 0.0001f;
456 for (PxU32 i = 0; i < 3; ++i)
457 {
458 for (PxU32 j = 0; j < 3; ++j)
459 {
460 if (PxAbs(matrix[i][j]) > eps)
461 return false;
462 }
463 }
464
465 return true;
466 }
467
468 PX_FORCE_INLINE bool isIdentity()
469 {
470 const bool topLeftIsIdentity = isIdentity(topLeft);
471
472 const bool topRightIsZero = isZero(topRight);
473
474 const bool bottomLeftIsZero = isZero(bottomLeft);
475
476 return topLeftIsIdentity && topRightIsZero && bottomLeftIsZero;
477 }
478
479 static bool isEqual(const PxMat33& s0, const PxMat33& s1)
480 {
481 const PxReal eps = 0.00001f;
482 for (PxU32 i = 0; i < 3; ++i)
483 {
484 for (PxU32 j = 0; j < 3; ++j)
485 {
486 const PxReal t = s0[i][j] - s1[i][j];
487 if (PxAbs(t) > eps)
488 return false;
489 }
490 }
491
492 return true;
493 }
494
495 PX_FORCE_INLINE bool isEqual(const SpatialMatrix& s)
496 {
497 const bool topLeftEqual = isEqual(topLeft, s.topLeft);
498 const bool topRightEqual = isEqual(topRight, s.topRight);
499 const bool bottomLeftEqual = isEqual(bottomLeft, s.bottomLeft);
500
501 return topLeftEqual && topRightEqual && bottomLeftEqual;
502 }
503
504 static PX_CUDA_CALLABLE PX_FORCE_INLINE PxMat33 invertSym33(const PxMat33& in)
505 {
506 const PxVec3 v0 = in[1].cross(in[2]);
507 const PxVec3 v1 = in[2].cross(in[0]);
508 const PxVec3 v2 = in[0].cross(in[1]);
509
510 const PxReal det = v0.dot(in[0]);
511
512 if (det != 0)
513 {
514 const PxReal recipDet = 1.0f / det;
515
516 return PxMat33(v0 * recipDet,
517 PxVec3(v0.y, v1.y, v1.z) * recipDet,
518 PxVec3(v0.z, v1.z, v2.z) * recipDet);
519 }
520 else
521 {
522 return PxMat33(PxIdentity);
523 }
524 }
525
526 static PX_FORCE_INLINE aos::Mat33V invertSym33(const aos::Mat33V& in)
527 {
528 using namespace aos;
529 const Vec3V v0 = V3Cross(in.col1, in.col2);
530 const Vec3V v1 = V3Cross(in.col2, in.col0);
531 const Vec3V v2 = V3Cross(in.col0, in.col1);
532
533 const FloatV det = V3Dot(v0, in.col0);
534
535 const FloatV recipDet = FRecip(det);
536
537 if (!FAllEq(det, FZero()))
538 {
539 return Mat33V(V3Scale(v0, recipDet),
540 V3Scale(V3Merge(V3GetY(v0), V3GetY(v1), V3GetZ(v1)), recipDet),
541 V3Scale(V3Merge(V3GetZ(v0), V3GetZ(v1), V3GetZ(v2)), recipDet));
542 }
543 else
544 {
545 return Mat33V(V3UnitX(), V3UnitY(), V3UnitZ());
546 }
547
548 //return M33Inverse(in);
549 }
550
551 PX_CUDA_CALLABLE PX_FORCE_INLINE SpatialMatrix invertInertia()
552 {
553 PxMat33 aa = bottomLeft, ll = topRight, la = topLeft;
554
555 aa = (aa + aa.getTranspose())*0.5f;
556 ll = (ll + ll.getTranspose())*0.5f;
557
558 const PxMat33 AAInv = invertSym33(aa);
559
560 const PxMat33 z = -la * AAInv;
561 const PxMat33 S = ll + z * la.getTranspose(); // Schur complement of mAA
562
563 const PxMat33 LL = invertSym33(S);
564
565 const PxMat33 LA = LL * z;
566 const PxMat33 AA = AAInv + z.getTranspose() * LA;
567
568 const SpatialMatrix result(LA.getTranspose(), AA, LL);// , LA);
569
570 return result;
571 }
572
573 PX_FORCE_INLINE void M33Store(const aos::Mat33V& src, PxMat33& dest)
574 {
575 aos::V3StoreU(src.col0, dest.column0);
576 aos::V3StoreU(src.col1, dest.column1);
577 aos::V3StoreU(src.col2, dest.column2);
578 }
579
580 PX_FORCE_INLINE void invertInertiaV(SpatialMatrix& result)
581 {
582 using namespace aos;
583 Mat33V aa = M33Load(bottomLeft), ll = M33Load(topRight), la = M33Load(topLeft);
584
585 aa = M33Scale(M33Add(aa, M33Trnsps(aa)), FHalf());
586 ll = M33Scale(M33Add(ll, M33Trnsps(ll)), FHalf());
587
588 const Mat33V AAInv = invertSym33(aa);
589
590 const Mat33V z = M33MulM33(M33Neg(la), AAInv);
591 const Mat33V S = M33Add(ll, M33MulM33(z, M33Trnsps(la))); // Schur complement of mAA
592
593 const Mat33V LL = invertSym33(S);
594
595 const Mat33V LA = M33MulM33(LL, z);
596 const Mat33V AA = M33Add(AAInv, M33MulM33(M33Trnsps(z), LA));
597
598 M33Store(M33Trnsps(LA), result.topLeft);
599 M33Store(AA, result.topRight);
600 M33Store(LL, result.bottomLeft);
601 }
602
603 SpatialMatrix getInverse()
604 {
605 const PxMat33 bottomRight = topLeft.getTranspose();
606
607 const PxMat33 blInverse = bottomLeft.getInverse();
608 const PxMat33 lComp0 = blInverse * (-bottomRight);
609 const PxMat33 lComp1 = topLeft * lComp0 + topRight;
610
611 //This can be simplified
612 const PxMat33 newBottomLeft = lComp1.getInverse();
613 const PxMat33 newTopLeft = lComp0 * newBottomLeft;
614
615 const PxMat33 trInverse = topRight.getInverse();
616 const PxMat33 rComp0 = trInverse * (-topLeft);
617 const PxMat33 rComp1 = bottomLeft + bottomRight * rComp0;
618
619 const PxMat33 newTopRight = rComp1.getInverse();
620
621 return SpatialMatrix(newTopLeft, newTopRight, newBottomLeft);
622 }
623
624 void zero()
625 {
626 topLeft = PxMat33(PxZero);
627 topRight = PxMat33(PxZero);
628 bottomLeft = PxMat33(PxZero);
629 }
630
631 };
632
634 {
635 Cm::SpatialVectorF rows[6];
636
637 Cm::SpatialVectorF getResponse(const Cm::SpatialVectorF& impulse) const
638 {
639 /*return rows[0] * impulse.top.x + rows[1] * impulse.top.y + rows[2] * impulse.top.z
640 + rows[3] * impulse.bottom.x + rows[4] * impulse.bottom.y + rows[5] * impulse.bottom.z;*/
641
642 using namespace aos;
643 const Cm::SpatialVectorV row0(V3LoadA(&rows[0].top.x), V3LoadA(&rows[0].bottom.x));
644 const Cm::SpatialVectorV row1(V3LoadA(&rows[1].top.x), V3LoadA(&rows[1].bottom.x));
645 const Cm::SpatialVectorV row2(V3LoadA(&rows[2].top.x), V3LoadA(&rows[2].bottom.x));
646 const Cm::SpatialVectorV row3(V3LoadA(&rows[3].top.x), V3LoadA(&rows[3].bottom.x));
647 const Cm::SpatialVectorV row4(V3LoadA(&rows[4].top.x), V3LoadA(&rows[4].bottom.x));
648 const Cm::SpatialVectorV row5(V3LoadA(&rows[5].top.x), V3LoadA(&rows[5].bottom.x));
649
650 const Vec4V top = V4LoadA(&impulse.top.x);
651 const Vec4V bottom = V4LoadA(&impulse.bottom.x);
652
653 const FloatV ix = V4GetX(top);
654 const FloatV iy = V4GetY(top);
655 const FloatV iz = V4GetZ(top);
656 const FloatV ia = V4GetX(bottom);
657 const FloatV ib = V4GetY(bottom);
658 const FloatV ic = V4GetZ(bottom);
659
660 Cm::SpatialVectorV res = row0 * ix + row1 * iy + row2 * iz + row3 * ia + row4 * ib + row5 * ic;
661
662 Cm::SpatialVectorF returnVal;
663 V4StoreA(Vec4V_From_Vec3V(res.linear), &returnVal.top.x);
664 V4StoreA(Vec4V_From_Vec3V(res.angular), &returnVal.bottom.x);
665
666 return returnVal;
667
668 }
669
670 Cm::SpatialVectorV getResponse(const Cm::SpatialVectorV& impulse) const
671 {
672 using namespace aos;
673 const Cm::SpatialVectorV row0(V3LoadA(&rows[0].top.x), V3LoadA(&rows[0].bottom.x));
674 const Cm::SpatialVectorV row1(V3LoadA(&rows[1].top.x), V3LoadA(&rows[1].bottom.x));
675 const Cm::SpatialVectorV row2(V3LoadA(&rows[2].top.x), V3LoadA(&rows[2].bottom.x));
676 const Cm::SpatialVectorV row3(V3LoadA(&rows[3].top.x), V3LoadA(&rows[3].bottom.x));
677 const Cm::SpatialVectorV row4(V3LoadA(&rows[4].top.x), V3LoadA(&rows[4].bottom.x));
678 const Cm::SpatialVectorV row5(V3LoadA(&rows[5].top.x), V3LoadA(&rows[5].bottom.x));
679
680 const Vec3V top = impulse.linear;
681 const Vec3V bottom = impulse.angular;
682
683 const FloatV ix = V3GetX(top);
684 const FloatV iy = V3GetY(top);
685 const FloatV iz = V3GetZ(top);
686 const FloatV ia = V3GetX(bottom);
687 const FloatV ib = V3GetY(bottom);
688 const FloatV ic = V3GetZ(bottom);
689
690 Cm::SpatialVectorV res = row0 * ix + row1 * iy + row2 * iz + row3 * ia + row4 * ib + row5 * ic;
691 return res;
692 }
693 };
694
695 struct Temp6x6Matrix;
696
698 {
699 PxReal column[3][6];
700 public:
701
703 {
704
705 }
706
707 Temp6x3Matrix(const Cm::SpatialVectorF* spatialAxis)
708 {
709 constructColumn(column[0], spatialAxis[0]);
710 constructColumn(column[1], spatialAxis[1]);
711 constructColumn(column[2], spatialAxis[2]);
712 }
713
714 void constructColumn(PxReal* dest, const Cm::SpatialVectorF& v)
715 {
716 dest[0] = v.top.x;
717 dest[1] = v.top.y;
718 dest[2] = v.top.z;
719
720 dest[3] = v.bottom.x;
721 dest[4] = v.bottom.y;
722 dest[5] = v.bottom.z;
723 }
724
725 Temp6x6Matrix operator * (PxReal s[6][3]);
726
728 //PX_FORCE_INLINE Temp6x6Matrix operator * (PxReal s[6][3])
729 //{
730 // Temp6x6Matrix temp;
731
732 // for (PxU32 i = 0; i < 6; ++i)
733 // {
734 // PxReal* tc = temp.column[i];
735
736 // for (PxU32 j = 0; j < 6; ++j)
737 // {
738 // tc[j] = 0.f;
739 // for (PxU32 k = 0; k < 3; ++k)
740 // {
741 // tc[j] += column[k][j] * s[i][k];
742 // }
743 // }
744 // }
745
746 // return temp;
747 //}
748
749 PX_FORCE_INLINE Temp6x3Matrix operator * (const PxMat33& s)
750 {
751 Temp6x3Matrix temp;
752
753 for (PxU32 i = 0; i < 3; ++i)
754 {
755 PxReal* tc = temp.column[i];
756 const PxVec3 sc = s[i];
757
758 for (PxU32 j = 0; j < 6; ++j)
759 {
760 tc[j] = 0.f;
761 for (PxU32 k = 0; k < 3; ++k)
762 {
763 tc[j] += column[k][j] * sc[k];
764 }
765 }
766 }
767
768 return temp;
769 }
770
771 PX_FORCE_INLINE bool isColumnEqual(const PxU32 ind, const Cm::SpatialVectorF& col)
772 {
773 PxReal temp[6];
774 constructColumn(temp, col);
775 const PxReal eps = 0.00001f;
776 for (PxU32 i = 0; i < 6; ++i)
777 {
778 const PxReal dif = column[ind][i] - temp[i];
779 if (PxAbs(dif) > eps)
780 return false;
781 }
782 return true;
783 }
784
785 };
786
787
789 {
790 PxReal column[6][6];
791 public:
793 {
794
795 }
796
797 Temp6x6Matrix(const SpatialMatrix& spatialMatrix)
798 {
799 constructColumn(column[0], spatialMatrix.topLeft.column0, spatialMatrix.bottomLeft.column0);
800 constructColumn(column[1], spatialMatrix.topLeft.column1, spatialMatrix.bottomLeft.column1);
801 constructColumn(column[2], spatialMatrix.topLeft.column2, spatialMatrix.bottomLeft.column2);
802
803 const PxMat33 bottomRight = spatialMatrix.getBottomRight();
804 constructColumn(column[3], spatialMatrix.topRight.column0, bottomRight.column0);
805 constructColumn(column[4], spatialMatrix.topRight.column1, bottomRight.column1);
806 constructColumn(column[5], spatialMatrix.topRight.column2, bottomRight.column2);
807 }
808
809 void constructColumn(const PxU32 ind, const PxReal* const values)
810 {
811 for (PxU32 i = 0; i < 6; ++i)
812 {
813 column[ind][i] = values[i];
814 }
815 }
816
817 void constructColumn(PxReal* dest, const PxVec3& top, const PxVec3& bottom)
818 {
819 dest[0] = top.x;
820 dest[1] = top.y;
821 dest[2] = top.z;
822
823 dest[3] = bottom.x;
824 dest[4] = bottom.y;
825 dest[5] = bottom.z;
826 }
827
828 Temp6x6Matrix getTranspose() const
829 {
830 Temp6x6Matrix temp;
831 for (PxU32 i = 0; i < 6; ++i)
832 {
833 for (PxU32 j = 0; j < 6; ++j)
834 {
835 temp.column[i][j] = column[j][i];
836 }
837 }
838 return temp;
839 }
840
841 PX_FORCE_INLINE Cm::SpatialVector operator * (const Cm::SpatialVector& s) const
842 {
843 Temp6x6Matrix tempMatrix = getTranspose();
844 PxReal st[6];
845 st[0] = s.angular.x; st[1] = s.angular.y; st[2] = s.angular.z;
846 st[3] = s.linear.x; st[4] = s.linear.y; st[5] = s.linear.z;
847
848 PxReal result[6];
849 for (PxU32 i = 0; i < 6; i++)
850 {
851 result[i] = 0;
852 for (PxU32 j = 0; j < 6; ++j)
853 {
854 result[i] += tempMatrix.column[i][j] * st[j];
855 }
856 }
857
858
860 temp.angular.x = result[0]; temp.angular.y = result[1]; temp.angular.z = result[2];
861 temp.linear.x = result[3]; temp.linear.y = result[4]; temp.linear.z = result[5];
862 return temp;
863 }
864
865
866 PX_FORCE_INLINE Cm::SpatialVectorF operator * (const Cm::SpatialVectorF& s) const
867 {
868 PxReal st[6];
869 st[0] = s.top.x; st[1] = s.top.y; st[2] = s.top.z;
870 st[3] = s.bottom.x; st[4] = s.bottom.y; st[5] = s.bottom.z;
871
872 PxReal result[6];
873 for (PxU32 i = 0; i < 6; ++i)
874 {
875 result[i] = 0.f;
876 for (PxU32 j = 0; j < 6; ++j)
877 {
878 result[i] += column[j][i] * st[j];
879 }
880 }
881
883 temp.top.x = result[0]; temp.top.y = result[1]; temp.top.z = result[2];
884 temp.bottom.x = result[3]; temp.bottom.y = result[4]; temp.bottom.z = result[5];
885 return temp;
886 }
887
888 PX_FORCE_INLINE Temp6x3Matrix operator * (const Temp6x3Matrix& s) const
889 {
890 Temp6x3Matrix temp;
891 for (PxU32 i = 0; i < 3; ++i)
892 {
893 PxReal* result = temp.column[i];
894
895 const PxReal* input = s.column[i];
896
897 for (PxU32 j = 0; j < 6; ++j)
898 {
899 result[j] = 0.f;
900 for (PxU32 k = 0; k < 6; ++k)
901 {
902 result[j] += column[k][j] * input[k];
903 }
904 }
905 }
906
907 return temp;
908
909 }
910
911 PX_FORCE_INLINE Cm::SpatialVector spatialVectorMul(const Cm::SpatialVector& s)
912 {
913 PxReal st[6];
914 st[0] = s.angular.x; st[1] = s.angular.y; st[2] = s.angular.z;
915 st[3] = s.linear.x; st[4] = s.linear.y; st[5] = s.linear.z;
916
917 PxReal result[6];
918 for (PxU32 i = 0; i < 6; ++i)
919 {
920 result[i] = 0.f;
921 for (PxU32 j = 0; j < 6; j++)
922 {
923 result[i] += column[i][j] * st[j];
924 }
925 }
926
928 temp.angular.x = result[0]; temp.angular.y = result[1]; temp.angular.z = result[2];
929 temp.linear.x = result[3]; temp.linear.y = result[4]; temp.linear.z = result[5];
930 return temp;
931 }
932
933 PX_FORCE_INLINE bool isEqual(const Cm::SpatialVectorF* m)
934 {
935 PxReal temp[6];
936 const PxReal eps = 0.00001f;
937 for (PxU32 i = 0; i < 6; ++i)
938 {
939 temp[0] = m[i].top.x; temp[1] = m[i].top.y; temp[2] = m[i].top.z;
940 temp[3] = m[i].bottom.x; temp[4] = m[i].bottom.y; temp[5] = m[i].bottom.z;
941
942 for (PxU32 j = 0; j < 6; ++j)
943 {
944 const PxReal dif = column[i][j] - temp[j];
945 if (PxAbs(dif) > eps)
946 return false;
947 }
948 }
949
950 return true;
951 }
952 };
953
954 //s is 3x6 matrix
955 PX_FORCE_INLINE Temp6x6Matrix Temp6x3Matrix::operator * (PxReal s[6][3])
956 {
957 Temp6x6Matrix temp;
958
959 for (PxU32 i = 0; i < 6; ++i)
960 {
961 PxReal* tc = temp.column[i];
962
963 for (PxU32 j = 0; j < 6; ++j)
964 {
965 tc[j] = 0.f;
966 for (PxU32 k = 0; k < 3; ++k)
967 {
968 tc[j] += column[k][j] * s[i][k];
969 }
970 }
971 }
972
973 return temp;
974 }
975
976 PX_FORCE_INLINE void calculateNewVelocity(const PxTransform& newTransform, const PxTransform& oldTransform,
977 const PxReal dt, PxVec3& linear, PxVec3& angular)
978 {
979 //calculate the new velocity
980 linear = (newTransform.p - oldTransform.p) / dt;
981 PxQuat quat = newTransform.q * oldTransform.q.getConjugate();
982
983 if (quat.w < 0) //shortest angle.
984 quat = -quat;
985
986 PxReal angle;
987 PxVec3 axis;
988 quat.toRadiansAndUnitAxis(angle, axis);
989 angular = (axis * angle) / dt;
990 }
991
992
993 // generates a pair of quaternions (swing, twist) such that in = swing * twist, with
994 // swing.x = 0
995 // twist.y = twist.z = 0, and twist is a unit quat
996 PX_CUDA_CALLABLE PX_FORCE_INLINE void separateSwingTwist(const PxQuat& q, PxQuat& twist, PxQuat& swing1, PxQuat& swing2)
997 {
998 twist = q.x != 0.0f ? PxQuat(q.x, 0, 0, q.w).getNormalized() : PxQuat(PxIdentity);
999 PxQuat swing = q * twist.getConjugate();
1000 swing1 = swing.y != 0.f ? PxQuat(0.f, swing.y, 0.f, swing.w).getNormalized() : PxQuat(PxIdentity);
1001 swing = swing * swing1.getConjugate();
1002 swing2 = swing.z != 0.f ? PxQuat(0.f, 0.f, swing.z, swing.w).getNormalized() : PxQuat(PxIdentity);
1003 }
1004
1005 PX_CUDA_CALLABLE PX_FORCE_INLINE void separateSwingTwist2(const PxQuat& q, PxQuat& twist, PxQuat& swing1, PxQuat& swing2)
1006 {
1007 swing2 = q.z != 0.0f ? PxQuat(0.f, 0.f, q.z, q.w).getNormalized() : PxQuat(PxIdentity);
1008 PxQuat swing = q * swing2.getConjugate();
1009 swing1 = swing.y != 0.f ? PxQuat(0.f, swing.y, 0.f, swing.w).getNormalized() : PxQuat(PxIdentity);
1010 swing = swing * swing1.getConjugate();
1011 twist = swing.x != 0.f ? PxQuat(swing.x, 0.f, 0.f, swing.w).getNormalized() : PxQuat(PxIdentity);
1012 }
1013
1014
1015} //namespace Dy
1016
1017}
1018
1019#endif
Definition CmSpatialVector.h:46
3x3 matrix class
Definition PxMat33.h:91
PX_CUDA_CALLABLE PX_INLINE const PxVec3 transformTranspose(const PxVec3 &other) const
Transform vector by matrix transpose, v' = M^t*v.
Definition PxMat33.h:332
PX_CUDA_CALLABLE PX_FORCE_INLINE const PxMat33 getTranspose() const
Get transposed matrix.
Definition PxMat33.h:190
PX_CUDA_CALLABLE PX_INLINE const PxMat33 getInverse() const
Get the real inverse.
Definition PxMat33.h:200
This is a quaternion class. For more information on quaternion mathematics consult a mathematics sour...
Definition PxQuat.h:50
PX_CUDA_CALLABLE PX_FORCE_INLINE const PxVec3 rotate(const PxVec3 &v) const
Definition PxQuat.h:287
PX_CUDA_CALLABLE PX_FORCE_INLINE const PxVec3 rotateInv(const PxVec3 &v) const
Definition PxQuat.h:301
3 Element vector class.
Definition PxVec3.h:50
PX_CUDA_CALLABLE PX_FORCE_INLINE float dot(const PxVec3 &v) const
returns the scalar product of this and other.
Definition PxVec3.h:276
qua< float, defaultp > quat
Quaternion of single-precision floating-point numbers.
Definition quaternion_float.hpp:35
GLM_FUNC_DECL T angle(qua< T, Q > const &x)
Definition quaternion_trigonometric.inl:6
#define PX_FORCE_INLINE
Definition PxPreprocessor.h:335
Sorts an array of objects in ascending order, assuming that the predicate implements the < operator:
Definition PxBoxController.h:39
PX_FORCE_INLINE void * PxMemSet(void *dest, PxI32 c, PxU32 count)
Sets the bytes of the provided buffer to the specified value.
Definition PxMemory.h:67
PX_CUDA_CALLABLE PX_FORCE_INLINE float PxAbs(float a)
abs returns the absolute value of its argument.
Definition PxMath.h:109
PxZERO
Definition Px.h:93
Definition CmSpatialVector.h:134
Definition CmSpatialVector.h:483
Definition CmSpatialVector.h:310
Definition DyFeatherstoneArticulationUtils.h:227
Definition DyFeatherstoneArticulationUtils.h:634
Definition DyFeatherstoneArticulationUtils.h:237
Definition DyFeatherstoneArticulationUtils.h:45
Definition DyFeatherstoneArticulationUtils.h:119
PX_CUDA_CALLABLE PX_FORCE_INLINE Cm::SpatialVectorF operator*(const Cm::SpatialVectorF &s) const
Definition DyFeatherstoneArticulationUtils.h:166
Definition DyFeatherstoneArticulationUtils.h:698
Definition DyFeatherstoneArticulationUtils.h:789
Definition PxVecMathAoSScalar.h:52
Definition PxVecMathAoSScalar.h:101
Definition PxVecMathAoSScalar.h:77
Definition PxVecMathAoSScalar.h:65