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
Documentation generated on Mon Jun 9 11:45:57 2008 |
Generated with doxygen by Dimitri van Heesch , 1997-2007 |