mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2025-12-11 18:48:26 +00:00
Correct scene making, merged the old raw into the new.
added option to automatically write the raw obj file Added scene colors to the obj use proper scene colors from hf
This commit is contained in:
@@ -1,7 +1,9 @@
|
||||
#include "Raw.h"
|
||||
#include "BinaryIO.h"
|
||||
#include "Logger.h"
|
||||
#include "SceneColor.h"
|
||||
#include <fstream>
|
||||
#include <algorithm>
|
||||
|
||||
namespace Raw {
|
||||
|
||||
@@ -279,16 +281,22 @@ namespace Raw {
|
||||
return; // No scene data available
|
||||
}
|
||||
|
||||
LOG("GenerateTerrainMesh: Processing %u chunks", raw.chunks.size());
|
||||
|
||||
uint32_t vertexOffset = 0;
|
||||
|
||||
for (const auto& chunk : raw.chunks) {
|
||||
// Skip chunks without scene maps
|
||||
if (chunk.sceneMap.empty() || chunk.colorMapResolution == 0 || chunk.heightMap.empty()) {
|
||||
LOG("Skipping chunk %u (sceneMap: %zu, colorMapRes: %u, heightMap: %zu)",
|
||||
chunk.id, chunk.sceneMap.size(), chunk.colorMapResolution, chunk.heightMap.size());
|
||||
continue;
|
||||
}
|
||||
|
||||
LOG("Processing chunk %u: width=%u, height=%u, colorMapRes=%u, sceneMapSize=%zu",
|
||||
chunk.id, chunk.width, chunk.height, chunk.colorMapResolution, chunk.sceneMap.size());
|
||||
|
||||
// Generate vertices for this chunk
|
||||
// Similar to RawChunk::GenerateMesh() in dTerrain but with scene IDs
|
||||
for (uint32_t i = 0; i < chunk.width; ++i) {
|
||||
for (uint32_t j = 0; j < chunk.height; ++j) {
|
||||
// Get height at this position
|
||||
@@ -310,21 +318,23 @@ namespace Raw {
|
||||
|
||||
NiPoint3 worldPos(worldX, worldY, worldZ);
|
||||
|
||||
// Get scene ID at this position
|
||||
// Map heightmap position to scene map position
|
||||
const float sceneMapX = (static_cast<float>(i) / static_cast<float>(chunk.width - 1)) * static_cast<float>(chunk.colorMapResolution - 1);
|
||||
const float sceneMapZ = (static_cast<float>(j) / static_cast<float>(chunk.height - 1)) * static_cast<float>(chunk.colorMapResolution - 1);
|
||||
|
||||
const uint32_t sceneX = std::min(static_cast<uint32_t>(sceneMapX), chunk.colorMapResolution - 1);
|
||||
const uint32_t sceneZ = std::min(static_cast<uint32_t>(sceneMapZ), chunk.colorMapResolution - 1);
|
||||
const uint32_t sceneIndex = sceneZ * chunk.colorMapResolution + sceneX;
|
||||
// Get scene ID at this position
|
||||
// Map heightmap position to scene map position
|
||||
// The scene map is colorMapResolution x colorMapResolution
|
||||
// We need to map from heightmap coordinates (i, j) to scene map coordinates
|
||||
const float sceneMapI = (static_cast<float>(i) / static_cast<float>(chunk.width - 1)) * static_cast<float>(chunk.colorMapResolution - 1);
|
||||
const float sceneMapJ = (static_cast<float>(j) / static_cast<float>(chunk.height - 1)) * static_cast<float>(chunk.colorMapResolution - 1);
|
||||
|
||||
const uint32_t sceneI = std::min(static_cast<uint32_t>(sceneMapI), chunk.colorMapResolution - 1);
|
||||
const uint32_t sceneJ = std::min(static_cast<uint32_t>(sceneMapJ), chunk.colorMapResolution - 1);
|
||||
// Scene map uses the same indexing pattern as heightmap: row * width + col
|
||||
const uint32_t sceneIndex = sceneI * chunk.colorMapResolution + sceneJ;
|
||||
|
||||
uint8_t sceneID = 0;
|
||||
if (sceneIndex < chunk.sceneMap.size()) {
|
||||
sceneID = chunk.sceneMap[sceneIndex];
|
||||
}
|
||||
|
||||
outMesh.vertices.emplace_back(worldPos, sceneID);
|
||||
uint8_t sceneID = 0;
|
||||
if (sceneIndex < chunk.sceneMap.size()) {
|
||||
sceneID = chunk.sceneMap[sceneIndex];
|
||||
}
|
||||
outMesh.vertices.emplace_back(worldPos, sceneID);
|
||||
|
||||
// Generate triangles (same pattern as dTerrain)
|
||||
if (i > 0 && j > 0) {
|
||||
@@ -346,8 +356,49 @@ namespace Raw {
|
||||
}
|
||||
}
|
||||
|
||||
vertexOffset += chunk.width * chunk.height;
|
||||
}
|
||||
vertexOffset += chunk.width * chunk.height;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Raw
|
||||
bool WriteTerrainMeshToOBJ(const TerrainMesh& mesh, const std::string& path) {
|
||||
try {
|
||||
std::ofstream file(path);
|
||||
if (!file.is_open()) {
|
||||
LOG("Failed to open OBJ file for writing: %s", path.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
// Create instance of SceneColor for color lookup
|
||||
SceneColor sceneColor;
|
||||
|
||||
// Write vertices with colors
|
||||
// OBJ format supports vertex colors as: v x y z r g b
|
||||
for (const auto& v : mesh.vertices) {
|
||||
file << "v " << v.position.x << ' ' << v.position.y << ' ' << v.position.z;
|
||||
|
||||
uint8_t sceneID = v.sceneID;
|
||||
|
||||
const NiColor& color = sceneColor.Get(sceneID);
|
||||
file << ' ' << color.m_Red << ' ' << color.m_Green << ' ' << color.m_Blue;
|
||||
file << '\n';
|
||||
}
|
||||
|
||||
// Write faces (triangles)
|
||||
for (size_t i = 0; i < mesh.triangles.size(); i += 3) {
|
||||
// OBJ indices are 1-based
|
||||
file << "f " << (mesh.triangles[i] + 1) << ' '
|
||||
<< (mesh.triangles[i + 1] + 1) << ' '
|
||||
<< (mesh.triangles[i + 2] + 1) << '\n';
|
||||
}
|
||||
|
||||
file.close();
|
||||
LOG("Successfully wrote terrain mesh to OBJ: %s (%zu vertices, %zu triangles)",
|
||||
path.c_str(), mesh.vertices.size(), mesh.triangles.size() / 3);
|
||||
return true;
|
||||
} catch (const std::exception& e) {
|
||||
LOG("Exception while writing OBJ file: %s", e.what());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Raw
|
||||
Reference in New Issue
Block a user