Optimize YASim/RigidBody.cpp utilizing symmetry of tensor.
This commit is contained in:
parent
6257c29fd8
commit
b447bbdc5e
2 changed files with 39 additions and 28 deletions
|
@ -130,31 +130,29 @@ public:
|
||||||
out[2] = x*m[2] + y*m[5] + z*m[8];
|
out[2] = x*m[2] + y*m[5] + z*m[8];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Invert matrix
|
/// Invert symmetric matrix; ~1/3 less calculations due to symmetry
|
||||||
static void invert33(float* m, float* out) {
|
static void invert33_sym(float* m, float* out) {
|
||||||
// Compute the inverse as the adjoint matrix times 1/(det M).
|
// Compute the inverse as the adjoint matrix times 1/(det M).
|
||||||
// A, B ... I are the cofactors of a b c
|
// A, B ... I are the cofactors of a b c
|
||||||
// d e f
|
// d e f
|
||||||
// g h i
|
// g h i
|
||||||
|
// symetric: d=b, g=c, h=f
|
||||||
float a=m[0], b=m[1], c=m[2];
|
float a=m[0], b=m[1], c=m[2];
|
||||||
float d=m[3], e=m[4], f=m[5];
|
float e=m[4], f=m[5];
|
||||||
float g=m[6], h=m[7], i=m[8];
|
float i=m[8];
|
||||||
|
|
||||||
float A = (e*i - h*f);
|
float A = (e*i - f*f);
|
||||||
float B = -(d*i - g*f);
|
float B = -(b*i - c*f);
|
||||||
float C = (d*h - g*e);
|
float C = (b*f - c*e);
|
||||||
float D = -(b*i - h*c);
|
float E = (a*i - c*c);
|
||||||
float E = (a*i - g*c);
|
float F = -(a*f - c*b);
|
||||||
float F = -(a*h - g*b);
|
float I = (a*e - b*b);
|
||||||
float G = (b*f - e*c);
|
|
||||||
float H = -(a*f - d*c);
|
|
||||||
float I = (a*e - d*b);
|
|
||||||
|
|
||||||
float id = 1/(a*A + b*B + c*C);
|
float id = 1/(a*A + b*B + c*C);
|
||||||
|
|
||||||
out[0] = id*A; out[1] = id*D; out[2] = id*G;
|
out[0] = id*A; out[1] = id*B; out[2] = id*C;
|
||||||
out[3] = id*B; out[4] = id*E; out[5] = id*H;
|
out[3] = out[1]; out[4] = id*E; out[5] = id*F;
|
||||||
out[6] = id*C; out[7] = id*F; out[8] = id*I;
|
out[6] = out[2]; out[7] = out[5]; out[8] = id*I;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Transpose matrix (for an orthonormal orientation matrix, this
|
// Transpose matrix (for an orthonormal orientation matrix, this
|
||||||
|
|
|
@ -82,6 +82,12 @@ void RigidBody::setGyro(float* angularMomentum)
|
||||||
Math::set3(angularMomentum, _gyro);
|
Math::set3(angularMomentum, _gyro);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// calculate the total mass, centre of gravity and inertia tensor
|
||||||
|
/**
|
||||||
|
recalc is used when compiling the model but more important it is called in
|
||||||
|
Model::iterate() e.g. at FDM rate (120 Hz)
|
||||||
|
We can save some CPU due to the symmetry of the tensor.
|
||||||
|
*/
|
||||||
void RigidBody::recalc()
|
void RigidBody::recalc()
|
||||||
{
|
{
|
||||||
// Calculate the c.g and total mass:
|
// Calculate the c.g and total mass:
|
||||||
|
@ -102,22 +108,29 @@ void RigidBody::recalc()
|
||||||
_tI[i] = 0;
|
_tI[i] = 0;
|
||||||
|
|
||||||
for(i=0; i<_nMasses; i++) {
|
for(i=0; i<_nMasses; i++) {
|
||||||
float m = _masses[i].m;
|
float m = _masses[i].m;
|
||||||
|
|
||||||
float x = _masses[i].p[0] - _cg[0];
|
float x = _masses[i].p[0] - _cg[0];
|
||||||
float y = _masses[i].p[1] - _cg[1];
|
float y = _masses[i].p[1] - _cg[1];
|
||||||
float z = _masses[i].p[2] - _cg[2];
|
float z = _masses[i].p[2] - _cg[2];
|
||||||
|
float mx = m*x;
|
||||||
|
float my = m*y;
|
||||||
|
float mz = m*z;
|
||||||
|
|
||||||
|
float xy = mx*y; float yz = my*z; float zx = mz*x;
|
||||||
|
float x2 = mx*x; float y2 = my*y; float z2 = mz*z;
|
||||||
|
|
||||||
float xy = m*x*y; float yz = m*y*z; float zx = m*z*x;
|
_tI[0] += y2+z2; _tI[1] -= xy; _tI[2] -= zx;
|
||||||
float x2 = m*x*x; float y2 = m*y*y; float z2 = m*z*z;
|
_tI[4] += x2+z2; _tI[5] -= yz;
|
||||||
|
_tI[8] += x2+y2;
|
||||||
_tI[0] += y2+z2; _tI[1] -= xy; _tI[2] -= zx;
|
|
||||||
_tI[3] -= xy; _tI[4] += x2+z2; _tI[5] -= yz;
|
|
||||||
_tI[6] -= zx; _tI[7] -= yz; _tI[8] += x2+y2;
|
|
||||||
}
|
}
|
||||||
|
// copy symmetric elements
|
||||||
|
_tI[3] = _tI[1];
|
||||||
|
_tI[6] = _tI[2];
|
||||||
|
_tI[7] = _tI[5];
|
||||||
|
|
||||||
// And its inverse
|
//calculate inverse
|
||||||
Math::invert33(_tI, _invI);
|
Math::invert33_sym(_tI, _invI);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RigidBody::reset()
|
void RigidBody::reset()
|
||||||
|
|
Loading…
Reference in a new issue