00001 #ifndef MASS_SPRING_ENGINE_INL
00002 #define MASS_SPRING_ENGINE_INL
00003 
00004 #include "massSpringEngine.h"
00005 #include <animal/linear.h>
00006 #include <animal/massspringsolver.inl>
00007 #include <animal/container_traits.h>
00008 #include <animal/picking.h>
00009 #include <animal/value.h>
00010 
00011 #include <iostream>
00012 #include <vector>
00013 using std::cerr;
00014 using std::endl;
00015 
00016 namespace animal
00017 {
00018 
00020 template< class Inv_Masses,
00021 class Velocities,
00022 class SpringStiffness,
00023 class IndexedSprings,
00024 class Points,
00025 class Real >
00026 MassSpringEngine< Inv_Masses, Velocities, SpringStiffness, IndexedSprings, Points, Real >
00027 ::MassSpringEngine()
00028         : _velocities(0)
00029         , _points(0)
00030         , _pointSize(8)
00031         , _lineWidth(4)
00032 {
00033     compressed_ok = false;
00034     elongated_ok = false;
00035     displayMassSpring = true;
00036 }
00037 
00039 template< class Inv_Masses,
00040 class Velocities,
00041 class SpringStiffness,
00042 class IndexedSprings,
00043 class Points,
00044 class Real >
00045 MassSpringEngine< Inv_Masses, Velocities, SpringStiffness, IndexedSprings, Points, Real >
00046 ::~MassSpringEngine()
00047 {}
00048 
00049 
00050 
00051 
00052 
00054 template< class Inv_Masses,
00055 class Velocities,
00056 class SpringStiffness,
00057 class IndexedSprings,
00058 class Points,
00059 class Real >
00060 void MassSpringEngine< Inv_Masses, Velocities, SpringStiffness, IndexedSprings, Points, Real >
00061 ::reset()
00062 {
00063 
00064     if (_points && _velocities)
00065     {
00066         v_eq(*_points, _initialPoints);
00067         v_eq(*_velocities, _initialVelocities);
00068         resize(elongation,size(*_stiffnesses));
00069         resize(colours,size(*_stiffnesses));
00070         for(unsigned i=0;i<size(*_links);i+=2)
00071         {
00072             elongation[i/2]=v_norm((*_points)[(*_links)[i]]-(*_points)[(*_links)[i+1]]) - (*get_rest_lengths())[i/2]; 
00073             colours[i/2].r=0.0;
00074             colours[i/2].g=0.0;
00075             colours[i/2].b=0.0;
00076         }
00077     }
00078 }
00079 
00080 template< class Inv_Masses,
00081 class Velocities,
00082 class SpringStiffness,
00083 class IndexedSprings,
00084 class Points,
00085 class Real >
00086 void MassSpringEngine< Inv_Masses, Velocities, SpringStiffness, IndexedSprings, Points, Real >
00087 ::draw()
00088 {
00089     if (get_displayMassSpring())
00090     {
00091         
00092         glPushAttrib(GL_LIGHTING_BIT | GL_POINT_BIT| GL_LINE_BIT);
00093         glDisable(GL_LIGHTING);
00094         glLineWidth(_lineWidth);
00095         if( _links )
00096         {
00097             glBegin(GL_LINES);
00098             unsigned i=0;
00099             
00100             Index p1=0;
00101             
00102             Index p2=0;
00103             float elong;
00104             
00105             
00106             while(i<size(*_links)-1)
00107             {
00108                 float r,g,b;
00109                 p1=(*_links)[i];
00110                 p2=(*_links)[i+1];
00111                 elong = v_norm((*_points)[p1]-(*_points)[p2]) - (*get_rest_lengths())[i/2]; 
00112 
00113                 
00114                 if(elongation[i/2]>elong && compressed_ok)
00115                 {
00116                     r=0.0;
00117                     g=1.0;
00118                     b=0.0;    
00119                     glColor3f(r,g,b);
00120                     elongation[i/2]=elong;
00121                     colours[i/2].r=r;
00122                     colours[i/2].g=g;
00123                     colours[i/2].b=b;
00124                 }
00125                 
00126                 else if(elongation[i/2]<elong && elongated_ok)
00127                 {
00128                     r=1.0;
00129                     g=0.0;
00130                     b=1.0;
00131                     glColor3f(r,g,b);
00132                     elongation[i/2]=elong;
00133                     colours[i/2].r=r;
00134                     colours[i/2].g=g;
00135                     colours[i/2].b=b;
00136                 }
00137                 
00138                 else
00139                 {
00140                     glColor3f(0,0,0);
00141                     elongation[i/2]=elong;
00142                 }
00143                 glVertex3f((*_points)[p1].x,(*_points)[p1].y,(*_points)[p1].z);
00144                 glVertex3f((*_points)[p2].x,(*_points)[p2].y,(*_points)[p2].z);
00145                 i=i+2;
00146             }
00147             glEnd();
00148         }
00149 
00150         
00151         glDisable(GL_POINT_SMOOTH);
00152         glPointSize(_pointSize);
00153         glBegin(GL_POINTS);
00154         glColor3f(1,1,1);
00155         for( unsigned int i=0; i<size(*_points); ++i )
00156         {
00157             glVertex3f((*_points)[i].x,(*_points)[i].y,(*_points)[i].z);
00158         }
00159         glEnd();
00160         glPopAttrib();
00161     }
00162 }
00163 
00165 template< class Inv_Masses,
00166 class Velocities,
00167 class SpringStiffness,
00168 class IndexedSprings,
00169 class Points,
00170 class Real >
00171 void MassSpringEngine< Inv_Masses, Velocities, SpringStiffness, IndexedSprings, Points, Real >
00172 ::move(double dt)
00173 {
00174     Velocities force;
00175     resize(force, size(*_velocities));
00176     if (_points && _velocities)
00177     {
00178         this->_MassSpringSolver::solveODE( *_points, *_velocities, dt );
00179         
00180         if (get_displayMassSpring())
00181             this->_MassSpringSolver::computeForces(force,*_points,*_velocities);
00182 
00183     }
00184 }
00185 
00187 template< class Inv_Masses,
00188 class Velocities,
00189 class SpringStiffness,
00190 class IndexedSprings,
00191 class Points,
00192 class Real >
00193 void MassSpringEngine< Inv_Masses, Velocities, SpringStiffness, IndexedSprings, Points, Real >
00194 ::getBoundingBox(float &minX, float &minY, float &minZ, float &maxX, float &maxY, float &maxZ)
00195 {
00196     if(_points->size()==0 )
00197     {
00198         cerr<<"MassSpringEngine::getBoundingBox can not find bounding box because there are no particles" << endl;
00199         return;
00200     }
00201     minX=maxX=(*_points)[0].x;
00202     minY=maxY=(*_points)[1].y;
00203     minZ=maxZ=(*_points)[2].z;
00204     for( unsigned i=1; i<_points->size(); ++i )
00205     {
00206         if( (*_points)[i].x<minX )
00207             minX=(*_points)[i].x;
00208         if( (*_points)[i].x>maxX )
00209             maxX=(*_points)[i].x;
00210         if( (*_points)[i].y<minY )
00211             minY=(*_points)[i].y;
00212         if( (*_points)[i].y>maxY )
00213             maxY=(*_points)[i].y;
00214         if( (*_points)[i].z<minZ )
00215             minZ=(*_points)[i].z;
00216         if( (*_points)[i].z>maxZ )
00217             maxZ=(*_points)[i].z;
00218     }
00219     
00220 }
00221 
00223 template< class Inv_Masses,
00224 class Velocities,
00225 class SpringStiffness,
00226 class IndexedSprings,
00227 class Points,
00228 class Real >
00229 void MassSpringEngine< Inv_Masses, Velocities, SpringStiffness, IndexedSprings, Points, Real >
00230 ::mousePressEvent( MouseEvent* )
00231 {
00232     
00233 }
00234 
00235 
00236 
00238 template< class Inv_Masses,
00239 class Velocities,
00240 class SpringStiffness,
00241 class IndexedSprings,
00242 class Points,
00243 class Real >
00244 MassSpringEngine< Inv_Masses, Velocities, SpringStiffness, IndexedSprings, Points, Real >
00245 ::ConstrainedPoint::ConstrainedPoint( MassSpringEngine* mse, int index )
00246         : _mse(mse)
00247         , _index(index)
00248         , invmass( (*mse->_invMasses)[index] )
00249 {
00250     
00251 }
00252 
00254 template< class Inv_Masses,
00255 class Velocities,
00256 class SpringStiffness,
00257 class IndexedSprings,
00258 class Points,
00259 class Real >
00260 void MassSpringEngine< Inv_Masses, Velocities, SpringStiffness, IndexedSprings, Points, Real >
00261 ::ConstrainedPoint::getPoint( float& x, float& y, float& z ) const
00262 {
00263     x= (*_mse->_points)[_index].x;
00264     y= (*_mse->_points)[_index].y;
00265     z= (*_mse->_points)[_index].z;
00266 }
00267 
00269 template< class Inv_Masses,
00270 class Velocities,
00271 class SpringStiffness,
00272 class IndexedSprings,
00273 class Points,
00274 class Real >
00275 void MassSpringEngine< Inv_Masses, Velocities, SpringStiffness, IndexedSprings, Points, Real >
00276 ::ConstrainedPoint::moveTo( float x, float y, float z ) const
00277 {
00278     (*_mse->_points)[_index].x = x;
00279     (*_mse->_points)[_index].y = y;
00280     (*_mse->_points)[_index].z = z;
00281     (*_mse->_invMasses)[_index] = 0.0;
00282     typedef typename container_traits<Velocities>::value_type Velocity;
00283     (*_mse->_velocities)[_index] = Value<Velocity>::zero() ;
00284 
00285     
00286 }
00287 
00289 template< class Inv_Masses,
00290 class Velocities,
00291 class SpringStiffness,
00292 class IndexedSprings,
00293 class Points,
00294 class Real >
00295 void MassSpringEngine< Inv_Masses, Velocities, SpringStiffness, IndexedSprings, Points, Real >
00296 ::ConstrainedPoint::print() const
00297 {
00298     
00299 }
00300 
00302 template< class Inv_Masses,
00303 class Velocities,
00304 class SpringStiffness,
00305 class IndexedSprings,
00306 class Points,
00307 class Real >
00308 MassSpringEngine< Inv_Masses, Velocities, SpringStiffness, IndexedSprings, Points, Real >
00309 ::ConstrainedPoint::~ConstrainedPoint()
00310 {
00311     (*_mse->_invMasses)[_index] = invmass;
00312 }
00313 
00315 template< class Inv_Masses,
00316 class Velocities,
00317 class SpringStiffness,
00318 class IndexedSprings,
00319 class Points,
00320 class Real >
00321 bool MassSpringEngine< Inv_Masses, Velocities, SpringStiffness, IndexedSprings, Points, Real >
00322 ::ConstrainedPoint::operator == ( const ConstrainedItem* it ) const
00323 {
00324     const ConstrainedPoint* ptr_item = dynamic_cast<const ConstrainedPoint*>(it);
00325     if( ptr_item )
00326     {
00327         if(ptr_item->_mse == this->_mse)
00328         {
00329             
00330         }
00331         return (ptr_item->_mse == this->_mse) && (ptr_item->_index == this->_index);
00332     }
00333     else
00334         return false;
00335 
00336 }
00337 
00339 template< class Inv_Masses,
00340 class Velocities,
00341 class SpringStiffness,
00342 class IndexedSprings,
00343 class Points,
00344 class Real >
00345 ConstrainedItem* MassSpringEngine< Inv_Masses, Velocities, SpringStiffness, IndexedSprings, Points, Real >
00346 ::pickPoint( float origin[3], float direction[3], float threshold )
00347 {
00348     
00349     int index;
00350     float distance;
00351     typedef typename container_traits<Points>::value_type Vect;
00352     Vect lineOrigin(origin[0], origin[1], origin[2]);
00353     Vect lineDirection(direction[0],direction[1],direction[2]);
00354     if( findClosestPointToLine( index, distance, *_points, lineOrigin, lineDirection, threshold ) )
00355         return new ConstrainedPoint(this,index);
00356     else
00357         return 0;
00358 }
00359 
00360 
00361 
00363 template< class Inv_Masses,
00364 class Velocities,
00365 class SpringStiffness,
00366 class IndexedSprings,
00367 class Points,
00368 class Real >
00369 bool MassSpringEngine< Inv_Masses, Velocities, SpringStiffness, IndexedSprings, Points, Real >
00370 ::get_compressed_ok()
00371 {
00372     return compressed_ok;
00373 }
00374 
00376 template< class Inv_Masses,
00377 class Velocities,
00378 class SpringStiffness,
00379 class IndexedSprings,
00380 class Points,
00381 class Real >
00382 void MassSpringEngine< Inv_Masses, Velocities, SpringStiffness, IndexedSprings, Points, Real >
00383 ::set_compressed_ok(bool ok)
00384 {
00385     compressed_ok = ok;
00386 }
00387 
00389 template< class Inv_Masses,
00390 class Velocities,
00391 class SpringStiffness,
00392 class IndexedSprings,
00393 class Points,
00394 class Real >
00395 bool MassSpringEngine< Inv_Masses, Velocities, SpringStiffness, IndexedSprings, Points, Real >
00396 ::get_elongated_ok()
00397 {
00398     return elongated_ok;
00399 }
00400 
00402 template< class Inv_Masses,
00403 class Velocities,
00404 class SpringStiffness,
00405 class IndexedSprings,
00406 class Points,
00407 class Real >
00408 void MassSpringEngine< Inv_Masses, Velocities, SpringStiffness, IndexedSprings, Points, Real >
00409 ::set_elongated_ok(bool ok)
00410 {
00411     elongated_ok = ok;
00412 }
00413 
00415 template< class Inv_Masses,
00416 class Velocities,
00417 class SpringStiffness,
00418 class IndexedSprings,
00419 class Points,
00420 class Real >
00421 bool MassSpringEngine< Inv_Masses, Velocities, SpringStiffness, IndexedSprings, Points, Real >
00422 ::get_displayMassSpring()
00423 {
00424     return displayMassSpring;
00425 }
00426 
00428 template< class Inv_Masses,
00429 class Velocities,
00430 class SpringStiffness,
00431 class IndexedSprings,
00432 class Points,
00433 class Real >
00434 void MassSpringEngine< Inv_Masses, Velocities, SpringStiffness, IndexedSprings, Points, Real >
00435 ::set_displayMassSpring(bool display)
00436 {
00437     displayMassSpring=display;
00438 }
00439 
00440 
00442 template< class Inv_Masses,
00443 class Velocities,
00444 class SpringStiffness,
00445 class IndexedSprings,
00446 class Points,
00447 class Real >
00448 int MassSpringEngine< Inv_Masses, Velocities, SpringStiffness, IndexedSprings, Points, Real >
00449 ::get_pointSize() const
00450 {
00451     return _pointSize;
00452 }
00453 
00455 template< class Inv_Masses,
00456 class Velocities,
00457 class SpringStiffness,
00458 class IndexedSprings,
00459 class Points,
00460 class Real >
00461 void MassSpringEngine< Inv_Masses, Velocities, SpringStiffness, IndexedSprings, Points, Real >
00462 ::set_pointSize(int s)
00463 {
00464     _pointSize=s;
00465 }
00466 
00468 template< class Inv_Masses,
00469 class Velocities,
00470 class SpringStiffness,
00471 class IndexedSprings,
00472 class Points,
00473 class Real >
00474 int MassSpringEngine< Inv_Masses, Velocities, SpringStiffness, IndexedSprings, Points, Real >
00475 ::get_lineWidth() const
00476 {
00477     return _lineWidth;
00478 }
00479 
00481 template< class Inv_Masses,
00482 class Velocities,
00483 class SpringStiffness,
00484 class IndexedSprings,
00485 class Points,
00486 class Real >
00487 void MassSpringEngine< Inv_Masses, Velocities, SpringStiffness, IndexedSprings, Points, Real >
00488 ::set_lineWidth(int s)
00489 {
00490     _lineWidth=s;
00491 }
00492 
00493 
00494 
00495 
00497 
00498 
00499 
00500 
00501 
00502 
00503 
00504 
00505 
00506 
00507 
00508 
00509 
00510 
00511 
00512 
00513 
00514 
00515 
00516 
00517 
00518 
00519 
00520 
00521 
00522 
00523 
00524 
00525 
00526 
00527 
00528 
00529 
00530 
00531 
00532 
00533 
00534 
00535 
00536 
00537 
00538 
00539 
00540 
00541 
00542 
00543 
00544 
00545 
00546 }
00547 
00548 #endif //MASS_SPRING_ENGINE_INL