From a64c4bfc6c802182d4555d43cedc9551e256239c Mon Sep 17 00:00:00 2001 From: kaetemi Date: Sun, 20 Sep 2015 16:44:56 +0200 Subject: [PATCH] Scene meta data --- code/nel/tools/3d/mesh_utils/mesh_utils.cpp | 95 ++++++++++++++++++--- code/nel/tools/3d/mesh_utils/scene_meta.cpp | 84 ++++++++++++++++++ code/nel/tools/3d/mesh_utils/scene_meta.h | 83 ++++++++++++++++++ 3 files changed, 251 insertions(+), 11 deletions(-) create mode 100644 code/nel/tools/3d/mesh_utils/scene_meta.cpp create mode 100644 code/nel/tools/3d/mesh_utils/scene_meta.h diff --git a/code/nel/tools/3d/mesh_utils/mesh_utils.cpp b/code/nel/tools/3d/mesh_utils/mesh_utils.cpp index 4af32091b..57fea70e6 100644 --- a/code/nel/tools/3d/mesh_utils/mesh_utils.cpp +++ b/code/nel/tools/3d/mesh_utils/mesh_utils.cpp @@ -23,6 +23,7 @@ #include #include "database_config.h" +#include "scene_meta.h" #include #include @@ -48,6 +49,7 @@ struct CNodeContext bool IsBone; }; +typedef std::map TNodeContextMap; struct CMeshUtilsContext { CMeshUtilsContext(const CMeshUtilsSettings &settings) : Settings(settings), AssimpScene(NULL) @@ -60,17 +62,13 @@ struct CMeshUtilsContext NLMISC::CToolLogger ToolLogger; const aiScene *AssimpScene; - std::map Nodes; - std::map MeshNames; // Maps meshes to a node name ********************* todo *************** + CSceneMeta SceneMeta; + + TNodeContextMap Nodes; + // std::map MeshNames; // Maps meshes to a node name ********************* todo *************** }; -struct CNodeMeta -{ - // TODO -}; -static const CNodeMeta g_DefaultMeta; - -void importNode(CMeshUtilsContext &context, const aiNode *node, const CNodeMeta *meta) +void importNode(CMeshUtilsContext &context, const aiNode *node) { 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) - importNode(context, node->mChildren[i], &g_DefaultMeta); + importNode(context, node->mChildren[i]); } 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 int exportScene(const CMeshUtilsSettings &settings) { @@ -175,11 +244,15 @@ int exportScene(const CMeshUtilsSettings &settings) //scene->mRootNode->mMetaData 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); flagAssimpBones(context); + flagMetaBones(context); + flagExpandedBones(context); - importNode(context, scene->mRootNode, &g_DefaultMeta); + importNode(context, scene->mRootNode); return EXIT_SUCCESS; } diff --git a/code/nel/tools/3d/mesh_utils/scene_meta.cpp b/code/nel/tools/3d/mesh_utils/scene_meta.cpp new file mode 100644 index 000000000..19260d201 --- /dev/null +++ b/code/nel/tools/3d/mesh_utils/scene_meta.cpp @@ -0,0 +1,84 @@ +// 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 "scene_meta.h" + +#include +#include +#include + +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 */ diff --git a/code/nel/tools/3d/mesh_utils/scene_meta.h b/code/nel/tools/3d/mesh_utils/scene_meta.h new file mode 100644 index 000000000..a3791bb50 --- /dev/null +++ b/code/nel/tools/3d/mesh_utils/scene_meta.h @@ -0,0 +1,83 @@ +// 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 + +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 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 */