diff --git a/Themes/_fallback/Scripts/00 Utility.lua b/Themes/_fallback/Scripts/00 Utility.lua index 18a6811b38..80a374d688 100644 --- a/Themes/_fallback/Scripts/00 Utility.lua +++ b/Themes/_fallback/Scripts/00 Utility.lua @@ -34,7 +34,6 @@ function isWindowed() end --- Get the actor's real X (Not relative to the parent like self:GetX()) by recursively grabbing the parents' position --- Does not take zoom into account. -- @tparam actor element the actor -- @treturn number function getTrueX(element) @@ -42,7 +41,6 @@ function getTrueX(element) end --- Get the actor's real Y (Not relative to the parent like self:GetY()) by recursively grabbing the parents' position --- Does not take zoom into account. -- @tparam actor element the actor -- @treturn number function getTrueY(element) diff --git a/src/Etterna/Actor/Base/Actor.cpp b/src/Etterna/Actor/Base/Actor.cpp index 328d9d449f..912fc2832e 100644 --- a/src/Etterna/Actor/Base/Actor.cpp +++ b/src/Etterna/Actor/Base/Actor.cpp @@ -305,16 +305,22 @@ Actor::IsOver(float mx, float my) auto x = GetTrueX(); auto y = GetTrueY(); + auto hal = GetHorizAlign(); auto val = GetVertAlign(); + auto wi = GetZoomedWidth() * GetFakeParentOrParent()->GetTrueZoom(); auto hi = GetZoomedHeight() * GetFakeParentOrParent()->GetTrueZoom(); - auto lr = x - (hal * wi); - auto rr = x + wi - (hal * wi); - auto ur = y - (val * hi); - auto br = ((y + hi) - (val * hi)); - bool withinX = mx >= lr && mx <= rr; - bool withinY = my >= ur && my <= br; + + auto rotZ = GetTrueRotationZ(); + + RageVector2 p1(mx - x, my - y); + RageVec2RotateFromOrigin(&p1, -rotZ); + p1.x += x; + p1.y += y; + + bool withinX = (p1.x >= (x - hal * wi)) && (p1.x <= (x + wi - hal * wi)); + bool withinY = (p1.y >= (y - val * hi)) && (p1.y <= (y + hi - val * hi)); return withinX && withinY; } Actor* @@ -336,7 +342,10 @@ Actor::GetTrueX() auto* mfp = GetFakeParentOrParent(); if (!mfp) return GetX(); - return GetX() * mfp->GetTrueZoom() + mfp->GetTrueX(); + RageVector2 p1(GetX(), GetY()); + RageVec2RotateFromOrigin(&p1, mfp->GetTrueRotationZ()); + + return p1.x * mfp->GetTrueZoom() + mfp->GetTrueX(); } float @@ -347,8 +356,23 @@ Actor::GetTrueY() auto* mfp = GetFakeParentOrParent(); if (!mfp) return GetY(); - return GetY() * mfp->GetTrueZoom() + mfp->GetTrueY(); + RageVector2 p1(GetX(), GetY()); + RageVec2RotateFromOrigin(&p1, mfp->GetTrueRotationZ()); + + return p1.y * mfp->GetTrueZoom() + mfp->GetTrueY(); +} + +float +Actor::GetTrueRotationZ() +{ + if (!this) + return 0.f; + auto* mfp = GetFakeParentOrParent(); + if (!mfp) + return GetRotationZ(); + return GetRotationZ() + mfp->GetTrueRotationZ(); } + float Actor::GetTrueZoom() { @@ -377,8 +401,7 @@ Actor::Draw() } if (m_FakeParent != nullptr) { - if (!m_FakeParent->m_bVisible || - m_FakeParent->EarlyAbortDraw()) { + if (!m_FakeParent->m_bVisible || m_FakeParent->EarlyAbortDraw()) { return; } m_FakeParent->PreDraw(); @@ -409,8 +432,7 @@ Actor::Draw() // -Kyz for (size_t i = m_WrapperStates.size(); i > 0 && dont_abort_draw; --i) { Actor* state = m_WrapperStates[i - 1]; - if (!state->m_bVisible || - state->EarlyAbortDraw()) { + if (!state->m_bVisible || state->EarlyAbortDraw()) { dont_abort_draw = false; } else { state->PreDraw(); diff --git a/src/Etterna/Actor/Base/Actor.h b/src/Etterna/Actor/Base/Actor.h index 3d5624a803..f10fb03161 100644 --- a/src/Etterna/Actor/Base/Actor.h +++ b/src/Etterna/Actor/Base/Actor.h @@ -263,11 +263,12 @@ class Actor : public MessageSubscriber bool IsOver(float mx, float my); Actor* GetFakeParentOrParent(); // fake parent > parent -mina - float GetTrueX(); // recursive with parent (for mouseovers) -mina - float GetTrueY(); // same - float GetTrueZoom(); // same - bool IsVisible(); // same but for gating updates on things that may not - // explicitly set visible = false -mina + float GetTrueX(); // recursive with parent (for mouseovers) -mina + float GetTrueY(); // same + float GetTrueRotationZ(); // same + float GetTrueZoom(); // same + bool IsVisible(); // same but for gating updates on things that may not + // explicitly set visible = false -mina /** * @brief Calls multiple functions for drawing the Actors. diff --git a/src/RageUtil/Misc/RageMath.cpp b/src/RageUtil/Misc/RageMath.cpp index 8738b5ca5c..6bfb29517e 100644 --- a/src/RageUtil/Misc/RageMath.cpp +++ b/src/RageUtil/Misc/RageMath.cpp @@ -1,4 +1,4 @@ -/* +/* * Most of these prototypes match up with the D3DX math functions. Take a * function name, replace "Rage" with "D3DX" and look it up in the D3D SDK * docs for details. @@ -13,6 +13,27 @@ #include #endif +void +RageVec2RotateFromOrigin(RageVector2* pOut, float degrees) +{ + auto radians = degrees * PI / 180; + auto outx = pOut->x * RageFastCos(radians) - pOut->y * RageFastSin(radians); + auto outy = pOut->x * RageFastSin(radians) + pOut->y * RageFastCos(radians); + pOut->x = outx; + pOut->y = outy; +} + +void +RageVec2RotateFromPoint(RageVector2* p1, RageVector2* p2, float degrees) +{ + auto xdiff = p2->x - p1->x; + auto ydiff = p2->y - p1->y; + RageVector2 p3(xdiff, ydiff); + RageVec2RotateFromOrigin(&p3, degrees); + p2->x = p1->x + p3.x; + p2->y = p1->y + p3.y; +} + void RageVec3ClearBounds(RageVector3& mins, RageVector3& maxs) { diff --git a/src/RageUtil/Misc/RageMath.h b/src/RageUtil/Misc/RageMath.h index f922567485..7e6c6ef60a 100644 --- a/src/RageUtil/Misc/RageMath.h +++ b/src/RageUtil/Misc/RageMath.h @@ -1,4 +1,4 @@ -/* RageMath - vector/matrix math utilities. */ +/* RageMath - vector/matrix math utilities. */ #ifndef RAGE_MATH_H #define RAGE_MATH_H @@ -13,6 +13,12 @@ struct RageVector3; struct RageVector4; struct RageMatrix; +void +RageVec2RotateFromOrigin(RageVector2* pOut, float degrees); + +void +RageVec2RotateFromPoint(RageVector2* p1, RageVector2* p2, float degrees); + void RageVec3ClearBounds(struct RageVector3& mins, RageVector3& maxs); void