IDMatVec.hpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489
  1. /// @file Built-In Matrix-Vector functions
  2. #ifndef IDMATVEC_HPP_
  3. #define IDMATVEC_HPP_
  4. #include <cstdlib>
  5. #include "../IDConfig.hpp"
  6. #define BT_ID_HAVE_MAT3X
  7. namespace btInverseDynamics
  8. {
  9. class vec3;
  10. class vecx;
  11. class mat33;
  12. class matxx;
  13. class mat3x;
  14. /// This is a very basic implementation to enable stand-alone use of the library.
  15. /// The implementation is not really optimized and misses many features that you would
  16. /// want from a "fully featured" linear math library.
  17. class vec3
  18. {
  19. public:
  20. idScalar& operator()(int i) { return m_data[i]; }
  21. const idScalar& operator()(int i) const { return m_data[i]; }
  22. const int size() const { return 3; }
  23. const vec3& operator=(const vec3& rhs);
  24. const vec3& operator+=(const vec3& b);
  25. const vec3& operator-=(const vec3& b);
  26. vec3 cross(const vec3& b) const;
  27. idScalar dot(const vec3& b) const;
  28. friend vec3 operator*(const mat33& a, const vec3& b);
  29. friend vec3 operator*(const vec3& a, const idScalar& s);
  30. friend vec3 operator*(const idScalar& s, const vec3& a);
  31. friend vec3 operator+(const vec3& a, const vec3& b);
  32. friend vec3 operator-(const vec3& a, const vec3& b);
  33. friend vec3 operator/(const vec3& a, const idScalar& s);
  34. private:
  35. idScalar m_data[3];
  36. };
  37. class mat33
  38. {
  39. public:
  40. idScalar& operator()(int i, int j) { return m_data[3 * i + j]; }
  41. const idScalar& operator()(int i, int j) const { return m_data[3 * i + j]; }
  42. const mat33& operator=(const mat33& rhs);
  43. mat33 transpose() const;
  44. const mat33& operator+=(const mat33& b);
  45. const mat33& operator-=(const mat33& b);
  46. friend mat33 operator*(const mat33& a, const mat33& b);
  47. friend vec3 operator*(const mat33& a, const vec3& b);
  48. friend mat33 operator*(const mat33& a, const idScalar& s);
  49. friend mat33 operator*(const idScalar& s, const mat33& a);
  50. friend mat33 operator+(const mat33& a, const mat33& b);
  51. friend mat33 operator-(const mat33& a, const mat33& b);
  52. friend mat33 operator/(const mat33& a, const idScalar& s);
  53. private:
  54. // layout is [0,1,2;3,4,5;6,7,8]
  55. idScalar m_data[9];
  56. };
  57. class vecx
  58. {
  59. public:
  60. vecx(int size) : m_size(size)
  61. {
  62. m_data = static_cast<idScalar*>(idMalloc(sizeof(idScalar) * size));
  63. }
  64. ~vecx() { idFree(m_data); }
  65. const vecx& operator=(const vecx& rhs);
  66. idScalar& operator()(int i) { return m_data[i]; }
  67. const idScalar& operator()(int i) const { return m_data[i]; }
  68. const int& size() const { return m_size; }
  69. friend vecx operator*(const vecx& a, const idScalar& s);
  70. friend vecx operator*(const idScalar& s, const vecx& a);
  71. friend vecx operator+(const vecx& a, const vecx& b);
  72. friend vecx operator-(const vecx& a, const vecx& b);
  73. friend vecx operator/(const vecx& a, const idScalar& s);
  74. private:
  75. int m_size;
  76. idScalar* m_data;
  77. };
  78. class matxx
  79. {
  80. public:
  81. matxx()
  82. {
  83. m_data = 0x0;
  84. m_cols = 0;
  85. m_rows = 0;
  86. }
  87. matxx(int rows, int cols) : m_rows(rows), m_cols(cols)
  88. {
  89. m_data = static_cast<idScalar*>(idMalloc(sizeof(idScalar) * rows * cols));
  90. }
  91. ~matxx() { idFree(m_data); }
  92. idScalar& operator()(int row, int col) { return m_data[row * m_cols + col]; }
  93. const idScalar& operator()(int row, int col) const { return m_data[row * m_cols + col]; }
  94. const int& rows() const { return m_rows; }
  95. const int& cols() const { return m_cols; }
  96. private:
  97. int m_rows;
  98. int m_cols;
  99. idScalar* m_data;
  100. };
  101. class mat3x
  102. {
  103. public:
  104. mat3x()
  105. {
  106. m_data = 0x0;
  107. m_cols = 0;
  108. }
  109. mat3x(const mat3x& rhs)
  110. {
  111. m_cols = rhs.m_cols;
  112. allocate();
  113. *this = rhs;
  114. }
  115. mat3x(int rows, int cols) : m_cols(cols)
  116. {
  117. allocate();
  118. };
  119. void operator=(const mat3x& rhs)
  120. {
  121. if (m_cols != rhs.m_cols)
  122. {
  123. bt_id_error_message("size missmatch, cols= %d but rhs.cols= %d\n", cols(), rhs.cols());
  124. abort();
  125. }
  126. for (int i = 0; i < 3 * m_cols; i++)
  127. {
  128. m_data[i] = rhs.m_data[i];
  129. }
  130. }
  131. ~mat3x()
  132. {
  133. free();
  134. }
  135. idScalar& operator()(int row, int col) { return m_data[row * m_cols + col]; }
  136. const idScalar& operator()(int row, int col) const { return m_data[row * m_cols + col]; }
  137. int rows() const { return m_rows; }
  138. const int& cols() const { return m_cols; }
  139. void resize(int rows, int cols)
  140. {
  141. m_cols = cols;
  142. free();
  143. allocate();
  144. }
  145. void setZero()
  146. {
  147. memset(m_data, 0x0, sizeof(idScalar) * m_rows * m_cols);
  148. }
  149. // avoid operators that would allocate -- use functions sub/add/mul in IDMath.hpp instead
  150. private:
  151. void allocate() { m_data = static_cast<idScalar*>(idMalloc(sizeof(idScalar) * m_rows * m_cols)); }
  152. void free() { idFree(m_data); }
  153. enum
  154. {
  155. m_rows = 3
  156. };
  157. int m_cols;
  158. idScalar* m_data;
  159. };
  160. inline void resize(mat3x& m, idArrayIdx size)
  161. {
  162. m.resize(3, size);
  163. m.setZero();
  164. }
  165. //////////////////////////////////////////////////
  166. // Implementations
  167. inline const vec3& vec3::operator=(const vec3& rhs)
  168. {
  169. if (&rhs != this)
  170. {
  171. memcpy(m_data, rhs.m_data, 3 * sizeof(idScalar));
  172. }
  173. return *this;
  174. }
  175. inline vec3 vec3::cross(const vec3& b) const
  176. {
  177. vec3 result;
  178. result.m_data[0] = m_data[1] * b.m_data[2] - m_data[2] * b.m_data[1];
  179. result.m_data[1] = m_data[2] * b.m_data[0] - m_data[0] * b.m_data[2];
  180. result.m_data[2] = m_data[0] * b.m_data[1] - m_data[1] * b.m_data[0];
  181. return result;
  182. }
  183. inline idScalar vec3::dot(const vec3& b) const
  184. {
  185. return m_data[0] * b.m_data[0] + m_data[1] * b.m_data[1] + m_data[2] * b.m_data[2];
  186. }
  187. inline const mat33& mat33::operator=(const mat33& rhs)
  188. {
  189. if (&rhs != this)
  190. {
  191. memcpy(m_data, rhs.m_data, 9 * sizeof(idScalar));
  192. }
  193. return *this;
  194. }
  195. inline mat33 mat33::transpose() const
  196. {
  197. mat33 result;
  198. result.m_data[0] = m_data[0];
  199. result.m_data[1] = m_data[3];
  200. result.m_data[2] = m_data[6];
  201. result.m_data[3] = m_data[1];
  202. result.m_data[4] = m_data[4];
  203. result.m_data[5] = m_data[7];
  204. result.m_data[6] = m_data[2];
  205. result.m_data[7] = m_data[5];
  206. result.m_data[8] = m_data[8];
  207. return result;
  208. }
  209. inline mat33 operator*(const mat33& a, const mat33& b)
  210. {
  211. mat33 result;
  212. result.m_data[0] =
  213. a.m_data[0] * b.m_data[0] + a.m_data[1] * b.m_data[3] + a.m_data[2] * b.m_data[6];
  214. result.m_data[1] =
  215. a.m_data[0] * b.m_data[1] + a.m_data[1] * b.m_data[4] + a.m_data[2] * b.m_data[7];
  216. result.m_data[2] =
  217. a.m_data[0] * b.m_data[2] + a.m_data[1] * b.m_data[5] + a.m_data[2] * b.m_data[8];
  218. result.m_data[3] =
  219. a.m_data[3] * b.m_data[0] + a.m_data[4] * b.m_data[3] + a.m_data[5] * b.m_data[6];
  220. result.m_data[4] =
  221. a.m_data[3] * b.m_data[1] + a.m_data[4] * b.m_data[4] + a.m_data[5] * b.m_data[7];
  222. result.m_data[5] =
  223. a.m_data[3] * b.m_data[2] + a.m_data[4] * b.m_data[5] + a.m_data[5] * b.m_data[8];
  224. result.m_data[6] =
  225. a.m_data[6] * b.m_data[0] + a.m_data[7] * b.m_data[3] + a.m_data[8] * b.m_data[6];
  226. result.m_data[7] =
  227. a.m_data[6] * b.m_data[1] + a.m_data[7] * b.m_data[4] + a.m_data[8] * b.m_data[7];
  228. result.m_data[8] =
  229. a.m_data[6] * b.m_data[2] + a.m_data[7] * b.m_data[5] + a.m_data[8] * b.m_data[8];
  230. return result;
  231. }
  232. inline const mat33& mat33::operator+=(const mat33& b)
  233. {
  234. for (int i = 0; i < 9; i++)
  235. {
  236. m_data[i] += b.m_data[i];
  237. }
  238. return *this;
  239. }
  240. inline const mat33& mat33::operator-=(const mat33& b)
  241. {
  242. for (int i = 0; i < 9; i++)
  243. {
  244. m_data[i] -= b.m_data[i];
  245. }
  246. return *this;
  247. }
  248. inline vec3 operator*(const mat33& a, const vec3& b)
  249. {
  250. vec3 result;
  251. result.m_data[0] =
  252. a.m_data[0] * b.m_data[0] + a.m_data[1] * b.m_data[1] + a.m_data[2] * b.m_data[2];
  253. result.m_data[1] =
  254. a.m_data[3] * b.m_data[0] + a.m_data[4] * b.m_data[1] + a.m_data[5] * b.m_data[2];
  255. result.m_data[2] =
  256. a.m_data[6] * b.m_data[0] + a.m_data[7] * b.m_data[1] + a.m_data[8] * b.m_data[2];
  257. return result;
  258. }
  259. inline const vec3& vec3::operator+=(const vec3& b)
  260. {
  261. for (int i = 0; i < 3; i++)
  262. {
  263. m_data[i] += b.m_data[i];
  264. }
  265. return *this;
  266. }
  267. inline const vec3& vec3::operator-=(const vec3& b)
  268. {
  269. for (int i = 0; i < 3; i++)
  270. {
  271. m_data[i] -= b.m_data[i];
  272. }
  273. return *this;
  274. }
  275. inline mat33 operator*(const mat33& a, const idScalar& s)
  276. {
  277. mat33 result;
  278. for (int i = 0; i < 9; i++)
  279. {
  280. result.m_data[i] = a.m_data[i] * s;
  281. }
  282. return result;
  283. }
  284. inline mat33 operator*(const idScalar& s, const mat33& a) { return a * s; }
  285. inline vec3 operator*(const vec3& a, const idScalar& s)
  286. {
  287. vec3 result;
  288. for (int i = 0; i < 3; i++)
  289. {
  290. result.m_data[i] = a.m_data[i] * s;
  291. }
  292. return result;
  293. }
  294. inline vec3 operator*(const idScalar& s, const vec3& a) { return a * s; }
  295. inline mat33 operator+(const mat33& a, const mat33& b)
  296. {
  297. mat33 result;
  298. for (int i = 0; i < 9; i++)
  299. {
  300. result.m_data[i] = a.m_data[i] + b.m_data[i];
  301. }
  302. return result;
  303. }
  304. inline vec3 operator+(const vec3& a, const vec3& b)
  305. {
  306. vec3 result;
  307. for (int i = 0; i < 3; i++)
  308. {
  309. result.m_data[i] = a.m_data[i] + b.m_data[i];
  310. }
  311. return result;
  312. }
  313. inline mat33 operator-(const mat33& a, const mat33& b)
  314. {
  315. mat33 result;
  316. for (int i = 0; i < 9; i++)
  317. {
  318. result.m_data[i] = a.m_data[i] - b.m_data[i];
  319. }
  320. return result;
  321. }
  322. inline vec3 operator-(const vec3& a, const vec3& b)
  323. {
  324. vec3 result;
  325. for (int i = 0; i < 3; i++)
  326. {
  327. result.m_data[i] = a.m_data[i] - b.m_data[i];
  328. }
  329. return result;
  330. }
  331. inline mat33 operator/(const mat33& a, const idScalar& s)
  332. {
  333. mat33 result;
  334. for (int i = 0; i < 9; i++)
  335. {
  336. result.m_data[i] = a.m_data[i] / s;
  337. }
  338. return result;
  339. }
  340. inline vec3 operator/(const vec3& a, const idScalar& s)
  341. {
  342. vec3 result;
  343. for (int i = 0; i < 3; i++)
  344. {
  345. result.m_data[i] = a.m_data[i] / s;
  346. }
  347. return result;
  348. }
  349. inline const vecx& vecx::operator=(const vecx& rhs)
  350. {
  351. if (size() != rhs.size())
  352. {
  353. bt_id_error_message("size missmatch, size()= %d but rhs.size()= %d\n", size(), rhs.size());
  354. abort();
  355. }
  356. if (&rhs != this)
  357. {
  358. memcpy(m_data, rhs.m_data, rhs.size() * sizeof(idScalar));
  359. }
  360. return *this;
  361. }
  362. inline vecx operator*(const vecx& a, const idScalar& s)
  363. {
  364. vecx result(a.size());
  365. for (int i = 0; i < result.size(); i++)
  366. {
  367. result.m_data[i] = a.m_data[i] * s;
  368. }
  369. return result;
  370. }
  371. inline vecx operator*(const idScalar& s, const vecx& a) { return a * s; }
  372. inline vecx operator+(const vecx& a, const vecx& b)
  373. {
  374. vecx result(a.size());
  375. // TODO: error handling for a.size() != b.size()??
  376. if (a.size() != b.size())
  377. {
  378. bt_id_error_message("size missmatch. a.size()= %d, b.size()= %d\n", a.size(), b.size());
  379. abort();
  380. }
  381. for (int i = 0; i < a.size(); i++)
  382. {
  383. result.m_data[i] = a.m_data[i] + b.m_data[i];
  384. }
  385. return result;
  386. }
  387. inline vecx operator-(const vecx& a, const vecx& b)
  388. {
  389. vecx result(a.size());
  390. // TODO: error handling for a.size() != b.size()??
  391. if (a.size() != b.size())
  392. {
  393. bt_id_error_message("size missmatch. a.size()= %d, b.size()= %d\n", a.size(), b.size());
  394. abort();
  395. }
  396. for (int i = 0; i < a.size(); i++)
  397. {
  398. result.m_data[i] = a.m_data[i] - b.m_data[i];
  399. }
  400. return result;
  401. }
  402. inline vecx operator/(const vecx& a, const idScalar& s)
  403. {
  404. vecx result(a.size());
  405. for (int i = 0; i < result.size(); i++)
  406. {
  407. result.m_data[i] = a.m_data[i] / s;
  408. }
  409. return result;
  410. }
  411. inline vec3 operator*(const mat3x& a, const vecx& b)
  412. {
  413. vec3 result;
  414. if (a.cols() != b.size())
  415. {
  416. bt_id_error_message("size missmatch. a.cols()= %d, b.size()= %d\n", a.cols(), b.size());
  417. abort();
  418. }
  419. result(0) = 0.0;
  420. result(1) = 0.0;
  421. result(2) = 0.0;
  422. for (int i = 0; i < b.size(); i++)
  423. {
  424. for (int k = 0; k < 3; k++)
  425. {
  426. result(k) += a(k, i) * b(i);
  427. }
  428. }
  429. return result;
  430. }
  431. inline void setMatxxElem(const idArrayIdx row, const idArrayIdx col, const idScalar val, matxx* m)
  432. {
  433. (*m)(row, col) = val;
  434. }
  435. inline void setMat3xElem(const idArrayIdx row, const idArrayIdx col, const idScalar val, mat3x* m)
  436. {
  437. (*m)(row, col) = val;
  438. }
  439. } // namespace btInverseDynamics
  440. #endif