コード例 #1
0
F32 CatmullRomBase::arcLength( F32 t1, F32 t2 )
{
   if ( t2 <= t1 )
      return 0.0f;

   if ( t1 < mTimes[0] )
      t1 = mTimes[0];

   if ( t2 > mTimes[mCount-1] )
      t2 = mTimes[mCount-1];

   // find segment and parameter
   U32 seg1;
   for ( seg1 = 0; seg1 < mCount-1; ++seg1 )
   {
      if ( t1 <= mTimes[seg1+1] )
      {
         break;
      }
   }
   F32 u1 = (t1 - mTimes[seg1])/(mTimes[seg1+1] - mTimes[seg1]);

   // find segment and parameter
   U32 seg2;
   for ( seg2 = 0; seg2 < mCount-1; ++seg2 )
   {
      if ( t2 <= mTimes[seg2+1] )
      {
         break;
      }
   }
   F32 u2 = (t2 - mTimes[seg2])/(mTimes[seg2+1] - mTimes[seg2]);

   F32 result;
   // both parameters lie in one segment
   if ( seg1 == seg2 )
   {
      result = segmentArcLength( seg1, u1, u2 );
   }
   // parameters cross segments
   else
   {
      result = segmentArcLength( seg1, u1, 1.0f );
      for ( U32 i = seg1+1; i < seg2; ++i )
         result += mLengths[i];
      result += segmentArcLength( seg2, 0.0f, u2 );
   }

   return result;
}
コード例 #2
0
void CatmullRomBase::_initialize( U32 count, const F32 *times )
{
   //AssertFatal( times, "CatmullRomBase::_initialize() - Got null position!" )
   AssertFatal( count > 1, "CatmullRomBase::_initialize() - Must have more than 2 points!" )

   // set up arrays
   mTimes = new F32[count];
   mCount = count;

   // set up curve segment lengths
   mLengths = new F32[count-1];
   mTotalLength = 0.0f;
   for ( U32 i = 0; i < count-1; ++i )
   {
      mLengths[i] = segmentArcLength(i, 0.0f, 1.0f);
      mTotalLength += mLengths[i];
   }

   // copy the times if we have them.
   F32 l = 0.0f;
   for ( U32 i = 0; i < count; ++i )
   {
      if ( times )
         mTimes[i] = times[i];
      else
      {
         if ( mIsZero( mTotalLength ) )
            mTimes[i] = 0.0f;
         else
            mTimes[i] = l / mTotalLength;
         if ( i < count-1 )
            l += mLengths[i];
      }
   }
}
コード例 #3
0
/*! 
Init curve with curve points and times. If no control
points are passed they will be calculated automatically
@param points Array of points on the Bézier curve (w = time)
@param controlPoints Array of control points with size = 2*(numPointsAndTimes-1)
*/
void SLCurveBezier::init(const SLVVec4f& points,
                         const SLVVec3f& controlPoints)
{   assert(points.size() > 1);

    dispose();
   
    // set up arrays
    _points.clear();
    _points.resize(points.size());
    _controls.resize(2*(points.size()-1));

    // copy interpolated data
    SLuint i;
    for (i = 0; i < _points.size(); ++i)
    {   _points[i] = points[i];
    }

    if (controlPoints.size()==0)
    {  
        if (points.size() > 2)
        {   // create approximating control points
            for (i = 0; i < _points.size()-1; ++i)
            {   if (i > 0)
                    _controls[2*i] = (_points[i] + (_points[i+1]-_points[i-1])/3.0f).vec3();
                if (i < _points.size()-2)
                    _controls[2*i+1] = (_points[i+1] - (_points[i+2]-_points[i  ])/3.0f).vec3();
            }

            _controls[0] = (SLVec4f(_controls[1]) - (_points[1] - _points[0])/3.0f).vec3();
            _controls[2*_points.size()-3] = (SLVec4f(_controls[2*_points.size()-4]) + 
                         (_points[_points.size()-1] - _points[_points.size()-2])/3.0f).vec3();
        } else
        {   _controls[0] = (_points[0] + (_points[1]-_points[0])/3.0f).vec3();
            _controls[1] = (_points[1] - (_points[1]-_points[0])/3.0f).vec3();
        }
    }
    else
    {  // copy approximating control points
        for (i = 0; i < 2*(_points.size()-1); ++i)
            _controls[i] = controlPoints[i];
    }

    // set up curve segment lengths
    _lengths.clear();
    _lengths.resize(_points.size()-1);
    _totalLength = 0.0f;

    _totalLength = 0.0f;
    for (SLuint i = 0; i < _points.size()-1; ++i)
    {   _lengths[i] = segmentArcLength(i, 0.0f, 1.0f);
        _totalLength += _lengths[i];
    }
}
コード例 #4
0
/*! 
Calculate length of curve between parameters t1 and t2
*/
SLfloat SLCurveBezier::arcLength(SLfloat t1, SLfloat t2)
{
    if (t2 <= t1) return 0.0f;
    if (t1 < _points[0].w) t1 = _points[0].w;
    if (t2 > _points[_points.size()-1].w) t2 = _points[_points.size()-1].w;

    // find segment and parameter
    unsigned int seg1;
    for (seg1 = 0; seg1 < _points.size()-1; ++seg1)
        if (t1 < _points[seg1+1].w)
            break;

    SLfloat u1 = (t1 - _points[seg1].w)/(_points[seg1+1].w - _points[seg1].w);
    
    // find segment and parameter
    unsigned int seg2;
    for (seg2 = 0; seg2 < _points.size()-1; ++seg2)
    if (t2 <= _points[seg2+1].w)
        break;

    SLfloat u2 = (t2 - _points[seg2].w)/(_points[seg2+1].w - _points[seg2].w);
    
    // both parameters lie in one segment
    SLfloat result;
    if (seg1 == seg2)
    result = segmentArcLength(seg1, u1, u2);

    // parameters cross segments
    else
    {   result = segmentArcLength(seg1, u1, 1.0f);
        for (SLuint i = seg1+1; i < seg2; ++i)
            result += _lengths[i];
        result += segmentArcLength(seg2, 0.0f, u2);
    }

    return result;
}