MCPcopy Create free account
hub / github.com/OpenLoco/OpenLoco / generate

Method generate

src/OpenLoco/src/Map/MapGenerator/PngTerrainGenerator.cpp:15–78  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

13namespace OpenLoco::World::MapGenerator
14{
15 void PngTerrainGenerator::generate(const Scenario::Options& options, const fs::path& path, HeightMap& heightMap)
16 {
17 if (!fs::is_regular_file(path))
18 {
19 Logging::error("Can't find heightmap file ({})", path);
20 return;
21 }
22
23 auto pngImage = Gfx::PngImage::loadFromFile(path);
24 if (pngImage == nullptr)
25 {
26 Logging::error("Can't load heightmap file ({})", path);
27 return;
28 }
29
30 // TODO: Move the constants to a more sensible place, values are taken from TileManager::adjustSurfaceHeight
31 constexpr int minLandHeight = 4 / kMicroToSmallZStep;
32 constexpr int maxLandHeight = 160 / kMicroToSmallZStep;
33
34 const int heightRange = maxLandHeight - std::max<int>(minLandHeight, options.minLandHeight);
35
36 std::fill_n(heightMap.data(), heightMap.size(), options.minLandHeight);
37
38 // Map the entire map area to the image with interpolation
39 for (int32_t y = 0; y < World::kMapRows; y++)
40 {
41 for (int32_t x = 0; x < World::kMapColumns; x++)
42 {
43 // Map from map coordinates to image coordinates
44 const float imgX = (x * pngImage->width) / static_cast<float>(World::kMapColumns);
45 const float imgY = (y * pngImage->height) / static_cast<float>(World::kMapRows);
46
47 // Bilinear interpolation coordinates
48 const int x0 = static_cast<int>(imgX);
49 const int y0 = static_cast<int>(imgY);
50 const int x1 = std::min(x0 + 1, pngImage->width - 1);
51 const int y1 = std::min(y0 + 1, pngImage->height - 1);
52
53 const float fx = imgX - x0;
54 const float fy = imgY - y0;
55
56 // Sample the four corners for bilinear interpolation
57 const auto c00 = pngImage->getPixel(x0, y0);
58 const auto c10 = pngImage->getPixel(x1, y0);
59 const auto c01 = pngImage->getPixel(x0, y1);
60 const auto c11 = pngImage->getPixel(x1, y1);
61
62 // Get max of RGB channels for each corner
63 const auto h00 = std::max({ c00.r, c00.g, c00.b });
64 const auto h10 = std::max({ c10.r, c10.g, c10.b });
65 const auto h01 = std::max({ c01.r, c01.g, c01.b });
66 const auto h11 = std::max({ c11.r, c11.g, c11.b });
67
68 // Perform bilinear interpolation
69 const auto h0 = h00 * (1.0f - fx) + h10 * fx;
70 const auto h1 = h01 * (1.0f - fx) + h11 * fx;
71 const auto imgHeight = h0 * (1.0f - fy) + h1 * fy;
72

Callers 1

generateHeightMapFunction · 0.45

Calls 4

errorFunction · 0.85
getPixelMethod · 0.80
dataMethod · 0.45
sizeMethod · 0.45

Tested by

no test coverage detected