11
#include "mapmanager.h"
19
#include <celutil/fsutils.h>
20
#include <celutil/logger.h>
22
using namespace std::string_view_literals;
23
using celestia::util::GetLogger;
28
constexpr std::array extensions = {"map"sv};
32
WarpMesh::WarpMesh(int nx, int ny, float *data) :
44
std::vector<float> WarpMesh::scopedDataForRendering() const
47
int size = (nx - 1) * (ny - 1) * step;
48
std::vector<float> renderingData(static_cast<std::size_t>(size));
49
for (int y = 0; y < ny - 1; y += 1)
51
for (int x = 0; x < nx - 1; x += 1)
53
float *destination = renderingData.data() + (y * (nx - 1) + x) * step;
54
const float *source = &data[(y * nx + x) * 5];
56
std::memcpy(destination, source + 5 * nx, sizeof(float) * 5);
57
std::memcpy(destination + 5, source, sizeof(float) * 5);
58
std::memcpy(destination + 10, source + 5, sizeof(float) * 5);
60
std::memcpy(destination + 15, source + 5 * nx, sizeof(float) * 5);
61
std::memcpy(destination + 20, source + 5, sizeof(float) * 5);
62
std::memcpy(destination + 25, source + 5 * nx + 5, sizeof(float) * 5);
68
int WarpMesh::count() const
70
return 6 * (nx - 1) * (ny - 1);
73
bool WarpMesh::mapVertex(float x, float y, float* u, float* v) const
77
float maxX = data[(nx * ny - 1) * 5];
78
float maxY = data[(nx * ny - 1) * 5 + 1];
80
float stepX = (maxX - minX) / (nx - 1);
81
float stepY = (maxY - minY) / (ny - 1);
83
float locX = (x - minX) / stepX;
84
float locY = (y - minY) / stepY;
85
auto floX = static_cast<int>(std::floor(locX));
86
auto floY = static_cast<int>(std::floor(locY));
90
if (floX < 0 || floX >= nx - 1 || floY < 0 || floY >= ny - 1)
93
float p1x = data[(floY * nx + floX) * 5 + 2];
94
float p1y = data[(floY * nx + floX) * 5 + 3];
95
float p2x = data[(floY * nx + floX + 1) * 5 + 2];
96
float p2y = data[(floY * nx + floX + 1) * 5 + 3];
97
float p3x = data[(floY * nx + floX + nx) * 5 + 2];
98
float p3y = data[(floY * nx + floX + nx) * 5 + 3];
99
float p4x = data[(floY * nx + floX + nx + 1) * 5 + 2];
100
float p4y = data[(floY * nx + floX + nx + 1) * 5 + 3];
102
if (locX + locY <= 1)
105
*u = p1x + locX * (p2x - p1x) + locY * (p3x - p1x);
106
*v = p1y + locX * (p2y - p1y) + locY * (p3y - p1y);
113
*u = p4x + locX * (p4x - p3x) + locY * (p4x - p2x);
114
*v = p4y + locX * (p4y - p3y) + locY * (p4y - p2y);
122
WarpMeshManager* GetWarpMeshManager()
124
static WarpMeshManager* const warpMeshManager = std::make_unique<WarpMeshManager>("warp").release();
125
return warpMeshManager;
128
fs::path WarpMeshInfo::resolve(const fs::path& baseDir) const
130
bool wildcard = source.extension() == ".*";
132
fs::path filename = baseDir / source;
136
fs::path matched = celestia::util::ResolveWildcard(filename, extensions);
137
if (!matched.empty())
145
std::unique_ptr<WarpMesh> WarpMeshInfo::load(const fs::path& name) const
147
#define MESHTYPE_RECT 2
148
std::ifstream f(name);
155
GetLogger()->error("Failed to read mesh header\n");
159
if (type != MESHTYPE_RECT)
161
GetLogger()->error("Unsupported mesh type found: {}\n", type);
165
if (!(f >> nx >> ny))
167
GetLogger()->error("Failed to read mesh header\n");
171
if (nx < 2 || ny < 2)
173
GetLogger()->error("Row and column numbers should be larger than 2\n");
177
float *data = new float[nx * ny * 5];
178
for (int y = 0; y < ny; y += 1)
180
for (int x = 0; x < nx; x += 1)
182
float *base = &data[(y * nx + x) * 5];
183
if (!(f >> base[0] >> base[1] >> base[2] >> base[3] >> base[4]))
185
GetLogger()->error("Failed to read mesh data\n");
191
GetLogger()->info("Read a mesh of {} x {}\n", nx, ny);
192
return std::make_unique<WarpMesh>(nx, ny, data);