Torque3D/Engine/source/util/catmullRom.cpp

174 lines
4.4 KiB
C++
Raw Normal View History

2012-09-19 15:15:01 +00:00
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#include "platform/platform.h"
#include "util/catmullRom.h"
#include "math/mMathFn.h"
const F32 CatmullRomBase::smX[] =
{
0.0000000000f, 0.5384693101f, -0.5384693101f, 0.9061798459f, -0.9061798459f
};
const F32 CatmullRomBase::smC[] =
{
0.5688888889f, 0.4786286705f, 0.4786286705f, 0.2369268850f, 0.2369268850f
};
CatmullRomBase::CatmullRomBase()
: mTimes( NULL ),
mLengths( NULL ),
mTotalLength( 0.0f ),
mCount( 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!" );
2012-09-19 15:15:01 +00:00
// 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];
}
}
}
void CatmullRomBase::clear()
{
delete [] mTimes;
mTimes = NULL;
delete [] mLengths;
mLengths = NULL;
mTotalLength = 0.0f;
mCount = 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;
}
U32 CatmullRomBase::getPrevNode( F32 t )
{
AssertFatal( mCount >= 2, "CatmullRomBase::getPrevNode - Bad point count!" );
// handle boundary conditions
if ( t <= mTimes[0] )
return 0;
else if ( t >= mTimes[mCount-1] )
return mCount-1;
// find segment and parameter
U32 i; // segment #
for ( i = 0; i < mCount-1; ++i )
{
if ( t <= mTimes[i+1] )
break;
}
AssertFatal( i >= 0 && i < mCount, "CatmullRomBase::getPrevNode - Got bad output index!" );
return i;
}
F32 CatmullRomBase::getTime( U32 idx )
{
AssertFatal( idx >= 0 && idx < mCount, "CatmullRomBase::getTime - Got bad index!" );
return mTimes[idx];
}