Monopoly — Portage moderne 0.1.0
Portage moderne C/C++23 du Monopoly de 1999
Loading...
Searching...
No Matches
LogicalViewport.cpp
Go to the documentation of this file.
1#include "LogicalViewport.hpp"
2
3#include <algorithm>
4#include <cmath>
5
7{
9 {
10 return
11 std::isfinite(scale) &&
12 std::isfinite(offsetX) &&
13 std::isfinite(offsetY) &&
14 std::isfinite(pixelWidth) &&
15 std::isfinite(pixelHeight) &&
16 scale > 0.0 &&
17 pixelWidth > 0.0 &&
18 pixelHeight > 0.0;
19 }
20
21 namespace
22 {
24 int targetWidth,
25 int targetHeight,
26 double logicalWidth,
27 double logicalHeight) noexcept
28 {
29 if (targetWidth <= 0 || targetHeight <= 0 ||
30 logicalWidth <= 0.0 || logicalHeight <= 0.0)
31 return {};
32
33 const double width = static_cast<double>(targetWidth);
34 const double height = static_cast<double>(targetHeight);
35 const double scale = std::min(
38 const double pixelWidth = logicalWidth * scale;
39 const double pixelHeight = logicalHeight * scale;
40
41 return {
42 scale,
43 (width - pixelWidth) / 2.0,
44 (height - pixelHeight) / 2.0,
45 pixelWidth,
46 pixelHeight
47 };
48 }
49 }
50
51
53 int targetWidth,
54 int targetHeight) noexcept
55 {
56 return fitCanvas(
61 }
62
63
74
75 std::optional<LogicalPoint> windowToLogical(
76 const Transform& transform,
77 double windowX,
78 double windowY) noexcept
79 {
80 if (!transform.valid() ||
81 !std::isfinite(windowX) ||
82 !std::isfinite(windowY))
83 {
84 return std::nullopt;
85 }
86
87 const double right =
88 transform.offsetX + transform.pixelWidth;
89
90 const double bottom =
91 transform.offsetY + transform.pixelHeight;
92
93 if (windowX < transform.offsetX ||
94 windowY < transform.offsetY ||
95 windowX >= right ||
96 windowY >= bottom)
97 {
98 return std::nullopt;
99 }
100
101 return LogicalPoint
102 {
103 (windowX - transform.offsetX) /
104 transform.scale,
105
106 (windowY - transform.offsetY) /
107 transform.scale
108 };
109 }
110
111 std::optional<LogicalPoint> windowToUIOverlay(
112 const Transform& uiTransform, double windowX, double windowY) noexcept
113 {
114 return windowToUIOverlay(uiTransform, windowX, windowY,
115 {0.0, 0.0, World3DWidth, World3DHeight});
116 }
117
118 std::optional<LogicalPoint> windowToUIOverlay(
119 const Transform& uiTransform, double windowX, double windowY,
120 const LogicalRect& worldViewport, bool modal) noexcept
121 {
122 const auto point = windowToLogical(uiTransform, windowX, windowY);
123 if (!point) return std::nullopt;
124 if (modal) return point;
125 if (!std::isfinite(worldViewport.x) || !std::isfinite(worldViewport.y) ||
126 !std::isfinite(worldViewport.width) || !std::isfinite(worldViewport.height) ||
127 worldViewport.width <= 0.0 || worldViewport.height <= 0.0)
128 return std::nullopt;
129 const bool inside = point->x >= worldViewport.x && point->y >= worldViewport.y &&
130 point->x < worldViewport.x + worldViewport.width &&
131 point->y < worldViewport.y + worldViewport.height;
132 return inside ? std::nullopt : point;
133 }
134
136 const Transform& transform,
137 const LogicalRect& logicalRect) noexcept
138 {
139 if (!transform.valid())
140 {
141 return {};
142 }
143
144 return
145 {
146 transform.offsetX +
147 logicalRect.x * transform.scale,
148
149 transform.offsetY +
150 logicalRect.y * transform.scale,
151
152 logicalRect.width * transform.scale,
153 logicalRect.height * transform.scale
154 };
155 }
156}
std::atomic< float > right
int bottom
std::uint32_t height
std::uint32_t width
unsigned index
std::optional< LogicalPoint > windowToUIOverlay(const Transform &uiTransform, double windowX, double windowY) noexcept
Transform makeTransform(int targetWidth, int targetHeight) noexcept
PixelRect logicalToPixelRect(const Transform &transform, const LogicalRect &logicalRect) noexcept
std::optional< LogicalPoint > windowToLogical(const Transform &transform, double windowX, double windowY) noexcept
Transform makeWorld3DTransform(int targetWidth, int targetHeight) noexcept