From dec6c2d88080f43c55cdc932e872c805d8f50ffd Mon Sep 17 00:00:00 2001 From: kaetemi Date: Sun, 20 Sep 2015 15:23:27 +0200 Subject: [PATCH] Centralized asset database configuration --HG-- branch : feature-export-assimp --- code/nel/include/nel/misc/tool_logger.h | 2 +- .../tools/3d/mesh_utils/database_config.cpp | 107 ++++++++++++++++++ .../nel/tools/3d/mesh_utils/database_config.h | 58 ++++++++++ code/nel/tools/3d/mesh_utils/mesh_utils.cpp | 22 ++-- code/nel/tools/3d/mesh_utils/mesh_utils.h | 4 +- 5 files changed, 182 insertions(+), 11 deletions(-) create mode 100644 code/nel/tools/3d/mesh_utils/database_config.cpp create mode 100644 code/nel/tools/3d/mesh_utils/database_config.h diff --git a/code/nel/include/nel/misc/tool_logger.h b/code/nel/include/nel/misc/tool_logger.h index 85171095c..3ef547045 100644 --- a/code/nel/include/nel/misc/tool_logger.h +++ b/code/nel/include/nel/misc/tool_logger.h @@ -88,7 +88,7 @@ private: FILE *m_DependLog; public: - inline CToolLogger() + inline CToolLogger() : m_ErrorLog(NULL), m_DependLog(NULL) { } diff --git a/code/nel/tools/3d/mesh_utils/database_config.cpp b/code/nel/tools/3d/mesh_utils/database_config.cpp new file mode 100644 index 000000000..7e6ea5b37 --- /dev/null +++ b/code/nel/tools/3d/mesh_utils/database_config.cpp @@ -0,0 +1,107 @@ +// NeL - MMORPG Framework +// Copyright (C) 2015 Winch Gate Property Limited +// Author: Jan Boon +// +// 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 +#include "database_config.h" + +#include +#include +#include + +using namespace std; +using namespace NLMISC; + +TPathString CDatabaseConfig::s_RootPath; +NLMISC::CConfigFile *CDatabaseConfig::s_ConfigFile = NULL; +CDatabaseConfig CDatabaseConfig::s_Instance; +uint32 CDatabaseConfig::s_ConfigFileModification; + +static std::set s_SearchPaths; + +void CDatabaseConfig::cleanup() +{ + delete CDatabaseConfig::s_ConfigFile; + CDatabaseConfig::s_ConfigFile = NULL; +} + +CDatabaseConfig::~CDatabaseConfig() +{ + cleanup(); +} + +bool CDatabaseConfig::init(const std::string &asset) +{ + // release(); + + TPathString rootPath = NLMISC::CPath::standardizePath(asset, false); + TPathString configPath = rootPath + "/database.cfg"; + while (!CFile::fileExists(configPath)) + { + int sep = CFile::getLastSeparator(rootPath); + if (sep == string::npos) + return false; + + rootPath = rootPath.substr(0, sep); + if (rootPath.empty()) + return false; + + configPath = rootPath + "/database.cfg"; + } + + rootPath += "/"; + uint32 configFileModification = CFile::getFileModificationDate(configPath); + if (rootPath == s_RootPath && s_ConfigFileModification == configFileModification) + return true; // Do not reload + + nldebug("Initializing database config '%s'", configPath.c_str()); + release(); + + s_RootPath = rootPath; + s_ConfigFileModification = configFileModification; + + s_ConfigFile = new CConfigFile(); + s_ConfigFile->load(configPath); + return true; +} + +void CDatabaseConfig::initTextureSearchDirectories() +{ + searchDirectories("TextureSearchDirectories"); +} + +void CDatabaseConfig::searchDirectories(const char *var) +{ + CConfigFile::CVar &paths = s_ConfigFile->getVar(var); + for (uint i = 0; i < paths.size(); i++) + { + TPathString path = paths.asString(i); + if (s_SearchPaths.find(path) == s_SearchPaths.end()) + { + CPath::addSearchPath(s_RootPath + path); + s_SearchPaths.insert(path); + } + } +} + +void CDatabaseConfig::release() +{ + s_SearchPaths.clear(); + CPath::clearMap(); + cleanup(); +} + +/* end of file */ diff --git a/code/nel/tools/3d/mesh_utils/database_config.h b/code/nel/tools/3d/mesh_utils/database_config.h new file mode 100644 index 000000000..25bcc2a00 --- /dev/null +++ b/code/nel/tools/3d/mesh_utils/database_config.h @@ -0,0 +1,58 @@ +// NeL - MMORPG Framework +// Copyright (C) 2015 Winch Gate Property Limited +// Author: Jan Boon +// +// 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 + +namespace NLMISC { + class CConfigFile; +} + +#ifdef NL_OS_WINDOWS +#include +typedef NLMISC::CSString TPathString; +#else +typedef std::string TPathString; +#endif + +/// Asset database configuration +class CDatabaseConfig +{ +public: + ~CDatabaseConfig(); + + /// Searches for the configuration for the specified asset path by recursively going through all parent directories looking for 'database.cfg', initializes and applies the configuration. + static bool init(const std::string &asset); + static void release(); + + static void initTextureSearchDirectories(); + + static inline const TPathString &rootPath() { return s_RootPath; } + static inline TPathString configPath() { return s_RootPath + "/database.cfg"; } + +private: + static void cleanup(); + static void searchDirectories(const char *var); + + static CDatabaseConfig s_Instance; + static uint32 s_ConfigFileModification; + + static TPathString s_RootPath; + static NLMISC::CConfigFile *s_ConfigFile; + +}; + +/* end of file */ diff --git a/code/nel/tools/3d/mesh_utils/mesh_utils.cpp b/code/nel/tools/3d/mesh_utils/mesh_utils.cpp index c8a0eb12d..4af32091b 100644 --- a/code/nel/tools/3d/mesh_utils/mesh_utils.cpp +++ b/code/nel/tools/3d/mesh_utils/mesh_utils.cpp @@ -22,15 +22,17 @@ #include #include +#include "database_config.h" + #include #include #include CMeshUtilsSettings::CMeshUtilsSettings() { - ShapeDirectory = "shape"; + /*ShapeDirectory = "shape"; IGDirectory = "ig"; - SkelDirectory = "skel"; + SkelDirectory = "skel";*/ } struct CNodeContext @@ -119,11 +121,11 @@ void flagAssimpBones(CMeshUtilsContext &context) const aiMesh *mesh = scene->mMeshes[i]; for (unsigned int j = 0; j < mesh->mNumBones; ++j) { - CNodeContext &nodeContext = context.Nodes[mesh->mBones[i]->mName.C_Str()]; + CNodeContext &nodeContext = context.Nodes[mesh->mBones[j]->mName.C_Str()]; if (!nodeContext.AssimpNode) { tlerror(context.ToolLogger, context.Settings.SourceFilePath.c_str(), - "Bone '%s' has no associated node", mesh->mBones[i]->mName.C_Str()); + "Bone '%s' has no associated node", mesh->mBones[j]->mName.C_Str()); } else { @@ -145,25 +147,28 @@ void flagAssimpBones(CMeshUtilsContext &context) int exportScene(const CMeshUtilsSettings &settings) { CMeshUtilsContext context(settings); + NLMISC::CFile::createDirectoryTree(settings.DestinationDirectoryPath); if (!settings.ToolDependLog.empty()) context.ToolLogger.initDepend(settings.ToolDependLog); if (!settings.ToolErrorLog.empty()) - context.ToolLogger.initDepend(settings.ToolErrorLog); + context.ToolLogger.initError(settings.ToolErrorLog); context.ToolLogger.writeDepend(NLMISC::BUILD, "*", context.Settings.SourceFilePath.c_str()); // Base input file - // Find database configuration - + // Apply database configuration + CDatabaseConfig::init(settings.SourceFilePath); + CDatabaseConfig::initTextureSearchDirectories(); Assimp::Importer importer; const aiScene *scene = importer.ReadFile(settings.SourceFilePath, aiProcess_Triangulate | aiProcess_ValidateDataStructure); // aiProcess_SplitLargeMeshes | aiProcess_LimitBoneWeights if (!scene) { const char *errs = importer.GetErrorString(); - if (errs) tlerror(context.ToolLogger, context.Settings.SourceFilePath.c_str(), errs); + if (errs) tlerror(context.ToolLogger, context.Settings.SourceFilePath.c_str(), "Assimp failed to load the scene: '%s'", errs); else tlerror(context.ToolLogger, context.Settings.SourceFilePath.c_str(), "Unable to load scene"); return EXIT_FAILURE; } + // aiProcess_Triangulate // aiProcess_ValidateDataStructure: TODO: Catch Assimp error output stream // aiProcess_RemoveRedundantMaterials: Not used because we may override materials with NeL Material from meta // aiProcess_ImproveCacheLocality: TODO: Verify this does not modify vertex indices @@ -171,6 +176,7 @@ int exportScene(const CMeshUtilsSettings &settings) context.AssimpScene = scene; + validateAssimpNodeNames(context, context.AssimpScene->mRootNode); flagAssimpBones(context); importNode(context, scene->mRootNode, &g_DefaultMeta); diff --git a/code/nel/tools/3d/mesh_utils/mesh_utils.h b/code/nel/tools/3d/mesh_utils/mesh_utils.h index 1af319dec..de6dd63fc 100644 --- a/code/nel/tools/3d/mesh_utils/mesh_utils.h +++ b/code/nel/tools/3d/mesh_utils/mesh_utils.h @@ -30,9 +30,9 @@ struct CMeshUtilsSettings std::string ToolErrorLog; // Relative Directories - std::string ShapeDirectory; + /*std::string ShapeDirectory; std::string IGDirectory; - std::string SkelDirectory; + std::string SkelDirectory;*/ }; int exportScene(const CMeshUtilsSettings &settings);