Skip to content

Commit

Permalink
MGEXEgui: Build distant landscape per atlas region, to avoid allocati…
Browse files Browse the repository at this point in the history
…ng a huge but mostly empty heightmap to cover the whole world.
  • Loading branch information
Hrnchamd committed Apr 8, 2023
1 parent 4f2c844 commit 1c259be
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 32 deletions.
9 changes: 8 additions & 1 deletion MGEfuncs/LandTessellator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,13 +98,20 @@ class LandMesh {
}

static bool SaveMeshes(LPCSTR file_path, vector<LandMesh>& meshes) {
HANDLE file = CreateFile(file_path, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0);
HANDLE file = CreateFile(file_path, GENERIC_READ|GENERIC_WRITE, 0, 0, OPEN_ALWAYS, 0, 0);
if (file == INVALID_HANDLE_VALUE) {
return false;
}

DWORD unused, mesh_count = meshes.size();
if (GetFileSize(file, NULL) > 0) {
DWORD existing_count;
ReadFile(file, &existing_count, sizeof(existing_count), &unused, 0);
mesh_count += existing_count;
SetFilePointer(file, 0, NULL, FILE_BEGIN);
}
WriteFile(file, &mesh_count, sizeof(mesh_count), &unused, 0);
SetFilePointer(file, 0, NULL, FILE_END);

for (size_t i = 0; i < meshes.size(); ++i) {
if (!meshes[i].Save(file)) {
Expand Down
68 changes: 37 additions & 31 deletions MGEgui/DistantLand/DistantLandForm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2231,30 +2231,6 @@ private void GenerateWorldMesh(int detail, string path) {
tolerance = toleranceOptions[detail];
}

// Produce large heightmap array
int MapSpanX = MapMaxX - MapMinX + 1;
int MapSpanY = MapMaxY - MapMinY + 1;
int DataSpanX = MapSpanX * 64;
int DataSpanY = MapSpanY * 64;

var height_data = new float[DataSpanX * DataSpanY];

for (int y1 = MapMinY; y1 <= MapMaxY; y1++) {
for (int y2 = 0; y2 < 64; y2++) {
for (int x1 = MapMinX; x1 <= MapMaxX; x1++) {
for (int x2 = 0; x2 < 64; x2++) {
int y = (y1 - MapMinY) * 64 + y2;
int x = (x1 - MapMinX) * 64 + x2;
if (LandMap[x1, y1] != null) {
height_data[y * DataSpanX + x] = (float)LandMap[x1, y1].Heights[x2, y2] * 8.0f;
} else {
height_data[y * DataSpanX + x] = -2048.0f;
}
}
}
}
}

// Produce packed atlas data
var atlas_data = new float[8 * Atlas.Count];
var iAtlas = 0;
Expand All @@ -2270,14 +2246,44 @@ private void GenerateWorldMesh(int detail, string path) {
iAtlas += 8;
}

// Generate optimized landscape mesh
float minX = (float)MapMinX * 8192.0f;
float maxX = (float)(MapMaxX + 1) * 8192.0f;
float minY = (float)MapMinY * 8192.0f;
float maxY = (float)(MapMaxY + 1) * 8192.0f;
// Ensure previous landscape data is erased
if (File.Exists(path)) {
File.Delete(path);
}

backgroundWorker.ReportProgress(10, strings["LandTessellating"]);
NativeMethods.TessellateLandscapeAtlased(path, height_data, (uint)DataSpanX, (uint)DataSpanY, atlas_data, (uint)Atlas.Count, minX, minY, maxX, maxY, tolerance);
// Generate optimized landscape mesh
foreach (var r in Atlas) {
// Produce atlas region heightmap array
int RegionSpanX = r.MaxX - r.MinX + 1;
int RegionSpanY = r.MaxY - r.MinY + 1;
int DataSpanX = RegionSpanX * 64;
int DataSpanY = RegionSpanY * 64;
var height_data = new float[DataSpanX * DataSpanY];

for (int y1 = r.MinY; y1 <= r.MaxY; y1++) {
for (int y2 = 0; y2 < 64; y2++) {
for (int x1 = r.MinX; x1 <= r.MaxX; x1++) {
for (int x2 = 0; x2 < 64; x2++) {
int y = (y1 - r.MinY) * 64 + y2;
int x = (x1 - r.MinX) * 64 + x2;
if (LandMap[x1, y1] != null) {
height_data[y * DataSpanX + x] = (float)LandMap[x1, y1].Heights[x2, y2] * 8.0f;
} else {
height_data[y * DataSpanX + x] = -2048.0f;
}
}
}
}
}

float minX = (float)r.MinX * 8192.0f;
float maxX = (float)(r.MaxX + 1) * 8192.0f;
float minY = (float)r.MinY * 8192.0f;
float maxY = (float)(r.MaxY + 1) * 8192.0f;

backgroundWorker.ReportProgress(10, strings["LandTessellating"]);
NativeMethods.TessellateLandscapeAtlased(path, height_data, (uint)DataSpanX, (uint)DataSpanY, atlas_data, (uint)Atlas.Count, minX, minY, maxX, maxY, tolerance);
}
}

/* Statics tab properties */
Expand Down

0 comments on commit 1c259be

Please sign in to comment.