mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-01-20 20:54:46 +00:00
Rephrase the macros so that they can be used in expressions, and properly require semicolons. And add the semicolons where missing.
174 lines
4.4 KiB
C++
174 lines
4.4 KiB
C++
//-----------------------------------------------------------------------------
|
|
// 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!" );
|
|
|
|
// 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];
|
|
} |