Scene meta data

--HG--
branch : feature-export-assimp
This commit is contained in:
kaetemi 2015-09-20 16:44:56 +02:00
parent dec6c2d880
commit fec41ebda9
3 changed files with 251 additions and 11 deletions

View file

@ -23,6 +23,7 @@
#include <nel/misc/sstring.h> #include <nel/misc/sstring.h>
#include "database_config.h" #include "database_config.h"
#include "scene_meta.h"
#include <assimp/postprocess.h> #include <assimp/postprocess.h>
#include <assimp/scene.h> #include <assimp/scene.h>
@ -48,6 +49,7 @@ struct CNodeContext
bool IsBone; bool IsBone;
}; };
typedef std::map<NLMISC::CSString, CNodeContext> TNodeContextMap;
struct CMeshUtilsContext struct CMeshUtilsContext
{ {
CMeshUtilsContext(const CMeshUtilsSettings &settings) : Settings(settings), AssimpScene(NULL) CMeshUtilsContext(const CMeshUtilsSettings &settings) : Settings(settings), AssimpScene(NULL)
@ -60,17 +62,13 @@ struct CMeshUtilsContext
NLMISC::CToolLogger ToolLogger; NLMISC::CToolLogger ToolLogger;
const aiScene *AssimpScene; const aiScene *AssimpScene;
std::map<NLMISC::CSString, CNodeContext> Nodes; CSceneMeta SceneMeta;
std::map<const aiMesh *, NLMISC::CSString> MeshNames; // Maps meshes to a node name ********************* todo ***************
TNodeContextMap Nodes;
// std::map<const aiMesh *, NLMISC::CSString> MeshNames; // Maps meshes to a node name ********************* todo ***************
}; };
struct CNodeMeta void importNode(CMeshUtilsContext &context, const aiNode *node)
{
// TODO
};
static const CNodeMeta g_DefaultMeta;
void importNode(CMeshUtilsContext &context, const aiNode *node, const CNodeMeta *meta)
{ {
if (node->mNumMeshes) if (node->mNumMeshes)
{ {
@ -78,7 +76,7 @@ void importNode(CMeshUtilsContext &context, const aiNode *node, const CNodeMeta
} }
for (unsigned int i = 0; i < node->mNumChildren; ++i) for (unsigned int i = 0; i < node->mNumChildren; ++i)
importNode(context, node->mChildren[i], &g_DefaultMeta); importNode(context, node->mChildren[i]);
} }
void validateAssimpNodeNames(CMeshUtilsContext &context, const aiNode *node) void validateAssimpNodeNames(CMeshUtilsContext &context, const aiNode *node)
@ -143,6 +141,77 @@ void flagAssimpBones(CMeshUtilsContext &context)
} }
} }
void flagRecursiveBones(CMeshUtilsContext &context, CNodeContext &nodeContext)
{
nodeContext.IsBone = true;
const aiNode *node = nodeContext.AssimpNode;
nlassert(node);
for (unsigned int i = 0; i < node->mNumChildren; ++i)
flagRecursiveBones(context, context.Nodes[node->mName.C_Str()]);
}
void flagMetaBones(CMeshUtilsContext &context)
{
for (TNodeContextMap::iterator it(context.Nodes.begin()), end(context.Nodes.end()); it != end; ++it)
{
CNodeContext &ctx = it->second;
CNodeMeta &meta = context.SceneMeta.Nodes[it->first];
if (meta.ExportBone == TBoneForce)
ctx.IsBone = true;
else if (meta.ExportBone == TBoneRoot)
flagRecursiveBones(context, ctx);
}
}
void flagLocalParentBones(CMeshUtilsContext &context, CNodeContext &nodeContext)
{
const aiNode *node = nodeContext.AssimpNode;
}
void flagAllParentBones(CMeshUtilsContext &context, CNodeContext &nodeContext)
{
const aiNode *parent = nodeContext.AssimpNode;
while (parent = parent->mParent) if (parent->mName.length)
context.Nodes[parent->mName.C_Str()].IsBone = true;
}
void flagExpandedBones(CMeshUtilsContext &context)
{
switch (context.SceneMeta.SkeletonMode)
{
case TSkelLocal:
for (TNodeContextMap::iterator it(context.Nodes.begin()), end(context.Nodes.end()); it != end; ++it)
{
CNodeContext &nodeContext = it->second;
if (nodeContext.IsBone)
{
}
}
break;
case TSkelRoot:
for (TNodeContextMap::iterator it(context.Nodes.begin()), end(context.Nodes.end()); it != end; ++it)
{
CNodeContext &nodeContext = it->second;
if (nodeContext.IsBone)
{
}
}
break;
case TSkelFull:
for (TNodeContextMap::iterator it(context.Nodes.begin()), end(context.Nodes.end()); it != end; ++it)
{
CNodeContext &nodeContext = it->second;
if (nodeContext.IsBone)
{
}
}
break;
}
}
// TODO: Separate load scene and save scene functions // TODO: Separate load scene and save scene functions
int exportScene(const CMeshUtilsSettings &settings) int exportScene(const CMeshUtilsSettings &settings)
{ {
@ -175,11 +244,15 @@ int exportScene(const CMeshUtilsSettings &settings)
//scene->mRootNode->mMetaData //scene->mRootNode->mMetaData
context.AssimpScene = scene; context.AssimpScene = scene;
if (context.SceneMeta.load(context.Settings.SourceFilePath))
context.ToolLogger.writeDepend(NLMISC::BUILD, "*", context.SceneMeta.metaFilePath().c_str()); // Meta input file
validateAssimpNodeNames(context, context.AssimpScene->mRootNode); validateAssimpNodeNames(context, context.AssimpScene->mRootNode);
flagAssimpBones(context); flagAssimpBones(context);
flagMetaBones(context);
flagExpandedBones(context);
importNode(context, scene->mRootNode, &g_DefaultMeta); importNode(context, scene->mRootNode);
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }

View file

@ -0,0 +1,84 @@
// 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 "scene_meta.h"
#include <nel/misc/debug.h>
#include <nel/misc/stream.h>
#include <nel/misc/file.h>
using namespace std;
using namespace NLMISC;
CNodeMeta::CNodeMeta() :
AddToIG(true),
ExportMesh(TMeshShape),
ExportBone(TBoneAuto)
{
}
void CNodeMeta::serial(NLMISC::IStream &s)
{
uint version = s.serialVersion(1);
s.serial(AddToIG);
s.serial((uint32 &)ExportMesh);
s.serial((uint32 &)ExportBone);
s.serial(InstanceShape);
s.serial(InstanceName);
s.serial(InstanceGroupName);
}
CSceneMeta::CSceneMeta() :
DefaultInstanceGroup(false),
SkeletonMode(TSkelLocal)
{
}
bool CSceneMeta::load(const std::string &filePath)
{
m_MetaFilePath = filePath + ".nelmeta";
if (CFile::fileExists(m_MetaFilePath))
{
CIFile f(m_MetaFilePath);
serial(f);
f.close();
return true;
}
return false;
}
void CSceneMeta::save()
{
COFile f(m_MetaFilePath, false, false, true);
serial(f);
f.close();
}
void CSceneMeta::serial(NLMISC::IStream &s)
{
uint version = s.serialVersion(1);
s.serial(DefaultInstanceGroup);
s.serial((uint32 &)SkeletonMode);
s.serialCont(Nodes);
}
/* end of file */

View file

@ -0,0 +1,83 @@
// 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 <nel/misc/sstring.h>
namespace NLMISC {
class IStream;
}
enum TMesh
{
TMeshDisabled = 0,
TMeshShape = 1,
TMeshCollisionInt = 2,
TMeshCollisionExt = 3,
TMeshZone = 4,
};
enum TBone
{
TBoneAuto = 0,
TBoneForce = 1, // Force this node to be part of a skeleton
TBoneRoot = 2, // Make this node the skeleton root, it will be exported using the scene name. There can only be one (editor should keep track and disable)
};
struct CNodeMeta
{
CNodeMeta();
bool AddToIG; // Add this node to an instance group
TMesh ExportMesh;
TBone ExportBone;
std::string InstanceShape;
std::string InstanceName;
std::string InstanceGroupName;
void serial(NLMISC::IStream &s);
};
enum TSkel
{
TSkelLocal = 0, // Export smallest skeleton possible from connected bones
TSkelRoot = 1, // Export skeleton from direct child node in the scene root node
TSkelFull = 2, // Include all connected child nodes in the skeleton
};
struct CSceneMeta
{
CSceneMeta();
bool DefaultInstanceGroup; // Export a default instance group from nodes the scene that do not have an instance group set
TSkel SkeletonMode;
std::map<NLMISC::CSString, CNodeMeta> Nodes;
const std::string &metaFilePath() const { return m_MetaFilePath; }
bool load(const std::string &filePath);
void save();
void serial(NLMISC::IStream &s);
private:
std::string m_MetaFilePath;
};
/* end of file */