Adding camera interpolation modes
by Very Interactive Person · in Torque Game Builder · 04/10/2007 (11:02 am) · 3 replies
TGB currently has 2 camera interpolation modes, LINEAR and SIGMOID. I would like to add some more. Adding them is pretty straight forward, but creating the interpolation functions isn't. Is there anyone out there with better math skills then myself who can give me some good interpolation functions? I'm looking for stuff like exponential easIn/easeOut, bounce (would be cool to add most of these
Here 's how the camera interpolation currently works in TGB.You see its easy to add some more modes... but I'm not good enough with maths to write the interpolation functions. Please help...:
On a side note... wouldn't it be cool to have this for sceneObjects too? So when you do a "moveTo", you can also set the interpolation mode. Or is this already possible?
Here 's how the camera interpolation currently works in TGB.You see its easy to add some more modes... but I'm not good enough with maths to write the interpolation functions. Please help...:
//-----------------------------------------------------------------------------
// Interpolate Arbitrator.
//-----------------------------------------------------------------------------
F32 t2dSceneWindow::interpolate( F32 from, F32 to, F32 delta )
{
// Linear.
if ( mCameraInterpolationMode == LINEAR )
return linearInterpolate( from, to, delta );
// Sigmoid.
else if ( mCameraInterpolationMode == SIGMOID )
return sigmoidInterpolate( from, to, delta );
// Hmmm...
else
return from;
}
//-----------------------------------------------------------------------------
// Linear Interpolate.
// Standard Linear Ramp Interpolation Function.
//-----------------------------------------------------------------------------
F32 t2dSceneWindow::linearInterpolate( F32 from, F32 to, F32 delta )
{
// Clamp if we're over/under time.
if ( delta <= 0.0f )
return from;
else if ( delta >= 1.0f )
return to;
// Calculate resultant interpolation.
return ( from * ( 1.0f - delta ) ) + ( to * delta );
}
//-----------------------------------------------------------------------------
// Sigmoid Interpolate.
// Slow-in / Slow-out Sigmoid Interpolation Function.
//-----------------------------------------------------------------------------
F32 t2dSceneWindow::sigmoidInterpolate( F32 from, F32 to, F32 delta )
{
// Range Expand/Clamp Delta to (-1 -> +1).
delta = mClampF( (delta - 0.5f) * 2.0f, -1.0f, 1.0f );
// Calculate interpolator value using sigmoid function.
F32 sigmoid = mClampF ( 1.0f / (1.0f + mPow(2.718282f, -15.0f * delta)), 0.0f, 1.0f );
// Calculate resultant interpolation.
return ( from * ( 1.0f - sigmoid ) ) + ( to * sigmoid );
}On a side note... wouldn't it be cool to have this for sceneObjects too? So when you do a "moveTo", you can also set the interpolation mode. Or is this already possible?
#2
It isn't optimized but you could plug in any of those equations verbatim if you do the following:
in t2dSceneWindow.cc @ line ~38 add:
in t2dSceneWindow.cc @ line ~1010 add:
in t2dSceneWindow.cc @ line ~1010 add:
in t2dSceneWindow.h @ line ~137 add:
in t2dSceneWindow.h @ line ~232 add:
I've tested about half a dozen and they all perform as expected. Some of the functions could be optimized a bit but they generally should perform well enough as-is. Of course all of these cool interp modes could be added as its own method/enum so you can choose from all of them from script.
04/11/2007 (11:18 am)
I've added a few in the past and I took a quick look at the Flash tutorial link you mentioned, lots of nice functions there. It isn't optimized but you could plug in any of those equations verbatim if you do the following:
in t2dSceneWindow.cc @ line ~38 add:
{ t2dSceneWindow::CUSTOM, "CUSTOM" },This adds a new entry to the interpolationModeLookup EnumTablein t2dSceneWindow.cc @ line ~1010 add:
// Custom.
else if ( mCameraInterpolationMode == CUSTOM)
return customInterpolate( from, to, delta );This adds the custom interp mode to the big if/then switch in the interpolate methodin t2dSceneWindow.cc @ line ~1010 add:
//-----------------------------------------------------------------------------
// Custom Interpolate.
//-----------------------------------------------------------------------------
F32 t2dSceneWindow::customInterpolate( F32 from, F32 to, F32 delta )
{
// Clamp if we're over/under time.
if ( delta <= 0.0f )
return from;
else if ( delta >= 1.0f )
return to;
F32 c = to - from;
F32 d = 1.0f;
F32 t = delta;
F32 b = from;
return c*(t/=d)*t + b; // quadratic ease in
}This is basically a cut-and-paste of the pre-exiting Linear interpolation method, with the proper variable defines to let any of those actionscript equations (found here) be dropped in verbatim; I've used the quadratic ease-in function above but all should work finein t2dSceneWindow.h @ line ~137 add:
CUSTOM,Add the enum for CUSTOM interp mode in the header
in t2dSceneWindow.h @ line ~232 add:
F32 customInterpolate( F32 from, F32 to, F32 delta );Declare the new interpolation method in the header
I've tested about half a dozen and they all perform as expected. Some of the functions could be optimized a bit but they generally should perform well enough as-is. Of course all of these cool interp modes could be added as its own method/enum so you can choose from all of them from script.
#3
Here are the ones I converted so far:
04/11/2007 (11:48 am)
Ah, you beat me to it. I was just about to post this here myself. Turns out I was smart enough to figure it out after all. Anyway, nice post! I took the time to optimize some of Robert Penners functions, but the way you did it is defenetly faster ;). We should convert them all and post them as a resource (and do the same for sceneObject moving).Here are the ones I converted so far:
//-----------------------------------------------------------------------------
// Interpolate Arbitrator.
//-----------------------------------------------------------------------------
F32 t2dSceneWindow::interpolate( F32 from, F32 to, F32 delta )
{
switch(mCameraInterpolationMode){
case LINEAR:
// Linear.
return linearInterpolate( from, to, delta );
case SIGMOID:
// Sigmoid.
return sigmoidInterpolate( from, to, delta );
case CUBIC_EASEIN:
//cubic easein
return cubicEaseInInterpolate(from, to, delta);
case CUBIC_EASEOUT:
//cubic easeout
return cubicEaseOutInterpolate(from, to, delta);
case BOUNCE_EASEIN:
//cubic easein
return bounceEaseInInterpolate(from, to, delta);
case BOUNCE_EASEOUT:
//cubic easeout
return bounceEaseOutInterpolate(from, to, delta);
case ELASTIC_EASEOUT:
//elastic easeout
return elasticEaseOutInterpolate(from, to, delta);
case SINE_EASEIN:
//sine easein
return sineEaseInInterpolate(from, to, delta);
case SINE_EASEOUT:
//sine easeout
return sineEaseOutInterpolate(from, to, delta);
}
// Hmmm...
return from;
}
//-----------------------------------------------------------------------------
// Cubic easeIn Interpolate.
// Cubic easeIn Interpolation Function.
//-----------------------------------------------------------------------------
F32 t2dSceneWindow::cubicEaseInInterpolate( F32 from, F32 to, F32 delta )
{
return (to-from)*(mPow(delta,3.0f)) + from;
}
//-----------------------------------------------------------------------------
// Cubic easeOut Interpolate.
// Cubic easeOut Interpolation Function.
//-----------------------------------------------------------------------------
F32 t2dSceneWindow::cubicEaseOutInterpolate( F32 from, F32 to, F32 delta )
{
delta=delta-1;
return (to-from)*(mPow(delta,3.0f) + 1) + from;
}
//-----------------------------------------------------------------------------
// Bounce easeIn Interpolate.
// Bounce easeIn Interpolation Function.
//-----------------------------------------------------------------------------
F32 t2dSceneWindow::bounceEaseInInterpolate( F32 from, F32 to, F32 delta )
{
F32 change= to-from;
return change - bounceEaseOutInterpolate (0, change,1-delta) + from;
}
//-----------------------------------------------------------------------------
// Bounce easeOut Interpolate.
// Bounce easeOut Interpolation Function.
//-----------------------------------------------------------------------------
F32 t2dSceneWindow::bounceEaseOutInterpolate( F32 from, F32 to, F32 delta )
{
F32 change=to-from;
if (delta < (1.0f/2.75f)) {
return change*(7.5625f*mPow(delta,2)) + from;
} else if (delta < (2.0f/2.75f)) {
return change*(7.5625f*(delta-=(1.5f/2.75f))*delta + 0.75f) + from;
} else if (delta < (2.5f/2.75f)) {
return change*(7.5625f*(delta-=(2.25f/2.75f))*delta + 0.9375f) + from;
} else {
return change*(7.5625f*(delta-=(2.625f/2.75f))*delta + 0.984375f) + from;
}
}
//-----------------------------------------------------------------------------
// Elastic easeOut Interpolate.
// Elastic easeOut Interpolation Function.
//-----------------------------------------------------------------------------
F32 t2dSceneWindow::elasticEaseOutInterpolate( F32 from, F32 to, F32 delta )
{
if (delta==0.0f)
return from;
if (delta==1.0f)
return to;
F32 p=0.3f;
F32 amplitude=1.0f;
F32 change=to-from;
F32 s=p/4.0f;
return (change*mPow(2.0f,-10.0f*delta) * mSin( (delta*1-s)*(2.0f*M_PI)/p ) + change + from);
}
//-----------------------------------------------------------------------------
// Sine easeOut Interpolate.
// Sine easeOut Interpolation Function.
//-----------------------------------------------------------------------------
F32 t2dSceneWindow::sineEaseOutInterpolate( F32 from, F32 to, F32 delta )
{
return (to-from) * mSin(delta * (M_PI/2)) + from;
}
//-----------------------------------------------------------------------------
// Sine easeIn Interpolate.
// Sine easeIn Interpolation Function.
//-----------------------------------------------------------------------------
F32 t2dSceneWindow::sineEaseInInterpolate( F32 from, F32 to, F32 delta )
{
F32 change=(to-from);
return -change * mCos(delta * (M_PI/2)) + change + from;
}
Torque Owner Thomas Buscaglia
(Edit: There are a few free graphing calculators that would make this very easy, knowing the shape of the graph you wanted.)
Also, scene objects have a similar moveTo method to interpolate position.