00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "physicalSolver.h"
00010 #include <animal/value.h>
00011 #include <animal/linear.h>
00012 #include <animal/odeSolver.inl>
00013
00014 namespace animal
00015 {
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 template < class P, class V, class I, class R >
00026 PhysicalSolver < P, V, I, R >::PhysicalSolver ():
00027 _gravity (Value < Vec >::zero ()),
00028 _useGravity (false),
00029 _exponentialDamping (0),
00030 _invMasses (0),
00031 _useExponentialDamping (false),
00032 _useMass (false),
00033 _useSingleMass (false)
00034 {
00035 }
00036 template < class P, class V, class I, class R > PhysicalSolver < P,
00037 V, I, R >::~PhysicalSolver ()
00038 {
00039 }
00040
00041
00042
00043 template < class P, class V, class I, class R >
00044 const typename PhysicalSolver < P,
00045 V, I, R >::Vec & PhysicalSolver < P, V, I, R >::get_gravity ()
00046 {
00047 return _gravity;
00048 }
00049
00051 template < class P, class V, class I, class R > void PhysicalSolver < P,
00052 V, I, R >::set_gravity (const Vec & _newVal)
00053 {
00054 _gravity = _newVal;
00055 set_useGravity (true);
00056 }
00058 template < class P, class V, class I, class R >
00059 const bool & PhysicalSolver < P, V, I, R >::get_useGravity ()
00060 {
00061 return _useGravity;
00062 }
00064 template < class P, class V, class I, class R > void PhysicalSolver < P,
00065 V, I, R >::set_useGravity (const bool & _newVal)
00066 {
00067 _useGravity = _newVal;
00068 }
00070 template < class P, class V, class I, class R >
00071 const bool & PhysicalSolver < P, V, I, R >::get_useExponentialDamping ()
00072 {
00073 return _useExponentialDamping;
00074 }
00076 template < class P, class V, class I, class R > void PhysicalSolver < P,
00077 V, I, R >::set_useExponentialDamping (const bool & _newVal)
00078 {
00079 cerr<<"PhysicalSolver::set_useExponentialDamping "<< _newVal << endl;
00080 _useExponentialDamping = _newVal;
00081 }
00083 template < class P, class V, class I, class R >
00084 const typename PhysicalSolver < P,
00085 V, I, R >::Real & PhysicalSolver < P, V, I, R >::get_exponentialDamping ()
00086 {
00087 return _exponentialDamping;
00088 }
00090 template < class P, class V, class I, class R > void PhysicalSolver < P,
00091 V, I, R >::set_exponentialDamping (const Real & _newVal)
00092 {
00093 _exponentialDamping = _newVal;
00094 set_useExponentialDamping (true);
00095 cerr<<"PhysicalSolver::set_exponentialDamping "<< _exponentialDamping << endl;
00096 }
00097
00099 template < class P, class V, class I, class R > void PhysicalSolver < P,
00100 V,
00101 I,
00102 R >::applyGravity (Vector & acc)
00103 {
00104 if (_useGravity)
00105 {
00106
00107 if (_useMass && !_useSingleMass)
00108 {
00109
00110 for (unsigned int i = 0; i < size (acc); ++i)
00111 if ((*_invMasses)[i] == 0)
00112 acc[i] = zero ();
00113 else v_peq(acc[i],_gravity);
00114 }
00115 else
00116 v_addall (acc, _gravity);
00117 }
00118
00119 }
00120
00122 template < class P, class V, class I, class R > void PhysicalSolver < P,
00123 V,
00124 I,
00125 R >::computeAccelerations (Vector & acc, const
00126 Positions & pos, const Vector & vel)
00127 {
00128
00129 computeForces (acc, pos, vel);
00130
00131
00132 applyForces( acc, acc );
00133
00134
00135
00136 applyGravity( acc );
00137
00138 }
00139
00141 template < class P, class V, class I, class R > void PhysicalSolver < P,
00142 V,
00143 I,
00144 R >::applyForces (Vector & acc, const Vector & f)
00145 {
00146 assert( size(acc)==size(f) );
00147
00148
00149
00150 if (_useMass)
00151 {
00152 if (_useSingleMass)
00153 v_eq_ab (acc, _singleInvMass, f );
00154 else
00155 for (unsigned int i = 0; i < size (acc); ++i)
00156 {
00157 v_eq_ab(acc[i], (*_invMasses)[i], f[i] );
00158 }
00159 }
00160 else
00161 {
00162 v_eq (acc, f);
00163 }
00164
00165
00166
00167
00168
00169 }
00171 template < class P, class V, class I, class R > void PhysicalSolver < P,
00172 V, I, R >::applyExponentialDamping (Vector & v, Real dt)
00173 {
00174 if (_useExponentialDamping)
00175 {
00176
00177 Real factor = exp (-_exponentialDamping * dt);
00178 v_teq (v, factor);
00179 }
00180 }
00182 template < class P, class V, class I, class R > void PhysicalSolver < P,
00183 V, I, R >::computeForces (Vector & f, const Positions &, const Vector &)
00184 {
00185 v_assign (f, zero ());
00186 }
00188 template < class P, class V, class I, class R >
00189 const bool & PhysicalSolver < P, V, I, R >::get_useMass ()
00190 {
00191 return _useMass;
00192 }
00194 template < class P, class V, class I, class R > void PhysicalSolver < P,
00195 V, I, R >::set_useMass (const bool & _newVal)
00196 {
00197 _useMass = _newVal;
00198 }
00200 template < class P, class V, class I, class R >
00201 const bool & PhysicalSolver < P, V, I, R >::get_useSingleMass ()
00202 {
00203 return _useSingleMass;
00204 }
00206 template < class P, class V, class I, class R > void PhysicalSolver < P,
00207 V, I, R >::set_useSingleMass (const bool & _newVal)
00208 {
00209 _useSingleMass = _newVal;
00210 }
00212 template < class P, class V, class I, class R >
00213 const typename PhysicalSolver < P,
00214 V, I, R >::InvMass & PhysicalSolver < P, V, I, R >::get_singleInvMass ()
00215 {
00216 return _singleInvMass;
00217 }
00219 template < class P, class V, class I, class R > void PhysicalSolver < P,
00220 V, I, R >::set_singleInvMass (const InvMass & _newVal)
00221 {
00222 _singleInvMass = _newVal;
00223 _useSingleMass = true;
00224 }
00226 template < class P, class V, class I, class R >
00227 const typename PhysicalSolver < P,
00228 V, I, R >::InvMasses * PhysicalSolver < P, V, I, R >::get_invMasses ()
00229 {
00230 return _invMasses;
00231 }
00233 template < class P, class V, class I, class R > void PhysicalSolver < P,
00234 V, I, R >::set_invMasses (InvMasses * _newVal)
00235 {
00236 _invMasses = _newVal;
00237 set_useMass(true);
00238 set_useSingleMass(false);
00239 }
00240
00241
00242 }