Apply zone heightmap after weld to fix rbank build failure, ryzomclassic/#58

hg/develop
kaetemi 5 years ago committed by Jan Boon
parent 20c339891d
commit a34541fe95

@ -32,6 +32,7 @@ IF(WITH_NEL_TOOLS)
zone_ig_lighter zone_ig_lighter
zone_lighter zone_lighter
zone_welder zone_welder
zone_elevation
shapes_exporter shapes_exporter
shape2obj shape2obj
zone_check_bind zone_check_bind

@ -5,7 +5,7 @@ SOURCE_GROUP("" FILES ${SRC})
ADD_EXECUTABLE(ig_elevation ${SRC}) ADD_EXECUTABLE(ig_elevation ${SRC})
TARGET_LINK_LIBRARIES(ig_elevation nelmisc nel3d nelligo) 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) NL_ADD_RUNTIME_FLAGS(ig_elevation)
INSTALL(TARGETS ig_elevation RUNTIME DESTINATION ${NL_BIN_PREFIX} COMPONENT tools3d) INSTALL(TARGETS ig_elevation RUNTIME DESTINATION ${NL_BIN_PREFIX} COMPONENT tools3d)

@ -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)

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

@ -0,0 +1,42 @@
#include <windows.h>
#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

@ -0,0 +1,396 @@
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
// 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 <http://www.gnu.org/licenses/>.
#include "../zone_lib/zone_utility.h"
#include <iostream>
#include <nel/misc/types_nl.h>
#include <nel/misc/file.h>
#include <nel/misc/i_xml.h>
#include <nel/misc/common.h>
#include <nel/misc/cmd_args.h>
#include <nel/misc/bitmap.h>
//#include <nel/3d/quad_tree.h>
#include <nel/3d/zone.h>
//#include <nel/3d/landscape.h>
//#include <nel/3d/zone_smoother.h>
//#include <nel/3d/zone_tgt_smoother.h>
//#include <nel/3d/zone_corner_smoother.h>
#include <nel/ligo/zone_region.h>
#include <vector>
#include <set>
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<CPatchInfo> zonePatches;
std::vector<CBorderVertex> 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;
}

@ -434,6 +434,7 @@ if not args.noverify:
findTool(log, ToolDirectories, BuildFarbankTool, ToolSuffix) findTool(log, ToolDirectories, BuildFarbankTool, ToolSuffix)
findTool(log, ToolDirectories, ZoneDependenciesTool, ToolSuffix) findTool(log, ToolDirectories, ZoneDependenciesTool, ToolSuffix)
findTool(log, ToolDirectories, ZoneWelderTool, ToolSuffix) findTool(log, ToolDirectories, ZoneWelderTool, ToolSuffix)
findTool(log, ToolDirectories, ZoneElevationTool, ToolSuffix)
findTool(log, ToolDirectories, BuildRbankTool, ToolSuffix) findTool(log, ToolDirectories, BuildRbankTool, ToolSuffix)
findTool(log, ToolDirectories, BuildIndoorRbankTool, ToolSuffix) findTool(log, ToolDirectories, BuildIndoorRbankTool, ToolSuffix)
findTool(log, ToolDirectories, BuildIgBoxesTool, ToolSuffix) findTool(log, ToolDirectories, BuildIgBoxesTool, ToolSuffix)

@ -60,6 +60,7 @@ BuildSmallbankTool = "build_smallbank"
BuildFarbankTool = "build_far_bank" BuildFarbankTool = "build_far_bank"
ZoneDependenciesTool = "zone_dependencies" ZoneDependenciesTool = "zone_dependencies"
ZoneWelderTool = "zone_welder" ZoneWelderTool = "zone_welder"
ZoneElevationTool = "zone_elevation"
BuildRbankTool = "build_rbank" BuildRbankTool = "build_rbank"
BuildIndoorRbankTool = "build_indoor_rbank" BuildIndoorRbankTool = "build_indoor_rbank"
BuildIgBoxesTool = "build_ig_boxes" BuildIgBoxesTool = "build_ig_boxes"

@ -46,6 +46,7 @@ printLog(log, "")
# Find tools # Find tools
ZoneDependencies = findTool(log, ToolDirectories, ZoneDependenciesTool, ToolSuffix) ZoneDependencies = findTool(log, ToolDirectories, ZoneDependenciesTool, ToolSuffix)
ZoneWelder = findTool(log, ToolDirectories, ZoneWelderTool, ToolSuffix) ZoneWelder = findTool(log, ToolDirectories, ZoneWelderTool, ToolSuffix)
ZoneElevation = findTool(log, ToolDirectories, ZoneElevationTool, ToolSuffix)
ExecTimeout = findTool(log, ToolDirectories, ExecTimeoutTool, ToolSuffix) ExecTimeout = findTool(log, ToolDirectories, ExecTimeoutTool, ToolSuffix)
printLog(log, "") printLog(log, "")
@ -99,7 +100,24 @@ if BuildQuality == 1:
printLog(log, "") printLog(log, "")
# For each zone directory # 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 == "": if ZoneWelder == "":
toolLogFail(log, ZoneWelderTool, ToolSuffix) toolLogFail(log, ZoneWelderTool, ToolSuffix)
elif ExecTimeout == "": elif ExecTimeout == "":
@ -107,29 +125,29 @@ elif ExecTimeout == "":
else: else:
mkPath(log, ExportBuildDirectory + "/" + ZoneExportDirectory) mkPath(log, ExportBuildDirectory + "/" + ZoneExportDirectory)
mkPath(log, ExportBuildDirectory + "/" + ZoneWeldBuildDirectory) mkPath(log, ExportBuildDirectory + "/" + ZoneWeldBuildDirectory)
files = findFiles(log, ExportBuildDirectory + "/" + ZoneExportDirectory, "", ".zone") files = findFiles(log, ExportBuildDirectory + "/" + ZoneExportDirectory, "", ".zonenh")
for file in files: for file in files:
sourceFile = ExportBuildDirectory + "/" + ZoneExportDirectory + "/" + file 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): if needUpdateLogRemoveDest(log, sourceFile, destFile):
subprocess.call([ ExecTimeout, str(ZoneBuildWeldTimeout), ZoneWelder, sourceFile, destFile ]) subprocess.call([ ExecTimeout, str(ZoneBuildWeldTimeout), ZoneWelder, sourceFile, destFile ])
printLog(log, "") printLog(log, "")
# For each zone directory printLog(log, ">>> Apply zone heightmap to welded zone <<<")
printLog(log, ">>> Build zone weld no heightmap <<<") if ZoneElevation == "":
if ZoneWelder == "": toolLogFail(log, ZoneElevationTool, ToolSuffix)
toolLogFail(log, ZoneWelderTool, ToolSuffix)
elif ExecTimeout == "":
toolLogFail(log, ExecTimeoutTool, ToolSuffix)
else: else:
mkPath(log, ExportBuildDirectory + "/" + ZoneExportDirectory)
mkPath(log, ExportBuildDirectory + "/" + ZoneWeldBuildDirectory) 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: for file in files:
sourceFile = ExportBuildDirectory + "/" + ZoneExportDirectory + "/" + file sourceFile = ExportBuildDirectory + "/" + ZoneWeldBuildDirectory + "/" + file
destFile = ExportBuildDirectory + "/" + ZoneWeldBuildDirectory + "/" + os.path.basename(file)[0:-len(".zonenh")] + ".zonenhw" destFile = ExportBuildDirectory + "/" + ZoneWeldBuildDirectory + "/" + os.path.basename(file)[0:-len(".zonenhw")] + ".zonew"
if needUpdateLogRemoveDest(log, sourceFile, destFile): 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, "") printLog(log, "")
log.close() log.close()

@ -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 // 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: 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: 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):"); nlwarning("More Details (information landscape / information landscape_with_No_Heightmap):");
for(uint j=0;j<errors.size();j++) for(uint j=0;j<errors.size();j++)
{ {

Loading…
Cancel
Save