diff --git a/code/nel/tools/3d/CMakeLists.txt b/code/nel/tools/3d/CMakeLists.txt index 0b6f6540d..e6ba62e3b 100644 --- a/code/nel/tools/3d/CMakeLists.txt +++ b/code/nel/tools/3d/CMakeLists.txt @@ -32,6 +32,7 @@ IF(WITH_NEL_TOOLS) zone_ig_lighter zone_lighter zone_welder + zone_elevation shapes_exporter shape2obj zone_check_bind diff --git a/code/nel/tools/3d/ig_elevation/CMakeLists.txt b/code/nel/tools/3d/ig_elevation/CMakeLists.txt index 9c3e0fe26..6f330bc2e 100644 --- a/code/nel/tools/3d/ig_elevation/CMakeLists.txt +++ b/code/nel/tools/3d/ig_elevation/CMakeLists.txt @@ -5,7 +5,7 @@ SOURCE_GROUP("" FILES ${SRC}) ADD_EXECUTABLE(ig_elevation ${SRC}) TARGET_LINK_LIBRARIES(ig_elevation nelmisc nel3d nelligo) -NL_DEFAULT_PROPS(ig_elevation "NeL, Tools, 3D: ig_elevation") +NL_DEFAULT_PROPS(ig_elevation "NeL, Tools, 3D: IG Elevation") NL_ADD_RUNTIME_FLAGS(ig_elevation) INSTALL(TARGETS ig_elevation RUNTIME DESTINATION ${NL_BIN_PREFIX} COMPONENT tools3d) diff --git a/code/nel/tools/3d/ig_elevation/main.cpp b/code/nel/tools/3d/ig_elevation/main.cpp index a3f7dba5f..122957eb0 100644 --- a/code/nel/tools/3d/ig_elevation/main.cpp +++ b/code/nel/tools/3d/ig_elevation/main.cpp @@ -259,13 +259,13 @@ int main(int nNbArg, char**ppArgs) printf ("ZFactor2 = 0.5;\n"); printf ("LandFile = \"w:/matis.land\";\n"); - return -1; + return EXIT_FAILURE; } SExportOptions options; if (!options.load(ppArgs[1])) { - return -1; + return EXIT_FAILURE; } // Get all ig files in the input directory and elevate to the z of the double heightmap @@ -358,7 +358,7 @@ int main(int nNbArg, char**ppArgs) for (uint32 i = 0; i < vAllFiles.size(); ++i) { - CInstanceGroup *pIG = LoadInstanceGroup (CPath::standardizePath(options.InputIGDir) + vAllFiles[i]); + CInstanceGroup *pIG = LoadInstanceGroup (vAllFiles[i]); if (pIG != NULL) { @@ -430,11 +430,13 @@ int main(int nNbArg, char**ppArgs) pIGout->build (vGlobalPos, IA, Clusters, Portals, PLN); pIGout->enableRealTimeSunContribution(realTimeSunContribution); - SaveInstanceGroup (CPath::standardizePath(options.OutputIGDir) + vAllFiles[i], pIGout); + std::string outFilePath = CPath::standardizePath(options.OutputIGDir, true) + CFile::getFilename(vAllFiles[i]); + nldebug("Writing %s...", outFilePath.c_str()); + SaveInstanceGroup(outFilePath, pIGout); delete pIG; } } - return 1; + return EXIT_SUCCESS; } diff --git a/code/nel/tools/3d/zone_elevation/CMakeLists.txt b/code/nel/tools/3d/zone_elevation/CMakeLists.txt new file mode 100644 index 000000000..20d715e13 --- /dev/null +++ b/code/nel/tools/3d/zone_elevation/CMakeLists.txt @@ -0,0 +1,11 @@ +FILE(GLOB SRC *.cpp *.h *.rc) + +SOURCE_GROUP("" FILES ${SRC}) + +ADD_EXECUTABLE(zone_elevation ${SRC}) + +TARGET_LINK_LIBRARIES(zone_elevation nel3d nelmisc nelligo) +NL_DEFAULT_PROPS(zone_elevation "NeL, Tools, 3D: Zone Elevation") +NL_ADD_RUNTIME_FLAGS(zone_elevation) + +INSTALL(TARGETS zone_elevation RUNTIME DESTINATION ${NL_BIN_PREFIX} COMPONENT tools3d) diff --git a/code/nel/tools/3d/zone_elevation/blue_pill.ico b/code/nel/tools/3d/zone_elevation/blue_pill.ico new file mode 100644 index 000000000..269907ec3 Binary files /dev/null and b/code/nel/tools/3d/zone_elevation/blue_pill.ico differ diff --git a/code/nel/tools/3d/zone_elevation/main.rc b/code/nel/tools/3d/zone_elevation/main.rc new file mode 100644 index 000000000..05cf7c976 --- /dev/null +++ b/code/nel/tools/3d/zone_elevation/main.rc @@ -0,0 +1,42 @@ +#include +#include "config.h" + +IDI_MAIN_ICON ICON DISCARDABLE "blue_pill.ico" + +#ifdef _DEBUG +#define NL_FILEEXT "_d" +#else +#define NL_FILEEXT "" +#endif + +VS_VERSION_INFO VERSIONINFO + FILEVERSION NL_VERSION_RC + PRODUCTVERSION NL_VERSION_RC + FILEFLAGSMASK VS_FFI_FILEFLAGSMASK +#ifdef _DEBUG + FILEFLAGS VS_FF_DEBUG +#else + FILEFLAGS 0x0L +#endif + FILEOS VOS_NT_WINDOWS32 + FILETYPE VFT_APP + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "CompanyName", AUTHOR + VALUE "FileDescription", "NeL Zone Heightmap" + VALUE "FileVersion", NL_VERSION + VALUE "LegalCopyright", COPYRIGHT + VALUE "OriginalFilename", "zone_heightmap" NL_FILEEXT ".exe" + VALUE "ProductName", "NeL Tools" + VALUE "ProductVersion", NL_PRODUCT_VERSION + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x9, 1200 + END +END diff --git a/code/nel/tools/3d/zone_elevation/zone_elevation.cpp b/code/nel/tools/3d/zone_elevation/zone_elevation.cpp new file mode 100644 index 000000000..3287a68ea --- /dev/null +++ b/code/nel/tools/3d/zone_elevation/zone_elevation.cpp @@ -0,0 +1,396 @@ +// NeL - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#include "../zone_lib/zone_utility.h" + +#include +#include +#include +#include +#include +#include +#include +//#include +#include +//#include +//#include +//#include +//#include +#include +#include +#include + +using namespace NL3D; +using namespace NLMISC; +using namespace NLLIGO; +using namespace std; + +namespace /* anonymous */ +{ + +sint32 s_ZoneMinX, s_ZoneMinY, s_ZoneMaxX, s_ZoneMaxY; +float s_CellSize = 160.0f; + +float s_ZFactor = 1.0f; +NLMISC::CBitmap *s_HeightMap; + +float s_ZFactor2 = 1.0f; +NLMISC::CBitmap *s_HeightMap2; + +std::string s_InputZone; // UTF-8 +std::string s_OutputZone; // UTF-8 + +CZoneRegion s_Land; + +bool loadLand(const string &filename) +{ + try + { + CIFile fileIn; + if (fileIn.open (filename)) + { + CIXml xml(true); + nlverify(xml.init(fileIn)); + s_Land.serial(xml); + } + else + { + nlwarning("Can't open the land file: %s", filename.c_str()); + return false; + } + } + catch (const Exception& e) + { + nlwarning("Error in land file: %s", e.what()); + return true; + } + return true; +} + +bool getXYFromZoneName(sint32 &x, sint32 &y, const string &zoneName) +{ + string xStr, yStr; + uint32 i = 0; + while (zoneName[i] != '_') + { + yStr += zoneName[i]; + ++i; + if (i == zoneName.size()) + goto Fail; + } + if (!NLMISC::fromString(yStr, y)) + goto Fail; + y = -y; + ++i; + while (i < zoneName.size()) + { + xStr += zoneName[i]; + ++i; + } + if (xStr.size() != 2) + goto Fail; + xStr = NLMISC::toUpper(xStr); + x = ((xStr[0] - 'A') * 26 + (xStr[1] - 'A')); + return true; +Fail: + x = -1; + y = -1; + return false; +} + +float getHeight(float x, float y) +{ + float deltaZ = 0.0f, deltaZ2 = 0.0f; + CRGBAF color; + 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)); + color = s_HeightMap->getColor(xc, yc); + color *= 255; + deltaZ = color.A; + deltaZ = deltaZ - 127.0f; // Median intensity is 127 + deltaZ *= s_ZFactor; + } + + if (s_HeightMap2 != NULL) + { + float xc = (x - s_CellSize * s_ZoneMinX) / (s_CellSize * sizeX); + float yc = 1.0f - ((y - s_CellSize * s_ZoneMinY) / (s_CellSize * sizeY)); + color = s_HeightMap2->getColor(xc, yc); + color *= 255; + deltaZ2 = color.A; + deltaZ2 = deltaZ2 - 127.0f; // Median intensity is 127 + deltaZ2 *= s_ZFactor2; + } + + return (deltaZ + deltaZ2); +} + +NLMISC::CVector getHeightNormal(float x, float y) +{ + sint32 SizeX = s_ZoneMaxX - s_ZoneMinX + 1; + sint32 SizeY = s_ZoneMaxY - s_ZoneMinY + 1; + sint32 bmpW, bmpH; + + // get width/height of the bitmap + if (s_HeightMap != NULL) + { + bmpW = s_HeightMap->getWidth(); + bmpH = s_HeightMap->getHeight(); + } + else if (s_HeightMap2 != NULL) + { + bmpW = s_HeightMap2->getWidth(); + bmpH = s_HeightMap2->getHeight(); + } + else + { + // no heightmap: unmodified normal + return CVector::K; + } + + // compute a good delta to compute tangents of the heightmap: 1/10 of a pixel, avoiding precision problem. + float dx = ((s_CellSize * SizeX) / bmpW) / 10; // eg: 160m/20pixels/10= 0.8 + float dy = ((s_CellSize * SizeY) / bmpH) / 10; + + // compute tangent around the position. + float hc = getHeight(x, y); + float hx = getHeight(x + dx, y); + float hy = getHeight(x, y + dy); + CVector ds(dx, 0, hx - hc); + CVector dt(0, dy, hy - hc); + + // compute the heightmap normal with the tangents + return (ds ^ dt).normed(); +} + +void applyZoneHeightmap() +{ + // Load zone + CIFile zoneFile(s_InputZone); + CZone zone; + zone.serial(zoneFile); + zoneFile.close(); + + // Retrieve patches and vertices + uint16 zoneId = zone.getZoneId(); + std::vector zonePatches; + std::vector zoneBorderVertices; + zone.retrieve(zonePatches, zoneBorderVertices); + + // Apply the Heighmap to all vertices/tangents/interiors (see Land Export tool.) + for (size_t i = 0; i < zonePatches.size(); ++i) + { + CPatchInfo &rPI = zonePatches[i]; + + // Elevate the vertices. + CVector verticesBeforeHeightMap[4]; + for (size_t j = 0; j < 4; ++j) + { + verticesBeforeHeightMap[j] = rPI.Patch.Vertices[j]; + float height = getHeight(rPI.Patch.Vertices[j].x, rPI.Patch.Vertices[j].y); + rPI.Patch.Vertices[j].z += height; + } + + // Interior and tangent are rotated to follow the heightmap normal, avoiding the "Stair Effect". + // Compute the matrix to apply to interiors and tangents. + CMatrix tgMatrix[4]; + for (size_t j = 0; j < 4; ++j) + { + // compute the normal of the heightmap. + CVector hmapNormal = getHeightNormal(rPI.Patch.Vertices[j].x, rPI.Patch.Vertices[j].y); + + // Compute the rotation which transforms the original normal: (0,0,1), to this normal. + CAngleAxis angleAxis; + angleAxis.Axis = CVector::K ^ hmapNormal; + angleAxis.Angle = (float)asin(angleAxis.Axis.norm()); + angleAxis.Axis.normalize(); + + // build the matrix which transform the old tgt/interior to his newValue: + // newVertexPos + rotate * (oldTgPos - oldVertexPos) + tgMatrix[j].identity(); + tgMatrix[j].translate(rPI.Patch.Vertices[j]); + tgMatrix[j].setRot(CQuat(angleAxis)); + tgMatrix[j].translate(-verticesBeforeHeightMap[j]); + } + + // For all interior. + for (size_t j = 0; j < 4; ++j) + rPI.Patch.Interiors[j] = tgMatrix[j] * rPI.Patch.Interiors[j]; + + // when j == 7 or 0 use vertex 0 for delta Z to ensure continuity of normals + // when j == 1 or 2 use vertex 1 + // when j == 3 or 4 use vertex 2 + // when j == 5 or 6 use vertex 3 + for (size_t j = 0; j < 8; ++j) + { + // get the correct vertex + uint vertexId = ((j + 1) / 2) % 4; + // apply the tgMatrix to the tangent + rPI.Patch.Tangents[j] = tgMatrix[vertexId] * rPI.Patch.Tangents[j]; + } + } + + // Save zone + zone.build(zoneId, zonePatches, zoneBorderVertices); + COFile centerSave(s_OutputZone); + nldebug("Writing file %s", s_OutputZone.c_str()); + zone.serial(centerSave); +} + +} /* anonymous namespace */ + +int main(int argc, char **argv) +{ + NLMISC::CApplicationContext myApplicationContext; + + NLMISC::CCmdArgs args; + + args.addAdditionalArg("zonenhw", "Input zone"); // .zonenhw + args.addAdditionalArg("zonew", "Output zone"); // .zonew + args.addArg("", "land", "land", "Ligo land file (either specify this or the boundaries)"); + args.addArg("", "zonemin", "zone", "Zone boundary"); + args.addArg("", "zonemax", "zone", "Zone boundary"); + args.addArg("", "cellsize", "meters", "Zone cell size"); + args.addArg("", "zfactor", "factor", "Factor for heightmap"); + args.addArg("", "heightmap", "bitmap", "Heightmap"); + args.addArg("", "zfactor2", "factor", "Factor for second heightmap"); + args.addArg("", "heightmap2", "bitmap", "Second heightmap"); + // TODO: args.addArg("", "batch", "", "Process all zones in input (specify input as C:/folder/.zonenhw)"); + + if (!args.parse(argc, argv)) + { + return EXIT_FAILURE; + } + + s_InputZone = args.getAdditionalArg("zonenhw")[0]; + s_OutputZone = args.getAdditionalArg("zonew")[0]; + + if (args.haveLongArg("zonemin") && args.haveLongArg("zonemax")) + { + sint32 zoneMinX, zoneMinY; + sint32 zoneMaxX, zoneMaxY; + if (!getXYFromZoneName(zoneMinX, zoneMinY, args.getLongArg("zonemin")[0]) + || !getXYFromZoneName(zoneMaxX, zoneMaxY, args.getLongArg("zonemax")[0])) + { + goto Fail; + } + s_ZoneMinX = min(zoneMinX, zoneMaxX); + s_ZoneMaxX = max(zoneMinX, zoneMaxX); + s_ZoneMinY = min(zoneMinY, zoneMaxY); + s_ZoneMaxY = max(zoneMinY, zoneMaxY); + } + else if (args.haveLongArg("land")) + { + if (!loadLand(args.getLongArg("land")[0])) + goto Fail; + s_ZoneMinX = s_Land.getMinX(); + s_ZoneMaxX = s_Land.getMaxX(); + s_ZoneMinY = s_Land.getMinY(); + s_ZoneMaxY = s_Land.getMaxY(); + } + else + { + nlwarning("Must have either both 'zonemin' and 'zonemax', or 'land' specified"); + goto Fail; + } + + if (args.haveLongArg("heightmap")) + { + nldebug("Loading height map"); + s_HeightMap = new CBitmap(); + try + { + CIFile inFile; + if (inFile.open(args.getLongArg("heightmap")[0])) + { + s_HeightMap->load(inFile); + } + else + { + nldebug("Cant load height map: %s", args.getLongArg("heightmap")[0].c_str()); + delete s_HeightMap; + s_HeightMap = NULL; + } + } + catch (const Exception &) + { + nldebug("Cant load height map: %s", args.getLongArg("heightmap")[0].c_str()); + delete s_HeightMap; + s_HeightMap = NULL; + } + } + + if (args.haveLongArg("heightmap2")) + { + nldebug("Loading height map"); + s_HeightMap2 = new CBitmap(); + try + { + CIFile inFile; + if (inFile.open(args.getLongArg("heightmap2")[0])) + { + s_HeightMap2->load(inFile); + } + else + { + nldebug("Cant load height map: %s", args.getLongArg("heightmap2")[0].c_str()); + delete s_HeightMap2; + s_HeightMap2 = NULL; + } + } + catch (const Exception &) + { + nldebug("Cant load height map: %s", args.getLongArg("heightmap2")[0].c_str()); + delete s_HeightMap2; + s_HeightMap2 = NULL; + } + } + + if (args.haveLongArg("zfactor")) + { + if (!NLMISC::fromString(args.getLongArg("zfactor")[0], s_ZFactor)) + goto Fail; + } + + if (args.haveLongArg("zfactor2")) + { + if (!NLMISC::fromString(args.getLongArg("zfactor2")[0], s_ZFactor2)) + goto Fail; + } + + if (args.haveLongArg("cellsize")) + { + if (!NLMISC::fromString(args.getLongArg("cellsize")[0], s_CellSize)) + goto Fail; + } + + applyZoneHeightmap(); + + return EXIT_SUCCESS; +Fail: + args.displayHelp(); + delete s_HeightMap; + delete s_HeightMap2; + return EXIT_FAILURE; +} diff --git a/code/nel/tools/build_gamedata/0_setup.py b/code/nel/tools/build_gamedata/0_setup.py index 69d825fed..00d19cbe6 100755 --- a/code/nel/tools/build_gamedata/0_setup.py +++ b/code/nel/tools/build_gamedata/0_setup.py @@ -434,6 +434,7 @@ if not args.noverify: findTool(log, ToolDirectories, BuildFarbankTool, ToolSuffix) findTool(log, ToolDirectories, ZoneDependenciesTool, ToolSuffix) findTool(log, ToolDirectories, ZoneWelderTool, ToolSuffix) + findTool(log, ToolDirectories, ZoneElevationTool, ToolSuffix) findTool(log, ToolDirectories, BuildRbankTool, ToolSuffix) findTool(log, ToolDirectories, BuildIndoorRbankTool, ToolSuffix) findTool(log, ToolDirectories, BuildIgBoxesTool, ToolSuffix) diff --git a/code/nel/tools/build_gamedata/configuration/tools.py b/code/nel/tools/build_gamedata/configuration/tools.py index b9a74820c..ebb1d07da 100755 --- a/code/nel/tools/build_gamedata/configuration/tools.py +++ b/code/nel/tools/build_gamedata/configuration/tools.py @@ -60,6 +60,7 @@ BuildSmallbankTool = "build_smallbank" BuildFarbankTool = "build_far_bank" ZoneDependenciesTool = "zone_dependencies" ZoneWelderTool = "zone_welder" +ZoneElevationTool = "zone_elevation" BuildRbankTool = "build_rbank" BuildIndoorRbankTool = "build_indoor_rbank" BuildIgBoxesTool = "build_ig_boxes" diff --git a/code/nel/tools/build_gamedata/processes/ig/2_build.py b/code/nel/tools/build_gamedata/processes/ig/2_build.py index afb84c312..c2ab57059 100755 --- a/code/nel/tools/build_gamedata/processes/ig/2_build.py +++ b/code/nel/tools/build_gamedata/processes/ig/2_build.py @@ -54,6 +54,8 @@ mkPath(log, configDir) def igElevation(inputIgDir, outputIgDir): printLog(log, ">>> IG Elevation <<<") + mkPath(log, inputIgDir) + mkPath(log, outputIgDir) needUpdateIg = needUpdateDirByTagLog(log, inputIgDir, ".ig", outputIgDir, ".ig") if needUpdateIg: printLog(log, "DETECT UPDATE IG->Elevated") @@ -100,7 +102,7 @@ def igElevation(inputIgDir, outputIgDir): os.remove(configFile) # Copy remaining IG files - copyFilesLogless(log, inputIgDir, outputIgDir) + #BUG:copyFilesLogless(log, inputIgDir, outputIgDir) else: printLog(log, "DETECT DECIDE SKIP") printLog(log, "SKIP *") diff --git a/code/nel/tools/build_gamedata/processes/zone/2_build.py b/code/nel/tools/build_gamedata/processes/zone/2_build.py index ad2f052fd..f9a31e3c4 100755 --- a/code/nel/tools/build_gamedata/processes/zone/2_build.py +++ b/code/nel/tools/build_gamedata/processes/zone/2_build.py @@ -46,6 +46,7 @@ printLog(log, "") # Find tools ZoneDependencies = findTool(log, ToolDirectories, ZoneDependenciesTool, ToolSuffix) ZoneWelder = findTool(log, ToolDirectories, ZoneWelderTool, ToolSuffix) +ZoneElevation = findTool(log, ToolDirectories, ZoneElevationTool, ToolSuffix) ExecTimeout = findTool(log, ToolDirectories, ExecTimeoutTool, ToolSuffix) printLog(log, "") @@ -99,7 +100,24 @@ if BuildQuality == 1: printLog(log, "") # For each zone directory -printLog(log, ">>> Build zone weld <<<") +#printLog(log, ">>> Build zone weld <<<") +#if ZoneWelder == "": +# toolLogFail(log, ZoneWelderTool, ToolSuffix) +#elif ExecTimeout == "": +# toolLogFail(log, ExecTimeoutTool, ToolSuffix) +#else: +# mkPath(log, ExportBuildDirectory + "/" + ZoneExportDirectory) +# mkPath(log, ExportBuildDirectory + "/" + ZoneWeldBuildDirectory) +# files = findFiles(log, ExportBuildDirectory + "/" + ZoneExportDirectory, "", ".zone") +# for file in files: +# sourceFile = ExportBuildDirectory + "/" + ZoneExportDirectory + "/" + file +# destFile = ExportBuildDirectory + "/" + ZoneWeldBuildDirectory + "/" + os.path.basename(file)[0:-len(".zone")] + ".zonew" +# if needUpdateLogRemoveDest(log, sourceFile, destFile): +# subprocess.call([ ExecTimeout, str(ZoneBuildWeldTimeout), ZoneWelder, sourceFile, destFile ]) +#printLog(log, "") + +# For each zone directory +printLog(log, ">>> Weld zone without heightmap <<<") if ZoneWelder == "": toolLogFail(log, ZoneWelderTool, ToolSuffix) elif ExecTimeout == "": @@ -107,29 +125,29 @@ elif ExecTimeout == "": else: mkPath(log, ExportBuildDirectory + "/" + ZoneExportDirectory) mkPath(log, ExportBuildDirectory + "/" + ZoneWeldBuildDirectory) - files = findFiles(log, ExportBuildDirectory + "/" + ZoneExportDirectory, "", ".zone") + files = findFiles(log, ExportBuildDirectory + "/" + ZoneExportDirectory, "", ".zonenh") for file in files: sourceFile = ExportBuildDirectory + "/" + ZoneExportDirectory + "/" + file - destFile = ExportBuildDirectory + "/" + ZoneWeldBuildDirectory + "/" + os.path.basename(file)[0:-len(".zone")] + ".zonew" + destFile = ExportBuildDirectory + "/" + ZoneWeldBuildDirectory + "/" + os.path.basename(file)[0:-len(".zonenh")] + ".zonenhw" if needUpdateLogRemoveDest(log, sourceFile, destFile): subprocess.call([ ExecTimeout, str(ZoneBuildWeldTimeout), ZoneWelder, sourceFile, destFile ]) printLog(log, "") -# For each zone directory -printLog(log, ">>> Build zone weld no heightmap <<<") -if ZoneWelder == "": - toolLogFail(log, ZoneWelderTool, ToolSuffix) -elif ExecTimeout == "": - toolLogFail(log, ExecTimeoutTool, ToolSuffix) +printLog(log, ">>> Apply zone heightmap to welded zone <<<") +if ZoneElevation == "": + toolLogFail(log, ZoneElevationTool, ToolSuffix) else: - mkPath(log, ExportBuildDirectory + "/" + ZoneExportDirectory) mkPath(log, ExportBuildDirectory + "/" + ZoneWeldBuildDirectory) - files = findFiles(log, ExportBuildDirectory + "/" + ZoneExportDirectory, "", ".zonenh") + mkPath(log, DatabaseDirectory + "/" + LigoBaseSourceDirectory); + land = DatabaseDirectory + "/" + LigoBaseSourceDirectory + "/" + LigoExportLand + heightMap1 = DatabaseDirectory + "/" + LigoBaseSourceDirectory + "/" + LigoExportHeightmap1 + heightMap2 = DatabaseDirectory + "/" + LigoBaseSourceDirectory + "/" + LigoExportHeightmap2 + files = findFiles(log, ExportBuildDirectory + "/" + ZoneWeldBuildDirectory, "", ".zonenhw") for file in files: - sourceFile = ExportBuildDirectory + "/" + ZoneExportDirectory + "/" + file - destFile = ExportBuildDirectory + "/" + ZoneWeldBuildDirectory + "/" + os.path.basename(file)[0:-len(".zonenh")] + ".zonenhw" + sourceFile = ExportBuildDirectory + "/" + ZoneWeldBuildDirectory + "/" + file + destFile = ExportBuildDirectory + "/" + ZoneWeldBuildDirectory + "/" + os.path.basename(file)[0:-len(".zonenhw")] + ".zonew" if needUpdateLogRemoveDest(log, sourceFile, destFile): - subprocess.call([ ExecTimeout, str(ZoneBuildWeldTimeout), ZoneWelder, sourceFile, destFile ]) + subprocess.call([ ZoneElevation, sourceFile, destFile, "--land", land, "--heightmap", heightMap1, "--zfactor", LigoExportZFactor1, "--heightmap2", heightMap2, "--zfactor2", LigoExportZFactor2 ]) printLog(log, "") log.close() diff --git a/code/nel/tools/pacs/build_rbank/build_surf.cpp b/code/nel/tools/pacs/build_rbank/build_surf.cpp index 465f5f94f..ba75234d1 100644 --- a/code/nel/tools/pacs/build_rbank/build_surf.cpp +++ b/code/nel/tools/pacs/build_rbank/build_surf.cpp @@ -880,6 +880,7 @@ void NLPACS::CZoneTessellation::checkSameLandscapeHmBinds(const NL3D::CLandscape // or at least the welding of zones should just keep the same welding as the non heightmapped one nlwarning("ERROR: The zone %s has a different bind strucutre in the landscape and in the landscape_with_No_Heightmap", zoneName.c_str()); nlwarning("ERROR: Hint: Check your heightmap: it may be too precise or has too much noise, causing the zonewelder to behav differently..."); + nlwarning("ERROR: Use the 'zone_heightmap' tool to resolve this!"); nlwarning("More Details (information landscape / information landscape_with_No_Heightmap):"); for(uint j=0;j