2 Copyright (c) 2003-2015 Erwin Coumans, Jakub Stepien
4 This software is provided 'as-is', without any express or implied warranty.
5 In no event will the authors be held liable for any damages arising from the use of this software.
6 Permission is granted to anyone to use this software for any purpose,
7 including commercial applications, and to alter it and redistribute it freely,
8 subject to the following restrictions:
10 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
11 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
12 3. This notice may not be removed or altered from any source distribution.
15 ///These spatial algebra classes are used for btMultiBody,
16 ///see BulletDynamics/Featherstone
18 #ifndef BT_SPATIAL_ALGEBRA_H
19 #define BT_SPATIAL_ALGEBRA_H
21 #include "btMatrix3x3.h"
23 struct btSpatialForceVector
25 btVector3 m_topVec, m_bottomVec;
27 btSpatialForceVector() { setZero(); }
28 btSpatialForceVector(const btVector3 &angular, const btVector3 &linear) : m_topVec(linear), m_bottomVec(angular) {}
29 btSpatialForceVector(const btScalar &ax, const btScalar &ay, const btScalar &az, const btScalar &lx, const btScalar &ly, const btScalar &lz)
31 setValue(ax, ay, az, lx, ly, lz);
34 void setVector(const btVector3 &angular, const btVector3 &linear)
37 m_bottomVec = angular;
39 void setValue(const btScalar &ax, const btScalar &ay, const btScalar &az, const btScalar &lx, const btScalar &ly, const btScalar &lz)
41 m_bottomVec.setValue(ax, ay, az);
42 m_topVec.setValue(lx, ly, lz);
45 void addVector(const btVector3 &angular, const btVector3 &linear)
48 m_bottomVec += angular;
50 void addValue(const btScalar &ax, const btScalar &ay, const btScalar &az, const btScalar &lx, const btScalar &ly, const btScalar &lz)
60 const btVector3 &getLinear() const { return m_topVec; }
61 const btVector3 &getAngular() const { return m_bottomVec; }
63 void setLinear(const btVector3 &linear) { m_topVec = linear; }
64 void setAngular(const btVector3 &angular) { m_bottomVec = angular; }
66 void addAngular(const btVector3 &angular) { m_bottomVec += angular; }
67 void addLinear(const btVector3 &linear) { m_topVec += linear; }
72 m_bottomVec.setZero();
75 btSpatialForceVector &operator+=(const btSpatialForceVector &vec)
77 m_topVec += vec.m_topVec;
78 m_bottomVec += vec.m_bottomVec;
81 btSpatialForceVector &operator-=(const btSpatialForceVector &vec)
83 m_topVec -= vec.m_topVec;
84 m_bottomVec -= vec.m_bottomVec;
87 btSpatialForceVector operator-(const btSpatialForceVector &vec) const { return btSpatialForceVector(m_bottomVec - vec.m_bottomVec, m_topVec - vec.m_topVec); }
88 btSpatialForceVector operator+(const btSpatialForceVector &vec) const { return btSpatialForceVector(m_bottomVec + vec.m_bottomVec, m_topVec + vec.m_topVec); }
89 btSpatialForceVector operator-() const { return btSpatialForceVector(-m_bottomVec, -m_topVec); }
90 btSpatialForceVector operator*(const btScalar &s) const { return btSpatialForceVector(s * m_bottomVec, s * m_topVec); }
91 //btSpatialForceVector & operator = (const btSpatialForceVector &vec) { m_topVec = vec.m_topVec; m_bottomVec = vec.m_bottomVec; return *this; }
94 struct btSpatialMotionVector
96 btVector3 m_topVec, m_bottomVec;
98 btSpatialMotionVector() { setZero(); }
99 btSpatialMotionVector(const btVector3 &angular, const btVector3 &linear) : m_topVec(angular), m_bottomVec(linear) {}
101 void setVector(const btVector3 &angular, const btVector3 &linear)
104 m_bottomVec = linear;
106 void setValue(const btScalar &ax, const btScalar &ay, const btScalar &az, const btScalar &lx, const btScalar &ly, const btScalar &lz)
108 m_topVec.setValue(ax, ay, az);
109 m_bottomVec.setValue(lx, ly, lz);
112 void addVector(const btVector3 &angular, const btVector3 &linear)
115 m_bottomVec += angular;
117 void addValue(const btScalar &ax, const btScalar &ay, const btScalar &az, const btScalar &lx, const btScalar &ly, const btScalar &lz)
122 m_bottomVec[0] += lx;
123 m_bottomVec[1] += ly;
124 m_bottomVec[2] += lz;
127 const btVector3 &getAngular() const { return m_topVec; }
128 const btVector3 &getLinear() const { return m_bottomVec; }
130 void setAngular(const btVector3 &angular) { m_topVec = angular; }
131 void setLinear(const btVector3 &linear) { m_bottomVec = linear; }
133 void addAngular(const btVector3 &angular) { m_topVec += angular; }
134 void addLinear(const btVector3 &linear) { m_bottomVec += linear; }
139 m_bottomVec.setZero();
142 btScalar dot(const btSpatialForceVector &b) const
144 return m_bottomVec.dot(b.m_topVec) + m_topVec.dot(b.m_bottomVec);
147 template <typename SpatialVectorType>
148 void cross(const SpatialVectorType &b, SpatialVectorType &out) const
150 out.m_topVec = m_topVec.cross(b.m_topVec);
151 out.m_bottomVec = m_bottomVec.cross(b.m_topVec) + m_topVec.cross(b.m_bottomVec);
153 template <typename SpatialVectorType>
154 SpatialVectorType cross(const SpatialVectorType &b) const
156 SpatialVectorType out;
157 out.m_topVec = m_topVec.cross(b.m_topVec);
158 out.m_bottomVec = m_bottomVec.cross(b.m_topVec) + m_topVec.cross(b.m_bottomVec);
162 btSpatialMotionVector &operator+=(const btSpatialMotionVector &vec)
164 m_topVec += vec.m_topVec;
165 m_bottomVec += vec.m_bottomVec;
168 btSpatialMotionVector &operator-=(const btSpatialMotionVector &vec)
170 m_topVec -= vec.m_topVec;
171 m_bottomVec -= vec.m_bottomVec;
174 btSpatialMotionVector &operator*=(const btScalar &s)
180 btSpatialMotionVector operator-(const btSpatialMotionVector &vec) const { return btSpatialMotionVector(m_topVec - vec.m_topVec, m_bottomVec - vec.m_bottomVec); }
181 btSpatialMotionVector operator+(const btSpatialMotionVector &vec) const { return btSpatialMotionVector(m_topVec + vec.m_topVec, m_bottomVec + vec.m_bottomVec); }
182 btSpatialMotionVector operator-() const { return btSpatialMotionVector(-m_topVec, -m_bottomVec); }
183 btSpatialMotionVector operator*(const btScalar &s) const { return btSpatialMotionVector(s * m_topVec, s * m_bottomVec); }
186 struct btSymmetricSpatialDyad
188 btMatrix3x3 m_topLeftMat, m_topRightMat, m_bottomLeftMat;
190 btSymmetricSpatialDyad() { setIdentity(); }
191 btSymmetricSpatialDyad(const btMatrix3x3 &topLeftMat, const btMatrix3x3 &topRightMat, const btMatrix3x3 &bottomLeftMat) { setMatrix(topLeftMat, topRightMat, bottomLeftMat); }
193 void setMatrix(const btMatrix3x3 &topLeftMat, const btMatrix3x3 &topRightMat, const btMatrix3x3 &bottomLeftMat)
195 m_topLeftMat = topLeftMat;
196 m_topRightMat = topRightMat;
197 m_bottomLeftMat = bottomLeftMat;
200 void addMatrix(const btMatrix3x3 &topLeftMat, const btMatrix3x3 &topRightMat, const btMatrix3x3 &bottomLeftMat)
202 m_topLeftMat += topLeftMat;
203 m_topRightMat += topRightMat;
204 m_bottomLeftMat += bottomLeftMat;
209 m_topLeftMat.setIdentity();
210 m_topRightMat.setIdentity();
211 m_bottomLeftMat.setIdentity();
214 btSymmetricSpatialDyad &operator-=(const btSymmetricSpatialDyad &mat)
216 m_topLeftMat -= mat.m_topLeftMat;
217 m_topRightMat -= mat.m_topRightMat;
218 m_bottomLeftMat -= mat.m_bottomLeftMat;
222 btSpatialForceVector operator*(const btSpatialMotionVector &vec)
224 return btSpatialForceVector(m_bottomLeftMat * vec.m_topVec + m_topLeftMat.transpose() * vec.m_bottomVec, m_topLeftMat * vec.m_topVec + m_topRightMat * vec.m_bottomVec);
228 struct btSpatialTransformationMatrix
230 btMatrix3x3 m_rotMat; //btMatrix3x3 m_trnCrossMat;
233 enum eOutputOperation
240 template <typename SpatialVectorType>
241 void transform(const SpatialVectorType &inVec,
242 SpatialVectorType &outVec,
243 eOutputOperation outOp = None)
247 outVec.m_topVec = m_rotMat * inVec.m_topVec;
248 outVec.m_bottomVec = -m_trnVec.cross(outVec.m_topVec) + m_rotMat * inVec.m_bottomVec;
250 else if (outOp == Add)
252 outVec.m_topVec += m_rotMat * inVec.m_topVec;
253 outVec.m_bottomVec += -m_trnVec.cross(outVec.m_topVec) + m_rotMat * inVec.m_bottomVec;
255 else if (outOp == Subtract)
257 outVec.m_topVec -= m_rotMat * inVec.m_topVec;
258 outVec.m_bottomVec -= -m_trnVec.cross(outVec.m_topVec) + m_rotMat * inVec.m_bottomVec;
262 template <typename SpatialVectorType>
263 void transformRotationOnly(const SpatialVectorType &inVec,
264 SpatialVectorType &outVec,
265 eOutputOperation outOp = None)
269 outVec.m_topVec = m_rotMat * inVec.m_topVec;
270 outVec.m_bottomVec = m_rotMat * inVec.m_bottomVec;
272 else if (outOp == Add)
274 outVec.m_topVec += m_rotMat * inVec.m_topVec;
275 outVec.m_bottomVec += m_rotMat * inVec.m_bottomVec;
277 else if (outOp == Subtract)
279 outVec.m_topVec -= m_rotMat * inVec.m_topVec;
280 outVec.m_bottomVec -= m_rotMat * inVec.m_bottomVec;
284 template <typename SpatialVectorType>
285 void transformInverse(const SpatialVectorType &inVec,
286 SpatialVectorType &outVec,
287 eOutputOperation outOp = None)
291 outVec.m_topVec = m_rotMat.transpose() * inVec.m_topVec;
292 outVec.m_bottomVec = m_rotMat.transpose() * (inVec.m_bottomVec + m_trnVec.cross(inVec.m_topVec));
294 else if (outOp == Add)
296 outVec.m_topVec += m_rotMat.transpose() * inVec.m_topVec;
297 outVec.m_bottomVec += m_rotMat.transpose() * (inVec.m_bottomVec + m_trnVec.cross(inVec.m_topVec));
299 else if (outOp == Subtract)
301 outVec.m_topVec -= m_rotMat.transpose() * inVec.m_topVec;
302 outVec.m_bottomVec -= m_rotMat.transpose() * (inVec.m_bottomVec + m_trnVec.cross(inVec.m_topVec));
306 template <typename SpatialVectorType>
307 void transformInverseRotationOnly(const SpatialVectorType &inVec,
308 SpatialVectorType &outVec,
309 eOutputOperation outOp = None)
313 outVec.m_topVec = m_rotMat.transpose() * inVec.m_topVec;
314 outVec.m_bottomVec = m_rotMat.transpose() * inVec.m_bottomVec;
316 else if (outOp == Add)
318 outVec.m_topVec += m_rotMat.transpose() * inVec.m_topVec;
319 outVec.m_bottomVec += m_rotMat.transpose() * inVec.m_bottomVec;
321 else if (outOp == Subtract)
323 outVec.m_topVec -= m_rotMat.transpose() * inVec.m_topVec;
324 outVec.m_bottomVec -= m_rotMat.transpose() * inVec.m_bottomVec;
328 void transformInverse(const btSymmetricSpatialDyad &inMat,
329 btSymmetricSpatialDyad &outMat,
330 eOutputOperation outOp = None)
332 const btMatrix3x3 r_cross(0, -m_trnVec[2], m_trnVec[1],
333 m_trnVec[2], 0, -m_trnVec[0],
334 -m_trnVec[1], m_trnVec[0], 0);
338 outMat.m_topLeftMat = m_rotMat.transpose() * (inMat.m_topLeftMat - inMat.m_topRightMat * r_cross) * m_rotMat;
339 outMat.m_topRightMat = m_rotMat.transpose() * inMat.m_topRightMat * m_rotMat;
340 outMat.m_bottomLeftMat = m_rotMat.transpose() * (r_cross * (inMat.m_topLeftMat - inMat.m_topRightMat * r_cross) + inMat.m_bottomLeftMat - inMat.m_topLeftMat.transpose() * r_cross) * m_rotMat;
342 else if (outOp == Add)
344 outMat.m_topLeftMat += m_rotMat.transpose() * (inMat.m_topLeftMat - inMat.m_topRightMat * r_cross) * m_rotMat;
345 outMat.m_topRightMat += m_rotMat.transpose() * inMat.m_topRightMat * m_rotMat;
346 outMat.m_bottomLeftMat += m_rotMat.transpose() * (r_cross * (inMat.m_topLeftMat - inMat.m_topRightMat * r_cross) + inMat.m_bottomLeftMat - inMat.m_topLeftMat.transpose() * r_cross) * m_rotMat;
348 else if (outOp == Subtract)
350 outMat.m_topLeftMat -= m_rotMat.transpose() * (inMat.m_topLeftMat - inMat.m_topRightMat * r_cross) * m_rotMat;
351 outMat.m_topRightMat -= m_rotMat.transpose() * inMat.m_topRightMat * m_rotMat;
352 outMat.m_bottomLeftMat -= m_rotMat.transpose() * (r_cross * (inMat.m_topLeftMat - inMat.m_topRightMat * r_cross) + inMat.m_bottomLeftMat - inMat.m_topLeftMat.transpose() * r_cross) * m_rotMat;
356 template <typename SpatialVectorType>
357 SpatialVectorType operator*(const SpatialVectorType &vec)
359 SpatialVectorType out;
365 template <typename SpatialVectorType>
366 void symmetricSpatialOuterProduct(const SpatialVectorType &a, const SpatialVectorType &b, btSymmetricSpatialDyad &out)
370 out.m_topLeftMat = outerProduct(a.m_topVec, b.m_bottomVec);
371 out.m_topRightMat = outerProduct(a.m_topVec, b.m_topVec);
372 out.m_topLeftMat = outerProduct(a.m_bottomVec, b.m_bottomVec);
373 //maybe simple a*spatTranspose(a) would be nicer?
376 template <typename SpatialVectorType>
377 btSymmetricSpatialDyad symmetricSpatialOuterProduct(const SpatialVectorType &a, const SpatialVectorType &b)
379 btSymmetricSpatialDyad out;
381 out.m_topLeftMat = outerProduct(a.m_topVec, b.m_bottomVec);
382 out.m_topRightMat = outerProduct(a.m_topVec, b.m_topVec);
383 out.m_bottomLeftMat = outerProduct(a.m_bottomVec, b.m_bottomVec);
386 //maybe simple a*spatTranspose(a) would be nicer?
389 #endif //BT_SPATIAL_ALGEBRA_H