Merge branch 'develop' into ryzomclassic-develop

ryzomclassic-develop
Jan Boon 5 years ago
commit 93f6770fe4

@ -58,19 +58,43 @@ public :
*/ */
explicit CSheetId( uint32 sheetRef = 0 ); explicit CSheetId( uint32 sheetRef = 0 );
/**
* Constructor
*/
explicit CSheetId( int sheetRef );
/** /**
* Constructor * Constructor
*/ */
explicit CSheetId( const std::string& sheetName ); explicit CSheetId( const std::string& sheetName );
/**
* Operator=
*/
explicit CSheetId( const char *sheetName );
/** /**
* Constructor, uses defaultType as extension when sheetName * Constructor, uses defaultType as extension when sheetName
* contains no file extension. * contains no file extension.
*/ */
explicit CSheetId( const std::string& sheetName, const std::string &defaultType ); explicit CSheetId( const std::string& sheetName, const std::string &defaultType );
/**
* Constructor, uses defaultType as extension when sheetName
* contains no file extension.
*/
explicit CSheetId( const std::string& sheetName, const char *defaultType );
/**
* Constructor, uses defaultType as extension when sheetName
* contains no file extension.
*/
explicit CSheetId( const char *sheetName, const char *defaultType );
// build from a string and returns true if the build succeed // build from a string and returns true if the build succeed
bool buildSheetId(const std::string& sheetName); bool buildSheetId(const char *sheetName, size_t sheetNameLen);
inline bool buildSheetId(const char *sheetName) { return buildSheetId(sheetName, strlen(sheetName)); }
inline bool buildSheetId(const std::string &sheetName) { return buildSheetId(sheetName.c_str(), sheetName.size()); }
// build from a SubSheetId and a type // build from a SubSheetId and a type
void buildSheetId(uint32 shortId, uint32 type); void buildSheetId(uint32 shortId, uint32 type);
@ -93,17 +117,22 @@ public :
/** /**
* Return the **whole** sheet id (id+type) * Return the **whole** sheet id (id+type)
*/ */
uint32 asInt() const { return _Id.Id; } inline uint32 asInt() const { return _Id.Id; }
/** /**
* Return the sheet type (sub part of the sheetid) * Return the sheet type (sub part of the sheetid)
*/ */
uint32 getSheetType() const { return _Id.IdInfos.Type; } inline uint32 getSheetType() const { return _Id.IdInfos.Type; }
/** /**
* Return the sheet sub id (sub part of the sheetid) * Return the sheet sub id (sub part of the sheetid)
*/ */
uint32 getShortId() const { return _Id.IdInfos.Id; } inline uint32 getShortId() const { return _Id.IdInfos.Id; }
/**
* Operator bool
*/
inline operator bool() const { return _Id.Id; }
/** /**
* Operator= * Operator=
@ -115,11 +144,21 @@ public :
*/ */
CSheetId& operator=( const std::string& sheetName ); CSheetId& operator=( const std::string& sheetName );
/**
* Operator=
*/
CSheetId& operator=( const char *sheetName );
/** /**
* Operator= * Operator=
*/ */
CSheetId& operator=( uint32 sheetRef ); CSheetId& operator=( uint32 sheetRef );
/**
* Operator=
*/
CSheetId& operator=( int sheetRef );
/** /**
* Operator< * Operator<
*/ */
@ -218,9 +257,12 @@ private :
} }
}; };
typedef CStaticMap<uint32, CChar> TSheetIdToNameMap;
typedef CStaticMap<CChar, uint32, CCharComp> TSheetNameToIdMap;
static CChar _AllStrings; static CChar _AllStrings;
static CStaticMap<uint32, CChar> _SheetIdToName; static TSheetIdToNameMap _SheetIdToName;
static CStaticMap<CChar,uint32, CCharComp> _SheetNameToId; static TSheetNameToIdMap _SheetNameToId;
static std::vector<std::string> _FileExtensions; static std::vector<std::string> _FileExtensions;
static bool _Initialised; static bool _Initialised;

@ -275,6 +275,21 @@ inline bool startsWith(const char *str, const char *prefix)
inline bool startsWith(const std::string &str, const char *prefix) { return startsWith(str.c_str(), prefix); } inline bool startsWith(const std::string &str, const char *prefix) { return startsWith(str.c_str(), prefix); }
inline bool startsWith(const std::string &str, const std::string &prefix) { return startsWith(str.c_str(), prefix.c_str()); } inline bool startsWith(const std::string &str, const std::string &prefix) { return startsWith(str.c_str(), prefix.c_str()); }
inline bool endsWith(const char *str, size_t strLen, const char *suffix, size_t suffixLen)
{
if (strLen < suffixLen)
return false;
int minLen = strLen < suffixLen ? strLen : suffixLen;
for (int i = 1; i <= minLen; ++i)
if (str[strLen - i] != suffix[suffixLen - i])
return false;
return true;
}
inline bool endsWith(const char *str, const char *suffix) { return endsWith(str, strlen(str), suffix, strlen(suffix)); }
inline bool endsWith(const std::string &str, const char *suffix) { return endsWith(str.c_str(), str.size(), suffix, strlen(suffix)); }
inline bool endsWith(const std::string &str, const std::string &suffix) { return endsWith(str.c_str(), str.size(), suffix.c_str(), suffix.size()); }
// Convert local codepage to UTF-8 // Convert local codepage to UTF-8
// On Windows, the local codepage is undetermined // On Windows, the local codepage is undetermined
// On Linux, the local codepage is always UTF-8 (no-op) // On Linux, the local codepage is always UTF-8 (no-op)

@ -1,6 +1,9 @@
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/> // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
// Copyright (C) 2010 Winch Gate Property Limited // Copyright (C) 2010 Winch Gate Property Limited
// //
// This source file has been modified by the following contributors:
// Copyright (C) 2019 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
//
// This program is free software: you can redistribute it and/or modify // This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as // it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the // published by the Free Software Foundation, either version 3 of the
@ -65,7 +68,23 @@ class CStringMapper
class CCharComp class CCharComp
{ {
public: public:
bool operator()(std::string *x, std::string *y) const #ifdef NL_CPP14
// https://www.fluentcpp.com/2017/06/09/search-set-another-type-key/
using is_transparent = void;
bool operator()(const std::string *x, const char *y) const
{
return strcmp(x->c_str(), y) < 0;
}
bool operator()(const char *x, const std::string *y) const
{
return strcmp(x, y->c_str()) < 0;
}
#endif
bool operator()(const std::string *x, const std::string *y) const
{ {
return (*x) < (*y); return (*x) < (*y);
} }
@ -73,53 +92,70 @@ class CStringMapper
class CAutoFastMutex class CAutoFastMutex
{ {
CFastMutex *_Mutex; CFastMutex *m_Mutex;
public: public:
CAutoFastMutex(CFastMutex *mtx) : _Mutex(mtx) {_Mutex->enter();} CAutoFastMutex(CFastMutex *mtx)
~CAutoFastMutex() {_Mutex->leave();} : m_Mutex(mtx)
{
m_Mutex->enter();
}
~CAutoFastMutex() { m_Mutex->leave(); }
}; };
// Local Data // Local Data
std::set<std::string*,CCharComp> _StringTable; typedef std::set<const std::string *, CCharComp> TStringTable;
std::string* _EmptyId; TStringTable m_StringTable;
CFastMutex _Mutex; // Must be thread-safe (Called by CPortal/CCluster, each of them called by CInstanceGroup) std::string *m_EmptyId;
CFastMutex m_Mutex; // Must be thread-safe (Called by CPortal/CCluster, each of them called by CInstanceGroup)
// The 'singleton' for static methods // The 'singleton' for static methods
static CStringMapper _GlobalMapper; static CStringMapper s_GlobalMapper;
// private constructor. // private constructor.
CStringMapper(); CStringMapper();
public: public:
~CStringMapper() ~CStringMapper()
{ {
localClear(); localClear();
delete m_EmptyId;
} }
/// Globaly map a string into a unique Id. ** This method IS Thread-Safe ** /// Globaly map a string into a unique Id. ** This method IS Thread-Safe **
static TStringId map(const std::string &str) { return _GlobalMapper.localMap(str); } static TStringId map(const std::string &str) { return s_GlobalMapper.localMap(str); }
/// Globaly map a string into a unique Id. ** This method IS Thread-Safe **
static TStringId map(const char *str) { return s_GlobalMapper.localMap(str); }
/// Globaly unmap a string. ** This method IS Thread-Safe ** /// Globaly unmap a string. ** This method IS Thread-Safe **
static const std::string &unmap(const TStringId &stringId) { return _GlobalMapper.localUnmap(stringId); } static const std::string &unmap(const TStringId &stringId) { return s_GlobalMapper.localUnmap(stringId); }
/// Globaly helper to serial a string id. ** This method IS Thread-Safe ** /// Globaly helper to serial a string id. ** This method IS Thread-Safe **
static void serialString(NLMISC::IStream &f, TStringId &id) {_GlobalMapper.localSerialString(f, id);} static void serialString(NLMISC::IStream &f, TStringId &id) { s_GlobalMapper.localSerialString(f, id); }
/// Return the global id for the empty string (helper function). NB: Works with every instance of CStringMapper /// Return the global id for the empty string (helper function). NB: Works with every instance of CStringMapper
static TStringId emptyId() { return 0; } static TStringId emptyId() { return NULL; }
// ** This method IS Thread-Safe ** // ** This method IS Thread-Safe **
static void clear() { _GlobalMapper.localClear(); } static void clear() { s_GlobalMapper.localClear(); }
/// Create a local mapper. You can dispose of it by deleting it. /// Create a local mapper. You can dispose of it by deleting it.
static CStringMapper * createLocalMapper(); static CStringMapper *createLocalMapper();
/// Localy map a string into a unique Id /// Localy map a string into a unique Id
TStringId localMap(const std::string &str); TStringId localMap(const std::string &str);
#ifdef NL_CPP14
/**
\brief Localy map a string into a unique Id.
Lookup in string mapper using `const char *`
to avoid an std::string allocation when using literals.
\author Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
\date 2019
*/
TStringId localMap(const char *str);
#endif
/// Localy unmap a string /// Localy unmap a string
const std::string &localUnmap(const TStringId &stringId) { return (stringId==0)?*_EmptyId:*((std::string*)stringId); } const std::string &localUnmap(const TStringId &stringId) const { return (stringId == NULL) ? *m_EmptyId : *((const std::string *)stringId); }
/// Localy helper to serial a string id /// Localy helper to serial a string id
void localSerialString(NLMISC::IStream &f, TStringId &id); void localSerialString(NLMISC::IStream &f, TStringId &id);
void localClear();
void localClear();
}; };
// linear from 0 (0 is empty string) (The TSStringId returned by CStaticStringMapper // linear from 0 (0 is empty string) (The TSStringId returned by CStaticStringMapper

@ -70,7 +70,13 @@
# endif # endif
# ifdef _MSC_VER # ifdef _MSC_VER
# define NL_COMP_VC # define NL_COMP_VC
# if _MSC_VER >= 1900 # if _MSC_VER >= 1920
# define NL_COMP_VC14
# define NL_COMP_VC_VERSION 142
# elif _MSC_VER >= 1910
# define NL_COMP_VC14
# define NL_COMP_VC_VERSION 141
# elif _MSC_VER >= 1900
# define NL_COMP_VC14 # define NL_COMP_VC14
# define NL_COMP_VC_VERSION 140 # define NL_COMP_VC_VERSION 140
# elif _MSC_VER >= 1800 # elif _MSC_VER >= 1800
@ -176,6 +182,16 @@
# define NL_NO_EXCEPTION_SPECS # define NL_NO_EXCEPTION_SPECS
#endif #endif
// https://docs.microsoft.com/en-us/cpp/overview/visual-cpp-language-conformance?view=vs-2019
// https://gcc.gnu.org/projects/cxx-status.html
#if (defined(_MSC_VER) && (_MSC_VER >= 1910) && (!defined(_HAS_CXX17) || _HAS_CXX17)) || (defined(__GNUC__ ) && (__GNUC__ >= 8) && (__cplusplus >= 201703L))
# define NL_CPP17
#endif
#if (defined(_MSC_VER) && (_MSC_VER >= 1900)) || (defined(__GNUC__ ) && (__GNUC__ >= 6) && (__cplusplus >= 201402L))
# define NL_CPP14
#endif
#if defined(NL_COMP_VC) && (NL_COMP_VC_VERSION >= 140) #if defined(NL_COMP_VC) && (NL_COMP_VC_VERSION >= 140)
#define nlmove(v) std::move(v) #define nlmove(v) std::move(v)
#else #else

@ -2,7 +2,7 @@
// Copyright (C) 2010 Winch Gate Property Limited // Copyright (C) 2010 Winch Gate Property Limited
// //
// This source file has been modified by the following contributors: // This source file has been modified by the following contributors:
// Copyright (C) 2013-2014 Jan BOON (Kaetemi) <jan.boon@kaetemi.be> // Copyright (C) 2013-2019 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
// //
// This program is free software: you can redistribute it and/or modify // This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as // it under the terms of the GNU Affero General Public License as
@ -1179,36 +1179,43 @@ void CZoneLighter::light (CLandscape &landscape, CZone& output, uint zoneToLight
// Set the thread state // Set the thread state
_LastPatchComputed.resize (_ProcessCount); _LastPatchComputed.resize (_ProcessCount);
// Launch threads if (patchCount)
uint process;
for (process=0; process<_ProcessCount; process++)
{ {
// Last patch // Launch threads
uint lastPatch=firstPatch+patchCountByThread; uint process;
lastPatch %= patchCount; for (process = 0; process < _ProcessCount; process++)
{
// Last patch
uint lastPatch = firstPatch + patchCountByThread;
lastPatch %= patchCount;
// Last patch computed // Last patch computed
_LastPatchComputed[process] = firstPatch; _LastPatchComputed[process] = firstPatch;
// Create a thread // Create a thread
CLightRunnable *runnable = new CLightRunnable (process, this, &description); CLightRunnable *runnable = new CLightRunnable(process, this, &description);
IThread *pThread=IThread::create (runnable); IThread *pThread = IThread::create(runnable);
runnable->Thread = pThread; runnable->Thread = pThread;
// New first patch // New first patch
firstPatch=lastPatch; firstPatch = lastPatch;
// Launch // Launch
pThread->start(); pThread->start();
} }
// Wait for others processes // Wait for others processes
while (_ProcessExited!=_ProcessCount) while (_ProcessExited != _ProcessCount)
{ {
nlSleep (1000); nlSleep(1000);
// Call the progress callback // Call the progress callback
progress ("Lighting patches", (float)_NumberOfPatchComputed/(float)_PatchInfo.size()); progress("Lighting patches", (float)_NumberOfPatchComputed / (float)_PatchInfo.size());
}
}
else
{
nlwarning("Empty zone");
} }
// Reset old thread mask // Reset old thread mask
@ -1765,7 +1772,7 @@ void CZoneLighter::addTriangles (const CMeshBase &meshBase, const CMeshGeom &mes
alphaTestThreshold)); alphaTestThreshold));
} }
} }
else else if (iba.getFormat() == CIndexBuffer::Indices16)
{ {
const uint16* triIndex=(const uint16*)iba.getPtr (); const uint16* triIndex=(const uint16*)iba.getPtr ();
uint numTri=primitive.getNumIndexes ()/3; uint numTri=primitive.getNumIndexes ()/3;
@ -1797,6 +1804,10 @@ void CZoneLighter::addTriangles (const CMeshBase &meshBase, const CMeshGeom &mes
alphaTestThreshold)); alphaTestThreshold));
} }
} }
else
{
nlerror("Invalid index buffer format");
}
} }
} }
} }
@ -1901,34 +1912,73 @@ void CZoneLighter::addTriangles (const CMeshBase &meshBase, const CMeshMRMGeom &
// Dump triangles // Dump triangles
CIndexBufferRead iba; CIndexBufferRead iba;
primitive.lock (iba); primitive.lock (iba);
const uint32* triIndex= (const uint32 *) iba.getPtr (); if (iba.getFormat() == CIndexBuffer::Indices32)
uint numTri=primitive.getNumIndexes ()/3;
uint tri;
for (tri=0; tri<numTri; tri++)
{ {
// Vertex const uint32 *triIndex = (const uint32 *)iba.getPtr();
CVector v0=modelMT*(*vba.getVertexCoordPointer (triIndex[tri*3])); uint numTri = primitive.getNumIndexes() / 3;
CVector v1=modelMT*(*vba.getVertexCoordPointer (triIndex[tri*3+1])); uint tri;
CVector v2=modelMT*(*vba.getVertexCoordPointer (triIndex[tri*3+2])); for (tri = 0; tri < numTri; tri++)
// UV
float u[3] = { 0.f };
float v[3] = { 0.f };
for (uint i=0; i<3; i++)
{ {
// Get UV coordinates // Vertex
float *uv = (float*)vba.getTexCoordPointer (triIndex[tri*3+i], 0); CVector v0 = modelMT * (*vba.getVertexCoordPointer(triIndex[tri * 3]));
if (uv) CVector v1 = modelMT * (*vba.getVertexCoordPointer(triIndex[tri * 3 + 1]));
CVector v2 = modelMT * (*vba.getVertexCoordPointer(triIndex[tri * 3 + 2]));
// UV
float u[3] = { 0.f };
float v[3] = { 0.f };
for (uint i = 0; i < 3; i++)
{ {
// Copy it // Get UV coordinates
u[i] = uv[0]; float *uv = (float *)vba.getTexCoordPointer(triIndex[tri * 3 + i], 0);
v[i] = uv[1]; if (uv)
{
// Copy it
u[i] = uv[0];
v[i] = uv[1];
}
} }
// Make a triangle
triangleArray.push_back(CTriangle(NLMISC::CTriangle(v0, v1, v2), doubleSided, texture, clampU, clampV, u, v,
alphaTestThreshold));
} }
}
else if (iba.getFormat() == CIndexBuffer::Indices16)
{
const uint16 *triIndex = (const uint16 *)iba.getPtr();
uint numTri = primitive.getNumIndexes() / 3;
uint tri;
for (tri = 0; tri < numTri; tri++)
{
// Vertex
CVector v0 = modelMT * (*vba.getVertexCoordPointer(triIndex[tri * 3]));
CVector v1 = modelMT * (*vba.getVertexCoordPointer(triIndex[tri * 3 + 1]));
CVector v2 = modelMT * (*vba.getVertexCoordPointer(triIndex[tri * 3 + 2]));
// UV
float u[3] = { 0.f };
float v[3] = { 0.f };
for (uint i = 0; i < 3; i++)
{
// Get UV coordinates
float *uv = (float *)vba.getTexCoordPointer(triIndex[tri * 3 + i], 0);
if (uv)
{
// Copy it
u[i] = uv[0];
v[i] = uv[1];
}
}
// Make a triangle // Make a triangle
triangleArray.push_back (CTriangle (NLMISC::CTriangle (v0, v1, v2), doubleSided, texture, clampU, clampV, u, v, triangleArray.push_back(CTriangle(NLMISC::CTriangle(v0, v1, v2), doubleSided, texture, clampU, clampV, u, v,
alphaTestThreshold)); alphaTestThreshold));
}
}
else
{
nlerror("Invalid index buffer format");
} }
} }
} }

@ -52,7 +52,7 @@ std::map<std::string, uint32> CSheetId::_DevTypeNameToId;
std::vector<std::vector<std::string>> CSheetId::_DevSheetIdToName; std::vector<std::vector<std::string>> CSheetId::_DevSheetIdToName;
std::map<std::string, uint32> CSheetId::_DevSheetNameToId; std::map<std::string, uint32> CSheetId::_DevSheetNameToId;
const CSheetId CSheetId::Unknown(0); const CSheetId CSheetId::Unknown((uint32)0);
void CSheetId::cbFileChange(const std::string &filename) void CSheetId::cbFileChange(const std::string &filename)
{ {
@ -74,7 +74,35 @@ CSheetId::CSheetId(uint32 sheetRef)
// For now, all static CSheetId are 0 (eg: CSheetId::Unknown) // For now, all static CSheetId are 0 (eg: CSheetId::Unknown)
if (sheetRef) if (sheetRef)
{ {
CStaticMap<uint32, CChar>::iterator it(_SheetIdToName.find(sheetRef)); TSheetIdToNameMap::iterator it(_SheetIdToName.find(sheetRef));
if (it != _SheetIdToName.end())
{
_DebugSheetName = it->second.Ptr;
}
else
_DebugSheetName = NULL;
}
else
{
_DebugSheetName = NULL;
}
#endif
}
//-----------------------------------------------
// CSheetId
//
//-----------------------------------------------
CSheetId::CSheetId(int sheetRef)
{
_Id.Id = (uint32)sheetRef;
#ifdef NL_DEBUG_SHEET_ID
// Yoyo: don't access the static map, because of order of static ctor call.
// For now, all static CSheetId are 0 (eg: CSheetId::Unknown)
if (sheetRef)
{
TSheetIdToNameMap::iterator it(_SheetIdToName.find(sheetRef));
if (it != _SheetIdToName.end()) if (it != _SheetIdToName.end())
{ {
_DebugSheetName = it->second.Ptr; _DebugSheetName = it->second.Ptr;
@ -95,7 +123,7 @@ CSheetId::CSheetId(uint32 sheetRef)
//----------------------------------------------- //-----------------------------------------------
CSheetId::CSheetId(const string &sheetName) CSheetId::CSheetId(const string &sheetName)
{ {
if (!buildSheetId(sheetName)) if (!buildSheetId(sheetName.c_str(), sheetName.size()))
{ {
if (sheetName.empty()) if (sheetName.empty())
nlwarning("SHEETID: Try to create an CSheetId with empty name. TODO: check why."); nlwarning("SHEETID: Try to create an CSheetId with empty name. TODO: check why.");
@ -115,6 +143,25 @@ CSheetId::CSheetId(const string &sheetName)
} // CSheetId // } // CSheetId //
//-----------------------------------------------
// CSheetId
//
//-----------------------------------------------
CSheetId::CSheetId(const char *sheetName)
{
if (!buildSheetId(sheetName, strlen(sheetName)))
{
if (!sheetName[0])
nlwarning("SHEETID: Try to create an CSheetId with empty name. TODO: check why.");
else
nlwarning("SHEETID: The sheet '%s' is not in sheet_id.bin, setting it to Unknown", sheetName);
*this = Unknown;
}
// nldebug("LIST_SHEET_ID: %s (%s)", toString().c_str(), sheetName.c_str());
} // CSheetId //
CSheetId::CSheetId(const std::string &sheetName, const std::string &defaultType) CSheetId::CSheetId(const std::string &sheetName, const std::string &defaultType)
{ {
// Don't use this function without defaultType, use the one above. // Don't use this function without defaultType, use the one above.
@ -132,11 +179,47 @@ CSheetId::CSheetId(const std::string &sheetName, const std::string &defaultType)
} }
} }
static std::string s_Dot = ".";
CSheetId::CSheetId(const std::string &sheetName, const char *defaultType)
{
// Don't use this function without defaultType, use the one above.
nlassert(defaultType[0]);
if (sheetName.rfind('.') == std::string::npos)
{
std::string withType = sheetName + s_Dot + defaultType;
*this = CSheetId(withType);
// nldebug("SHEETID: Constructing CSheetId from name '%s' without explicit type, defaulting as '%s' to '%s'", sheetName.c_str(), defaultType.c_str(), withType.c_str());
}
else
{
*this = CSheetId(sheetName);
}
}
CSheetId::CSheetId(const char *sheetName, const char *defaultType)
{
// Don't use this function without defaultType, use the one above.
nlassert(defaultType[0]);
if (!strchr(sheetName, '.'))
{
std::string withType = sheetName + s_Dot + defaultType;
*this = CSheetId(withType);
// nldebug("SHEETID: Constructing CSheetId from name '%s' without explicit type, defaulting as '%s' to '%s'", sheetName.c_str(), defaultType.c_str(), withType.c_str());
}
else
{
*this = CSheetId(sheetName);
}
}
//----------------------------------------------- //-----------------------------------------------
// Build // Build
// //
//----------------------------------------------- //-----------------------------------------------
bool CSheetId::buildSheetId(const std::string &sheetName) bool CSheetId::buildSheetId(const char *sheetName, size_t sheetNameLen)
{ {
nlassert(_Initialised); nlassert(_Initialised);
@ -184,14 +267,23 @@ bool CSheetId::buildSheetId(const std::string &sheetName)
} }
// try looking up the sheet name in _SheetNameToId // try looking up the sheet name in _SheetNameToId
CStaticMap<CChar, uint32, CCharComp>::const_iterator itId; TSheetNameToIdMap::const_iterator itId;
CChar c; CChar c;
#ifdef alloca
#pragma warning(push)
#pragma warning(disable : 6255)
c.Ptr = (char *)alloca(sheetNameLen + 1);
#pragma warning(pop)
#else
c.Ptr = new char[sheetName.size() + 1]; c.Ptr = new char[sheetName.size() + 1];
strcpy(c.Ptr, sheetName.c_str()); #endif
strcpy(c.Ptr, sheetName);
toLower(c.Ptr); toLower(c.Ptr);
itId = _SheetNameToId.find(c); itId = _SheetNameToId.find(c);
delete[] c.Ptr; #ifndef alloca
delete[] c.Ptr; // Don't delete alloca
#endif
if (itId != _SheetNameToId.end()) if (itId != _SheetNameToId.end())
{ {
_Id.Id = itId->second; _Id.Id = itId->second;
@ -203,11 +295,10 @@ bool CSheetId::buildSheetId(const std::string &sheetName)
} }
// we failed to find the sheet name in the sheetname map so see if the string is numeric // we failed to find the sheet name in the sheetname map so see if the string is numeric
if (sheetName.size() > 1 && sheetName[0] == '#') if (sheetName[0] == '#' && sheetName[1])
{ {
uint32 numericId; uint32 numericId;
NLMISC::fromString((const char *)(sheetName.c_str() + 1), numericId); if (NLMISC::fromString((const char *)(sheetName + 1), numericId))
if (NLMISC::toString("#%u", numericId) == sheetName)
{ {
_Id.Id = numericId; _Id.Id = numericId;
return true; return true;
@ -316,7 +407,7 @@ void CSheetId::loadSheetId()
{ {
uint32 nSize = (uint32)_SheetIdToName.size(); uint32 nSize = (uint32)_SheetIdToName.size();
_SheetNameToId.reserve(nSize); _SheetNameToId.reserve(nSize);
CStaticMap<uint32, CChar>::iterator itStr; TSheetIdToNameMap::iterator itStr;
for (itStr = _SheetIdToName.begin(); itStr != _SheetIdToName.end(); ++itStr) for (itStr = _SheetIdToName.begin(); itStr != _SheetIdToName.end(); ++itStr)
{ {
// add entry to the inverse map // add entry to the inverse map
@ -428,7 +519,7 @@ CSheetId &CSheetId::operator=(const CSheetId &sheetId)
CSheetId &CSheetId::operator=(const string &sheetName) CSheetId &CSheetId::operator=(const string &sheetName)
{ {
if (!buildSheetId(sheetName)) if (!buildSheetId(sheetName.c_str(), sheetName.size()))
*this = Unknown; *this = Unknown;
// nldebug("LIST_SHEET_ID: %s (%s)", toString().c_str(), sheetName.c_str()); // nldebug("LIST_SHEET_ID: %s (%s)", toString().c_str(), sheetName.c_str());
@ -437,6 +528,22 @@ CSheetId &CSheetId::operator=(const string &sheetName)
} // operator= // } // operator= //
//-----------------------------------------------
// operator=
//
//-----------------------------------------------
CSheetId &CSheetId::operator=(const char *sheetName)
{
if (!buildSheetId(sheetName, strlen(sheetName)))
*this = Unknown;
// nldebug("LIST_SHEET_ID: %s (%s)", toString().c_str(), sheetName);
return *this;
} // operator= //
//----------------------------------------------- //-----------------------------------------------
// operator= // operator=
// //
@ -452,6 +559,21 @@ CSheetId &CSheetId::operator=(uint32 sheetRef)
} // operator= // } // operator= //
//-----------------------------------------------
// operator=
//
//-----------------------------------------------
CSheetId &CSheetId::operator=(int sheetRef)
{
if (!_Initialised)
init(false);
_Id.Id = (uint32)sheetRef;
return *this;
} // operator= //
//----------------------------------------------- //-----------------------------------------------
// operator< // operator<
// //
@ -499,7 +621,7 @@ string CSheetId::toString(bool ifNotFoundUseNumericId) const
} }
} }
CStaticMap<uint32, CChar>::const_iterator itStr = _SheetIdToName.find(_Id.Id); TSheetIdToNameMap::const_iterator itStr = _SheetIdToName.find(_Id.Id);
if (itStr != _SheetIdToName.end()) if (itStr != _SheetIdToName.end())
{ {
return string((*itStr).second.Ptr); return string((*itStr).second.Ptr);
@ -528,7 +650,7 @@ void CSheetId::serial(NLMISC::IStream &f)
f.serial(_Id.Id); f.serial(_Id.Id);
#ifdef NL_DEBUG_SHEET_ID #ifdef NL_DEBUG_SHEET_ID
CStaticMap<uint32, CChar>::iterator it(_SheetIdToName.find(_Id.Id)); TSheetIdToNameMap::iterator it(_SheetIdToName.find(_Id.Id));
if (it != _SheetIdToName.end()) if (it != _SheetIdToName.end())
_DebugSheetName = it->second.Ptr; _DebugSheetName = it->second.Ptr;
else else
@ -564,7 +686,7 @@ void CSheetId::display()
if (!_Initialised) if (!_Initialised)
init(false); init(false);
CStaticMap<uint32, CChar>::const_iterator itStr; TSheetIdToNameMap::const_iterator itStr;
for (itStr = _SheetIdToName.begin(); itStr != _SheetIdToName.end(); ++itStr) for (itStr = _SheetIdToName.begin(); itStr != _SheetIdToName.end(); ++itStr)
{ {
//nlinfo("%d %s",(*itStr).first,(*itStr).second.c_str()); //nlinfo("%d %s",(*itStr).first,(*itStr).second.c_str());
@ -582,7 +704,7 @@ void CSheetId::display(uint32 type)
if (!_Initialised) if (!_Initialised)
init(false); init(false);
CStaticMap<uint32, CChar>::const_iterator itStr; TSheetIdToNameMap::const_iterator itStr;
for (itStr = _SheetIdToName.begin(); itStr != _SheetIdToName.end(); ++itStr) for (itStr = _SheetIdToName.begin(); itStr != _SheetIdToName.end(); ++itStr)
{ {
// work out the type value for this entry in the map // work out the type value for this entry in the map
@ -608,7 +730,7 @@ void CSheetId::buildIdVector(std::vector<CSheetId> &result)
if (!_Initialised) if (!_Initialised)
init(false); init(false);
CStaticMap<uint32, CChar>::const_iterator itStr; TSheetIdToNameMap::const_iterator itStr;
for (itStr = _SheetIdToName.begin(); itStr != _SheetIdToName.end(); ++itStr) for (itStr = _SheetIdToName.begin(); itStr != _SheetIdToName.end(); ++itStr)
{ {
result.push_back((CSheetId)(*itStr).first); result.push_back((CSheetId)(*itStr).first);
@ -626,7 +748,7 @@ void CSheetId::buildIdVector(std::vector<CSheetId> &result, uint32 type)
init(false); init(false);
nlassert(type < (1 << (NL_SHEET_ID_TYPE_BITS))); nlassert(type < (1 << (NL_SHEET_ID_TYPE_BITS)));
CStaticMap<uint32, CChar>::const_iterator itStr; TSheetIdToNameMap::const_iterator itStr;
for (itStr = _SheetIdToName.begin(); itStr != _SheetIdToName.end(); ++itStr) for (itStr = _SheetIdToName.begin(); itStr != _SheetIdToName.end(); ++itStr)
{ {
// work out the type value for this entry in the map // work out the type value for this entry in the map
@ -652,7 +774,7 @@ void CSheetId::buildIdVector(std::vector<CSheetId> &result, std::vector<std::str
init(false); init(false);
nlassert(type < (1 << (NL_SHEET_ID_TYPE_BITS))); nlassert(type < (1 << (NL_SHEET_ID_TYPE_BITS)));
CStaticMap<uint32, CChar>::const_iterator itStr; TSheetIdToNameMap::const_iterator itStr;
for (itStr = _SheetIdToName.begin(); itStr != _SheetIdToName.end(); ++itStr) for (itStr = _SheetIdToName.begin(); itStr != _SheetIdToName.end(); ++itStr)
{ {
// work out the type value for this entry in the map // work out the type value for this entry in the map
@ -737,7 +859,7 @@ void CSheetId::buildSheetId(uint32 shortId, uint32 type)
_Id.IdInfos.Type = type; _Id.IdInfos.Type = type;
#ifdef NL_DEBUG_SHEET_ID #ifdef NL_DEBUG_SHEET_ID
CStaticMap<uint32, CChar>::iterator it(_SheetIdToName.find(_Id.Id)); TSheetIdToNameMap::iterator it(_SheetIdToName.find(_Id.Id));
if (it != _SheetIdToName.end()) if (it != _SheetIdToName.end())
{ {
_DebugSheetName = it->second.Ptr; _DebugSheetName = it->second.Ptr;

@ -27,13 +27,12 @@ using namespace std;
namespace NLMISC namespace NLMISC
{ {
CStringMapper CStringMapper::_GlobalMapper; CStringMapper CStringMapper::s_GlobalMapper;
// **************************************************************************** // ****************************************************************************
CStringMapper::CStringMapper() CStringMapper::CStringMapper()
{ {
_EmptyId = new string(); m_EmptyId = new string();
} }
// **************************************************************************** // ****************************************************************************
@ -46,39 +45,54 @@ CStringMapper *CStringMapper::createLocalMapper()
TStringId CStringMapper::localMap(const std::string &str) TStringId CStringMapper::localMap(const std::string &str)
{ {
if (str.empty()) if (str.empty())
return 0; return NULL;
CAutoFastMutex automutex(&_Mutex);
string *pStr = new string; CAutoFastMutex autoMutex(&m_Mutex);
*pStr = str;
std::set<string*,CCharComp>::iterator it = _StringTable.find(pStr); TStringTable::const_iterator it = m_StringTable.find((const std::string *)&str);
if (it == _StringTable.end()) if (it == m_StringTable.end())
{ {
_StringTable.insert(pStr); string *pStr = new string(str);
m_StringTable.insert(pStr);
return pStr;
} }
else return (TStringId)(*it);
}
#ifdef NL_CPP14
// ****************************************************************************
TStringId CStringMapper::localMap(const char *str)
{
if (!str[0])
return NULL;
CAutoFastMutex autoMutex(&m_Mutex);
TStringTable::const_iterator it = m_StringTable.find(str);
if (it == m_StringTable.end())
{ {
delete pStr; string *pStr = new string(str);
pStr = (*it); m_StringTable.insert(pStr);
return pStr;
} }
return (TStringId)pStr; return (TStringId)(*it);
} }
#endif
// *************************************************************************** // ***************************************************************************
void CStringMapper::localSerialString(NLMISC::IStream &f, TStringId &id) void CStringMapper::localSerialString(NLMISC::IStream &f, TStringId &id)
{ {
std::string str; std::string str;
if(f.isReading()) if (f.isReading())
{ {
f.serial(str); f.serial(str);
id= localMap(str); id = localMap(str);
} }
else else
{ {
str= localUnmap(id); str = localUnmap(id);
f.serial(str); f.serial(str);
} }
} }
@ -86,17 +100,16 @@ void CStringMapper::localSerialString(NLMISC::IStream &f, TStringId &id)
// **************************************************************************** // ****************************************************************************
void CStringMapper::localClear() void CStringMapper::localClear()
{ {
CAutoFastMutex automutex(&_Mutex); CAutoFastMutex autoMutex(&m_Mutex);
std::set<string*,CCharComp>::iterator it = _StringTable.begin(); TStringTable::iterator it = m_StringTable.begin();
while (it != _StringTable.end()) while (it != m_StringTable.end())
{ {
string *ptrTmp = (*it); const std::string *ptrTmp = (*it);
delete ptrTmp; delete ptrTmp;
it++; it++;
} }
_StringTable.clear(); m_StringTable.clear();
delete _EmptyId;
} }
// **************************************************************************** // ****************************************************************************

@ -17,6 +17,10 @@ IF(WITH_NEL_TOOLS)
ADD_SUBDIRECTORY(pacs) ADD_SUBDIRECTORY(pacs)
ENDIF() ENDIF()
IF(WITH_LIGO)
ADD_SUBDIRECTORY(ligo)
ENDIF()
IF(WITH_LOGIC) IF(WITH_LOGIC)
ADD_SUBDIRECTORY(logic) ADD_SUBDIRECTORY(logic)
ENDIF() ENDIF()

@ -0,0 +1,6 @@
IF(WITH_LIGO)
IF(WITH_3D)
ADD_SUBDIRECTORY(unbuild_land)
ENDIF()
ENDIF()

@ -0,0 +1,11 @@
FILE(GLOB SRC *.cpp *.h *.rc)
SOURCE_GROUP("" FILES ${SRC})
ADD_EXECUTABLE(unbuild_land ${SRC})
TARGET_LINK_LIBRARIES(unbuild_land nel3d nelmisc nelligo)
NL_DEFAULT_PROPS(unbuild_land "NeL, Tools, Ligo: Unbuild Land")
NL_ADD_RUNTIME_FLAGS(unbuild_land)
INSTALL(TARGETS unbuild_land RUNTIME DESTINATION ${NL_BIN_PREFIX} COMPONENT toolsligo)

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 "gold_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 Unbuild Land"
VALUE "FileVersion", NL_VERSION
VALUE "LegalCopyright", COPYRIGHT
VALUE "OriginalFilename", "unbuild_land" 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,500 @@
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
// Copyright (C) 2019 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
//
// 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/>.
//
// This utility is intended to rescue a lost .land file from existing
// runtime zones. It does not recover the heightmap.
//
// Author: Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
// #include "../../3d/zone_lib/zone_utility.h"
#include <iostream>
#include <nel/misc/types_nl.h>
#include <nel/misc/file.h>
#include <nel/misc/o_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;
bool s_Height = false;
std::string s_ZoneBricksDirIn; // UTF-8 path
std::string s_ZoneRuntimeDirIn; // UTF-8 path
std::string s_LandFileOut; // UTF-8 path
CZoneRegion s_Land;
bool saveLand()
{
try
{
COFile fileOut;
if (fileOut.open(s_LandFileOut, false, true, false))
{
COXml xml;
nlverify(xml.init(&fileOut));
s_Land.serial(xml);
}
else
{
nlwarning("Can't open the land file for writing: %s", s_LandFileOut.c_str());
return false;
}
}
catch (const Exception &e)
{
nlwarning("Error in writing 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;
}
void centerVertices(std::vector<CVector> &vertices)
{
CVector avg = CVector(0.0f, 0.0f, 0.0f);
for (ptrdiff_t i = 0; i < vertices.size(); ++i)
avg += vertices[i];
avg /= (float)vertices.size();
nldebug("Average: %f, %f", avg.x, avg.y);
for (ptrdiff_t i = 0; i < vertices.size(); ++i)
vertices[i] -= avg;
}
void offsetVertices(std::vector<CVector> &vertices, int x, int y)
{
CVector off = CVector((float)x * s_CellSize, (float)y * s_CellSize, 0.0f);
for (ptrdiff_t i = 0; i < vertices.size(); ++i)
vertices[i] -= off;
}
float ratePoints(const std::vector<CVector> &zone, const std::vector<CVector> &ref, float xx, float xy, float yx, float yy)
{
// Rudimentary distance rating of vertices (not very reliable, but good enough!)
float md = 0.f;
// std::vector<CVector> refcpy = ref;
std::vector<bool> usedref;
usedref.resize(ref.size(), false);
for (ptrdiff_t i = 0; i < zone.size(); ++i)
{
if (ref.size())
{
int lowj = 0;
float lowv = (CVector(ref[0].x * xx + ref[0].y * xy, ref[0].x * yx + ref[0].y * yy, ref[0].z) - zone[i]).sqrnorm();
for (ptrdiff_t j = 1; j < ref.size(); ++j)
{
float v = (CVector(ref[j].x * xx + ref[j].y * xy, ref[j].x * yx + ref[j].y * yy, ref[j].z) - zone[i]).sqrnorm();
if (v < lowv)
{
lowj = j;
lowv = v;
}
}
md += sqrtf(lowv);
usedref[lowj] = true;
// keep it! - refcpy.erase(refcpy.begin() + lowj);
}
else
{
md += zone[i].norm();
}
}
#if 0
md = 0.f;
std::vector<bool> usedzone;
usedzone.resize(zone.size(), false);
for (ptrdiff_t j = 0; j < ref.size(); ++j)
{
if (usedref[j])
{
if (zone.size())
{
int lowi = 0;
float lowv = (CVector2f(ref[j].x * xx + ref[j].y * xy, ref[j].x * yx + ref[j].y * yy) - zone[0]).sqrnorm();
for (ptrdiff_t i = 1; i < zone.size(); ++i)
{
float v = (CVector2f(ref[j].x * xx + ref[j].y * xy, ref[j].x * yx + ref[j].y * yy) - zone[i]).sqrnorm();
if (v < lowv)
{
lowi = i;
lowv = v;
}
}
md += lowv;
usedzone[lowi] = true;
}
else
{
md += ref[j].norm();
}
}
}
md = 0.f;
int nc = 0;
for (ptrdiff_t i = 0; i < zone.size(); ++i)
{
if (usedzone[i])
{
if (ref.size())
{
int lowj = 0;
float lowv = (CVector2f(ref[0].x * xx + ref[0].y * xy, ref[0].x * yx + ref[0].y * yy) - zone[i]).sqrnorm();
for (ptrdiff_t j = 1; j < ref.size(); ++j)
{
float v = (CVector2f(ref[j].x * xx + ref[j].y * xy, ref[j].x * yx + ref[j].y * yy) - zone[i]).sqrnorm();
if (v < lowv)
{
lowj = j;
lowv = v;
}
}
md += sqrtf(lowv);
usedref[lowj] = true;
// keep it! - refcpy.erase(refcpy.begin() + lowj);
}
else
{
md += zone[i].norm();
}
}
else
{
++nc;
// md += 1.0f;
// md += 0.01;
}
}
for (ptrdiff_t j = 0; j < ref.size(); ++j)
{
if (!usedref[j])
{
// md += 1.0f;
// md += 0.01;
}
}
if (nc * 8 > zone.size())
return md + 10000;
#endif
return md;
}
void findBestBrick(std::string &brick, int &rotate, int &flip, float &es, std::vector<CVector> &zoneVertices, const std::map<std::string, std::vector<CVector>> &brickVertices)
{
float bestPoints = (float)(uint32)~0;
for (std::map<std::string, std::vector<CVector>>::const_iterator it = brickVertices.begin(), end = brickVertices.end(); it != end; ++it)
{
float rating;
rating = ratePoints(zoneVertices, it->second, 1.0, 0.0, 0.0, 1.0);
if (rating < bestPoints)
{
brick = it->first;
rotate = 0;
flip = 0;
bestPoints = rating;
}
rating = ratePoints(zoneVertices, it->second, 0.0, -1.0, 1.0, 0.0);
if (rating < bestPoints)
{
brick = it->first;
rotate = 1;
flip = 0;
bestPoints = rating;
}
rating = ratePoints(zoneVertices, it->second, -1.0, 0.0, 0.0, -1.0);
if (rating < bestPoints)
{
brick = it->first;
rotate = 2;
flip = 0;
bestPoints = rating;
}
rating = ratePoints(zoneVertices, it->second, 0.0, 1.0, -1.0, 0.0);
if (rating < bestPoints)
{
brick = it->first;
rotate = 3;
flip = 0;
}
rating = ratePoints(zoneVertices, it->second, -1.0, 0.0, 0.0, 1.0);
if (rating < bestPoints)
{
brick = it->first;
rotate = 0;
flip = 1;
bestPoints = rating;
}
rating = ratePoints(zoneVertices, it->second, 0.0, -1.0, -1.0, 0.0);
if (rating < bestPoints)
{
brick = it->first;
rotate = 1;
flip = 1;
bestPoints = rating;
}
rating = ratePoints(zoneVertices, it->second, 1.0, 0.0, 0.0, -1.0);
if (rating < bestPoints)
{
brick = it->first;
rotate = 2;
flip = 1;
bestPoints = rating;
}
rating = ratePoints(zoneVertices, it->second, 0.0, 1.0, 1.0, 0.0);
if (rating < bestPoints)
{
brick = it->first;
rotate = 3;
flip = 1;
bestPoints = rating;
}
}
es = bestPoints;
}
bool unbuildLand()
{
s_Land.resize(s_ZoneMinX, s_ZoneMaxX, s_ZoneMinY, s_ZoneMaxY);
// float th = s_CellSize * 0.5f;
float th = (s_CellSize * 0.5f) - (s_CellSize * 0.2f * 0.5f);
// Read in all the bricks
std::vector<std::string> brickFiles;
CPath::getPathContent(s_ZoneBricksDirIn, false, false, true, brickFiles);
std::map<std::string, std::vector<CVector>> brickVertices;
for (std::vector<std::string>::const_iterator it = brickFiles.begin(), end = brickFiles.end(); it != end; ++it)
{
if (CFile::getExtension(*it) != "zone")
continue;
if (NLMISC::startsWith(CFile::getFilename(*it), "converted-")) // Not a real ligo
continue;
// if (NLMISC::startsWith(CFile::getFilename(*it), "foret-moor")) // Not useful for r2_forest
// continue;
// if (NLMISC::startsWith(CFile::getFilename(*it), "goo-")) // Not useful for r2_forest
// continue;
// if (NLMISC::endsWith(CFile::getFilenameWithoutExtension(*it), "_zc")) // Not useful for r2_forest
// continue;
nldebug("Load %s", CFile::getFilenameWithoutExtension(*it).c_str());
CIFile zoneFile(*it);
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);
brickVertices[CFile::getFilenameWithoutExtension(*it)] = std::vector<CVector>();
std::vector<CVector> &vec = brickVertices[CFile::getFilenameWithoutExtension(*it)];
CVector off = CVector(s_CellSize * 0.5f, s_CellSize * 0.5f, 0.0f);
for (ptrdiff_t i = 0; i < zonePatches.size(); ++i)
{
for (ptrdiff_t j = 0; j < 4; ++j)
{
float rx = zonePatches[i].Patch.Vertices[j].x - off.x;
float ry = zonePatches[i].Patch.Vertices[j].y - off.y;
if (rx <= -th || rx >= th
|| ry <= -th || ry >= th)
goto SkipA;
}
for (ptrdiff_t j = 0; j < 4; ++j)
{
float rx = zonePatches[i].Patch.Vertices[j].x - off.x;
float ry = zonePatches[i].Patch.Vertices[j].y - off.y;
vec.push_back(CVector(rx, ry, s_Height ? zonePatches[i].Patch.Vertices[j].z : 0.0f));
}
SkipA:;
}
// centerVertices(vec);
}
std::vector<std::string> runtimeFiles;
CPath::getPathContent(s_ZoneRuntimeDirIn, false, false, true, runtimeFiles);
for (std::vector<std::string>::const_iterator it = runtimeFiles.begin(), end = runtimeFiles.end(); it != end; ++it)
{
if (CFile::getExtension(*it) != "zonel")
continue;
int x, y;
std::string zoneName = CFile::getFilenameWithoutExtension(*it);
if (!getXYFromZoneName(x, y, zoneName))
{
nlerrornoex("Bad zone name: %s", zoneName.c_str());
continue;
}
CIFile zoneFile(*it);
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);
std::vector<CVector> vec;
CVector off = CVector((float)x * s_CellSize, (float)y * s_CellSize, 0.0f) + CVector(s_CellSize * 0.5f, s_CellSize * 0.5f, 0.0f);
for (ptrdiff_t i = 0; i < zonePatches.size(); ++i)
{
for (ptrdiff_t j = 0; j < 4; ++j)
{
float rx = zonePatches[i].Patch.Vertices[j].x - off.x;
float ry = zonePatches[i].Patch.Vertices[j].y - off.y;
if (rx <= -th || rx >= th
|| ry <= -th || ry >= th)
goto SkipB;
}
for (ptrdiff_t j = 0; j < 4; ++j)
{
float rx = zonePatches[i].Patch.Vertices[j].x - off.x;
float ry = zonePatches[i].Patch.Vertices[j].y - off.y;
vec.push_back(CVector(rx, ry, s_Height ? zonePatches[i].Patch.Vertices[j].z : 0.0f));
}
SkipB:;
}
// offsetVertices(vec, x, y);
// centerVertices(vec);
std::string brick;
int rotate;
int flip;
float es;
findBestBrick(brick, rotate, flip, es, vec, brickVertices);
nlinfo("Zone: %s, brick: %s, rotate: %i; flip: %i, error score: %f", zoneName.c_str(), brick.c_str(), rotate, flip, es);
s_Land.setName(x, y, brick);
s_Land.setRot(x, y, rotate);
s_Land.setFlip(x, y, flip);
}
return saveLand();
}
} /* anonymous namespace */
int main(int argc, char **argv)
{
NLMISC::CApplicationContext myApplicationContext;
NLMISC::CCmdArgs args;
args.addAdditionalArg("land", "Output ligo land file");
args.addAdditionalArg("zonebricks", "Input zone bricks directory");
args.addAdditionalArg("zoneruntime", "Input runtime zone directory");
args.addAdditionalArg("zonemin", "Zone boundary");
args.addAdditionalArg("zonemax", "Zone boundary");
args.addArg("", "cellsize", "meters", "Zone cell size");
args.addArg("", "height", "", "Take Z coordinate into account");
if (!args.parse(argc, argv))
{
return EXIT_FAILURE;
}
s_LandFileOut = args.getAdditionalArg("land")[0];
s_ZoneBricksDirIn = args.getAdditionalArg("zonebricks")[0];
s_ZoneRuntimeDirIn = args.getAdditionalArg("zoneruntime")[0];
sint32 zoneMinX, zoneMinY;
sint32 zoneMaxX, zoneMaxY;
if (!getXYFromZoneName(zoneMinX, zoneMinY, args.getAdditionalArg("zonemin")[0])
|| !getXYFromZoneName(zoneMaxX, zoneMaxY, args.getAdditionalArg("zonemax")[0]))
{
goto Fail;
}
s_ZoneMinX = min(zoneMinX, zoneMaxX);
s_ZoneMaxX = max(zoneMinX, zoneMaxX);
s_ZoneMinY = min(zoneMinY, zoneMaxY);
s_ZoneMaxY = max(zoneMinY, zoneMaxY);
s_Height = args.haveLongArg("height");
if (args.haveLongArg("cellsize"))
{
if (!NLMISC::fromString(args.getLongArg("cellsize")[0], s_CellSize))
goto Fail;
}
if (!unbuildLand())
return EXIT_FAILURE;
return EXIT_SUCCESS;
Fail:
args.displayHelp();
return EXIT_FAILURE;
}

@ -867,7 +867,7 @@ void initAutoLogin()
void initAltLogin() void initAltLogin()
{ {
// Check the alt param // Check the alt param
if (!LoginCustomParameters.empty()) if (!LoginCustomParameters.empty() && LoginCustomParameters != "&dbg=1")
{ {
// don't use login and password for alternate login // don't use login and password for alternate login
string res = checkLogin("", "", ClientApp, LoginCustomParameters); string res = checkLogin("", "", ClientApp, LoginCustomParameters);

@ -307,6 +307,11 @@ bool endsWith( const CSString& s, const CSString& substring )
return (s.right( (uint)substring.size() ) == substring); return (s.right( (uint)substring.size() ) == substring);
} }
bool endsWith( const CSString& s, const char *substring )
{
return endsWith(s, CSString(substring));
}
// Generate item names // Generate item names
void GenerateItemNames( const CSString& nomMP, char eco, int level, bool mission, bool creature, CSString& outStr ) void GenerateItemNames( const CSString& nomMP, char eco, int level, bool mission, bool creature, CSString& outStr )

Loading…
Cancel
Save