Monopoly — Portage moderne 0.1.0
Portage moderne C/C++23 du Monopoly de 1999
Loading...
Searching...
No Matches
ModernSceneCatalog.cpp
Go to the documentation of this file.
2
3#include "Display.hpp"
5#include "RuleTypes.hpp"
6#include "TextureCatalog.hpp"
7
8#include <cmath>
9
10namespace monopoly::data
11{
12 namespace
13 {
14 constexpr ModernSceneDefinition ParisBoard{
17 "board/paris_board_runtime.glb"};
18 constexpr ModernSceneDefinition UsaBoard{
20 "board/usa_board_runtime.glb"};
21 constexpr ModernSceneDefinition ProceduralUsaBoard{
23 "board/usa_procedural_runtime.glb"};
24 constexpr ModernSceneDefinition House{
27 "buildings/house.glb"};
28 constexpr ModernSceneDefinition Hotel{
31 "buildings/hotel.glb"};
32 constexpr ModernSceneDefinition Unknown{};
33 constexpr int ParisCity = 1;
34 // The recovered printed prices use euros, not the retail francs mode.
35 constexpr int EuroCurrency = 12;
36 constexpr float RetailHouseHeight = 95.0F;
37 constexpr double AuthoredHouseHeightMetres = 0.445803434;
38 }
39
40 std::expected<ParsedModernSceneOptions, std::string> parseModernSceneArguments(
41 std::span<const std::string_view> arguments)
42 {
44 bool boardSeen{};
45 bool buildingsSeen{};
46 bool environmentSeen{};
47 for (const auto argument : arguments)
48 {
49 if (argument == "--modern-board" || argument.starts_with("--modern-board="))
50 {
51 if (boardSeen) return std::unexpected("duplicate --modern-board option");
52 boardSeen = true;
53 if (argument == "--modern-board=paris") parsed.options.parisBoard = true;
54 else if (argument == "--modern-board=usa") parsed.options.usaBoard = true;
55 else if (argument == "--modern-board=procedural") parsed.options.proceduralBoard = true;
56 else if (argument == "--modern-board=retail") parsed.options.parisBoard = false;
57 else return std::unexpected("--modern-board requires paris, usa, procedural or retail");
58 }
59 else if (argument == "--modern-buildings" || argument.starts_with("--modern-buildings="))
60 {
61 if (buildingsSeen) return std::unexpected("duplicate --modern-buildings option");
62 buildingsSeen = true;
63 if (argument == "--modern-buildings=house") parsed.options.house = true;
64 else if (argument == "--modern-buildings=retail") parsed.options.house = false;
65 else return std::unexpected("--modern-buildings requires house or retail");
66 }
67 else if (argument == "--modern-environment" || argument.starts_with("--modern-environment="))
68 {
69 if (environmentSeen) return std::unexpected("duplicate --modern-environment option");
70 environmentSeen = true;
71 if (argument == "--modern-environment=paris") parsed.options.environment = true;
72 else if (argument == "--modern-environment=procedural")
73 { parsed.options.environment = true; parsed.options.proceduralEnvironment = true; }
74 else if (argument == "--modern-environment=retail") parsed.options.environment = false;
75 else return std::unexpected("--modern-environment requires paris, procedural or retail");
76 }
77 else parsed.remaining.push_back(argument);
78 }
79 return parsed;
80 }
81
94
96 std::optional<DataId> rootSequenceDataId, std::uint16_t priority,
97 const ModernSceneOptions& options, const ModernSceneContext& context) noexcept
98 {
102 return false;
103 const auto& definition = modernSceneDefinition(kind);
104 if (meshId != definition.legacyMeshId || !rootSequenceDataId ||
105 *rootSequenceDataId != definition.legacyMeshId)
106 return false;
108 return options.parisBoard && priority == display::Board3DPriority &&
109 context.edition == BoardEdition::Europe && context.city == ParisCity &&
110 context.language == LanguageId::French && context.currency == EuroCurrency &&
111 context.customBoardPath.empty();
113 return (kind == ModernSceneKind::UsaBoard ? options.usaBoard : options.proceduralBoard) &&
115 context.edition == BoardEdition::Usa && context.city == 0 &&
116 context.language == LanguageId::EnglishUs && context.currency == 13 &&
117 context.customBoardPath.empty();
118 const auto endPriority = static_cast<std::uint32_t>(pieces::BoardHousingPriority) +
119 static_cast<std::uint32_t>(rules::SquareCount) * pieces::HouseSlotCount;
120 return options.house && priority >= pieces::BoardHousingPriority && priority < endPriority &&
123 }
124
125 std::optional<ModernGltfLoadOptions> modernSceneLoadOptions(ModernSceneKind kind) noexcept
126 {
128 {
129 ModernGltfLoadOptions options;
130 options.unitsPerMeter = 200.0F;
131 options.yawDegrees = 0.0F;
132 options.localOffset = {2430.0F, 0.0F, 2430.0F};
133 options.groundToZero = false;
134 return options;
135 }
137 {
138 // Exact production board vertices exported in raw retail units.
139 ModernGltfLoadOptions options; options.unitsPerMeter = 1.0F;
140 options.groundToZero = false; return options;
141 }
143 {
144 // Author at 200 raw units/metre: glTF Y-up bounds
145 // [-.325,0,-.45]..[.325,.775,.45]. The existing gameplay .10
146 // sequence scale gives a 13x15.5x18 world-unit hotel. Loaded
147 // geometry must independently satisfy the retail bounds below.
148 ModernGltfLoadOptions options;
149 options.unitsPerMeter = 200.0F;
150 options.groundToZero = true;
151 return options;
152 }
153 if (kind != ModernSceneKind::House) return std::nullopt;
154 ModernGltfLoadOptions options;
155 options.unitsPerMeter = static_cast<float>(RetailHouseHeight / AuthoredHouseHeightMetres);
156 options.yawDegrees = 0.0F;
157 options.localOffset = {0.0F, 0.0F, 0.0F};
158 options.groundToZero = true;
159 return options;
160 }
161
163 {
167 mesh.vertices.empty() || mesh.indices.empty()) return false;
168 // Immutable production HMD bounds, in raw retail units.
169 const std::array<float,3> minimum = kind == ModernSceneKind::ProceduralUsaBoard
170 ? std::array<float,3>{-84,-69.2000046F,-84} : kind == ModernSceneKind::UsaBoard
171 ? std::array<float,3>{-84,-64,-84} : std::array<float,3>{-65,0,-90};
172 const std::array<float,3> maximum = kind == ModernSceneKind::ProceduralUsaBoard
173 ? std::array<float,3>{4944,23,4944} : kind == ModernSceneKind::UsaBoard
174 ? std::array<float,3>{4944,50,4944} : std::array<float,3>{65,155,90};
175 constexpr float tolerance = 0.001F;
176 for (std::size_t axis = 0; axis < 3; ++axis)
177 if (!std::isfinite(mesh.bounds.minimum[axis]) || !std::isfinite(mesh.bounds.maximum[axis]) ||
178 std::abs(mesh.bounds.minimum[axis] - minimum[axis]) > tolerance ||
179 std::abs(mesh.bounds.maximum[axis] - maximum[axis]) > tolerance) return false;
180 return true;
181 }
182}
std::uint16_t priority
unsigned index
Kind kind
bool qualifiedModernSceneGeometry(ModernSceneKind kind, const MeshRenderData &mesh) noexcept
std::uint32_t DataId
Definition DataBanks.hpp:10
constexpr DataId boardMeshDataId(BoardMeshKind mesh) noexcept
bool qualifiedModernSceneSequence(ModernSceneKind kind, DataId meshId, std::optional< DataId > rootSequenceDataId, std::uint16_t priority, const ModernSceneOptions &options, const ModernSceneContext &context) noexcept
std::optional< ModernGltfLoadOptions > modernSceneLoadOptions(ModernSceneKind kind) noexcept
std::expected< ParsedModernSceneOptions, std::string > parseModernSceneArguments(std::span< const std::string_view > arguments)
constexpr DataId packDataId(std::uint16_t group, DataTag tag) noexcept
Definition DataBanks.hpp:39
const ModernSceneDefinition & modernSceneDefinition(ModernSceneKind kind) noexcept
constexpr std::uint16_t Board3DPriority
Definition Display.hpp:39
constexpr std::uint8_t HouseSlotCount
constexpr data::DataTag HotelMeshTag
constexpr std::uint16_t BoardHousingPriority
constexpr data::DataTag HouseMeshTag
constexpr std::size_t SquareCount
Definition RuleTypes.hpp:24