Don't evaluate the ActorScroller transform function every time though Draw.

Cache TweenState values at a provided interval, then interpolate between the TweenStates.
TODO: Precalculate these TweenStates in Init?
This commit is contained in:
Chris Danford
2005-09-02 21:42:34 +00:00
parent 2bfa9b23dd
commit f55e8a54e6
8 changed files with 79 additions and 3 deletions
+2
View File
@@ -2917,6 +2917,7 @@ PostSwitchPageSeconds=0
ScrollerSecondsPerItem=0
ScrollerNumItemsToDraw=20
ScrollerTransform=function(self,offset,itemIndex,numItems) end
ScrollerSubdivisions=1
OverrideLockInputSeconds=0
LockInputSeconds=0
OverrideSleepAfterTweenOffSeconds=0
@@ -3155,6 +3156,7 @@ PostSwitchPageSeconds=0
ScrollerSecondsPerItem=0
ScrollerNumItemsToDraw=20
ScrollerTransform=function(self,offset,itemIndex,numItems) end
ScrollerSubdivisions=1
StyleIcon=1
OverrideSleepAfterTweenOffSeconds=0
SleepAfterTweenOffSeconds=0
+40 -3
View File
@@ -39,6 +39,8 @@ ActorScroller::ActorScroller()
m_quadMask.SetBlendMode( BLEND_NO_EFFECT ); // don't change color values
m_quadMask.SetUseZBuffer( true ); // we want to write to the Zbuffer
m_quadMask.SetHidden( true );
m_iSubdivisions = 1;
}
void ActorScroller::Load2(
@@ -62,6 +64,7 @@ void ActorScroller::Load2(
m_exprTransformFunction.SetFromExpression(
ssprintf("function(self,offset,itemIndex,numItems) return self:y(%f*offset) end",fItemHeight)
);
m_iSubdivisions = 1;
m_bLoop = bLoop;
m_fSecondsPerItem = fSecondsPerItem;
@@ -90,6 +93,7 @@ void ActorScroller::Load3(
float fNumItemsToDraw,
bool bFastCatchup,
const CString &sTransformFunction,
int iSubdivisions,
bool bUseMask,
bool bLoop
)
@@ -98,6 +102,7 @@ void ActorScroller::Load3(
m_fNumItemsToDraw = fNumItemsToDraw;
m_bFastCatchup = bFastCatchup;
m_exprTransformFunction.SetFromExpression( sTransformFunction );
m_iSubdivisions = iSubdivisions;
m_fQuantizePixels = 0;
m_bUseMask = bUseMask;
m_bLoop = bLoop;
@@ -131,12 +136,14 @@ void ActorScroller::LoadFromNode( const CString &sDir, const XNode *pNode )
float fItemPaddingStart = 0;
float fItemPaddingEnd = 0;
CString sTransformFunction;
int iSubdivisions = 0;
GET_VALUE( "SecondsPerItem", fSecondsPerItem );
GET_VALUE( "NumItemsToDraw", fNumItemsToDraw );
GET_VALUE( "ItemPaddingStart", fItemPaddingStart );
GET_VALUE( "ItemPaddingEnd", fItemPaddingEnd );
GET_VALUE( "TransformFunction", sTransformFunction );
pNode->GetAttrValue( "Subdivisions", m_iSubdivisions );
#undef GET_VALUE
Load3(
@@ -144,6 +151,7 @@ void ActorScroller::LoadFromNode( const CString &sDir, const XNode *pNode )
fNumItemsToDraw,
false,
sTransformFunction,
iSubdivisions,
false,
false );
SetCurrentAndDestinationItem( -fItemPaddingStart );
@@ -201,18 +209,47 @@ void ActorScroller::UpdateInternal( float fDeltaTime )
m_fCurrentItem = fmodf( m_fCurrentItem, m_fNumItemsToDraw+1 );
}
void ActorScroller::PositionItem( Actor *pActor, float fPositionOffsetFromCenter, int iItemIndex, int iNumItems )
const Actor::TweenState &ActorScroller::GetPosition( float fPositionOffsetFromCenter, int iItemIndex, int iNumItems )
{
PositionOffsetAndItemIndex key = { fPositionOffsetFromCenter, iItemIndex };
map<PositionOffsetAndItemIndex,Actor::TweenState>::iterator iter = m_mapPositionToTweenStateCache.find( key );
if( iter != m_mapPositionToTweenStateCache.end() )
return iter->second;
Actor a;
Lua *L = LUA->Get();
m_exprTransformFunction.PushSelf( L );
ASSERT( !lua_isnil(L, -1) );
pActor->PushSelf( L );
a.PushSelf( L );
LuaHelpers::Push( fPositionOffsetFromCenter, L );
LuaHelpers::Push( iItemIndex, L );
LuaHelpers::Push( iNumItems, L );
lua_call( L, 4, 0 ); // 4 args, 0 results
LUA->Release(L);
return m_mapPositionToTweenStateCache[key] = a.DestTweenState();
}
void ActorScroller::PositionItem( Actor *pActor, float fPositionOffsetFromCenter, int iItemIndex, int iNumItems )
{
float fInterval = 1.0f / m_iSubdivisions;
float fFloor = QuantizeDown( fPositionOffsetFromCenter, fInterval );
float fCeil = QuantizeUp( fPositionOffsetFromCenter, fInterval );
if( fFloor == fCeil )
{
pActor->DestTweenState() = GetPosition( fCeil, iItemIndex, iNumItems );
}
else
{
const Actor::TweenState &tsFloor = GetPosition( fFloor, iItemIndex, iNumItems );
const Actor::TweenState &tsCeil = GetPosition( fCeil, iItemIndex, iNumItems );
float fPercentTowardCeil = SCALE( fPositionOffsetFromCenter, fFloor, fCeil, 0.0f, 1.0f );
Actor::TweenState::MakeWeightedAverage( pActor->DestTweenState(), tsFloor, tsCeil, fPercentTowardCeil );
}
}
void ActorScroller::DrawPrimitives()
+19
View File
@@ -25,6 +25,7 @@ public:
float fNumItemsToDraw,
bool bFastCatchup,
const CString &sTransformFunction,
int iSubdivisions,
bool bUseMask,
bool bLoop );
@@ -48,6 +49,7 @@ public:
void PushSelf( lua_State *L );
protected:
const Actor::TweenState &GetPosition( float fPositionOffsetFromCenter, int iItemIndex, int iNumItems );
void PositionItem( Actor *pActor, float fPositionOffsetFromCenter, int iItemIndex, int iNumItems );
bool m_bLoaded;
@@ -67,6 +69,23 @@ protected:
Quad m_quadMask;
LuaExpression m_exprTransformFunction; // params: self,offset,itemIndex,numItems
int m_iSubdivisions; // 1 == one evaluation per position
struct PositionOffsetAndItemIndex
{
float fPositionOffsetFromCenter;
int iItemIndex;
bool operator<( const PositionOffsetAndItemIndex &other ) const
{
if( fPositionOffsetFromCenter < other.fPositionOffsetFromCenter )
return true;
else if( fPositionOffsetFromCenter > other.fPositionOffsetFromCenter )
return false;
else
return iItemIndex < other.iItemIndex;
}
};
map<PositionOffsetAndItemIndex,Actor::TweenState> m_mapPositionToTweenStateCache;
};
class ActorScrollerAutoDeleteChildren : public ActorScroller
+11
View File
@@ -207,6 +207,17 @@ inline float QuantizeUp( float i, float iInterval )
return ceilf( i/iInterval ) * iInterval;
}
/* Return i rounded down to the nearest multiple of iInterval. */
inline int QuantizeDown( int i, int iInterval )
{
return int( (i-iInterval+1)/iInterval ) * iInterval;
}
inline float QuantizeDown( float i, float iInterval )
{
return floorf( i/iInterval ) * iInterval;
}
// Move val toward other_val by to_move.
void fapproach( float& val, float other_val, float to_move );
+3
View File
@@ -185,6 +185,7 @@ void ScreenCredits::Init()
4,
false,
sBackgroundsTransformFunction,
1,
false,
false );
SET_XY( m_ScrollerBackgrounds );
@@ -196,6 +197,7 @@ void ScreenCredits::Init()
4,
false,
sBackgroundsTransformFunction,
1,
false,
false );
SET_XY( m_ScrollerFrames );
@@ -247,6 +249,7 @@ void ScreenCredits::Init()
40,
false,
sTextsTransformFunction,
1,
false,
false );
SET_XY( m_ScrollerTexts );
@@ -120,6 +120,7 @@ void HighScoreWheel::Load( const HighScoreList& hsl, int iIndexToFocus )
10.5,
false,
sTransformFunction,
1,
false,
false );
Scroll();
+2
View File
@@ -45,6 +45,7 @@ ScreenSelectMaster::ScreenSelectMaster( CString sClassName ) : ScreenSelect( sCl
SCROLLER_SECONDS_PER_ITEM(m_sName,"ScrollerSecondsPerItem"),
SCROLLER_NUM_ITEMS_TO_DRAW(m_sName,"ScrollerNumItemsToDraw"),
SCROLLER_TRANSFORM(m_sName,"ScrollerTransform"),
SCROLLER_SUBDIVISIONS(m_sName,"ScrollerSubdivisions"),
DEFAULT_CHOICE(m_sName,"DefaultChoice")
{
}
@@ -110,6 +111,7 @@ void ScreenSelectMaster::Init()
SCROLLER_NUM_ITEMS_TO_DRAW,
SCROLLER_FAST_CATCHUP,
SCROLLER_TRANSFORM,
SCROLLER_SUBDIVISIONS,
false,
LOOP_SCROLLER );
m_Scroller[*p].SetName( "Scroller"+PLAYER_APPEND_NO_SPACE(*p) );
+1
View File
@@ -55,6 +55,7 @@ protected:
ThemeMetric<float> SCROLLER_SECONDS_PER_ITEM;
ThemeMetric<float> SCROLLER_NUM_ITEMS_TO_DRAW;
ThemeMetric<CString> SCROLLER_TRANSFORM;
ThemeMetric<int> SCROLLER_SUBDIVISIONS;
ThemeMetric<CString> DEFAULT_CHOICE;
int m_Next[NUM_MENU_DIRS][MAX_CHOICES];