Restructure
--HG-- branch : feature-export-assimp
This commit is contained in:
parent
33dd77d516
commit
e60a9747b8
7 changed files with 208 additions and 53 deletions
41
code/nel/tools/3d/mesh_utils/assimp_shape.cpp
Normal file
41
code/nel/tools/3d/mesh_utils/assimp_shape.cpp
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
// 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 "assimp_shape.h"
|
||||||
|
|
||||||
|
#include <assimp/postprocess.h>
|
||||||
|
#include <assimp/scene.h>
|
||||||
|
#include <assimp/Importer.hpp>
|
||||||
|
|
||||||
|
#define NL_NODE_INTERNAL_TYPE aiNode
|
||||||
|
#define NL_SCENE_INTERNAL_TYPE aiScene
|
||||||
|
#include "scene_context.h"
|
||||||
|
|
||||||
|
#include <nel/misc/debug.h>
|
||||||
|
#include <nel/misc/path.h>
|
||||||
|
#include <nel/misc/tool_logger.h>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace NLMISC;
|
||||||
|
|
||||||
|
void assimpShape(CMeshUtilsContext &context, CNodeContext &nodeContext)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* end of file */
|
25
code/nel/tools/3d/mesh_utils/assimp_shape.h
Normal file
25
code/nel/tools/3d/mesh_utils/assimp_shape.h
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
// 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>
|
||||||
|
|
||||||
|
struct CMeshUtilsContext;
|
||||||
|
struct CNodeContext;
|
||||||
|
|
||||||
|
void assimpShape(CMeshUtilsContext &context, CNodeContext &nodeContext);
|
||||||
|
|
||||||
|
/* end of file */
|
|
@ -29,6 +29,11 @@
|
||||||
#include <assimp/scene.h>
|
#include <assimp/scene.h>
|
||||||
#include <assimp/Importer.hpp>
|
#include <assimp/Importer.hpp>
|
||||||
|
|
||||||
|
#define NL_NODE_INTERNAL_TYPE aiNode
|
||||||
|
#define NL_SCENE_INTERNAL_TYPE aiScene
|
||||||
|
#include "scene_context.h"
|
||||||
|
#include "assimp_shape.h"
|
||||||
|
|
||||||
CMeshUtilsSettings::CMeshUtilsSettings()
|
CMeshUtilsSettings::CMeshUtilsSettings()
|
||||||
{
|
{
|
||||||
/*ShapeDirectory = "shape";
|
/*ShapeDirectory = "shape";
|
||||||
|
@ -36,52 +41,29 @@ CMeshUtilsSettings::CMeshUtilsSettings()
|
||||||
SkelDirectory = "skel";*/
|
SkelDirectory = "skel";*/
|
||||||
}
|
}
|
||||||
|
|
||||||
struct CNodeContext
|
void importShapes(CMeshUtilsContext &context, const aiNode *node)
|
||||||
{
|
{
|
||||||
CNodeContext() :
|
if (node != context.InternalScene->mRootNode)
|
||||||
AssimpNode(NULL),
|
|
||||||
IsBone(false)
|
|
||||||
{
|
{
|
||||||
|
CNodeContext &nodeContext = context.Nodes[node->mName.C_Str()];
|
||||||
}
|
CNodeMeta &nodeMeta = context.SceneMeta.Nodes[node->mName.C_Str()];
|
||||||
|
if (nodeMeta.ExportMesh == TMeshShape)
|
||||||
const aiNode *AssimpNode;
|
{
|
||||||
bool IsBone;
|
if (node->mNumMeshes)
|
||||||
};
|
{
|
||||||
|
nldebug("Shape '%s' found containing '%u' meshes", node->mName.C_Str(), node->mNumMeshes);
|
||||||
typedef std::map<NLMISC::CSString, CNodeContext> TNodeContextMap;
|
assimpShape(context, nodeContext);
|
||||||
struct CMeshUtilsContext
|
}
|
||||||
{
|
}
|
||||||
CMeshUtilsContext(const CMeshUtilsSettings &settings) : Settings(settings), AssimpScene(NULL)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
const CMeshUtilsSettings &Settings;
|
|
||||||
|
|
||||||
NLMISC::CToolLogger ToolLogger;
|
|
||||||
|
|
||||||
const aiScene *AssimpScene;
|
|
||||||
CSceneMeta SceneMeta;
|
|
||||||
|
|
||||||
TNodeContextMap Nodes; // Impl note: Should never end up containing the scene root node.
|
|
||||||
// std::map<const aiMesh *, NLMISC::CSString> MeshNames; // Maps meshes to a node name ********************* todo ***************
|
|
||||||
};
|
|
||||||
|
|
||||||
void importNode(CMeshUtilsContext &context, const aiNode *node)
|
|
||||||
{
|
|
||||||
if (node->mNumMeshes)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned int i = 0; i < node->mNumChildren; ++i)
|
for (unsigned int i = 0; i < node->mNumChildren; ++i)
|
||||||
importNode(context, node->mChildren[i]);
|
importShapes(context, node->mChildren[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void validateAssimpNodeNames(CMeshUtilsContext &context, const aiNode *node)
|
void validateInternalNodeNames(CMeshUtilsContext &context, const aiNode *node)
|
||||||
{
|
{
|
||||||
if (!node->mParent || node == context.AssimpScene->mRootNode)
|
if (!node->mParent || node == context.InternalScene->mRootNode)
|
||||||
{
|
{
|
||||||
// do nothing
|
// do nothing
|
||||||
}
|
}
|
||||||
|
@ -94,25 +76,25 @@ void validateAssimpNodeNames(CMeshUtilsContext &context, const aiNode *node)
|
||||||
{
|
{
|
||||||
CNodeContext &nodeContext = context.Nodes[node->mName.C_Str()];
|
CNodeContext &nodeContext = context.Nodes[node->mName.C_Str()];
|
||||||
|
|
||||||
if (nodeContext.AssimpNode && nodeContext.AssimpNode != node)
|
if (nodeContext.InternalNode && nodeContext.InternalNode != node)
|
||||||
{
|
{
|
||||||
tlerror(context.ToolLogger, context.Settings.SourceFilePath.c_str(),
|
tlerror(context.ToolLogger, context.Settings.SourceFilePath.c_str(),
|
||||||
"Node name '%s' appears multiple times", node->mName.C_Str());
|
"Node name '%s' appears multiple times", node->mName.C_Str());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
nodeContext.AssimpNode = node;
|
nodeContext.InternalNode = node;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned int i = 0; i < node->mNumChildren; ++i)
|
for (unsigned int i = 0; i < node->mNumChildren; ++i)
|
||||||
validateAssimpNodeNames(context, node->mChildren[i]);
|
validateInternalNodeNames(context, node->mChildren[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void flagAssimpBones(CMeshUtilsContext &context)
|
void flagAssimpBones(CMeshUtilsContext &context)
|
||||||
{
|
{
|
||||||
// Find out which nodes are bones by checking the mesh meta info
|
// Find out which nodes are bones by checking the mesh meta info
|
||||||
const aiScene *scene = context.AssimpScene;
|
const aiScene *scene = context.InternalScene;
|
||||||
for (unsigned int i = 0; i < scene->mNumMeshes; ++i)
|
for (unsigned int i = 0; i < scene->mNumMeshes; ++i)
|
||||||
{
|
{
|
||||||
// nldebug("FOUND MESH '%s'\n", scene->mMeshes[i]->mName.C_Str());
|
// nldebug("FOUND MESH '%s'\n", scene->mMeshes[i]->mName.C_Str());
|
||||||
|
@ -120,7 +102,7 @@ void flagAssimpBones(CMeshUtilsContext &context)
|
||||||
for (unsigned int j = 0; j < mesh->mNumBones; ++j)
|
for (unsigned int j = 0; j < mesh->mNumBones; ++j)
|
||||||
{
|
{
|
||||||
CNodeContext &nodeContext = context.Nodes[mesh->mBones[j]->mName.C_Str()];
|
CNodeContext &nodeContext = context.Nodes[mesh->mBones[j]->mName.C_Str()];
|
||||||
if (!nodeContext.AssimpNode)
|
if (!nodeContext.InternalNode)
|
||||||
{
|
{
|
||||||
tlerror(context.ToolLogger, context.Settings.SourceFilePath.c_str(),
|
tlerror(context.ToolLogger, context.Settings.SourceFilePath.c_str(),
|
||||||
"Bone '%s' has no associated node", mesh->mBones[j]->mName.C_Str());
|
"Bone '%s' has no associated node", mesh->mBones[j]->mName.C_Str());
|
||||||
|
@ -131,7 +113,7 @@ void flagAssimpBones(CMeshUtilsContext &context)
|
||||||
nodeContext.IsBone = true;
|
nodeContext.IsBone = true;
|
||||||
|
|
||||||
// Flag all parents as bones
|
// Flag all parents as bones
|
||||||
/*const aiNode *parent = nodeContext.AssimpNode;
|
/*const aiNode *parent = nodeContext.InternalNode;
|
||||||
while (parent = parent->mParent) if (parent->mName.length)
|
while (parent = parent->mParent) if (parent->mName.length)
|
||||||
{
|
{
|
||||||
context.Nodes[parent->mName.C_Str()].IsBone = true;
|
context.Nodes[parent->mName.C_Str()].IsBone = true;
|
||||||
|
@ -147,7 +129,7 @@ void flagAssimpBones(CMeshUtilsContext &context)
|
||||||
void flagRecursiveBones(CMeshUtilsContext &context, CNodeContext &nodeContext, bool autoStop = false)
|
void flagRecursiveBones(CMeshUtilsContext &context, CNodeContext &nodeContext, bool autoStop = false)
|
||||||
{
|
{
|
||||||
nodeContext.IsBone = true;
|
nodeContext.IsBone = true;
|
||||||
const aiNode *node = nodeContext.AssimpNode;
|
const aiNode *node = nodeContext.InternalNode;
|
||||||
nlassert(node);
|
nlassert(node);
|
||||||
for (unsigned int i = 0; i < node->mNumChildren; ++i)
|
for (unsigned int i = 0; i < node->mNumChildren; ++i)
|
||||||
{
|
{
|
||||||
|
@ -173,13 +155,13 @@ void flagMetaBones(CMeshUtilsContext &context)
|
||||||
|
|
||||||
void flagLocalParentBones(CMeshUtilsContext &context, CNodeContext &nodeContext)
|
void flagLocalParentBones(CMeshUtilsContext &context, CNodeContext &nodeContext)
|
||||||
{
|
{
|
||||||
const aiNode *node = nodeContext.AssimpNode;
|
const aiNode *node = nodeContext.InternalNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
void flagAllParentBones(CMeshUtilsContext &context, CNodeContext &nodeContext, bool autoStop = false)
|
void flagAllParentBones(CMeshUtilsContext &context, CNodeContext &nodeContext, bool autoStop = false)
|
||||||
{
|
{
|
||||||
const aiNode *parent = nodeContext.AssimpNode;
|
const aiNode *parent = nodeContext.InternalNode;
|
||||||
while (parent = parent->mParent) if (parent->mName.length && parent != context.AssimpScene->mRootNode)
|
while (parent = parent->mParent) if (parent->mName.length && parent != context.InternalScene->mRootNode)
|
||||||
{
|
{
|
||||||
CNodeContext &ctx = context.Nodes[parent->mName.C_Str()];
|
CNodeContext &ctx = context.Nodes[parent->mName.C_Str()];
|
||||||
if (autoStop && ctx.IsBone)
|
if (autoStop && ctx.IsBone)
|
||||||
|
@ -190,8 +172,8 @@ void flagAllParentBones(CMeshUtilsContext &context, CNodeContext &nodeContext, b
|
||||||
|
|
||||||
bool hasIndirectParentBone(CMeshUtilsContext &context, CNodeContext &nodeContext)
|
bool hasIndirectParentBone(CMeshUtilsContext &context, CNodeContext &nodeContext)
|
||||||
{
|
{
|
||||||
const aiNode *parent = nodeContext.AssimpNode;
|
const aiNode *parent = nodeContext.InternalNode;
|
||||||
while (parent = parent->mParent) if (parent->mName.length && parent != context.AssimpScene->mRootNode)
|
while (parent = parent->mParent) if (parent->mName.length && parent != context.InternalScene->mRootNode)
|
||||||
if (context.Nodes[parent->mName.C_Str()].IsBone) return true;
|
if (context.Nodes[parent->mName.C_Str()].IsBone) return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -264,11 +246,11 @@ int exportScene(const CMeshUtilsSettings &settings)
|
||||||
// aiProcess_ImproveCacheLocality: TODO: Verify this does not modify vertex indices
|
// aiProcess_ImproveCacheLocality: TODO: Verify this does not modify vertex indices
|
||||||
//scene->mRootNode->mMetaData
|
//scene->mRootNode->mMetaData
|
||||||
|
|
||||||
context.AssimpScene = scene;
|
context.InternalScene = scene;
|
||||||
if (context.SceneMeta.load(context.Settings.SourceFilePath))
|
if (context.SceneMeta.load(context.Settings.SourceFilePath))
|
||||||
context.ToolLogger.writeDepend(NLMISC::BUILD, "*", context.SceneMeta.metaFilePath().c_str()); // Meta input file
|
context.ToolLogger.writeDepend(NLMISC::BUILD, "*", context.SceneMeta.metaFilePath().c_str()); // Meta input file
|
||||||
|
|
||||||
validateAssimpNodeNames(context, context.AssimpScene->mRootNode);
|
validateInternalNodeNames(context, context.InternalScene->mRootNode);
|
||||||
|
|
||||||
// -- SKEL FLAG --
|
// -- SKEL FLAG --
|
||||||
flagAssimpBones(context);
|
flagAssimpBones(context);
|
||||||
|
@ -283,7 +265,7 @@ int exportScene(const CMeshUtilsSettings &settings)
|
||||||
// ]
|
// ]
|
||||||
// -- SKEL FLAG --
|
// -- SKEL FLAG --
|
||||||
|
|
||||||
importNode(context, scene->mRootNode);
|
importShapes(context, context.InternalScene->mRootNode);
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
// You should have received a copy of the GNU Affero General Public License
|
// 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/>.
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#ifndef NL_MESH_UTILS_H
|
||||||
|
#define NL_MESH_UTILS_H
|
||||||
#include <nel/misc/types_nl.h>
|
#include <nel/misc/types_nl.h>
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
@ -37,4 +39,6 @@ struct CMeshUtilsSettings
|
||||||
|
|
||||||
int exportScene(const CMeshUtilsSettings &settings);
|
int exportScene(const CMeshUtilsSettings &settings);
|
||||||
|
|
||||||
|
#endif /* NL_MESH_UTILS_H */
|
||||||
|
|
||||||
/* end of file */
|
/* end of file */
|
||||||
|
|
30
code/nel/tools/3d/mesh_utils/scene_context.cpp
Normal file
30
code/nel/tools/3d/mesh_utils/scene_context.cpp
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
// 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_context.h"
|
||||||
|
|
||||||
|
#include <nel/misc/debug.h>
|
||||||
|
#include <nel/misc/path.h>
|
||||||
|
#include <nel/misc/tool_logger.h>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace NLMISC;
|
||||||
|
|
||||||
|
void dummy_scene_context_cpp();
|
||||||
|
|
||||||
|
/* end of file */
|
69
code/nel/tools/3d/mesh_utils/scene_context.h
Normal file
69
code/nel/tools/3d/mesh_utils/scene_context.h
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
// 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/>.
|
||||||
|
|
||||||
|
#ifndef NL_SCENE_CONTEXT_H
|
||||||
|
#define NL_SCENE_CONTEXT_H
|
||||||
|
#include <nel/misc/types_nl.h>
|
||||||
|
|
||||||
|
#include "mesh_utils.h"
|
||||||
|
#include "scene_meta.h"
|
||||||
|
|
||||||
|
#include <nel/misc/sstring.h>
|
||||||
|
#include <nel/misc/tool_logger.h>
|
||||||
|
|
||||||
|
#ifndef NL_NODE_INTERNAL_TYPE
|
||||||
|
#define NL_NODE_INTERNAL_TYPE void
|
||||||
|
#endif
|
||||||
|
#ifndef NL_SCENE_INTERNAL_TYPE
|
||||||
|
#define NL_SCENE_INTERNAL_TYPE void
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct CNodeContext
|
||||||
|
{
|
||||||
|
CNodeContext() :
|
||||||
|
InternalNode(NULL),
|
||||||
|
IsBone(false)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const NL_NODE_INTERNAL_TYPE *InternalNode;
|
||||||
|
bool IsBone;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::map<NLMISC::CSString, CNodeContext> TNodeContextMap;
|
||||||
|
struct CMeshUtilsContext
|
||||||
|
{
|
||||||
|
CMeshUtilsContext(const CMeshUtilsSettings &settings) : Settings(settings), InternalScene(NULL)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const CMeshUtilsSettings &Settings;
|
||||||
|
|
||||||
|
NLMISC::CToolLogger ToolLogger;
|
||||||
|
|
||||||
|
const NL_SCENE_INTERNAL_TYPE *InternalScene;
|
||||||
|
CSceneMeta SceneMeta;
|
||||||
|
|
||||||
|
TNodeContextMap Nodes; // Impl note: Should never end up containing the scene root node.
|
||||||
|
// std::map<const aiMesh *, NLMISC::CSString> MeshNames; // Maps meshes to a node name ********************* todo ***************
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* NL_SCENE_CONTEXT_H */
|
||||||
|
|
||||||
|
/* end of file */
|
|
@ -15,6 +15,8 @@
|
||||||
// You should have received a copy of the GNU Affero General Public License
|
// 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/>.
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#ifndef NL_SCENE_META_H
|
||||||
|
#define NL_SCENE_META_H
|
||||||
#include <nel/misc/types_nl.h>
|
#include <nel/misc/types_nl.h>
|
||||||
|
|
||||||
#include <nel/misc/sstring.h>
|
#include <nel/misc/sstring.h>
|
||||||
|
@ -80,4 +82,6 @@ private:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#endif NL_SCENE_META_H
|
||||||
|
|
||||||
/* end of file */
|
/* end of file */
|
||||||
|
|
Loading…
Reference in a new issue