Update ActorMultiVertex.cpp

Encapsulate actor resize functionality.

Significant performance improvement on the `UpdateAnimationState` function which was bottlenecking many operations.

See ITGmania PR #253 for more information.
This commit is contained in:
sukibaby
2024-06-18 06:37:44 -07:00
committed by teejusb
parent 9e3c7fc207
commit ae6d7cecb5
2 changed files with 125 additions and 104 deletions
+124 -104
View File
@@ -180,14 +180,23 @@ void ActorMultiVertex::SetNumVertices( std::size_t n )
} }
} }
void ActorMultiVertex::ResizeVertices(std::vector<RageSpriteVertex>& vertices, int size)
{
if (vertices.capacity() < size)
{
vertices.reserve(size);
}
vertices.resize(size);
}
void ActorMultiVertex::AddVertex() void ActorMultiVertex::AddVertex()
{ {
for( std::size_t i = 0; i < AMV_Tweens.size(); ++i ) for( std::size_t i = 0; i < AMV_Tweens.size(); ++i )
{ {
AMV_Tweens[i].vertices.push_back( RageSpriteVertex() ); AMV_Tweens[i].vertices.emplace_back( RageSpriteVertex() );
} }
AMV_current.vertices.push_back( RageSpriteVertex() ); AMV_current.vertices.emplace_back( RageSpriteVertex() );
AMV_start.vertices.push_back( RageSpriteVertex() ); AMV_start.vertices.emplace_back( RageSpriteVertex() );
} }
void ActorMultiVertex::AddVertices( int Add ) void ActorMultiVertex::AddVertices( int Add )
@@ -196,10 +205,10 @@ void ActorMultiVertex::AddVertices( int Add )
size += Add; size += Add;
for( std::size_t i = 0; i < AMV_Tweens.size(); ++i ) for( std::size_t i = 0; i < AMV_Tweens.size(); ++i )
{ {
AMV_Tweens[i].vertices.resize( size ); ResizeVertices(AMV_Tweens[i].vertices, size);
} }
AMV_current.vertices.resize( size ); ResizeVertices(AMV_current.vertices, size);
AMV_start.vertices.resize( size ); ResizeVertices(AMV_start.vertices, size);
} }
void ActorMultiVertex::SetVertexPos( int index, float x, float y, float z ) void ActorMultiVertex::SetVertexPos( int index, float x, float y, float z )
@@ -460,109 +469,120 @@ void ActorMultiVertex::UpdateAnimationState(bool force_update)
{ {
std::size_t first= dest.FirstToDraw; std::size_t first= dest.FirstToDraw;
std::size_t last= first+dest.GetSafeNumToDraw(dest._DrawMode, dest.NumToDraw); std::size_t last= first+dest.GetSafeNumToDraw(dest._DrawMode, dest.NumToDraw);
#define STATE_ID const std::size_t state_id= (_cur_state + qs[quad_id % qs.size()]) % _states.size();
switch(AMV_DestTweenState()._DrawMode) switch(AMV_DestTweenState()._DrawMode)
{ {
case DrawMode_Quads: case DrawMode_Quads:
for(std::size_t i= first; i < last; ++i) for (std::size_t i = first; i < last; ++i)
{
const std::size_t quad_id = (i - first) / 4;
const std::size_t state_id = (_cur_state + qs[quad_id % qs.size()]) % _states.size();
const auto& rect = _states[state_id].rect;
switch ((i - first) % 4)
{ {
const std::size_t quad_id= (i-first)/4; case 0:
STATE_ID; verts[i].t.x = rect.left;
switch((i-first)%4) verts[i].t.y = rect.top;
{ break;
case 0:
verts[i].t.x= _states[state_id].rect.left; case 1:
verts[i].t.y= _states[state_id].rect.top; verts[i].t.x = rect.right;
break; verts[i].t.y = rect.top;
case 1: break;
verts[i].t.x= _states[state_id].rect.right;
verts[i].t.y= _states[state_id].rect.top; case 2:
break; verts[i].t.x = rect.right;
case 2: verts[i].t.y = rect.bottom;
verts[i].t.x= _states[state_id].rect.right; break;
verts[i].t.y= _states[state_id].rect.bottom;
break; case 3:
case 3: verts[i].t.x = rect.left;
verts[i].t.x= _states[state_id].rect.left; verts[i].t.y = rect.bottom;
verts[i].t.y= _states[state_id].rect.bottom; break;
break;
}
} }
break; }
case DrawMode_QuadStrip: case DrawMode_QuadStrip:
for(std::size_t i= first; i < last; ++i) for (std::size_t i = first; i < last; ++i)
{
const std::size_t quad_id = (i - first) / 2;
const std::size_t state_id = (_cur_state + qs[quad_id % qs.size()]) % _states.size();
const auto& rect = _states[state_id].rect;
switch ((i - first) % 2)
{ {
const std::size_t quad_id= (i-first)/2; case 0:
STATE_ID; verts[i].t.x = rect.left;
switch((i-first)%2) verts[i].t.y = rect.top;
{ break;
case 0: case 1:
verts[i].t.x= _states[state_id].rect.left; verts[i].t.x = rect.left;
verts[i].t.y= _states[state_id].rect.top; verts[i].t.y = rect.bottom;
break; break;
case 1:
verts[i].t.x= _states[state_id].rect.left;
verts[i].t.y= _states[state_id].rect.bottom;
break;
}
} }
break; }
case DrawMode_Strip: break;
case DrawMode_Fan: case DrawMode_Strip:
for(std::size_t i= first; i < last; ++i) case DrawMode_Fan:
for (std::size_t i = first; i < last; ++i)
{
const std::size_t quad_id = (i - first);
const std::size_t state_id = (_cur_state + qs[quad_id % qs.size()]) % _states.size();
const auto& rect = _states[state_id].rect;
verts[i].t.x = rect.left;
verts[i].t.y = rect.top;
}
break;
case DrawMode_Triangles:
for (std::size_t i = first; i < last; ++i)
{
const std::size_t quad_id = (i - first) / 3;
const std::size_t state_id = (_cur_state + qs[quad_id % qs.size()]) % _states.size();
const auto& rect = _states[state_id].rect;
switch ((i - first) % 3)
{ {
const std::size_t quad_id= (i-first); case 0:
STATE_ID; verts[i].t.x = rect.left;
verts[i].t.x= _states[state_id].rect.left; verts[i].t.y = rect.top;
verts[i].t.y= _states[state_id].rect.top; break;
case 1:
verts[i].t.x = rect.right;
verts[i].t.y = rect.top;
break;
case 2:
verts[i].t.x = rect.right;
verts[i].t.y = rect.bottom;
break;
} }
break; }
case DrawMode_Triangles: break;
for(std::size_t i= first; i < last; ++i) case DrawMode_SymmetricQuadStrip:
for (std::size_t i = first; i < last; ++i)
{
const std::size_t quad_id = (i - first) / 3;
const std::size_t state_id = (_cur_state + qs[quad_id % qs.size()]) % _states.size();
const auto& rect = _states[state_id].rect;
switch ((i - first) % 3)
{ {
const std::size_t quad_id= (i-first)/3; case 0:
STATE_ID; case 2:
switch((i-first)%3) verts[i].t.x = rect.left;
{ verts[i].t.y = rect.top;
case 0: break;
verts[i].t.x= _states[state_id].rect.left; case 1:
verts[i].t.y= _states[state_id].rect.top; verts[i].t.x = rect.right;
break; verts[i].t.y = rect.top;
case 1: break;
verts[i].t.x= _states[state_id].rect.right;
verts[i].t.y= _states[state_id].rect.top;
break;
case 2:
verts[i].t.x= _states[state_id].rect.right;
verts[i].t.y= _states[state_id].rect.bottom;
break;
}
} }
break; }
case DrawMode_SymmetricQuadStrip: break;
for(std::size_t i= first; i < last; ++i) default:
{ break;
const std::size_t quad_id= (i-first)/3;
STATE_ID;
switch((i-first)%3)
{
case 0:
case 2:
verts[i].t.x= _states[state_id].rect.left;
verts[i].t.y= _states[state_id].rect.top;
break;
case 1:
verts[i].t.x= _states[state_id].rect.right;
verts[i].t.y= _states[state_id].rect.top;
break;
}
}
break;
default:
break;
} }
} }
#undef STATE_ID
} }
void ActorMultiVertex::EnableAnimation(bool bEnable) void ActorMultiVertex::EnableAnimation(bool bEnable)
@@ -616,13 +636,13 @@ void ActorMultiVertex::BeginTweening( float time, ITween *pTween )
{ {
Actor::BeginTweening( time, pTween ); Actor::BeginTweening( time, pTween );
if( AMV_Tweens.size() >= 1 ) // if there was already a TS on the stack if (!AMV_Tweens.empty()) // if there was already a TS on the stack
{ {
AMV_Tweens.push_back( AMV_Tweens.back() ); AMV_Tweens.emplace_back(AMV_Tweens.back());
} }
else else
{ {
AMV_Tweens.push_back( AMV_current ); AMV_Tweens.emplace_back(AMV_current);
} }
} }
@@ -1032,10 +1052,10 @@ public:
{ {
luaL_error(L, "The texture must be set before adding states."); luaL_error(L, "The texture must be set before adding states.");
} }
const float width_pix= tex->GetImageToTexCoordsRatioX(); const float width_pix = tex->GetImageToTexCoordsRatioX();
const float height_pix= tex->GetImageToTexCoordsRatioY(); const float height_pix = tex->GetImageToTexCoordsRatioY();
const float width_ratio= 1.0f / tex->GetImageToTexCoordsRatioX(); const float width_ratio = width_pix != 0 ? 1.0f / width_pix : 0;
const float height_ratio= 1.0f / tex->GetImageToTexCoordsRatioY(); const float height_ratio = height_pix != 0 ? 1.0f / height_pix : 0;
const ActorMultiVertex::State& state= const ActorMultiVertex::State& state=
p->GetStateData(ValidStateIndex(p, L, 1)); p->GetStateData(ValidStateIndex(p, L, 1));
lua_createtable(L, 2, 0); lua_createtable(L, 2, 0);
+1
View File
@@ -92,6 +92,7 @@ public:
void UnloadTexture(); void UnloadTexture();
void SetNumVertices( std::size_t n ); void SetNumVertices( std::size_t n );
void ResizeVertices(std::vector<RageSpriteVertex>& vertices, int size);
void AddVertex(); void AddVertex();
void AddVertices( int Add ); void AddVertices( int Add );