From b6b05b595a2ab2cd7ef1ee1d7b88197a6f925240 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Wed, 6 Jan 2021 05:56:24 +0800 Subject: [PATCH] Make heightmap bitmap coordinates stable between map extensions --- nel/tools/3d/ig_elevation/main.cpp | 34 +++++++++++++++---- .../unbuild_elevation/unbuild_elevation.cpp | 31 ++++++++++++----- .../3d/zone_elevation/zone_elevation.cpp | 24 +++++++++++-- .../build_gamedata/processes/ig/2_build.py | 1 + .../build_gamedata/processes/ligo/0_setup.py | 1 + .../build_gamedata/processes/zone/2_build.py | 5 ++- .../world_editor/land_export/main.cpp | 1 + .../world_editor/land_export_lib/export.cpp | 29 ++++++++++++---- .../world_editor/land_export_lib/export.h | 1 + 9 files changed, 101 insertions(+), 26 deletions(-) diff --git a/nel/tools/3d/ig_elevation/main.cpp b/nel/tools/3d/ig_elevation/main.cpp index a3d485bd8..65de8fb82 100644 --- a/nel/tools/3d/ig_elevation/main.cpp +++ b/nel/tools/3d/ig_elevation/main.cpp @@ -65,6 +65,7 @@ struct SExportOptions float ZFactor1; string HeightMapFile2; float ZFactor2; + bool ExtendCoords; string LandFile; // ----------------------------------------------------------------------- @@ -105,6 +106,9 @@ struct SExportOptions CConfigFile::CVar &cvZFactor2 = cf.getVar("ZFactor2"); ZFactor2 = cvZFactor2.asFloat(); + CConfigFile::CVar &cvExtendCoords = cf.getVar("ExtendCoords"); + ExtendCoords = cvExtendCoords.asFloat(); + CConfigFile::CVar &cvLandFile = cf.getVar("LandFile"); LandFile = cvLandFile.asString(); } @@ -214,13 +218,19 @@ static float getHeightMapZ(float x, float y, const CZoneLimits &zl, const SExpo sint32 SizeX = zl._ZoneMaxX - zl._ZoneMinX + 1; sint32 SizeY = zl._ZoneMaxY - zl._ZoneMinY + 1; - clamp (x, options.CellSize * zl._ZoneMinX, options.CellSize * (zl._ZoneMaxX + 1)); - clamp (y, options.CellSize * zl._ZoneMinY, options.CellSize * (zl._ZoneMaxY + 1)); - if (heightMap1 != NULL) { - color = heightMap1->getColor ( (x - options.CellSize * zl._ZoneMinX) / (options.CellSize * SizeX), - 1.0f - ((y - options.CellSize * zl._ZoneMinY) / (options.CellSize * SizeY))); + float xc = (x - options.CellSize * zl._ZoneMinX) / (options.CellSize * SizeX); + float yc = 1.0f - ((y - options.CellSize * zl._ZoneMinY) / (options.CellSize * SizeY)); + if (options.ExtendCoords) + { + uint32 w = heightMap1->getWidth(), h = heightMap1->getHeight(); + xc -= .5f / (float)w; + yc -= .5f / (float)h; + xc = xc * (float)(w + 1) / (float)w; + yc = yc * (float)(h + 1) / (float)h; + } + color = heightMap1->getColor(xc, yc); color *= 255.f; deltaZ = color.A; deltaZ = deltaZ - 127.0f; // Median intensity is 127 @@ -229,8 +239,17 @@ static float getHeightMapZ(float x, float y, const CZoneLimits &zl, const SExpo if (heightMap2 != NULL) { - color = heightMap2->getColor ( (x - options.CellSize * zl._ZoneMinX) / (options.CellSize * SizeX), - 1.0f - ((y - options.CellSize * zl._ZoneMinY) / (options.CellSize * SizeY))); + float xc = (x - options.CellSize * zl._ZoneMinX) / (options.CellSize * SizeX); + float yc = 1.0f - ((y - options.CellSize * zl._ZoneMinY) / (options.CellSize * SizeY)); + if (options.ExtendCoords) + { + uint32 w = heightMap2->getWidth(), h = heightMap2->getHeight(); + xc -= .5f / (float)w; + yc -= .5f / (float)h; + xc = xc * (float)(w + 1) / (float)w; + yc = yc * (float)(h + 1) / (float)h; + } + color = heightMap2->getColor(xc, yc); color *= 255.f; deltaZ2 = color.A; deltaZ2 = deltaZ2 - 127.0f; // Median intensity is 127 @@ -260,6 +279,7 @@ int main(int nNbArg, char**ppArgs) printf ("ZFactor1 = 1.0;\n"); printf ("HeightMapFile2 = \"R:/graphics/landscape/ligo/jungle/noise.tga\";\n"); printf ("ZFactor2 = 0.5;\n"); + printf ("ExtendCoords = 0;\n"); printf ("LandFile = \"w:/matis.land\";\n"); return EXIT_FAILURE; diff --git a/nel/tools/3d/unbuild_elevation/unbuild_elevation.cpp b/nel/tools/3d/unbuild_elevation/unbuild_elevation.cpp index f3c109a25..ffb428deb 100644 --- a/nel/tools/3d/unbuild_elevation/unbuild_elevation.cpp +++ b/nel/tools/3d/unbuild_elevation/unbuild_elevation.cpp @@ -43,6 +43,7 @@ namespace /* anonymous */ sint32 s_ZoneMinX, s_ZoneMinY, s_ZoneMaxX, s_ZoneMaxY; float s_CellSize = 160.0f; +bool s_ExtendCoords; std::string s_SourceDir; /* R:\reference\2008_july\data\r2_desert */ std::string s_ReferenceDir; /* R:\pipeline\export\continents\r2_desert\zone_weld */ @@ -58,11 +59,15 @@ int s_Warnings; // unbuild_elevation --land "R:\graphics\landscape\ligo\desert\r2_desert.land" "Y:\temp\r2_desert_elevation.Py" "R:\reference\2008_july\data\r2_desert" "R:\pipeline\export\continents\r2_desert\zone_weld" // --land "R:\graphics\landscape\ligo\jungle\zorai.land" --referenceext zonenhw "X:\wsl\big_zorai.py" "R:\reference\2008_july\data\zorai_zones" "R:\pipeline\export\continents\zorai\zone_weld" -// --land "R:\graphics\landscape\ligo\desert\r2_desert.land" "X:\wsl\big_r2_desert.py" "R:\reference\2008_july\data\r2_desert" "R:\pipeline\export\continents\r2_desert\zone_weld" -// --land "R:\graphics\landscape\ligo\jungle\r2_jungle.land" "X:\wsl\big_r2_jungle.py" "R:\reference\2008_july\data\r2_jungle" "R:\pipeline\export\continents\r2_jungle\zone_weld" -// --land "R:\graphics\landscape\ligo\jungle\r2_forest.land" "X:\wsl\big_r2_forest.py" "R:\reference\2008_july\data\r2_forest" "R:\pipeline\export\continents\r2_forest\zone_weld" -// --land "R:\graphics\landscape\ligo\lacustre\r2_lakes.land" "X:\wsl\big_r2_lakes.py" "R:\reference\2008_july\data\r2_lakes" "R:\pipeline\export\continents\r2_lakes\zone_weld" -// --land "R:\graphics\landscape\ligo\primes_racines\r2_roots.land" "X:\wsl\big_r2_roots.py" "R:\reference\2008_july\data\r2_roots" "R:\pipeline\export\continents\r2_roots\zone_weld" + +// --land "R:\graphics\landscape\ligo\desert\r2_desert.land" "X:\wsl\big_r2_desert.py" "R:\reference\2008_july\data\r2_desert" "R:\pipeline\export\continents\r2_desert\zone_weld" --extendcoords +// --land "R:\graphics\landscape\ligo\jungle\r2_jungle.land" "X:\wsl\big_r2_jungle.py" "R:\reference\2008_july\data\r2_jungle" "R:\pipeline\export\continents\r2_jungle\zone_weld" --extendcoords +// --land "R:\graphics\landscape\ligo\jungle\r2_forest.land" "X:\wsl\big_r2_forest.py" "R:\reference\2008_july\data\r2_forest" "R:\pipeline\export\continents\r2_forest\zone_weld" --extendcoords +// --land "R:\graphics\landscape\ligo\lacustre\r2_lakes.land" "X:\wsl\big_r2_lakes.py" "R:\reference\2008_july\data\r2_lakes" "R:\pipeline\export\continents\r2_lakes\zone_weld" --extendcoords +// --land "R:\graphics\landscape\ligo\primes_racines\r2_roots.land" "X:\wsl\big_r2_roots.py" "R:\reference\2008_july\data\r2_roots" "R:\pipeline\export\continents\r2_roots\zone_weld" --extendcoords + +// --land "R:\graphics\landscape\ligo\desert\r2_desert.land" --referenceext zonew "X:\wsl\check_r2_desert.py" "R:\reference\2008_july\data\r2_desert" "R:\pipeline\export\continents\r2_desert\zone_weld" --extendcoords +// --land "R:\graphics\landscape\ligo\jungle\r2_jungle.land" --referenceext zonew "X:\wsl\check_r2_jungle.py" "R:\reference\2008_july\data\r2_jungle" "R:\pipeline\export\continents\r2_jungle\zone_weld" --extendcoords bool loadLand(const string &filename) { @@ -135,11 +140,18 @@ void getBitmapCoord(float &xc, float &yc, float x, float y) sint32 sizeX = s_ZoneMaxX - s_ZoneMinX + 1; sint32 sizeY = s_ZoneMaxY - s_ZoneMinY + 1; - clamp(x, s_CellSize * s_ZoneMinX, s_CellSize * (s_ZoneMaxX + 1)); - clamp(y, s_CellSize * s_ZoneMinY, s_CellSize * (s_ZoneMaxY + 1)); - xc = (x - s_CellSize * s_ZoneMinX) / (s_CellSize * sizeX); yc = 1.0f - ((y - s_CellSize * s_ZoneMinY) / (s_CellSize * sizeY)); + + if (s_ExtendCoords) + { + int w, h; + getBitmapSize(w, h); + xc -= .5f / (float)w; + yc -= .5f / (float)h; + xc = xc * (float)(w + 1) / (float)w; + yc = yc * (float)(h + 1) / (float)h; + } } bool processZone(std::vector &output, const std::string &sourceFile, const std::string &referenceFile) @@ -427,6 +439,8 @@ bool unbuildElevation(NLMISC::CCmdArgs &args) return false; } + s_ExtendCoords = args.haveLongArg("extendcoords"); + if (args.haveLongArg("sourceext")) { s_SourceExt = args.getLongArg("sourceext")[0]; @@ -459,6 +473,7 @@ int main(int argc, char **argv) args.addArg("", "zonemin", "zone", "Zone boundary"); args.addArg("", "zonemax", "zone", "Zone boundary"); args.addArg("", "cellsize", "meters", "Zone cell size (default: 160)"); + args.addArg("", "extendcoords", "flag", "Extend coordinates to edge of bitmap pixels"); if (!args.parse(argc, argv)) { diff --git a/nel/tools/3d/zone_elevation/zone_elevation.cpp b/nel/tools/3d/zone_elevation/zone_elevation.cpp index abe9b511c..fe583a87d 100644 --- a/nel/tools/3d/zone_elevation/zone_elevation.cpp +++ b/nel/tools/3d/zone_elevation/zone_elevation.cpp @@ -53,6 +53,8 @@ NLMISC::CBitmap *s_HeightMap; float s_ZFactor2 = 1.0f; NLMISC::CBitmap *s_HeightMap2; +bool s_ExtendCoords; + std::string s_InputZone; // UTF-8 std::string s_OutputZone; // UTF-8 @@ -121,13 +123,18 @@ float getHeight(float x, float y) sint32 sizeX = s_ZoneMaxX - s_ZoneMinX + 1; sint32 sizeY = s_ZoneMaxY - s_ZoneMinY + 1; - clamp(x, s_CellSize * s_ZoneMinX, s_CellSize * (s_ZoneMaxX + 1)); - clamp(y, s_CellSize * s_ZoneMinY, s_CellSize * (s_ZoneMaxY + 1)); - if (s_HeightMap != NULL) { float xc = (x - s_CellSize * s_ZoneMinX) / (s_CellSize * sizeX); float yc = 1.0f - ((y - s_CellSize * s_ZoneMinY) / (s_CellSize * sizeY)); + if (s_ExtendCoords) + { + uint32 w = s_HeightMap->getWidth(), h = s_HeightMap->getHeight(); + xc -= .5f / (float)w; + yc -= .5f / (float)h; + xc = xc * (float)(w + 1) / (float)w; + yc = yc * (float)(h + 1) / (float)h; + } color = s_HeightMap->getColor(xc, yc); color *= 255; deltaZ = color.A; @@ -139,6 +146,14 @@ float getHeight(float x, float y) { float xc = (x - s_CellSize * s_ZoneMinX) / (s_CellSize * sizeX); float yc = 1.0f - ((y - s_CellSize * s_ZoneMinY) / (s_CellSize * sizeY)); + if (s_ExtendCoords) + { + uint32 w = s_HeightMap2->getWidth(), h = s_HeightMap2->getHeight(); + xc -= .5f / (float)w; + yc -= .5f / (float)h; + xc = xc * (float)(w + 1) / (float)w; + yc = yc * (float)(h + 1) / (float)h; + } color = s_HeightMap2->getColor(xc, yc); color *= 255; deltaZ2 = color.A; @@ -475,6 +490,7 @@ int main(int argc, char **argv) args.addArg("", "heightmap", "bitmap", "Heightmap"); args.addArg("", "zfactor2", "factor", "Factor for second heightmap"); args.addArg("", "heightmap2", "bitmap", "Second heightmap"); + args.addArg("", "extendcoords", "flag", "Extend coordinates to edge of bitmap pixels"); // TODO: args.addArg("", "batch", "", "Process all zones in input (specify input as C:/folder/.zonenhw)"); if (!args.parse(argc, argv)) @@ -578,6 +594,8 @@ int main(int argc, char **argv) goto Fail; } + s_ExtendCoords = args.haveLongArg("extendcoords"); + if (args.haveLongArg("cellsize")) { if (!NLMISC::fromString(args.getLongArg("cellsize")[0], s_CellSize)) diff --git a/nel/tools/build_gamedata/processes/ig/2_build.py b/nel/tools/build_gamedata/processes/ig/2_build.py index c2ab57059..2d461de99 100755 --- a/nel/tools/build_gamedata/processes/ig/2_build.py +++ b/nel/tools/build_gamedata/processes/ig/2_build.py @@ -94,6 +94,7 @@ def igElevation(inputIgDir, outputIgDir): cf.write("ZFactor1 = " + LigoExportZFactor1 + ";\n") cf.write("HeightMapFile2 = \"" + DatabaseDirectory + "/" + LigoBaseSourceDirectory + "/" + LigoExportHeightmap2 + "\";\n") cf.write("ZFactor2 = " + LigoExportZFactor2 + ";\n") + cf.write("ExtendCoords = " + str(LigoExportExtendCoords) + ";\n") cf.write("\n") cf.write("LandFile = \"" + DatabaseDirectory + "/" + LigoBaseSourceDirectory + "/" + LigoExportLand + "\";\n") cf.write("\n") diff --git a/nel/tools/build_gamedata/processes/ligo/0_setup.py b/nel/tools/build_gamedata/processes/ligo/0_setup.py index 32a74bf63..79fb2a43b 100755 --- a/nel/tools/build_gamedata/processes/ligo/0_setup.py +++ b/nel/tools/build_gamedata/processes/ligo/0_setup.py @@ -96,6 +96,7 @@ if LigoExportLand != "": cf.write("ZFactor1 = " + LigoExportZFactor1 + ";\n") cf.write("HeightMapFile2 = \"" + DatabaseDirectory + "/" + LigoBaseSourceDirectory + "/" + LigoExportHeightmap2 + "\";\n") cf.write("ZFactor2 = " + LigoExportZFactor2 + ";\n") + cf.write("ExtendCoords = " + str(LigoExportExtendCoords) + ";\n") cf.write("\n") cf.write("ZoneLight = 0;\n") cf.write("CellSize = 160;\n") diff --git a/nel/tools/build_gamedata/processes/zone/2_build.py b/nel/tools/build_gamedata/processes/zone/2_build.py index 6dca1c0d5..1e018031a 100755 --- a/nel/tools/build_gamedata/processes/zone/2_build.py +++ b/nel/tools/build_gamedata/processes/zone/2_build.py @@ -147,7 +147,10 @@ else: sourceFile = ExportBuildDirectory + "/" + ZoneWeldBuildDirectory + "/" + file destFile = ExportBuildDirectory + "/" + ZoneWeldBuildDirectory + "/" + os.path.basename(file)[0:-len(".zonenhw")] + ".zone" if needUpdateLogRemoveDest(log, sourceFile, destFile): - callParallelProcess([ ZoneElevation, sourceFile, destFile, "--land", land, "--heightmap", heightMap1, "--zfactor", LigoExportZFactor1, "--heightmap2", heightMap2, "--zfactor2", LigoExportZFactor2 ]) + command = [ ZoneElevation, sourceFile, destFile, "--land", land, "--heightmap", heightMap1, "--zfactor", LigoExportZFactor1, "--heightmap2", heightMap2, "--zfactor2", LigoExportZFactor2 ] + if LigoExportExtendCoords != 0: + command.append("--extendcoords") + callParallelProcess(command) flushParallelProcesses() printLog(log, "") diff --git a/ryzom/tools/leveldesign/world_editor/land_export/main.cpp b/ryzom/tools/leveldesign/world_editor/land_export/main.cpp index 205002417..78ab057c1 100644 --- a/ryzom/tools/leveldesign/world_editor/land_export/main.cpp +++ b/ryzom/tools/leveldesign/world_editor/land_export/main.cpp @@ -176,6 +176,7 @@ struct SOptions : public SExportOptions this->ZFactor = getFloat ("ZFactor1"); this->HeightMapFile2 = getStr ("HeightMapFile2"); this->ZFactor2 = getFloat ("ZFactor2"); + this->ExtendCoords = getFloat ("ExtendCoords"); this->Light = (uint8)getInt ("ZoneLight"); this->CellSize = getFloat ("CellSize"); this->Threshold = getFloat ("Threshold"); diff --git a/ryzom/tools/leveldesign/world_editor/land_export_lib/export.cpp b/ryzom/tools/leveldesign/world_editor/land_export_lib/export.cpp index 319925584..d49a64b0f 100644 --- a/ryzom/tools/leveldesign/world_editor/land_export_lib/export.cpp +++ b/ryzom/tools/leveldesign/world_editor/land_export_lib/export.cpp @@ -2171,13 +2171,19 @@ float CExport::getHeight (float x, float y) sint32 SizeX = _ZoneMaxX - _ZoneMinX + 1; sint32 SizeY = _ZoneMaxY - _ZoneMinY + 1; - clamp (x, _Options->CellSize*_ZoneMinX, _Options->CellSize*(_ZoneMaxX+1)); - clamp (y, _Options->CellSize*_ZoneMinY, _Options->CellSize*(_ZoneMaxY+1)); - if (_HeightMap != NULL) { - color = _HeightMap->getColor ( (x-_Options->CellSize*_ZoneMinX)/(_Options->CellSize*SizeX), - 1.0f - ((y-_Options->CellSize*_ZoneMinY)/(_Options->CellSize*SizeY))); + float xc = (x - _Options->CellSize * _ZoneMinX) / (_Options->CellSize * SizeX); + float yc = 1.0f - ((y - _Options->CellSize * _ZoneMinY) / (_Options->CellSize * SizeY)); + if (_Options->ExtendCoords) + { + uint32 w = _HeightMap->getWidth(), h = _HeightMap->getHeight(); + xc -= .5f / (float)w; + yc -= .5f / (float)h; + xc = xc * (float)(w + 1) / (float)w; + yc = yc * (float)(h + 1) / (float)h; + } + color = _HeightMap->getColor(xc, yc); color *= 255; deltaZ = color.A; deltaZ = deltaZ - 127.0f; // Median intensity is 127 @@ -2186,8 +2192,17 @@ float CExport::getHeight (float x, float y) if (_HeightMap2 != NULL) { - color = _HeightMap2->getColor ( (x-_Options->CellSize*_ZoneMinX)/(_Options->CellSize*SizeX), - 1.0f - ((y-_Options->CellSize*_ZoneMinY)/(_Options->CellSize*SizeY))); + float xc = (x - _Options->CellSize * _ZoneMinX) / (_Options->CellSize * SizeX); + float yc = 1.0f - ((y - _Options->CellSize * _ZoneMinY) / (_Options->CellSize * SizeY)); + if (_Options->ExtendCoords) + { + uint32 w = _HeightMap2->getWidth(), h = _HeightMap2->getHeight(); + xc -= .5f / (float)w; + yc -= .5f / (float)h; + xc = xc * (float)(w + 1) / (float)w; + yc = yc * (float)(h + 1) / (float)h; + } + color = _HeightMap2->getColor(xc, yc); color *= 255; deltaZ2 = color.A; deltaZ2 = deltaZ2 - 127.0f; // Median intensity is 127 diff --git a/ryzom/tools/leveldesign/world_editor/land_export_lib/export.h b/ryzom/tools/leveldesign/world_editor/land_export_lib/export.h index a8a6b93cb..46ec0f4b7 100644 --- a/ryzom/tools/leveldesign/world_editor/land_export_lib/export.h +++ b/ryzom/tools/leveldesign/world_editor/land_export_lib/export.h @@ -101,6 +101,7 @@ struct SExportOptions float ZFactor; std::string HeightMapFile2; float ZFactor2; + bool ExtendCoords; uint8 Light; // Roughly light the zone (0-none, 1-patch, 2-noise)