Centralized asset database configuration

--HG--
branch : feature-export-assimp
This commit is contained in:
kaetemi 2015-09-20 15:23:27 +02:00
parent 8036d53411
commit dec6c2d880
5 changed files with 182 additions and 11 deletions

View file

@ -88,7 +88,7 @@ private:
FILE *m_DependLog; FILE *m_DependLog;
public: public:
inline CToolLogger() inline CToolLogger() : m_ErrorLog(NULL), m_DependLog(NULL)
{ {
} }

View file

@ -0,0 +1,107 @@
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
// Copyright (C) 2015 Winch Gate Property Limited
// Author: Jan Boon <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/>.
#include <nel/misc/types_nl.h>
#include "database_config.h"
#include <nel/misc/debug.h>
#include <nel/misc/path.h>
#include <nel/misc/config_file.h>
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<TPathString> 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 */

View file

@ -0,0 +1,58 @@
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
// Copyright (C) 2015 Winch Gate Property Limited
// Author: Jan Boon <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/>.
#include <nel/misc/types_nl.h>
namespace NLMISC {
class CConfigFile;
}
#ifdef NL_OS_WINDOWS
#include <nel/misc/sstring.h>
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 */

View file

@ -22,15 +22,17 @@
#include <nel/misc/tool_logger.h> #include <nel/misc/tool_logger.h>
#include <nel/misc/sstring.h> #include <nel/misc/sstring.h>
#include "database_config.h"
#include <assimp/postprocess.h> #include <assimp/postprocess.h>
#include <assimp/scene.h> #include <assimp/scene.h>
#include <assimp/Importer.hpp> #include <assimp/Importer.hpp>
CMeshUtilsSettings::CMeshUtilsSettings() CMeshUtilsSettings::CMeshUtilsSettings()
{ {
ShapeDirectory = "shape"; /*ShapeDirectory = "shape";
IGDirectory = "ig"; IGDirectory = "ig";
SkelDirectory = "skel"; SkelDirectory = "skel";*/
} }
struct CNodeContext struct CNodeContext
@ -119,11 +121,11 @@ void flagAssimpBones(CMeshUtilsContext &context)
const aiMesh *mesh = scene->mMeshes[i]; const aiMesh *mesh = scene->mMeshes[i];
for (unsigned int j = 0; j < mesh->mNumBones; ++j) 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) if (!nodeContext.AssimpNode)
{ {
tlerror(context.ToolLogger, context.Settings.SourceFilePath.c_str(), 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 else
{ {
@ -145,25 +147,28 @@ void flagAssimpBones(CMeshUtilsContext &context)
int exportScene(const CMeshUtilsSettings &settings) int exportScene(const CMeshUtilsSettings &settings)
{ {
CMeshUtilsContext context(settings); CMeshUtilsContext context(settings);
NLMISC::CFile::createDirectoryTree(settings.DestinationDirectoryPath);
if (!settings.ToolDependLog.empty()) if (!settings.ToolDependLog.empty())
context.ToolLogger.initDepend(settings.ToolDependLog); context.ToolLogger.initDepend(settings.ToolDependLog);
if (!settings.ToolErrorLog.empty()) 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 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; Assimp::Importer importer;
const aiScene *scene = importer.ReadFile(settings.SourceFilePath, aiProcess_Triangulate | aiProcess_ValidateDataStructure); // aiProcess_SplitLargeMeshes | aiProcess_LimitBoneWeights const aiScene *scene = importer.ReadFile(settings.SourceFilePath, aiProcess_Triangulate | aiProcess_ValidateDataStructure); // aiProcess_SplitLargeMeshes | aiProcess_LimitBoneWeights
if (!scene) if (!scene)
{ {
const char *errs = importer.GetErrorString(); 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"); else tlerror(context.ToolLogger, context.Settings.SourceFilePath.c_str(), "Unable to load scene");
return EXIT_FAILURE; return EXIT_FAILURE;
} }
// aiProcess_Triangulate
// aiProcess_ValidateDataStructure: TODO: Catch Assimp error output stream // aiProcess_ValidateDataStructure: TODO: Catch Assimp error output stream
// aiProcess_RemoveRedundantMaterials: Not used because we may override materials with NeL Material from meta // aiProcess_RemoveRedundantMaterials: Not used because we may override materials with NeL Material from meta
// aiProcess_ImproveCacheLocality: TODO: Verify this does not modify vertex indices // aiProcess_ImproveCacheLocality: TODO: Verify this does not modify vertex indices
@ -171,6 +176,7 @@ int exportScene(const CMeshUtilsSettings &settings)
context.AssimpScene = scene; context.AssimpScene = scene;
validateAssimpNodeNames(context, context.AssimpScene->mRootNode);
flagAssimpBones(context); flagAssimpBones(context);
importNode(context, scene->mRootNode, &g_DefaultMeta); importNode(context, scene->mRootNode, &g_DefaultMeta);

View file

@ -30,9 +30,9 @@ struct CMeshUtilsSettings
std::string ToolErrorLog; std::string ToolErrorLog;
// Relative Directories // Relative Directories
std::string ShapeDirectory; /*std::string ShapeDirectory;
std::string IGDirectory; std::string IGDirectory;
std::string SkelDirectory; std::string SkelDirectory;*/
}; };
int exportScene(const CMeshUtilsSettings &settings); int exportScene(const CMeshUtilsSettings &settings);