Split out tween weighting functions. Add tweening from 1d and 2d
bezier curves.
The "bouncebegin" and "bounceend" tweens are now implemented in Lua,
using 2D beziers which approximate the old behavior very closely.
Added "ease" tween, which works like Flash's.
Custom tweens can be used, passing in a table of 4 values for a
1D bezier, or 8 values for 2D.
tween,.5,TweenBezier,{ 0, p1, p2, 1 }
tween,.5,TweenBezier,{ 0, 0, x1, y1, x2, y2, 1, 1 }
As with all tweens, the first parameter is the duration.
The 1D bezier { a, b, c, d } is equivalent to the 2D bezier
{ 0, a, 1/3, b, 2/3, c, 1, d }, but a 1D bezier is more efficient.
This commit is contained in:
@@ -646,8 +646,69 @@ float RageFastCos( float x )
|
||||
return RageFastSin( x + 0.5f*PI );
|
||||
}
|
||||
|
||||
float RageQuadradtic::Evaluate( float fT ) const
|
||||
{
|
||||
// optimized (m_fA * fT*fT*fT) + (m_fB * fT*fT) + (m_fC * fT) + m_fD;
|
||||
return ((m_fA*fT + m_fB)*fT + m_fC)*fT + m_fD;
|
||||
}
|
||||
|
||||
void RageQuadradtic::SetFromBezier( float fX1, float fX2, float fX3, float fX4 )
|
||||
{
|
||||
m_fD = fX1;
|
||||
m_fC = 3.0f * (fX2 - fX1);
|
||||
m_fB = 3.0f * (fX3 - fX2) - m_fC;
|
||||
m_fA = fX4 - fX1 - m_fC - m_fB;
|
||||
}
|
||||
|
||||
void RageQuadradtic::GetBezier( float &fX1, float &fX2, float &fX3, float &fX4 ) const
|
||||
{
|
||||
fX1 = m_fD;
|
||||
fX2 = m_fD + m_fC/3.0f;
|
||||
fX3 = m_fD + 2*m_fC/3.0f + m_fB/3.0f;
|
||||
fX4 = m_fD + m_fC + m_fB + m_fA;
|
||||
}
|
||||
|
||||
float RageQuadradtic::GetSlope( float fT ) const
|
||||
{
|
||||
return 3*m_fA*fT*fT + 2*m_fB*fT + m_fC;
|
||||
}
|
||||
|
||||
void RageBezier2D::Evaluate( float fT, float *pX, float *pY ) const
|
||||
{
|
||||
*pX = m_X.Evaluate( fT );
|
||||
*pY = m_Y.Evaluate( fT );
|
||||
}
|
||||
|
||||
float RageBezier2D::EvaluateYFromX( float fX ) const
|
||||
{
|
||||
/* Quickly approximate T using Newton-Raphelson successive optimization (see
|
||||
* http://www.tinaja.com/text/bezmath.html). This usually finds T within an
|
||||
* acceptable error margin in a few steps. */
|
||||
float fT = SCALE( fX, m_X.GetBezierStart(), m_X.GetBezierEnd(), 0, 1 );
|
||||
while(1)
|
||||
{
|
||||
float fGuessedX = m_X.Evaluate( fT );
|
||||
float fError = fX-fGuessedX;
|
||||
|
||||
/* If our guess is good enough, evaluate the result Y and return. */
|
||||
if( unlikely(fabsf(fError) < 0.0001f) )
|
||||
return m_Y.Evaluate( fT );
|
||||
|
||||
float fSlope = m_X.GetSlope( fT );
|
||||
fT += fError/fSlope;
|
||||
}
|
||||
}
|
||||
|
||||
void RageBezier2D::SetFromBezier(
|
||||
float fC1X, float fC1Y, float fC2X, float fC2Y,
|
||||
float fC3X, float fC3Y, float fC4X, float fC4Y )
|
||||
{
|
||||
m_X.SetFromBezier( fC1X, fC2X, fC3X, fC4X );
|
||||
m_Y.SetFromBezier( fC1Y, fC2Y, fC3Y, fC4Y );
|
||||
}
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001-2003 Chris Danford
|
||||
* Copyright (c) 2001-2006 Chris Danford, Glenn Maynard
|
||||
* All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
|
||||
Reference in New Issue
Block a user