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:
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 );
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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) );
|
||||
|
||||
@@ -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];
|
||||
|
||||
Reference in New Issue
Block a user