00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #ifndef SOFA_DEFAULTTYPE_LAPAROSCOPICRIGIDTYPES_H
00028 #define SOFA_DEFAULTTYPE_LAPAROSCOPICRIGIDTYPES_H
00029
00030
00031 #include <sofa/defaulttype/RigidTypes.h>
00032 #include <sofa/defaulttype/DataTypeInfo.h>
00033 #include <sofa/defaulttype/Vec.h>
00034 #include <sofa/core/objectmodel/BaseContext.h>
00035 #include <sofa/core/componentmodel/behavior/Mass.h>
00036 #include <sofa/helper/vector.h>
00037 #include <iostream>
00038
00039 namespace sofa
00040 {
00041
00042 namespace defaulttype
00043 {
00044
00045 using sofa::helper::vector;
00046
00047 class LaparoscopicRigid3Types
00048 {
00049 public:
00050
00051 typedef SReal Real;
00052
00053 class Deriv
00054 {
00055 private:
00056 Real vTranslation;
00057 Vector3 vOrientation;
00058 public:
00059 typedef Real value_type;
00060 friend class Coord;
00061
00062 Deriv (const Real &velTranslation, const Vector3 &velOrient)
00063 : vTranslation(velTranslation), vOrientation(velOrient) {}
00064 Deriv () { clear(); }
00065
00066 void clear() { vTranslation = 0; vOrientation.clear(); }
00067
00068 void operator +=(const Deriv& a)
00069 {
00070 vTranslation += a.vTranslation;
00071 vOrientation += a.vOrientation;
00072 }
00073
00074 Deriv operator + (const Deriv& a) const
00075 {
00076 Deriv d;
00077 d.vTranslation = vTranslation + a.vTranslation;
00078 d.vOrientation = vOrientation + a.vOrientation;
00079 return d;
00080 }
00081
00082 void operator*=(Real a)
00083 {
00084 vTranslation *= a;
00085 vOrientation *= a;
00086 }
00087
00088 Deriv operator*(Real a) const
00089 {
00090 Deriv r = *this;
00091 r*=a;
00092 return r;
00093 }
00094
00095 Deriv operator - () const
00096 {
00097 return Deriv(-vTranslation, -vOrientation);
00098 }
00099
00101 Real operator*(const Deriv& a) const
00102 {
00103 return vTranslation*a.vTranslation
00104 +vOrientation[0]*a.vOrientation[0]+vOrientation[1]*a.vOrientation[1]
00105 +vOrientation[2]*a.vOrientation[2];
00106 }
00107
00108 Real& getVTranslation (void) { return vTranslation; }
00109 Vector3& getVOrientation (void) { return vOrientation; }
00110 const Real& getVTranslation (void) const { return vTranslation; }
00111 const Vector3& getVOrientation (void) const { return vOrientation; }
00112 inline friend std::ostream& operator << (std::ostream& out, const Deriv& v ){
00113 out<<v.getVTranslation();
00114 out<<" "<<v.getVOrientation();
00115 return out;
00116 }
00117 inline friend std::istream& operator >> (std::istream& in, Deriv& v ){
00118 in>>v.vTranslation;
00119 in>>v.vOrientation;
00120 return in;
00121 }
00122 };
00123
00124 class Coord
00125 {
00126
00127 private:
00128 Real translation;
00129 Quat orientation;
00130 public:
00131 typedef Real value_type;
00132 Coord (const Real &posTranslation, const Quat &orient)
00133 : translation(posTranslation), orientation(orient) {}
00134 Coord () { clear(); }
00135
00136 void clear() { translation = 0; orientation.clear(); }
00137
00138 void operator +=(const Deriv& a)
00139 {
00140 translation += a.getVTranslation();
00141 orientation.normalize();
00142 Quat qDot = orientation.vectQuatMult(a.getVOrientation());
00143 for (int i = 0; i < 4; i++)
00144 orientation[i] += qDot[i] * (SReal)0.5;
00145 orientation.normalize();
00146 }
00147
00148 Coord operator + (const Deriv& a) const
00149 {
00150 Coord c = *this;
00151 c.translation += a.getVTranslation();
00152 c.orientation.normalize();
00153 Quat qDot = c.orientation.vectQuatMult(a.getVOrientation());
00154 for (int i = 0; i < 4; i++)
00155 c.orientation[i] += qDot[i] * (SReal)0.5;
00156 c.orientation.normalize();
00157 return c;
00158 }
00159
00160 void operator +=(const Coord& a)
00161 {
00162
00163 translation += a.getTranslation();
00164
00165
00166 }
00167
00168 void operator*=(Real a)
00169 {
00170
00171 translation *= a;
00172
00173 }
00174
00175 Coord operator*(Real a) const
00176 {
00177 Coord r = *this;
00178 r*=a;
00179 return r;
00180 }
00181
00183 Real operator*(const Coord& a) const
00184 {
00185 return translation*a.translation
00186 +orientation[0]*a.orientation[0]+orientation[1]*a.orientation[1]
00187 +orientation[2]*a.orientation[2]+orientation[3]*a.orientation[3];
00188 }
00189
00190 Real& getTranslation () { return translation; }
00191 Quat& getOrientation () { return orientation; }
00192 const Real& getTranslation () const { return translation; }
00193 const Quat& getOrientation () const { return orientation; }
00194 inline friend std::ostream& operator << (std::ostream& out, const Coord& c ){
00195 out<<c.getTranslation();
00196 out<<" "<<c.getOrientation();
00197 return out;
00198 }
00199 inline friend std::istream& operator >> (std::istream& in, Coord& c ){
00200 in>>c.translation;
00201 in>>c.orientation;
00202 return in;
00203 }
00204
00205 static Coord identity() {
00206 Coord c;
00207 return c;
00208 }
00209
00211 void multRight( const Coord& c )
00212 {
00213 translation += c.getTranslation();
00214 orientation = orientation * c.getOrientation();
00215 }
00216
00218 Coord mult( const Coord& c ) const {
00219 Coord r;
00220 r.translation = translation + c.translation;
00221 r.orientation = orientation * c.getOrientation();
00222 return r;
00223 }
00225 Vector3 vectorToChild( const Vector3& v ) const {
00226 return orientation.inverseRotate(v);
00227 }
00228 };
00229
00230 template <class T>
00231 class SparseData
00232 {
00233 public:
00234 SparseData(unsigned int _index, const T& _data): index(_index), data(_data){};
00235 unsigned int index;
00236 T data;
00237 };
00238
00239 typedef SparseData<Coord> SparseCoord;
00240 typedef SparseData<Deriv> SparseDeriv;
00241
00242 typedef vector<SparseCoord> SparseVecCoord;
00243 typedef vector<SparseDeriv> SparseVecDeriv;
00244
00246 typedef vector<SparseVecDeriv> VecConst;
00247
00248 typedef vector<Coord> VecCoord;
00249 typedef vector<Deriv> VecDeriv;
00250 typedef vector<Real> VecReal;
00251
00252 template<typename T>
00253 static void set(Coord& c, T x, T, T)
00254 {
00255 c.getTranslation() = (Real)x;
00256 }
00257
00258 template<typename T>
00259 static void get(T& x, T&, T&, const Coord& c)
00260 {
00261 x = (T)c.getTranslation();
00262 }
00263
00264 template<typename T>
00265 static void add(Coord& c, T x, T, T)
00266 {
00267 c.getTranslation() += (Real)x;
00268 }
00269
00270 template<typename T>
00271 static void set(Deriv& c, T x, T, T)
00272 {
00273 c.getVTranslation() = (Real)x;
00274 }
00275
00276 template<typename T>
00277 static void get(T& x, T& y, T& z, const Deriv& c)
00278 {
00279 x = (T)c.getVTranslation();
00280 y = (T)0;
00281 z = (T)0;
00282 }
00283
00284 template<typename T>
00285 static void add(Deriv& c, T x, T, T)
00286 {
00287 c.getVTranslation() += (T)x;
00288 }
00289 static const char* Name()
00290 {
00291 return "LaparoscopicRigid3";
00292 }
00293
00294 static Coord interpolate(const helper::vector< Coord > &ancestors, const helper::vector< Real > &coefs)
00295 {
00296 assert(ancestors.size() == coefs.size());
00297
00298 Coord c;
00299
00300 for (unsigned int i = 0; i < ancestors.size(); i++)
00301 {
00302 c += ancestors[i] * coefs[i];
00303 }
00304
00305 return c;
00306 }
00307
00308 static Deriv interpolate(const helper::vector< Deriv > &ancestors, const helper::vector< Real > &coefs)
00309 {
00310 assert(ancestors.size() == coefs.size());
00311
00312 Deriv d;
00313
00314 for (unsigned int i = 0; i < ancestors.size(); i++)
00315 {
00316 d += ancestors[i] * coefs[i];
00317 }
00318
00319 return d;
00320 }
00321 };
00322
00323 inline LaparoscopicRigid3Types::Deriv operator*(const LaparoscopicRigid3Types::Deriv& d, const Rigid3Mass& m)
00324 {
00325 LaparoscopicRigid3Types::Deriv res;
00326 res.getVTranslation() = d.getVTranslation() * m.mass;
00327 res.getVOrientation() = m.inertiaMassMatrix * d.getVOrientation();
00328 return res;
00329 }
00330
00331 inline LaparoscopicRigid3Types::Deriv operator/(const LaparoscopicRigid3Types::Deriv& d, const Rigid3Mass& m)
00332 {
00333 LaparoscopicRigid3Types::Deriv res;
00334 res.getVTranslation() = d.getVTranslation() / m.mass;
00335 res.getVOrientation() = m.invInertiaMassMatrix * d.getVOrientation();
00336 return res;
00337 }
00338
00339 typedef LaparoscopicRigid3Types LaparoscopicRigidTypes;
00340
00341 template<>
00342 class DataTypeInfo<LaparoscopicRigidTypes::Coord>
00343 {
00344 public:
00345 static unsigned int size() { return 5; }
00346
00347 template <typename T>
00348 static void getValue(const LaparoscopicRigidTypes::Coord &type, unsigned int index, T& value)
00349 {
00350 if (index < 1)
00351 value = static_cast<T>(type.getTranslation());
00352 else
00353 value = static_cast<T>(type.getOrientation()[index-1]);
00354 }
00355
00356 template<typename T>
00357 static void setValue(LaparoscopicRigidTypes::Coord &type, unsigned int index, const T& value )
00358 {
00359 if (index < 1)
00360 type.getTranslation() = static_cast<LaparoscopicRigidTypes::Coord::value_type>(value);
00361 else
00362 type.getOrientation()[index-1] = static_cast<LaparoscopicRigidTypes::Coord::value_type>(value);
00363 }
00364 };
00365
00366 template<>
00367 class DataTypeInfo<LaparoscopicRigidTypes::Deriv>
00368 {
00369 public:
00370 static unsigned int size() { return 4; }
00371
00372 template <typename T>
00373 static void getValue(const LaparoscopicRigidTypes::Deriv &type, unsigned int index, T& value)
00374 {
00375 if (index < 1)
00376 value = static_cast<T>(type.getVTranslation());
00377 else
00378 value = static_cast<T>(type.getVOrientation()[index-1]);
00379 }
00380
00381 template<typename T>
00382 static void setValue(LaparoscopicRigidTypes::Deriv &type, unsigned int index, const T& value )
00383 {
00384 if (index < 1)
00385 type.getVTranslation() = static_cast<LaparoscopicRigidTypes::Deriv::value_type>(value);
00386 else
00387 type.getVOrientation()[index-1] = static_cast<LaparoscopicRigidTypes::Deriv::value_type>(value);
00388 }
00389 };
00390
00391 }
00392
00393
00394
00395
00396
00397
00398 namespace core {
00399 namespace componentmodel {
00400 namespace behavior {
00402 template <>
00403 inline defaulttype::LaparoscopicRigid3Types::Deriv inertiaForce<
00404 defaulttype::LaparoscopicRigid3Types::Coord,
00405 defaulttype::LaparoscopicRigid3Types::Deriv,
00406 defaulttype::Vector3,
00407 defaulttype::Rigid3Mass,
00408 objectmodel::BaseContext::SpatialVector
00409 >
00410 (
00411 const objectmodel::BaseContext::SpatialVector& vframe,
00412 const defaulttype::Vector3& aframe,
00413 const defaulttype::Rigid3Mass& mass,
00414 const defaulttype::LaparoscopicRigid3Types::Coord& x,
00415 const defaulttype::LaparoscopicRigid3Types::Deriv& v )
00416 {
00417 defaulttype::Vector3 omega( vframe.lineVec[0], vframe.lineVec[1], vframe.lineVec[2] );
00418 defaulttype::Vector3 origin, finertia, zero(0,0,0);
00419 origin[0] = x.getTranslation();
00420
00421 finertia = -( aframe + omega.cross( omega.cross(origin) + defaulttype::Vector3(v.getVTranslation()*2,0,0) ))*mass.mass;
00422 return defaulttype::LaparoscopicRigid3Types::Deriv( finertia[0], zero );
00424 }
00425
00426 }
00427
00428 }
00429
00430 }
00431
00432 }
00433
00434 #endif