2017-08-01 12:30:58 +00:00
|
|
|
#ifndef IDLINEARMATHINTERFACE_HPP_
|
|
|
|
#define IDLINEARMATHINTERFACE_HPP_
|
|
|
|
|
|
|
|
#include <cstdlib>
|
|
|
|
|
|
|
|
#include "../IDConfig.hpp"
|
|
|
|
|
|
|
|
#include "../../LinearMath/btMatrix3x3.h"
|
|
|
|
#include "../../LinearMath/btVector3.h"
|
|
|
|
#include "../../LinearMath/btMatrixX.h"
|
|
|
|
#define BT_ID_HAVE_MAT3X
|
|
|
|
|
2019-01-03 13:26:51 +00:00
|
|
|
namespace btInverseDynamics
|
|
|
|
{
|
2017-08-01 12:30:58 +00:00
|
|
|
class vec3;
|
|
|
|
class vecx;
|
|
|
|
class mat33;
|
|
|
|
typedef btMatrixX<idScalar> matxx;
|
|
|
|
|
2019-01-03 13:26:51 +00:00
|
|
|
class vec3 : public btVector3
|
|
|
|
{
|
2017-08-01 12:30:58 +00:00
|
|
|
public:
|
|
|
|
vec3() : btVector3() {}
|
|
|
|
vec3(const btVector3& btv) { *this = btv; }
|
|
|
|
idScalar& operator()(int i) { return (*this)[i]; }
|
|
|
|
const idScalar& operator()(int i) const { return (*this)[i]; }
|
|
|
|
int size() const { return 3; }
|
2019-01-03 13:26:51 +00:00
|
|
|
const vec3& operator=(const btVector3& rhs)
|
|
|
|
{
|
2017-08-01 12:30:58 +00:00
|
|
|
*static_cast<btVector3*>(this) = rhs;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2019-01-03 13:26:51 +00:00
|
|
|
class mat33 : public btMatrix3x3
|
|
|
|
{
|
2017-08-01 12:30:58 +00:00
|
|
|
public:
|
|
|
|
mat33() : btMatrix3x3() {}
|
|
|
|
mat33(const btMatrix3x3& btm) { *this = btm; }
|
|
|
|
idScalar& operator()(int i, int j) { return (*this)[i][j]; }
|
|
|
|
const idScalar& operator()(int i, int j) const { return (*this)[i][j]; }
|
2019-01-03 13:26:51 +00:00
|
|
|
const mat33& operator=(const btMatrix3x3& rhs)
|
|
|
|
{
|
2017-08-01 12:30:58 +00:00
|
|
|
*static_cast<btMatrix3x3*>(this) = rhs;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
friend mat33 operator*(const idScalar& s, const mat33& a);
|
|
|
|
friend mat33 operator/(const mat33& a, const idScalar& s);
|
|
|
|
};
|
|
|
|
|
|
|
|
inline mat33 operator/(const mat33& a, const idScalar& s) { return a * (1.0 / s); }
|
|
|
|
|
|
|
|
inline mat33 operator*(const idScalar& s, const mat33& a) { return a * s; }
|
|
|
|
|
2019-01-03 13:26:51 +00:00
|
|
|
class vecx : public btVectorX<idScalar>
|
|
|
|
{
|
2017-08-01 12:30:58 +00:00
|
|
|
public:
|
2018-09-07 14:11:04 +00:00
|
|
|
vecx(int size) : btVectorX<idScalar>(size) {}
|
2019-01-03 13:26:51 +00:00
|
|
|
const vecx& operator=(const btVectorX<idScalar>& rhs)
|
|
|
|
{
|
2018-09-07 14:11:04 +00:00
|
|
|
*static_cast<btVectorX<idScalar>*>(this) = rhs;
|
2017-08-01 12:30:58 +00:00
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
idScalar& operator()(int i) { return (*this)[i]; }
|
|
|
|
const idScalar& operator()(int i) const { return (*this)[i]; }
|
|
|
|
|
|
|
|
friend vecx operator*(const vecx& a, const idScalar& s);
|
|
|
|
friend vecx operator*(const idScalar& s, const vecx& a);
|
|
|
|
|
|
|
|
friend vecx operator+(const vecx& a, const vecx& b);
|
|
|
|
friend vecx operator-(const vecx& a, const vecx& b);
|
|
|
|
friend vecx operator/(const vecx& a, const idScalar& s);
|
|
|
|
};
|
|
|
|
|
2019-01-03 13:26:51 +00:00
|
|
|
inline vecx operator*(const vecx& a, const idScalar& s)
|
|
|
|
{
|
2017-08-01 12:30:58 +00:00
|
|
|
vecx result(a.size());
|
2019-01-03 13:26:51 +00:00
|
|
|
for (int i = 0; i < result.size(); i++)
|
|
|
|
{
|
2017-08-01 12:30:58 +00:00
|
|
|
result(i) = a(i) * s;
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
inline vecx operator*(const idScalar& s, const vecx& a) { return a * s; }
|
2019-01-03 13:26:51 +00:00
|
|
|
inline vecx operator+(const vecx& a, const vecx& b)
|
|
|
|
{
|
2017-08-01 12:30:58 +00:00
|
|
|
vecx result(a.size());
|
|
|
|
// TODO: error handling for a.size() != b.size()??
|
2019-01-03 13:26:51 +00:00
|
|
|
if (a.size() != b.size())
|
|
|
|
{
|
2018-09-07 14:11:04 +00:00
|
|
|
bt_id_error_message("size missmatch. a.size()= %d, b.size()= %d\n", a.size(), b.size());
|
2017-08-01 12:30:58 +00:00
|
|
|
abort();
|
|
|
|
}
|
2019-01-03 13:26:51 +00:00
|
|
|
for (int i = 0; i < a.size(); i++)
|
|
|
|
{
|
2017-08-01 12:30:58 +00:00
|
|
|
result(i) = a(i) + b(i);
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2019-01-03 13:26:51 +00:00
|
|
|
inline vecx operator-(const vecx& a, const vecx& b)
|
|
|
|
{
|
2017-08-01 12:30:58 +00:00
|
|
|
vecx result(a.size());
|
|
|
|
// TODO: error handling for a.size() != b.size()??
|
2019-01-03 13:26:51 +00:00
|
|
|
if (a.size() != b.size())
|
|
|
|
{
|
2018-09-07 14:11:04 +00:00
|
|
|
bt_id_error_message("size missmatch. a.size()= %d, b.size()= %d\n", a.size(), b.size());
|
2017-08-01 12:30:58 +00:00
|
|
|
abort();
|
|
|
|
}
|
2019-01-03 13:26:51 +00:00
|
|
|
for (int i = 0; i < a.size(); i++)
|
|
|
|
{
|
2017-08-01 12:30:58 +00:00
|
|
|
result(i) = a(i) - b(i);
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
2019-01-03 13:26:51 +00:00
|
|
|
inline vecx operator/(const vecx& a, const idScalar& s)
|
|
|
|
{
|
2017-08-01 12:30:58 +00:00
|
|
|
vecx result(a.size());
|
2019-01-03 13:26:51 +00:00
|
|
|
for (int i = 0; i < result.size(); i++)
|
|
|
|
{
|
2017-08-01 12:30:58 +00:00
|
|
|
result(i) = a(i) / s;
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
// use btMatrixX to implement 3xX matrix
|
2019-01-03 13:26:51 +00:00
|
|
|
class mat3x : public matxx
|
|
|
|
{
|
2017-08-01 12:30:58 +00:00
|
|
|
public:
|
2019-01-03 13:26:51 +00:00
|
|
|
mat3x() {}
|
|
|
|
mat3x(const mat3x& rhs)
|
|
|
|
{
|
|
|
|
matxx::resize(rhs.rows(), rhs.cols());
|
|
|
|
*this = rhs;
|
|
|
|
}
|
|
|
|
mat3x(int rows, int cols) : matxx(3, cols)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
void operator=(const mat3x& rhs)
|
|
|
|
{
|
|
|
|
if (m_cols != rhs.m_cols)
|
|
|
|
{
|
|
|
|
bt_id_error_message("size missmatch, cols= %d but rhs.cols= %d\n", cols(), rhs.cols());
|
|
|
|
abort();
|
|
|
|
}
|
|
|
|
for (int i = 0; i < rows(); i++)
|
|
|
|
{
|
|
|
|
for (int k = 0; k < cols(); k++)
|
|
|
|
{
|
|
|
|
setElem(i, k, rhs(i, k));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
void setZero()
|
|
|
|
{
|
|
|
|
matxx::setZero();
|
2017-08-01 12:30:58 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2019-01-03 13:26:51 +00:00
|
|
|
inline vec3 operator*(const mat3x& a, const vecx& b)
|
|
|
|
{
|
|
|
|
vec3 result;
|
|
|
|
if (a.cols() != b.size())
|
|
|
|
{
|
|
|
|
bt_id_error_message("size missmatch. a.cols()= %d, b.size()= %d\n", a.cols(), b.size());
|
|
|
|
abort();
|
|
|
|
}
|
|
|
|
result(0) = 0.0;
|
|
|
|
result(1) = 0.0;
|
|
|
|
result(2) = 0.0;
|
|
|
|
for (int i = 0; i < b.size(); i++)
|
|
|
|
{
|
|
|
|
for (int k = 0; k < 3; k++)
|
|
|
|
{
|
|
|
|
result(k) += a(k, i) * b(i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return result;
|
2017-08-01 12:30:58 +00:00
|
|
|
}
|
|
|
|
|
2019-01-03 13:26:51 +00:00
|
|
|
inline void resize(mat3x& m, idArrayIdx size)
|
|
|
|
{
|
|
|
|
m.resize(3, size);
|
|
|
|
m.setZero();
|
2017-08-01 12:30:58 +00:00
|
|
|
}
|
|
|
|
|
2019-01-03 13:26:51 +00:00
|
|
|
inline void setMatxxElem(const idArrayIdx row, const idArrayIdx col, const idScalar val, matxx* m)
|
|
|
|
{
|
|
|
|
m->setElem(row, col, val);
|
2017-08-01 12:30:58 +00:00
|
|
|
}
|
|
|
|
|
2019-01-03 13:26:51 +00:00
|
|
|
inline void setMat3xElem(const idArrayIdx row, const idArrayIdx col, const idScalar val, mat3x* m)
|
|
|
|
{
|
|
|
|
m->setElem(row, col, val);
|
2017-08-01 12:30:58 +00:00
|
|
|
}
|
|
|
|
|
2019-01-03 13:26:51 +00:00
|
|
|
} // namespace btInverseDynamics
|
2017-08-01 12:30:58 +00:00
|
|
|
|
|
|
|
#endif // IDLINEARMATHINTERFACE_HPP_
|