2#include "RigidBody.hpp"
12 _masses =
new Mass[_massesAlloced];
13 _gyro[0] = _gyro[1] = _gyro[2] = 0;
14 _spin[0] = _spin[1] = _spin[2] = 0;
15 _bodyN =
fgGetNode(
"/fdm/yasim/model/masses",
true);
18RigidBody::~RigidBody()
25int RigidBody::addMass(
float mass,
const float* pos,
bool isStatic)
28 if(_nMasses == _massesAlloced) {
30 Mass *m2 =
new Mass[_massesAlloced];
32 for(
i=0;
i<_nMasses;
i++)
37 setMass(_nMasses, mass, pos, isStatic);
43void RigidBody::setMass(
int handle,
float mass)
45 if (_masses[handle].m == mass)
47 _masses[handle].m = mass;
50 if (_masses[handle].isStatic)
53 _bodyN->getChild(
"mass", handle,
true)->getNode(
"mass",
true)->setFloatValue(mass);
56void RigidBody::setMass(
int handle,
float mass,
const float* pos,
bool isStatic)
58 _masses[handle].isStatic = isStatic;
59 Math::set3(pos, _masses[handle].
p);
60 setMass(handle, mass);
62 SGPropertyNode_ptr n = _bodyN->getChild(
"mass", handle,
true);
63 n->getNode(
"isStatic",
true)->setValue(isStatic);
64 n->getNode(
"pos-x",
true)->setFloatValue(pos[0]);
65 n->getNode(
"pos-y",
true)->setFloatValue(pos[1]);
66 n->getNode(
"pos-z",
true)->setFloatValue(pos[2]);
70void RigidBody::getMassPosition(
int handle,
float* out)
const
72 Math::set3(_masses[handle].
p, out);
77void RigidBody::pointVelocity(
const float* pos,
const float* rot,
float* out)
79 Math::sub3(pos, _cg, out);
80 Math::cross3(rot, out, out);
83void RigidBody::_recalcStatic()
87 Math::zero3(_staticMass.p);
90 for(
i=0;
i<_nMasses;
i++) {
91 if (_masses[
i].isStatic) {
93 float mass = _masses[
i].m;
94 _staticMass.m += mass;
96 Math::mul3(mass, _masses[
i].
p, momentum);
97 Math::add3(momentum, _staticMass.p, _staticMass.p);
100 Math::mul3(1/_staticMass.m, _staticMass.p, _staticMass.p);
102 _bodyN->getNode(
"aggregated-mass",
true)->setFloatValue(_staticMass.m);
103 _bodyN->getNode(
"aggregated-count",
true)->setIntValue(s);
104 _bodyN->getNode(
"aggregated-pos-x",
true)->setFloatValue(_staticMass.p[0]);
105 _bodyN->getNode(
"aggregated-pos-y",
true)->setFloatValue(_staticMass.p[1]);
106 _bodyN->getNode(
"aggregated-pos-z",
true)->setFloatValue(_staticMass.p[2]);
112 for(
i=0;
i<_nMasses;
i++) {
113 if (_masses[
i].isStatic) {
114 float m = _masses[
i].m;
116 float x = _masses[
i].p[0] - _staticMass.p[0];
117 float y = _masses[
i].p[1] - _staticMass.p[1];
118 float z = _masses[
i].p[2] - _staticMass.p[2];
120 float xy = m*x*y;
float yz = m*y*z;
float zx = m*z*x;
121 float x2 = m*x*x;
float y2 = m*y*y;
float z2 = m*z*z;
124 _tI_static[0] += y2+z2; _tI_static[1] -= xy; _tI_static[2] -= zx;
125 _tI_static[4] += x2+z2; _tI_static[5] -= yz;
126 _tI_static[8] += x2+y2;
130 _tI_static[3] = _tI_static[1];
131 _tI_static[6] = _tI_static[2];
132 _tI_static[7] = _tI_static[5];
142void RigidBody::recalc()
145 if (_staticMass.m == 0) _recalcStatic();
149 _totalMass = _staticMass.m;
150 Math::mul3(_staticMass.m, _staticMass.p, _cg);
152 for(
i=0;
i<_nMasses;
i++) {
154 if (!_masses[
i].isStatic) {
155 float mass = _masses[
i].m;
158 Math::mul3(mass, _masses[
i].
p, momentum);
159 Math::add3(momentum, _cg, _cg);
162 Math::mul3(1/_totalMass, _cg, _cg);
166 _tI[
i] = _tI_static[
i];
168 for(
i=0;
i<_nMasses;
i++) {
169 if (!_masses[
i].isStatic) {
170 float m = _masses[
i].m;
172 float x = _masses[
i].p[0] - _cg[0];
173 float y = _masses[
i].p[1] - _cg[1];
174 float z = _masses[
i].p[2] - _cg[2];
179 float xy = mx*y;
float yz = my*z;
float zx = mz*x;
180 float x2 = mx*x;
float y2 = my*y;
float z2 = mz*z;
182 _tI[0] += y2+z2; _tI[1] -= xy; _tI[2] -= zx;
183 _tI[4] += x2+z2; _tI[5] -= yz;
193 Math::invert33_sym(_tI, _invI);
196void RigidBody::reset()
198 Math::zero3(_torque);
202void RigidBody::addForce(
const float* pos,
const float* force)
209 Math::sub3(_cg, pos, v);
210 Math::cross3(force, v, t);
214void RigidBody::getAccel(
const float* pos,
float* accelOut)
const
221 float rate = Math::mag3(_spin);
222 Math::set3(_spin, a);
224 Math::mul3(1/rate, a, a);
227 Math::sub3(_cg, pos, v);
228 Math::mul3(Math::dot3(v, a), a, a);
234 Math::mul3(rate*rate, v, v);
235 Math::add3(v, accelOut, accelOut);
238void RigidBody::getAngularAccel(
float* accelOut)
const
243 Math::cross3(_gyro, _spin, tau);
244 Math::add3(_torque, tau, tau);
249 Math::vmul33(_tI, _spin, v);
250 Math::cross3(_spin, v, v);
251 Math::add3(tau, v, v);
252 Math::vmul33(_invI, v, v);
255void RigidBody::getInertiaMatrix(
float* inertiaOut)
const
261 inertiaOut[
i] = _tI[
i];
SGPropertyNode * fgGetNode(const char *path, bool create)
Get a property node.