1 /// @file Built-In Matrix-Vector functions
7 #include "../IDConfig.hpp"
8 #define BT_ID_HAVE_MAT3X
10 namespace btInverseDynamics
{
17 /// This is a very basic implementation to enable stand-alone use of the library.
18 /// The implementation is not really optimized and misses many features that you would
19 /// want from a "fully featured" linear math library.
22 idScalar
& operator()(int i
) { return m_data
[i
]; }
23 const idScalar
& operator()(int i
) const { return m_data
[i
]; }
24 const int size() const { return 3; }
25 const vec3
& operator=(const vec3
& rhs
);
26 const vec3
& operator+=(const vec3
& b
);
27 const vec3
& operator-=(const vec3
& b
);
28 vec3
cross(const vec3
& b
) const;
29 idScalar
dot(const vec3
& b
) const;
31 friend vec3
operator*(const mat33
& a
, const vec3
& b
);
32 friend vec3
operator*(const vec3
& a
, const idScalar
& s
);
33 friend vec3
operator*(const idScalar
& s
, const vec3
& a
);
35 friend vec3
operator+(const vec3
& a
, const vec3
& b
);
36 friend vec3
operator-(const vec3
& a
, const vec3
& b
);
37 friend vec3
operator/(const vec3
& a
, const idScalar
& s
);
45 idScalar
& operator()(int i
, int j
) { return m_data
[3 * i
+ j
]; }
46 const idScalar
& operator()(int i
, int j
) const { return m_data
[3 * i
+ j
]; }
47 const mat33
& operator=(const mat33
& rhs
);
48 mat33
transpose() const;
49 const mat33
& operator+=(const mat33
& b
);
50 const mat33
& operator-=(const mat33
& b
);
52 friend mat33
operator*(const mat33
& a
, const mat33
& b
);
53 friend vec3
operator*(const mat33
& a
, const vec3
& b
);
54 friend mat33
operator*(const mat33
& a
, const idScalar
& s
);
55 friend mat33
operator*(const idScalar
& s
, const mat33
& a
);
56 friend mat33
operator+(const mat33
& a
, const mat33
& b
);
57 friend mat33
operator-(const mat33
& a
, const mat33
& b
);
58 friend mat33
operator/(const mat33
& a
, const idScalar
& s
);
61 // layout is [0,1,2;3,4,5;6,7,8]
67 vecx(int size
) : m_size(size
) {
68 m_data
= static_cast<idScalar
*>(idMalloc(sizeof(idScalar
) * size
));
70 ~vecx() { idFree(m_data
); }
71 const vecx
& operator=(const vecx
& rhs
);
72 idScalar
& operator()(int i
) { return m_data
[i
]; }
73 const idScalar
& operator()(int i
) const { return m_data
[i
]; }
74 const int& size() const { return m_size
; }
76 friend vecx
operator*(const vecx
& a
, const idScalar
& s
);
77 friend vecx
operator*(const idScalar
& s
, const vecx
& a
);
79 friend vecx
operator+(const vecx
& a
, const vecx
& b
);
80 friend vecx
operator-(const vecx
& a
, const vecx
& b
);
81 friend vecx
operator/(const vecx
& a
, const idScalar
& s
);
95 matxx(int rows
, int cols
) : m_rows(rows
), m_cols(cols
) {
96 m_data
= static_cast<idScalar
*>(idMalloc(sizeof(idScalar
) * rows
* cols
));
98 ~matxx() { idFree(m_data
); }
99 idScalar
& operator()(int row
, int col
) { return m_data
[row
* m_cols
+ col
]; }
100 const idScalar
& operator()(int row
, int col
) const { return m_data
[row
* m_cols
+ col
]; }
101 const int& rows() const { return m_rows
; }
102 const int& cols() const { return m_cols
; }
116 mat3x(const mat3x
&rhs
) {
121 mat3x(int rows
, int cols
): m_cols(cols
) {
124 void operator=(const mat3x
& rhs
) {
125 if (m_cols
!= rhs
.m_cols
) {
126 error_message("size missmatch, cols= %d but rhs.cols= %d\n", cols(), rhs
.cols());
129 for(int i
=0;i
<3*m_cols
;i
++) {
130 m_data
[i
] = rhs
.m_data
[i
];
137 idScalar
& operator()(int row
, int col
) { return m_data
[row
* m_cols
+ col
]; }
138 const idScalar
& operator()(int row
, int col
) const { return m_data
[row
* m_cols
+ col
]; }
139 int rows() const { return m_rows
; }
140 const int& cols() const { return m_cols
; }
141 void resize(int rows
, int cols
) {
147 memset(m_data
,0x0,sizeof(idScalar
)*m_rows
*m_cols
);
149 // avoid operators that would allocate -- use functions sub/add/mul in IDMath.hpp instead
151 void allocate(){m_data
= static_cast<idScalar
*>(idMalloc(sizeof(idScalar
) * m_rows
* m_cols
));}
152 void free() { idFree(m_data
);}
158 inline void resize(mat3x
&m
, idArrayIdx size
) {
163 //////////////////////////////////////////////////
165 inline const vec3
& vec3::operator=(const vec3
& rhs
) {
167 memcpy(m_data
, rhs
.m_data
, 3 * sizeof(idScalar
));
172 inline vec3
vec3::cross(const vec3
& b
) const {
174 result
.m_data
[0] = m_data
[1] * b
.m_data
[2] - m_data
[2] * b
.m_data
[1];
175 result
.m_data
[1] = m_data
[2] * b
.m_data
[0] - m_data
[0] * b
.m_data
[2];
176 result
.m_data
[2] = m_data
[0] * b
.m_data
[1] - m_data
[1] * b
.m_data
[0];
181 inline idScalar
vec3::dot(const vec3
& b
) const {
182 return m_data
[0] * b
.m_data
[0] + m_data
[1] * b
.m_data
[1] + m_data
[2] * b
.m_data
[2];
185 inline const mat33
& mat33::operator=(const mat33
& rhs
) {
187 memcpy(m_data
, rhs
.m_data
, 9 * sizeof(idScalar
));
191 inline mat33
mat33::transpose() const {
193 result
.m_data
[0] = m_data
[0];
194 result
.m_data
[1] = m_data
[3];
195 result
.m_data
[2] = m_data
[6];
196 result
.m_data
[3] = m_data
[1];
197 result
.m_data
[4] = m_data
[4];
198 result
.m_data
[5] = m_data
[7];
199 result
.m_data
[6] = m_data
[2];
200 result
.m_data
[7] = m_data
[5];
201 result
.m_data
[8] = m_data
[8];
206 inline mat33
operator*(const mat33
& a
, const mat33
& b
) {
209 a
.m_data
[0] * b
.m_data
[0] + a
.m_data
[1] * b
.m_data
[3] + a
.m_data
[2] * b
.m_data
[6];
211 a
.m_data
[0] * b
.m_data
[1] + a
.m_data
[1] * b
.m_data
[4] + a
.m_data
[2] * b
.m_data
[7];
213 a
.m_data
[0] * b
.m_data
[2] + a
.m_data
[1] * b
.m_data
[5] + a
.m_data
[2] * b
.m_data
[8];
215 a
.m_data
[3] * b
.m_data
[0] + a
.m_data
[4] * b
.m_data
[3] + a
.m_data
[5] * b
.m_data
[6];
217 a
.m_data
[3] * b
.m_data
[1] + a
.m_data
[4] * b
.m_data
[4] + a
.m_data
[5] * b
.m_data
[7];
219 a
.m_data
[3] * b
.m_data
[2] + a
.m_data
[4] * b
.m_data
[5] + a
.m_data
[5] * b
.m_data
[8];
221 a
.m_data
[6] * b
.m_data
[0] + a
.m_data
[7] * b
.m_data
[3] + a
.m_data
[8] * b
.m_data
[6];
223 a
.m_data
[6] * b
.m_data
[1] + a
.m_data
[7] * b
.m_data
[4] + a
.m_data
[8] * b
.m_data
[7];
225 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 inline const mat33
& mat33::operator+=(const mat33
& b
) {
231 for (int i
= 0; i
< 9; i
++) {
232 m_data
[i
] += b
.m_data
[i
];
238 inline const mat33
& mat33::operator-=(const mat33
& b
) {
239 for (int i
= 0; i
< 9; i
++) {
240 m_data
[i
] -= b
.m_data
[i
];
245 inline vec3
operator*(const mat33
& a
, const vec3
& b
) {
249 a
.m_data
[0] * b
.m_data
[0] + a
.m_data
[1] * b
.m_data
[1] + a
.m_data
[2] * b
.m_data
[2];
251 a
.m_data
[3] * b
.m_data
[0] + a
.m_data
[4] * b
.m_data
[1] + a
.m_data
[5] * b
.m_data
[2];
253 a
.m_data
[6] * b
.m_data
[0] + a
.m_data
[7] * b
.m_data
[1] + a
.m_data
[8] * b
.m_data
[2];
258 inline const vec3
& vec3::operator+=(const vec3
& b
) {
259 for (int i
= 0; i
< 3; i
++) {
260 m_data
[i
] += b
.m_data
[i
];
265 inline const vec3
& vec3::operator-=(const vec3
& b
) {
266 for (int i
= 0; i
< 3; i
++) {
267 m_data
[i
] -= b
.m_data
[i
];
272 inline mat33
operator*(const mat33
& a
, const idScalar
& s
) {
274 for (int i
= 0; i
< 9; i
++) {
275 result
.m_data
[i
] = a
.m_data
[i
] * s
;
280 inline mat33
operator*(const idScalar
& s
, const mat33
& a
) { return a
* s
; }
282 inline vec3
operator*(const vec3
& a
, const idScalar
& s
) {
284 for (int i
= 0; i
< 3; i
++) {
285 result
.m_data
[i
] = a
.m_data
[i
] * s
;
289 inline vec3
operator*(const idScalar
& s
, const vec3
& a
) { return a
* s
; }
291 inline mat33
operator+(const mat33
& a
, const mat33
& b
) {
293 for (int i
= 0; i
< 9; i
++) {
294 result
.m_data
[i
] = a
.m_data
[i
] + b
.m_data
[i
];
298 inline vec3
operator+(const vec3
& a
, const vec3
& b
) {
300 for (int i
= 0; i
< 3; i
++) {
301 result
.m_data
[i
] = a
.m_data
[i
] + b
.m_data
[i
];
306 inline mat33
operator-(const mat33
& a
, const mat33
& b
) {
308 for (int i
= 0; i
< 9; i
++) {
309 result
.m_data
[i
] = a
.m_data
[i
] - b
.m_data
[i
];
313 inline vec3
operator-(const vec3
& a
, const vec3
& b
) {
315 for (int i
= 0; i
< 3; i
++) {
316 result
.m_data
[i
] = a
.m_data
[i
] - b
.m_data
[i
];
321 inline mat33
operator/(const mat33
& a
, const idScalar
& s
) {
323 for (int i
= 0; i
< 9; i
++) {
324 result
.m_data
[i
] = a
.m_data
[i
] / s
;
329 inline vec3
operator/(const vec3
& a
, const idScalar
& s
) {
331 for (int i
= 0; i
< 3; i
++) {
332 result
.m_data
[i
] = a
.m_data
[i
] / s
;
337 inline const vecx
& vecx::operator=(const vecx
& rhs
) {
338 if (size() != rhs
.size()) {
339 error_message("size missmatch, size()= %d but rhs.size()= %d\n", size(), rhs
.size());
343 memcpy(m_data
, rhs
.m_data
, rhs
.size() * sizeof(idScalar
));
347 inline vecx
operator*(const vecx
& a
, const idScalar
& s
) {
348 vecx
result(a
.size());
349 for (int i
= 0; i
< result
.size(); i
++) {
350 result
.m_data
[i
] = a
.m_data
[i
] * s
;
354 inline vecx
operator*(const idScalar
& s
, const vecx
& a
) { return a
* s
; }
355 inline vecx
operator+(const vecx
& a
, const vecx
& b
) {
356 vecx
result(a
.size());
357 // TODO: error handling for a.size() != b.size()??
358 if (a
.size() != b
.size()) {
359 error_message("size missmatch. a.size()= %d, b.size()= %d\n", a
.size(), b
.size());
362 for (int i
= 0; i
< a
.size(); i
++) {
363 result
.m_data
[i
] = a
.m_data
[i
] + b
.m_data
[i
];
368 inline vecx
operator-(const vecx
& a
, const vecx
& b
) {
369 vecx
result(a
.size());
370 // TODO: error handling for a.size() != b.size()??
371 if (a
.size() != b
.size()) {
372 error_message("size missmatch. a.size()= %d, b.size()= %d\n", a
.size(), b
.size());
375 for (int i
= 0; i
< a
.size(); i
++) {
376 result
.m_data
[i
] = a
.m_data
[i
] - b
.m_data
[i
];
380 inline vecx
operator/(const vecx
& a
, const idScalar
& s
) {
381 vecx
result(a
.size());
382 for (int i
= 0; i
< result
.size(); i
++) {
383 result
.m_data
[i
] = a
.m_data
[i
] / s
;
389 inline vec3
operator*(const mat3x
& a
, const vecx
& b
) {
391 if (a
.cols() != b
.size()) {
392 error_message("size missmatch. a.cols()= %d, b.size()= %d\n", a
.cols(), b
.size());
398 for(int i
=0;i
<b
.size();i
++) {
399 for(int k
=0;k
<3;k
++) {
400 result(k
)+=a(k
,i
)*b(i
);
406 inline void setMatxxElem(const idArrayIdx row
, const idArrayIdx col
, const idScalar val
, matxx
*m
){
407 (*m
)(row
, col
) = val
;
410 inline void setMat3xElem(const idArrayIdx row
, const idArrayIdx col
, const idScalar val
, mat3x
*m
){
411 (*m
)(row
, col
) = val
;
414 } // namespace btInverseDynamcis