OMKTrajectory.cpp

Go to the documentation of this file.
00001 #include "OMKTrajectory.h"
00002 #include "OMKParametersAccessor.inl"
00003 #include "OMKAttribute.inl"
00004 #include "OMKTracer.h"
00005 #include "Wm4BSplineCurve3.h"
00006 #include "OMKTransformType.h"
00007 
00008 using namespace OMK ;
00009 using namespace OMK::Type ;
00010 
00011 //-------------------------------------------------------------------------
00012 REGISTER_OBJECT_FACTORY( Trajectory, "Trajectory" ) ;
00013 //-----------------------------------------------------------------------------
00014 
00015 Trajectory::Trajectory( Controller& ctrl, const ObjectDescriptor& objectDescriptor )
00016 : OMK::SimplePoint( ctrl, objectDescriptor ),
00017   _bSpline( 0 ),
00018   _positionBetweenTargets( 1.0f ), 
00019   _currentTarget( 0 ),
00020   _followOrientation( false ), 
00021   _step( "Step", 0.0f )
00022 { 
00023   addAttribute( _step ) ;
00024 }
00025 
00026 //-----------------------------------------------------------------------------
00027 
00028 Trajectory::~Trajectory( void ) 
00029 {
00030 }
00031 //-----------------------------------------------------------------------------
00032 
00033 bool Trajectory::loadParameters( const ConfigurationParameterDescriptor * node )
00034 {
00035   SimplePoint::loadParameters( node ) ;
00036   if( !ParametersAccessor::get( node, "Targets", _targets ) )
00037   {
00038     _targets.push_back( Transform( Wm4::Vector3f(  10, 0,  10 ) ) ) ;
00039     _targets.push_back( Transform( Wm4::Vector3f(  10, 0, -10 ) ) ) ;
00040     _targets.push_back( Transform( Wm4::Vector3f( -10, 0, -10 ) ) ) ;
00041     _targets.push_back( Transform( Wm4::Vector3f( -10, 0,  10 ) ) ) ;
00042   }
00043   ParametersAccessor::get( node, "Orientation", _followOrientation ) ;
00044   bool bspline = false ;
00045   ParametersAccessor::get( node, "BSpline", bspline ) ;
00046   if( bspline && 2 <= _targets.size() )
00047   { // At least 2 points to define a B-spline
00048     int degree = 2 ; // Default value
00049     ParametersAccessor::get( node, "Degree", degree ) ;
00050     degree = degree < (int)_targets.size() ? degree : _targets.size() - 1 ;
00051     Wm4::Vector3f* targets = new Wm4::Vector3f[ _targets.size() ] ;
00052     for( unsigned int i = 0 ; i < _targets.size() ; i++ )
00053     {
00054       targets[ i ] = _targets[ i ].getTranslate() ;
00055     }
00056     _bSpline = new Wm4::BSplineCurve3f( _targets.size(), targets, degree, true, false ) ;
00057     delete[] targets ;
00058     _refOrientation = _bSpline->GetFirstDerivative( 0.0f ) ;
00059     _refOrientation.Normalize() ;
00060   }
00061   else
00062   {
00063     _refOrientation = _targets[ 1 ].getTranslate() - _targets[ 0 ].getTranslate() ;
00064     _refOrientation.Normalize() ;
00065   }
00066   
00067   _refPosition = _position.get() ;
00068   OMK::Type::Transform position( _refPosition ) ;
00069   position.setTranslate( _targets[ 0 ].getTranslate() ) ;
00070   _position.set( position ) ;
00071   _position.setValueToOutput() ;
00072   return true ; 
00073 }
00074 //-----------------------------------------------------------------------------
00075 
00076 void Trajectory::computeParameters() 
00077 {
00078   float step = _step.get() * ( _bSpline ? 1.0f : _targets.size() ) ;
00079   // Get the increment
00080   if ( 1.0f <= _positionBetweenTargets ) 
00081   { // step > 0
00082     _currentTarget = ( _currentTarget + 1 ) % _targets.size() ;
00083     _positionBetweenTargets = step ;
00084   }
00085   else if ( _positionBetweenTargets <= 0.0f ) 
00086   { // step < 0
00087     _currentTarget = ( _currentTarget + _targets.size() - 1 ) % _targets.size() ;
00088     _positionBetweenTargets = 1.0f + step ;
00089   }
00090   else
00091   {
00092     _positionBetweenTargets += step ;
00093   }
00094   
00095   // Get the translate and the rotate
00096   OMK::Type::Transform position( _refPosition ) ;
00097   Wm4::Vector3f orientation ;
00098   if( _bSpline )
00099   { // For B-spline
00100     if( _followOrientation ) 
00101     {
00102       Wm4::Vector3f translate ;
00103       _bSpline->Get( _positionBetweenTargets, &translate, &orientation, 0, 0 ) ;
00104       position.setTranslate( translate ) ;
00105     }
00106     else
00107     {
00108       position.setTranslate( _bSpline->GetPosition( _positionBetweenTargets ) ) ;
00109     }
00110   }
00111   else
00112   { // For segments
00113     int previousTarget( ( _currentTarget + _targets.size() - 1 ) % _targets.size() ) ;
00114     orientation = _targets[ _currentTarget ].getTranslate() - _targets[ previousTarget ].getTranslate() ;
00115     position.setTranslate( _targets[previousTarget].getTranslate() + orientation * _positionBetweenTargets ) ;
00116   }
00117   
00118   if( _followOrientation ) 
00119   { // Calculate the orientation
00120     orientation.Normalize() ;
00121     Wm4::Vector3f axis( orientation.Cross( _refOrientation ) ) ;
00122     axis.Normalize() ;
00123     float angle = -Wm4::Math<float>::ACos( orientation.Dot( _refOrientation ) ) ;
00124     Wm4::Matrix3f rotationMatrix( axis, angle ) ;
00125     position.setRotate( position.getRotate() * rotationMatrix ) ;
00126   }
00127   // Set the new position
00128   _position.set( position ) ;
00129 }
00130 
00131 
00132 

logo OpenMask

Documentation generated on Mon Jun 9 11:45:57 2008

Generated with doxygen by Dimitri van Heesch ,   1997-2007