mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2025-12-11 18:48:26 +00:00
clamp search to bounds
This commit is contained in:
@@ -1974,8 +1974,8 @@ namespace DEVGMCommands {
|
|||||||
const float y = chunk.heightMap[heightIndex];
|
const float y = chunk.heightMap[heightIndex];
|
||||||
|
|
||||||
// Map heightmap position to scene map position (same as GenerateTerrainMesh)
|
// Map heightmap position to scene map position (same as GenerateTerrainMesh)
|
||||||
const float sceneMapI = (static_cast<float>(i) / static_cast<float>(chunk.width - 1)) * static_cast<float>(chunk.colorMapResolution - 1);
|
const float sceneMapI = ((i) / (chunk.width - 1)) * (chunk.colorMapResolution - 1);
|
||||||
const float sceneMapJ = (static_cast<float>(j) / static_cast<float>(chunk.height - 1)) * static_cast<float>(chunk.colorMapResolution - 1);
|
const float sceneMapJ = ((j) / (chunk.height - 1)) * (chunk.colorMapResolution - 1);
|
||||||
|
|
||||||
const uint32_t sceneI = std::min(static_cast<uint32_t>(sceneMapI), 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);
|
const uint32_t sceneJ = std::min(static_cast<uint32_t>(sceneMapJ), chunk.colorMapResolution - 1);
|
||||||
@@ -1987,15 +1987,13 @@ namespace DEVGMCommands {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check if this point belongs to the current scene
|
// Check if this point belongs to the current scene
|
||||||
if (sceneID == currentSceneID.GetSceneID()) {
|
if (sceneID == currentSceneID.GetSceneID()) {
|
||||||
// Calculate world position (same as GenerateTerrainMesh)
|
// Calculate world position (same as GenerateTerrainMesh)
|
||||||
const float worldX = (static_cast<float>(i) + (chunk.offsetWorldX / chunk.scaleFactor)) * chunk.scaleFactor;
|
const float worldX = ((i) + (chunk.offsetX / chunk.scaleFactor)) * chunk.scaleFactor;
|
||||||
const float worldY = (y / chunk.scaleFactor) * chunk.scaleFactor;
|
const float worldY = (y / chunk.scaleFactor) * chunk.scaleFactor;
|
||||||
const float worldZ = (static_cast<float>(j) + (chunk.offsetWorldZ / chunk.scaleFactor)) * chunk.scaleFactor;
|
const float worldZ = ((j) + (chunk.offsetZ / chunk.scaleFactor)) * chunk.scaleFactor;
|
||||||
|
|
||||||
NiPoint3 spawnPos(worldX, worldY, worldZ);
|
NiPoint3 spawnPos(worldX, worldY, worldZ); EntityInfo info;
|
||||||
|
|
||||||
EntityInfo info;
|
|
||||||
info.lot = lot + currentSceneID.GetSceneID(); // to differentiate scenes
|
info.lot = lot + currentSceneID.GetSceneID(); // to differentiate scenes
|
||||||
info.pos = spawnPos;
|
info.pos = spawnPos;
|
||||||
info.rot = QuatUtils::IDENTITY;
|
info.rot = QuatUtils::IDENTITY;
|
||||||
@@ -2065,8 +2063,8 @@ namespace DEVGMCommands {
|
|||||||
const float y = chunk.heightMap[heightIndex];
|
const float y = chunk.heightMap[heightIndex];
|
||||||
|
|
||||||
// Map heightmap position to scene map position (same as GenerateTerrainMesh)
|
// Map heightmap position to scene map position (same as GenerateTerrainMesh)
|
||||||
const float sceneMapI = (static_cast<float>(i) / static_cast<float>(chunk.width - 1)) * static_cast<float>(chunk.colorMapResolution - 1);
|
const float sceneMapI = ((i) / (chunk.width - 1)) * (chunk.colorMapResolution - 1);
|
||||||
const float sceneMapJ = (static_cast<float>(j) / static_cast<float>(chunk.height - 1)) * static_cast<float>(chunk.colorMapResolution - 1);
|
const float sceneMapJ = ((j) / (chunk.height - 1)) * (chunk.colorMapResolution - 1);
|
||||||
|
|
||||||
const uint32_t sceneI = std::min(static_cast<uint32_t>(sceneMapI), 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);
|
const uint32_t sceneJ = std::min(static_cast<uint32_t>(sceneMapJ), chunk.colorMapResolution - 1);
|
||||||
@@ -2080,14 +2078,12 @@ namespace DEVGMCommands {
|
|||||||
// Skip invalid scenes (scene ID 0 typically means no scene)
|
// Skip invalid scenes (scene ID 0 typically means no scene)
|
||||||
if (sceneID == 0) continue;
|
if (sceneID == 0) continue;
|
||||||
|
|
||||||
// Calculate world position (same as GenerateTerrainMesh)
|
// Calculate world position (same as GenerateTerrainMesh)
|
||||||
const float worldX = (static_cast<float>(i) + (chunk.offsetWorldX / chunk.scaleFactor)) * chunk.scaleFactor;
|
const float worldX = ((i) + (chunk.offsetX / chunk.scaleFactor)) * chunk.scaleFactor;
|
||||||
const float worldY = (y / chunk.scaleFactor) * chunk.scaleFactor;
|
const float worldY = (y / chunk.scaleFactor) * chunk.scaleFactor;
|
||||||
const float worldZ = (static_cast<float>(j) + (chunk.offsetWorldZ / chunk.scaleFactor)) * chunk.scaleFactor;
|
const float worldZ = ((j) + (chunk.offsetZ / chunk.scaleFactor)) * chunk.scaleFactor;
|
||||||
|
|
||||||
NiPoint3 spawnPos(worldX, worldY, worldZ);
|
NiPoint3 spawnPos(worldX, worldY, worldZ); EntityInfo info;
|
||||||
|
|
||||||
EntityInfo info;
|
|
||||||
info.lot = lot + sceneID; // to show different scenes
|
info.lot = lot + sceneID; // to show different scenes
|
||||||
info.pos = spawnPos;
|
info.pos = spawnPos;
|
||||||
info.rot = QuatUtils::IDENTITY;
|
info.rot = QuatUtils::IDENTITY;
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#include "SceneColor.h"
|
#include "SceneColor.h"
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
namespace Raw {
|
namespace Raw {
|
||||||
|
|
||||||
@@ -51,22 +52,20 @@ namespace Raw {
|
|||||||
*/
|
*/
|
||||||
static bool ReadChunk(std::istream& stream, Chunk& chunk, uint16_t version) {
|
static bool ReadChunk(std::istream& stream, Chunk& chunk, uint16_t version) {
|
||||||
try {
|
try {
|
||||||
// Read basic chunk info
|
// Read basic chunk info
|
||||||
BinaryIO::BinaryRead(stream, chunk.id);
|
BinaryIO::BinaryRead(stream, chunk.id);
|
||||||
if (stream.fail()) {
|
if (stream.fail()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
BinaryIO::BinaryRead(stream, chunk.width);
|
BinaryIO::BinaryRead(stream, chunk.width);
|
||||||
BinaryIO::BinaryRead(stream, chunk.height);
|
BinaryIO::BinaryRead(stream, chunk.height);
|
||||||
BinaryIO::BinaryRead(stream, chunk.offsetWorldX);
|
BinaryIO::BinaryRead(stream, chunk.offsetX);
|
||||||
BinaryIO::BinaryRead(stream, chunk.offsetWorldZ);
|
BinaryIO::BinaryRead(stream, chunk.offsetZ);
|
||||||
|
|
||||||
if (stream.fail()) {
|
if (stream.fail()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
} // For version < 32, shader ID comes before texture IDs
|
||||||
|
|
||||||
// For version < 32, shader ID comes before texture IDs
|
|
||||||
if (version < 32) {
|
if (version < 32) {
|
||||||
BinaryIO::BinaryRead(stream, chunk.shaderId);
|
BinaryIO::BinaryRead(stream, chunk.shaderId);
|
||||||
}
|
}
|
||||||
@@ -264,9 +263,30 @@ namespace Raw {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Calculate terrain bounds from all chunks
|
||||||
|
if (!outRaw.chunks.empty()) {
|
||||||
|
outRaw.minBoundsX = std::numeric_limits<float>::max();
|
||||||
|
outRaw.minBoundsZ = std::numeric_limits<float>::max();
|
||||||
|
outRaw.maxBoundsX = std::numeric_limits<float>::lowest();
|
||||||
|
outRaw.maxBoundsZ = std::numeric_limits<float>::lowest();
|
||||||
|
|
||||||
|
for (const auto& chunk : outRaw.chunks) {
|
||||||
|
// Calculate chunk bounds
|
||||||
|
const float chunkMinX = chunk.offsetX;
|
||||||
|
const float chunkMinZ = chunk.offsetZ;
|
||||||
|
const float chunkMaxX = chunkMinX + (chunk.width * chunk.scaleFactor);
|
||||||
|
const float chunkMaxZ = chunkMinZ + (chunk.height * chunk.scaleFactor);
|
||||||
|
|
||||||
|
// Update overall bounds
|
||||||
|
outRaw.minBoundsX = std::min(outRaw.minBoundsX, chunkMinX);
|
||||||
|
outRaw.minBoundsZ = std::min(outRaw.minBoundsZ, chunkMinZ);
|
||||||
|
outRaw.maxBoundsX = std::max(outRaw.maxBoundsX, chunkMaxX);
|
||||||
|
outRaw.maxBoundsZ = std::max(outRaw.maxBoundsZ, chunkMaxZ);
|
||||||
|
} LOG("Raw terrain bounds: X[%.2f, %.2f], Z[%.2f, %.2f]",
|
||||||
|
outRaw.minBoundsX, outRaw.maxBoundsX, outRaw.minBoundsZ, outRaw.maxBoundsZ);
|
||||||
}
|
}
|
||||||
|
} return true;
|
||||||
return true;
|
|
||||||
} catch (const std::exception&) {
|
} catch (const std::exception&) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -302,40 +322,32 @@ namespace Raw {
|
|||||||
const uint32_t heightIndex = chunk.width * i + j;
|
const uint32_t heightIndex = chunk.width * i + j;
|
||||||
if (heightIndex >= chunk.heightMap.size()) continue;
|
if (heightIndex >= chunk.heightMap.size()) continue;
|
||||||
|
|
||||||
const float y = chunk.heightMap[heightIndex];
|
const float y = chunk.heightMap[heightIndex];
|
||||||
|
|
||||||
// Calculate world position
|
// Calculate world position
|
||||||
// Based on RawFile::GenerateFinalMeshFromChunks in dTerrain:
|
const float worldX = ((i) + (chunk.offsetX / chunk.scaleFactor)) * chunk.scaleFactor;
|
||||||
// tempVert.SetX(tempVert.GetX() + (chunk->m_X / chunk->m_HeightMap->m_ScaleFactor));
|
const float worldY = (y / chunk.scaleFactor) * chunk.scaleFactor;
|
||||||
// tempVert.SetY(tempVert.GetY() / chunk->m_HeightMap->m_ScaleFactor);
|
const float worldZ = ((j) + (chunk.offsetZ / chunk.scaleFactor)) * chunk.scaleFactor;
|
||||||
// tempVert.SetZ(tempVert.GetZ() + (chunk->m_Z / chunk->m_HeightMap->m_ScaleFactor));
|
|
||||||
// tempVert *= chunk->m_HeightMap->m_ScaleFactor;
|
|
||||||
|
|
||||||
float worldX = (static_cast<float>(i) + (chunk.offsetWorldX / chunk.scaleFactor)) * chunk.scaleFactor;
|
|
||||||
float worldY = (y / chunk.scaleFactor) * chunk.scaleFactor;
|
|
||||||
float worldZ = (static_cast<float>(j) + (chunk.offsetWorldZ / chunk.scaleFactor)) * chunk.scaleFactor;
|
|
||||||
|
|
||||||
NiPoint3 worldPos(worldX, worldY, worldZ);
|
const NiPoint3 worldPos(worldX, worldY, worldZ);
|
||||||
|
|
||||||
// Get scene ID at this position
|
// Get scene ID at this position
|
||||||
// Map heightmap position to scene map position
|
// Map heightmap position to scene map position
|
||||||
// The scene map is colorMapResolution x colorMapResolution
|
// The scene map is colorMapResolution x colorMapResolution
|
||||||
// We need to map from heightmap coordinates (i, j) to scene map coordinates
|
// 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 sceneMapI = ((i) / (chunk.width - 1)) * (chunk.colorMapResolution - 1);
|
||||||
const float sceneMapJ = (static_cast<float>(j) / static_cast<float>(chunk.height - 1)) * static_cast<float>(chunk.colorMapResolution - 1);
|
const float sceneMapJ = ((j) / (chunk.height - 1)) * (chunk.colorMapResolution - 1);
|
||||||
|
|
||||||
const uint32_t sceneI = std::min(static_cast<uint32_t>(sceneMapI), 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);
|
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
|
// Scene map uses the same indexing pattern as heightmap: row * width + col
|
||||||
const uint32_t sceneIndex = sceneI * chunk.colorMapResolution + sceneJ;
|
const uint32_t sceneIndex = sceneI * chunk.colorMapResolution + sceneJ;
|
||||||
|
|
||||||
uint8_t sceneID = 0;
|
uint8_t sceneID = 0;
|
||||||
if (sceneIndex < chunk.sceneMap.size()) {
|
if (sceneIndex < chunk.sceneMap.size()) {
|
||||||
sceneID = chunk.sceneMap[sceneIndex];
|
sceneID = chunk.sceneMap[sceneIndex];
|
||||||
}
|
}
|
||||||
outMesh.vertices.emplace_back(worldPos, sceneID);
|
outMesh.vertices.emplace_back(worldPos, sceneID);
|
||||||
|
|
||||||
// Generate triangles (same pattern as dTerrain)
|
|
||||||
if (i > 0 && j > 0) {
|
if (i > 0 && j > 0) {
|
||||||
const uint32_t currentVert = vertexOffset + chunk.width * i + j;
|
const uint32_t currentVert = vertexOffset + chunk.width * i + j;
|
||||||
const uint32_t leftVert = currentVert - 1;
|
const uint32_t leftVert = currentVert - 1;
|
||||||
|
|||||||
@@ -68,8 +68,8 @@ struct Chunk {
|
|||||||
uint32_t id;
|
uint32_t id;
|
||||||
uint32_t width;
|
uint32_t width;
|
||||||
uint32_t height;
|
uint32_t height;
|
||||||
float offsetWorldX;
|
float offsetX;
|
||||||
float offsetWorldZ;
|
float offsetZ;
|
||||||
uint32_t shaderId;
|
uint32_t shaderId;
|
||||||
|
|
||||||
// Texture IDs (4 textures per chunk)
|
// Texture IDs (4 textures per chunk)
|
||||||
@@ -119,6 +119,12 @@ struct Raw {
|
|||||||
uint32_t numChunksWidth = 0;
|
uint32_t numChunksWidth = 0;
|
||||||
uint32_t numChunksHeight = 0;
|
uint32_t numChunksHeight = 0;
|
||||||
std::vector<Chunk> chunks;
|
std::vector<Chunk> chunks;
|
||||||
|
|
||||||
|
// Calculated bounds of the entire terrain
|
||||||
|
float minBoundsX = 0.0f;
|
||||||
|
float minBoundsZ = 0.0f;
|
||||||
|
float maxBoundsX = 0.0f;
|
||||||
|
float maxBoundsZ = 0.0f;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -313,23 +313,27 @@ LWOSCENEID dZoneManager::GetSceneIDFromPosition(const NiPoint3& position) const
|
|||||||
return LWOSCENEID_INVALID;
|
return LWOSCENEID_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Convert 3D position to 2D (XZ plane) and clamp to terrain bounds
|
||||||
|
float posX = std::clamp(position.x, raw.minBoundsX, raw.maxBoundsX);
|
||||||
|
float posZ = std::clamp(position.z, raw.minBoundsZ, raw.maxBoundsZ);
|
||||||
|
|
||||||
// Find the chunk containing this position
|
// Find the chunk containing this position
|
||||||
// Reverse the world position calculation from GenerateTerrainMesh
|
// Reverse the world position calculation from GenerateTerrainMesh
|
||||||
for (const auto& chunk : raw.chunks) {
|
for (const auto& chunk : raw.chunks) {
|
||||||
if (chunk.sceneMap.empty()) continue;
|
if (chunk.sceneMap.empty()) continue;
|
||||||
|
|
||||||
// Reverse: worldX = (i + offsetWorldX/scaleFactor) * scaleFactor
|
// Reverse: worldX = (i + offsetX/scaleFactor) * scaleFactor
|
||||||
// Therefore: i = worldX/scaleFactor - offsetWorldX/scaleFactor
|
// Therefore: i = worldX/scaleFactor - offsetX/scaleFactor
|
||||||
const float heightI = position.x / chunk.scaleFactor - (chunk.offsetWorldX / chunk.scaleFactor);
|
const float heightI = posX / chunk.scaleFactor - (chunk.offsetX / chunk.scaleFactor);
|
||||||
const float heightJ = position.z / chunk.scaleFactor - (chunk.offsetWorldZ / chunk.scaleFactor);
|
const float heightJ = posZ / chunk.scaleFactor - (chunk.offsetZ / chunk.scaleFactor);
|
||||||
|
|
||||||
// Check if position is within this chunk's heightmap bounds
|
// Check if position is within this chunk's heightmap bounds
|
||||||
if (heightI >= 0.0f && heightI < chunk.width &&
|
if (heightI >= 0.0f && heightI < static_cast<float>(chunk.width) &&
|
||||||
heightJ >= 0.0f && heightJ < chunk.height) {
|
heightJ >= 0.0f && heightJ < static_cast<float>(chunk.height)) {
|
||||||
|
|
||||||
// Map heightmap position to scene map position (same as GenerateTerrainMesh)
|
// Map heightmap position to scene map position (same as GenerateTerrainMesh)
|
||||||
const float sceneMapI = (heightI / (chunk.width - 1)) * (chunk.colorMapResolution - 1);
|
const float sceneMapI = (heightI / static_cast<float>(chunk.width - 1)) * static_cast<float>(chunk.colorMapResolution - 1);
|
||||||
const float sceneMapJ = (heightJ / (chunk.height - 1)) * (chunk.colorMapResolution - 1);
|
const float sceneMapJ = (heightJ / 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 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);
|
const uint32_t sceneJ = std::min(static_cast<uint32_t>(sceneMapJ), chunk.colorMapResolution - 1);
|
||||||
|
|||||||
Reference in New Issue
Block a user