Further Point refactoring (#1111)
* Split up viewport transforms * Make naming more concistent * Move into namespace, make constexpr
This commit is contained in:
parent
055def4215
commit
a48d0c7c74
|
@ -620,7 +620,7 @@ namespace OpenLoco::Audio
|
|||
}
|
||||
|
||||
volume += calculateVolumeFromViewport(id, loc, *viewport);
|
||||
pan = viewport->mapToUi(vpos).x;
|
||||
pan = viewport->viewportToScreen(vpos).x;
|
||||
if (volume < -10000)
|
||||
{
|
||||
return;
|
||||
|
|
|
@ -96,6 +96,16 @@ namespace OpenLoco::Math::Vector
|
|||
{
|
||||
return { static_cast<T>(x / rhs), static_cast<T>(y / rhs) };
|
||||
}
|
||||
|
||||
constexpr const TVector2 operator<<(const uint8_t rhs) const
|
||||
{
|
||||
return { static_cast<T>(x << rhs), static_cast<T>(y << rhs) };
|
||||
}
|
||||
|
||||
constexpr const TVector2 operator>>(const uint8_t rhs) const
|
||||
{
|
||||
return { static_cast<T>(x >> rhs), static_cast<T>(y >> rhs) };
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T, T TResolution = 1>
|
||||
|
|
|
@ -377,7 +377,7 @@ namespace OpenLoco::Ui::ViewportInteraction
|
|||
|
||||
uint32_t nearestDistance = std::numeric_limits<uint32_t>().max();
|
||||
Vehicles::VehicleBase* nearestVehicle = nullptr;
|
||||
auto targetPosition = viewport->uiToMap({ tempX, tempY });
|
||||
auto targetPosition = viewport->screenToViewport({ tempX, tempY });
|
||||
|
||||
for (auto v : EntityManager::VehicleList())
|
||||
{
|
||||
|
@ -993,7 +993,7 @@ namespace OpenLoco::Ui::ViewportInteraction
|
|||
continue;
|
||||
|
||||
chosenV = vp;
|
||||
auto vpPos = vp->uiToMap({ screenPos.x, screenPos.y });
|
||||
auto vpPos = vp->screenToViewport({ screenPos.x, screenPos.y });
|
||||
_context1->zoom_level = vp->zoom;
|
||||
_context1->x = (0xFFFF << vp->zoom) & vpPos.x;
|
||||
_context1->y = (0xFFFF << vp->zoom) & vpPos.y;
|
||||
|
@ -1058,7 +1058,7 @@ namespace OpenLoco::Ui::ViewportInteraction
|
|||
const auto minPosition = info.pos; // E40128/A
|
||||
const auto maxPosition = info.pos + Pos2{ 31, 31 }; // E4012C/E
|
||||
auto mapPos = info.pos + Pos2{ 16, 16 };
|
||||
const auto initialVPPos = viewport->uiToMap(screenCoords);
|
||||
const auto initialVPPos = viewport->screenToViewport(screenCoords);
|
||||
|
||||
for (int32_t i = 0; i < 5; i++)
|
||||
{
|
||||
|
@ -1091,7 +1091,7 @@ namespace OpenLoco::Ui::ViewportInteraction
|
|||
const auto minPosition = info.pos; // E40128/A
|
||||
const auto maxPosition = info.pos + Pos2{ 31, 31 }; // E4012C/E
|
||||
auto mapPos = info.pos + Pos2{ 16, 16 };
|
||||
const auto initialVPPos = viewport->uiToMap(screenCoords);
|
||||
const auto initialVPPos = viewport->screenToViewport(screenCoords);
|
||||
|
||||
for (int32_t i = 0; i < 5; i++)
|
||||
{
|
||||
|
|
|
@ -33,7 +33,7 @@ namespace OpenLoco::Ui
|
|||
return;
|
||||
}
|
||||
auto intersection = contextRect.intersection(viewRect);
|
||||
paint(context, uiToMap(intersection));
|
||||
paint(context, screenToViewport(intersection));
|
||||
}
|
||||
|
||||
// 0x0045A1A4
|
||||
|
|
|
@ -54,6 +54,18 @@ namespace OpenLoco::Ui
|
|||
constexpr uint32_t station_names_displayed = 1 << 10;
|
||||
}
|
||||
|
||||
struct Viewport;
|
||||
|
||||
namespace ScreenToViewport
|
||||
{
|
||||
[[nodiscard]] constexpr Point applyTransform(const Point& uiPoint, const Viewport& vp);
|
||||
}
|
||||
|
||||
namespace ViewportToScreen
|
||||
{
|
||||
[[nodiscard]] constexpr Point applyTransform(const Point& vpPoint, const Viewport& vp);
|
||||
}
|
||||
|
||||
struct Viewport
|
||||
{
|
||||
int16_t width; // 0x00
|
||||
|
@ -117,29 +129,27 @@ namespace OpenLoco::Ui
|
|||
/**
|
||||
* Maps a 2D viewport position to a UI (screen) position.
|
||||
*/
|
||||
Point mapToUi(const viewport_pos& vpos) const
|
||||
Point viewportToScreen(const viewport_pos& vpos) const
|
||||
{
|
||||
auto uiX = x + ((vpos.x - view_x) >> zoom);
|
||||
auto uiY = y + ((vpos.y - view_y) >> zoom);
|
||||
return Point(uiX, uiY);
|
||||
const auto vpPoint = ViewportToScreen::applyTransform({ vpos.x, vpos.y }, *this);
|
||||
return vpPoint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps a UI (screen) position to a 2D viewport position.
|
||||
*/
|
||||
viewport_pos uiToMap(const Point& pos) const
|
||||
viewport_pos screenToViewport(const Point& pos) const
|
||||
{
|
||||
int16_t viewport_x = ((pos.x - x) << zoom) + view_x;
|
||||
int16_t viewport_y = ((pos.y - y) << zoom) + view_y;
|
||||
return { viewport_x, viewport_y };
|
||||
const auto vpPoint = ScreenToViewport::applyTransform(pos, *this);
|
||||
return { vpPoint.x, vpPoint.y };
|
||||
}
|
||||
/**
|
||||
* Maps a UI (screen) rectangle to a 2D viewport rectangle.
|
||||
*/
|
||||
Rect uiToMap(const Rect& rect)
|
||||
Rect screenToViewport(const Rect& rect)
|
||||
{
|
||||
auto leftTop = uiToMap(Point(rect.left(), rect.top()));
|
||||
auto rightBottom = uiToMap(Point(rect.right(), rect.bottom()));
|
||||
auto leftTop = screenToViewport(Point(rect.left(), rect.top()));
|
||||
auto rightBottom = screenToViewport(Point(rect.right(), rect.bottom()));
|
||||
return Rect::fromLTRB(leftTop.x, leftTop.y, rightBottom.x, rightBottom.y);
|
||||
}
|
||||
|
||||
|
@ -162,4 +172,50 @@ namespace OpenLoco::Ui
|
|||
int16_t saved_view_x; // 0x2
|
||||
int16_t saved_view_y; // 0x4
|
||||
};
|
||||
|
||||
namespace ScreenToViewport
|
||||
{
|
||||
[[nodiscard]] constexpr Point uiOffsetTransform(const Point& uiPoint, const Viewport& vp)
|
||||
{
|
||||
return uiPoint - Point{ vp.x, vp.y };
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr Point scaleTransform(const Point& uiPoint, const Viewport& vp)
|
||||
{
|
||||
return uiPoint << vp.zoom;
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr Point viewOffsetTransform(const Point& point, const Viewport& vp)
|
||||
{
|
||||
return point + Point{ vp.view_x, vp.view_y };
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr Point applyTransform(const Point& uiPoint, const Viewport& vp)
|
||||
{
|
||||
return viewOffsetTransform(scaleTransform(uiOffsetTransform(uiPoint, vp), vp), vp);
|
||||
}
|
||||
}
|
||||
|
||||
namespace ViewportToScreen
|
||||
{
|
||||
[[nodiscard]] constexpr Point uiOffsetTransform(const Point& uiPoint, const Viewport& vp)
|
||||
{
|
||||
return uiPoint + Point{ vp.x, vp.y };
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr Point scaleTransform(const Point& uiPoint, const Viewport& vp)
|
||||
{
|
||||
return uiPoint >> vp.zoom;
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr Point viewOffsetTransform(const Point& point, const Viewport& vp)
|
||||
{
|
||||
return point - Point{ vp.view_x, vp.view_y };
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr Point applyTransform(const Point& vpPoint, const Viewport& vp)
|
||||
{
|
||||
return uiOffsetTransform(scaleTransform(viewOffsetTransform(vpPoint, vp), vp), vp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -141,7 +141,7 @@ namespace OpenLoco::Ui
|
|||
|
||||
if (vp->containsUi(mouse))
|
||||
{
|
||||
viewport_pos vpos = vp->uiToMap(mouse);
|
||||
viewport_pos vpos = vp->screenToViewport(mouse);
|
||||
Map::Pos2 position = viewportCoordToMapCoord(vpos.x, vpos.y, z, WindowManager::getCurrentRotation());
|
||||
if (position.x <= 0x2FFF && position.y <= 0x2FFF)
|
||||
{
|
||||
|
|
|
@ -659,11 +659,11 @@ namespace OpenLoco::Ui::Windows::Construction
|
|||
bool isPointCloserToNextOrPreviousTile(const Point& point, const Viewport& viewport)
|
||||
{
|
||||
const auto vpPosNext = gameToScreen(*_nextTile + Map::Pos3(16, 16, 0), viewport.getRotation());
|
||||
const auto uiPosNext = viewport.mapToUi(vpPosNext);
|
||||
const auto uiPosNext = viewport.viewportToScreen(vpPosNext);
|
||||
const auto distanceToNext = Math::Vector::manhattanDistance(uiPosNext, point);
|
||||
|
||||
const auto vpPosPrevious = gameToScreen(*_previousTile + Map::Pos3(16, 16, 0), viewport.getRotation());
|
||||
const auto uiPosPrevious = viewport.mapToUi(vpPosPrevious);
|
||||
const auto uiPosPrevious = viewport.viewportToScreen(vpPosPrevious);
|
||||
const auto distanceToPrevious = Math::Vector::manhattanDistance(uiPosPrevious, point);
|
||||
|
||||
return distanceToNext < distanceToPrevious;
|
||||
|
|
|
@ -3537,7 +3537,7 @@ namespace OpenLoco::Ui::Windows::Vehicle
|
|||
}
|
||||
|
||||
auto viewPos = Map::gameToScreen(*nodeLoc, res.second->getRotation());
|
||||
auto uiPos = res.second->mapToUi(viewPos);
|
||||
auto uiPos = res.second->viewportToScreen(viewPos);
|
||||
auto distance = Math::Vector::manhattanDistance(uiPos, Point{ x, y });
|
||||
if (distance < bestDistance)
|
||||
{
|
||||
|
@ -3611,7 +3611,7 @@ namespace OpenLoco::Ui::Windows::Vehicle
|
|||
{
|
||||
auto potentialLoc = roadFirstTile + moveInfo.loc;
|
||||
auto viewPos = Map::gameToScreen(potentialLoc, viewport.getRotation());
|
||||
auto uiPos = viewport.mapToUi(viewPos);
|
||||
auto uiPos = viewport.viewportToScreen(viewPos);
|
||||
auto distance = Math::Vector::manhattanDistance(uiPos, cursorLoc);
|
||||
if (distance < bestDistance)
|
||||
{
|
||||
|
@ -3717,7 +3717,7 @@ namespace OpenLoco::Ui::Windows::Vehicle
|
|||
{
|
||||
auto potentialLoc = trackFirstTile + moveInfo.loc;
|
||||
auto viewPos = Map::gameToScreen(potentialLoc, viewport.getRotation());
|
||||
auto uiPos = viewport.mapToUi(viewPos);
|
||||
auto uiPos = viewport.viewportToScreen(viewPos);
|
||||
auto distance = Math::Vector::manhattanDistance(uiPos, cursorLoc);
|
||||
if (distance < bestDistance)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue