From ae6d7cecb53db5cfa3f1afd11971fec27a62de6c Mon Sep 17 00:00:00 2001 From: sukibaby <163092272+sukibaby@users.noreply.github.com> Date: Sat, 18 May 2024 08:48:56 -0700 Subject: [PATCH] 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. --- src/ActorMultiVertex.cpp | 228 +++++++++++++++++++++------------------ src/ActorMultiVertex.h | 1 + 2 files changed, 125 insertions(+), 104 deletions(-) diff --git a/src/ActorMultiVertex.cpp b/src/ActorMultiVertex.cpp index ea2dd9824a..209c8a34c0 100644 --- a/src/ActorMultiVertex.cpp +++ b/src/ActorMultiVertex.cpp @@ -179,15 +179,24 @@ void ActorMultiVertex::SetNumVertices( std::size_t n ) AMV_start.vertices.resize( n ); } } + +void ActorMultiVertex::ResizeVertices(std::vector& vertices, int size) +{ + if (vertices.capacity() < size) + { + vertices.reserve(size); + } + vertices.resize(size); +} void ActorMultiVertex::AddVertex() { 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_start.vertices.push_back( RageSpriteVertex() ); + AMV_current.vertices.emplace_back( RageSpriteVertex() ); + AMV_start.vertices.emplace_back( RageSpriteVertex() ); } void ActorMultiVertex::AddVertices( int Add ) @@ -196,10 +205,10 @@ void ActorMultiVertex::AddVertices( int Add ) size += Add; 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 ); - AMV_start.vertices.resize( size ); + ResizeVertices(AMV_current.vertices, size); + ResizeVertices(AMV_start.vertices, size); } 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 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) { - case DrawMode_Quads: - for(std::size_t i= first; i < last; ++i) + case DrawMode_Quads: + 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; - STATE_ID; - switch((i-first)%4) - { - case 0: - 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; - case 2: - verts[i].t.x= _states[state_id].rect.right; - verts[i].t.y= _states[state_id].rect.bottom; - break; - case 3: - verts[i].t.x= _states[state_id].rect.left; - verts[i].t.y= _states[state_id].rect.bottom; - break; - } + case 0: + verts[i].t.x = rect.left; + verts[i].t.y = 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; + + case 3: + verts[i].t.x = rect.left; + verts[i].t.y = rect.bottom; + break; } - break; - case DrawMode_QuadStrip: - for(std::size_t i= first; i < last; ++i) + } + case DrawMode_QuadStrip: + 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; - STATE_ID; - switch((i-first)%2) - { - case 0: - 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.left; - verts[i].t.y= _states[state_id].rect.bottom; - break; - } + case 0: + verts[i].t.x = rect.left; + verts[i].t.y = rect.top; + break; + case 1: + verts[i].t.x = rect.left; + verts[i].t.y = rect.bottom; + break; } - break; - case DrawMode_Strip: - case DrawMode_Fan: - for(std::size_t i= first; i < last; ++i) + } + break; + case DrawMode_Strip: + 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); - STATE_ID; - verts[i].t.x= _states[state_id].rect.left; - verts[i].t.y= _states[state_id].rect.top; + case 0: + verts[i].t.x = rect.left; + verts[i].t.y = 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: - for(std::size_t i= first; i < last; ++i) + } + break; + 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; - STATE_ID; - switch((i-first)%3) - { - case 0: - 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; - case 2: - verts[i].t.x= _states[state_id].rect.right; - verts[i].t.y= _states[state_id].rect.bottom; - break; - } + case 0: + case 2: + verts[i].t.x = rect.left; + verts[i].t.y = rect.top; + break; + case 1: + verts[i].t.x = rect.right; + verts[i].t.y = rect.top; + break; } - break; - case DrawMode_SymmetricQuadStrip: - for(std::size_t i= first; i < last; ++i) - { - 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; + } + break; + default: + break; } } -#undef STATE_ID } void ActorMultiVertex::EnableAnimation(bool bEnable) @@ -616,13 +636,13 @@ void ActorMultiVertex::BeginTweening( float time, ITween *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 { - 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."); } - const float width_pix= tex->GetImageToTexCoordsRatioX(); - const float height_pix= tex->GetImageToTexCoordsRatioY(); - const float width_ratio= 1.0f / tex->GetImageToTexCoordsRatioX(); - const float height_ratio= 1.0f / tex->GetImageToTexCoordsRatioY(); + const float width_pix = tex->GetImageToTexCoordsRatioX(); + const float height_pix = tex->GetImageToTexCoordsRatioY(); + const float width_ratio = width_pix != 0 ? 1.0f / width_pix : 0; + const float height_ratio = height_pix != 0 ? 1.0f / height_pix : 0; const ActorMultiVertex::State& state= p->GetStateData(ValidStateIndex(p, L, 1)); lua_createtable(L, 2, 0); diff --git a/src/ActorMultiVertex.h b/src/ActorMultiVertex.h index 44fe7128d1..7118a3db7c 100644 --- a/src/ActorMultiVertex.h +++ b/src/ActorMultiVertex.h @@ -92,6 +92,7 @@ public: void UnloadTexture(); void SetNumVertices( std::size_t n ); + void ResizeVertices(std::vector& vertices, int size); void AddVertex(); void AddVertices( int Add );