1 /// @file Built-In Matrix-Vector functions
7 #include "../IDConfig.hpp"
8 #define BT_ID_HAVE_MAT3X
10 namespace btInverseDynamics
18 /// This is a very basic implementation to enable stand-alone use of the library.
19 /// The implementation is not really optimized and misses many features that you would
20 /// want from a "fully featured" linear math library.
24 idScalar& operator()(int i) { return m_data[i]; }
25 const idScalar& operator()(int i) const { return m_data[i]; }
26 const int size() const { return 3; }
27 const vec3& operator=(const vec3& rhs);
28 const vec3& operator+=(const vec3& b);
29 const vec3& operator-=(const vec3& b);
30 vec3 cross(const vec3& b) const;
31 idScalar dot(const vec3& b) const;
33 friend vec3 operator*(const mat33& a, const vec3& b);
34 friend vec3 operator*(const vec3& a, const idScalar& s);
35 friend vec3 operator*(const idScalar& s, const vec3& a);
37 friend vec3 operator+(const vec3& a, const vec3& b);
38 friend vec3 operator-(const vec3& a, const vec3& b);
39 friend vec3 operator/(const vec3& a, const idScalar& s);
48 idScalar& operator()(int i, int j) { return m_data[3 * i + j]; }
49 const idScalar& operator()(int i, int j) const { return m_data[3 * i + j]; }
50 const mat33& operator=(const mat33& rhs);
51 mat33 transpose() const;
52 const mat33& operator+=(const mat33& b);
53 const mat33& operator-=(const mat33& b);
55 friend mat33 operator*(const mat33& a, const mat33& b);
56 friend vec3 operator*(const mat33& a, const vec3& b);
57 friend mat33 operator*(const mat33& a, const idScalar& s);
58 friend mat33 operator*(const idScalar& s, const mat33& a);
59 friend mat33 operator+(const mat33& a, const mat33& b);
60 friend mat33 operator-(const mat33& a, const mat33& b);
61 friend mat33 operator/(const mat33& a, const idScalar& s);
64 // layout is [0,1,2;3,4,5;6,7,8]
71 vecx(int size) : m_size(size)
73 m_data = static_cast<idScalar*>(idMalloc(sizeof(idScalar) * size));
75 ~vecx() { idFree(m_data); }
76 const vecx& operator=(const vecx& rhs);
77 idScalar& operator()(int i) { return m_data[i]; }
78 const idScalar& operator()(int i) const { return m_data[i]; }
79 const int& size() const { return m_size; }
81 friend vecx operator*(const vecx& a, const idScalar& s);
82 friend vecx operator*(const idScalar& s, const vecx& a);
84 friend vecx operator+(const vecx& a, const vecx& b);
85 friend vecx operator-(const vecx& a, const vecx& b);
86 friend vecx operator/(const vecx& a, const idScalar& s);
102 matxx(int rows, int cols) : m_rows(rows), m_cols(cols)
104 m_data = static_cast<idScalar*>(idMalloc(sizeof(idScalar) * rows * cols));
106 ~matxx() { idFree(m_data); }
107 idScalar& operator()(int row, int col) { return m_data[row * m_cols + col]; }
108 const idScalar& operator()(int row, int col) const { return m_data[row * m_cols + col]; }
109 const int& rows() const { return m_rows; }
110 const int& cols() const { return m_cols; }
126 mat3x(const mat3x& rhs)
132 mat3x(int rows, int cols) : m_cols(cols)
136 void operator=(const mat3x& rhs)
138 if (m_cols != rhs.m_cols)
140 bt_id_error_message("size missmatch, cols= %d but rhs.cols= %d\n", cols(), rhs.cols());
143 for (int i = 0; i < 3 * m_cols; i++)
145 m_data[i] = rhs.m_data[i];
153 idScalar& operator()(int row, int col) { return m_data[row * m_cols + col]; }
154 const idScalar& operator()(int row, int col) const { return m_data[row * m_cols + col]; }
155 int rows() const { return m_rows; }
156 const int& cols() const { return m_cols; }
157 void resize(int rows, int cols)
165 memset(m_data, 0x0, sizeof(idScalar) * m_rows * m_cols);
167 // avoid operators that would allocate -- use functions sub/add/mul in IDMath.hpp instead
169 void allocate() { m_data = static_cast<idScalar*>(idMalloc(sizeof(idScalar) * m_rows * m_cols)); }
170 void free() { idFree(m_data); }
179 inline void resize(mat3x& m, idArrayIdx size)
185 //////////////////////////////////////////////////
187 inline const vec3& vec3::operator=(const vec3& rhs)
191 memcpy(m_data, rhs.m_data, 3 * sizeof(idScalar));
196 inline vec3 vec3::cross(const vec3& b) const
199 result.m_data[0] = m_data[1] * b.m_data[2] - m_data[2] * b.m_data[1];
200 result.m_data[1] = m_data[2] * b.m_data[0] - m_data[0] * b.m_data[2];
201 result.m_data[2] = m_data[0] * b.m_data[1] - m_data[1] * b.m_data[0];
206 inline idScalar vec3::dot(const vec3& b) const
208 return m_data[0] * b.m_data[0] + m_data[1] * b.m_data[1] + m_data[2] * b.m_data[2];
211 inline const mat33& mat33::operator=(const mat33& rhs)
215 memcpy(m_data, rhs.m_data, 9 * sizeof(idScalar));
219 inline mat33 mat33::transpose() const
222 result.m_data[0] = m_data[0];
223 result.m_data[1] = m_data[3];
224 result.m_data[2] = m_data[6];
225 result.m_data[3] = m_data[1];
226 result.m_data[4] = m_data[4];
227 result.m_data[5] = m_data[7];
228 result.m_data[6] = m_data[2];
229 result.m_data[7] = m_data[5];
230 result.m_data[8] = m_data[8];
235 inline mat33 operator*(const mat33& a, const mat33& b)
239 a.m_data[0] * b.m_data[0] + a.m_data[1] * b.m_data[3] + a.m_data[2] * b.m_data[6];
241 a.m_data[0] * b.m_data[1] + a.m_data[1] * b.m_data[4] + a.m_data[2] * b.m_data[7];
243 a.m_data[0] * b.m_data[2] + a.m_data[1] * b.m_data[5] + a.m_data[2] * b.m_data[8];
245 a.m_data[3] * b.m_data[0] + a.m_data[4] * b.m_data[3] + a.m_data[5] * b.m_data[6];
247 a.m_data[3] * b.m_data[1] + a.m_data[4] * b.m_data[4] + a.m_data[5] * b.m_data[7];
249 a.m_data[3] * b.m_data[2] + a.m_data[4] * b.m_data[5] + a.m_data[5] * b.m_data[8];
251 a.m_data[6] * b.m_data[0] + a.m_data[7] * b.m_data[3] + a.m_data[8] * b.m_data[6];
253 a.m_data[6] * b.m_data[1] + a.m_data[7] * b.m_data[4] + a.m_data[8] * b.m_data[7];
255 a.m_data[6] * b.m_data[2] + a.m_data[7] * b.m_data[5] + a.m_data[8] * b.m_data[8];
260 inline const mat33& mat33::operator+=(const mat33& b)
262 for (int i = 0; i < 9; i++)
264 m_data[i] += b.m_data[i];
270 inline const mat33& mat33::operator-=(const mat33& b)
272 for (int i = 0; i < 9; i++)
274 m_data[i] -= b.m_data[i];
279 inline vec3 operator*(const mat33& a, const vec3& b)
284 a.m_data[0] * b.m_data[0] + a.m_data[1] * b.m_data[1] + a.m_data[2] * b.m_data[2];
286 a.m_data[3] * b.m_data[0] + a.m_data[4] * b.m_data[1] + a.m_data[5] * b.m_data[2];
288 a.m_data[6] * b.m_data[0] + a.m_data[7] * b.m_data[1] + a.m_data[8] * b.m_data[2];
293 inline const vec3& vec3::operator+=(const vec3& b)
295 for (int i = 0; i < 3; i++)
297 m_data[i] += b.m_data[i];
302 inline const vec3& vec3::operator-=(const vec3& b)
304 for (int i = 0; i < 3; i++)
306 m_data[i] -= b.m_data[i];
311 inline mat33 operator*(const mat33& a, const idScalar& s)
314 for (int i = 0; i < 9; i++)
316 result.m_data[i] = a.m_data[i] * s;
321 inline mat33 operator*(const idScalar& s, const mat33& a) { return a * s; }
323 inline vec3 operator*(const vec3& a, const idScalar& s)
326 for (int i = 0; i < 3; i++)
328 result.m_data[i] = a.m_data[i] * s;
332 inline vec3 operator*(const idScalar& s, const vec3& a) { return a * s; }
334 inline mat33 operator+(const mat33& a, const mat33& b)
337 for (int i = 0; i < 9; i++)
339 result.m_data[i] = a.m_data[i] + b.m_data[i];
343 inline vec3 operator+(const vec3& a, const vec3& b)
346 for (int i = 0; i < 3; i++)
348 result.m_data[i] = a.m_data[i] + b.m_data[i];
353 inline mat33 operator-(const mat33& a, const mat33& b)
356 for (int i = 0; i < 9; i++)
358 result.m_data[i] = a.m_data[i] - b.m_data[i];
362 inline vec3 operator-(const vec3& a, const vec3& b)
365 for (int i = 0; i < 3; i++)
367 result.m_data[i] = a.m_data[i] - b.m_data[i];
372 inline mat33 operator/(const mat33& a, const idScalar& s)
375 for (int i = 0; i < 9; i++)
377 result.m_data[i] = a.m_data[i] / s;
382 inline vec3 operator/(const vec3& a, const idScalar& s)
385 for (int i = 0; i < 3; i++)
387 result.m_data[i] = a.m_data[i] / s;
392 inline const vecx& vecx::operator=(const vecx& rhs)
394 if (size() != rhs.size())
396 bt_id_error_message("size missmatch, size()= %d but rhs.size()= %d\n", size(), rhs.size());
401 memcpy(m_data, rhs.m_data, rhs.size() * sizeof(idScalar));
405 inline vecx operator*(const vecx& a, const idScalar& s)
407 vecx result(a.size());
408 for (int i = 0; i < result.size(); i++)
410 result.m_data[i] = a.m_data[i] * s;
414 inline vecx operator*(const idScalar& s, const vecx& a) { return a * s; }
415 inline vecx operator+(const vecx& a, const vecx& b)
417 vecx result(a.size());
418 // TODO: error handling for a.size() != b.size()??
419 if (a.size() != b.size())
421 bt_id_error_message("size missmatch. a.size()= %d, b.size()= %d\n", a.size(), b.size());
424 for (int i = 0; i < a.size(); i++)
426 result.m_data[i] = a.m_data[i] + b.m_data[i];
431 inline vecx operator-(const vecx& a, const vecx& b)
433 vecx result(a.size());
434 // TODO: error handling for a.size() != b.size()??
435 if (a.size() != b.size())
437 bt_id_error_message("size missmatch. a.size()= %d, b.size()= %d\n", a.size(), b.size());
440 for (int i = 0; i < a.size(); i++)
442 result.m_data[i] = a.m_data[i] - b.m_data[i];
446 inline vecx operator/(const vecx& a, const idScalar& s)
448 vecx result(a.size());
449 for (int i = 0; i < result.size(); i++)
451 result.m_data[i] = a.m_data[i] / s;
457 inline vec3 operator*(const mat3x& a, const vecx& b)
460 if (a.cols() != b.size())
462 bt_id_error_message("size missmatch. a.cols()= %d, b.size()= %d\n", a.cols(), b.size());
468 for (int i = 0; i < b.size(); i++)
470 for (int k = 0; k < 3; k++)
472 result(k) += a(k, i) * b(i);
478 inline void setMatxxElem(const idArrayIdx row, const idArrayIdx col, const idScalar val, matxx* m)
480 (*m)(row, col) = val;
483 inline void setMat3xElem(const idArrayIdx row, const idArrayIdx col, const idScalar val, mat3x* m)
485 (*m)(row, col) = val;
488 } // namespace btInverseDynamics