Export shape

--HG--
branch : feature-export-assimp
This commit is contained in:
kaetemi 2015-09-20 21:41:53 +02:00
parent c9aef7b5a4
commit efccbdd3af
4 changed files with 85 additions and 7 deletions

View file

@ -48,10 +48,8 @@ inline CRGBA convColor(const aiColor4D &ac)
return CRGBA(ac.r * 255.99f, ac.g * 255.99f, ac.b * 255.99f, ac.a * 255.99f); return CRGBA(ac.r * 255.99f, ac.g * 255.99f, ac.b * 255.99f, ac.a * 255.99f);
} }
CSmartPtr<CMaterial> assimpMaterial(CMeshUtilsContext &context, const aiMaterial *am) void assimpMaterial(NL3D::CMaterial &mat, CMeshUtilsContext &context, const aiMaterial *am)
{ {
CSmartPtr<CMaterial> matp = new CMaterial();
CMaterial &mat = *matp;
mat.initLighted(); mat.initLighted();
mat.setShader(CMaterial::Normal); mat.setShader(CMaterial::Normal);
@ -107,12 +105,20 @@ CSmartPtr<CMaterial> assimpMaterial(CMeshUtilsContext &context, const aiMaterial
if (am->Get(AI_MATKEY_COLOR_EMISSIVE, c3) == aiReturn_SUCCESS) if (am->Get(AI_MATKEY_COLOR_EMISSIVE, c3) == aiReturn_SUCCESS)
mat.setEmissive(convColor(c3)); mat.setEmissive(convColor(c3));
}
CSmartPtr<CMaterial> assimpMaterial(CMeshUtilsContext &context, const aiMaterial *am)
{
CSmartPtr<CMaterial> matp = new CMaterial();
CMaterial &mat = *matp;
assimpMaterial(mat, context, am);
return matp; return matp;
} }
void assimpMaterials(CMeshUtilsContext &context) void assimpMaterials(CMeshUtilsContext &context)
{ {
set<CSString> materialNames;
const aiScene *scene = context.InternalScene; const aiScene *scene = context.InternalScene;
for (unsigned int mi = 0; mi < scene->mNumMaterials; ++mi) for (unsigned int mi = 0; mi < scene->mNumMaterials; ++mi)
{ {
@ -131,10 +137,18 @@ void assimpMaterials(CMeshUtilsContext &context)
"Material has no name"); "Material has no name");
continue; continue;
} }
if (materialNames.find(amname.C_Str()) != materialNames.end())
{
tlerror(context.ToolLogger, context.Settings.SourceFilePath.c_str(),
"Material name '%s' used more than once", amname.C_Str());
continue;
}
if (context.SceneMeta.Materials.find(amname.C_Str()) if (context.SceneMeta.Materials.find(amname.C_Str())
== context.SceneMeta.Materials.end()) == context.SceneMeta.Materials.end())
{ {
materialNames.insert(amname.C_Str());
context.SceneMeta.Materials[amname.C_Str()] = assimpMaterial(context, am); context.SceneMeta.Materials[amname.C_Str()] = assimpMaterial(context, am);
} }
} }

View file

@ -17,8 +17,12 @@
#include <nel/misc/types_nl.h> #include <nel/misc/types_nl.h>
struct CMeshUtilsContext; namespace NL3D {
class CMaterial;
}
struct CMeshUtilsContext;
void assimpMaterial(NL3D::CMaterial &mat, CMeshUtilsContext &context, const aiMaterial *am);
void assimpMaterials(CMeshUtilsContext &context); void assimpMaterials(CMeshUtilsContext &context);
/* end of file */ /* end of file */

View file

@ -32,6 +32,8 @@
#include <nel/3d/mesh.h> #include <nel/3d/mesh.h>
#include "assimp_material.h"
using namespace std; using namespace std;
using namespace NLMISC; using namespace NLMISC;
using namespace NL3D; using namespace NL3D;
@ -50,10 +52,31 @@ using namespace NL3D;
// TODO: Skinned - reverse transform by skeleton root bone to align? // TODO: Skinned - reverse transform by skeleton root bone to align?
void assimpBuildBaseMesh(CMeshBase::CMeshBaseBuild &buildBaseMesh, CNodeContext &nodeContext) void assimpBuildBaseMesh(CMeshBase::CMeshBaseBuild &buildBaseMesh, CMeshUtilsContext &context, CNodeContext &nodeContext)
{ {
const aiNode *node = nodeContext.InternalNode; const aiNode *node = nodeContext.InternalNode;
// TODO: Reference CExportNel::buildBaseMeshInterface // Reference CExportNel::buildBaseMeshInterface
// Load materials
buildBaseMesh.Materials.resize(node->mNumMeshes);
for (unsigned int mi = 0; mi < node->mNumMeshes; ++mi)
{
const aiMesh *mesh = context.InternalScene->mMeshes[node->mMeshes[mi]];
const aiMaterial *am = context.InternalScene->mMaterials[mesh->mMaterialIndex];
aiString amname;
if (am->Get(AI_MATKEY_NAME, amname) != aiReturn_SUCCESS)
{
tlerror(context.ToolLogger, context.Settings.SourceFilePath.c_str(),
"Material used by node '%s' has no name", node->mName.C_Str()); // TODO: Maybe autogen names by index in mesh or node if this is actually a thing
assimpMaterial(buildBaseMesh.Materials[mi], context, am);
}
else
{
buildBaseMesh.Materials[mi] = *context.SceneMeta.Materials[amname.C_Str()];
}
}
} }
inline CVector convVector(const aiVector3D &av) inline CVector convVector(const aiVector3D &av)
@ -101,6 +124,9 @@ bool assimpBuildMesh(CMesh::CMeshBuild &buildMesh, CMeshBase::CMeshBaseBuild &bu
} }
} }
// Default vertex flags
buildMesh.VertexFlags = CVertexBuffer::PositionFlag | CVertexBuffer::NormalFlag;
// TODO: UV Channels // TODO: UV Channels
for (uint i = 0; i < CVertexBuffer::MaxStage; ++i) for (uint i = 0; i < CVertexBuffer::MaxStage; ++i)
buildMesh.UVRouting[i] = i; buildMesh.UVRouting[i] = i;
@ -208,7 +234,7 @@ bool assimpShape(CMeshUtilsContext &context, CNodeContext &nodeContext)
// Fill the build interface of CMesh // Fill the build interface of CMesh
CMeshBase::CMeshBaseBuild buildBaseMesh; CMeshBase::CMeshBaseBuild buildBaseMesh;
assimpBuildBaseMesh(buildBaseMesh, nodeContext); assimpBuildBaseMesh(buildBaseMesh, context, nodeContext);
CMesh::CMeshBuild buildMesh; CMesh::CMeshBuild buildMesh;
if (!assimpBuildMesh(buildMesh, buildBaseMesh, context, nodeContext)) if (!assimpBuildMesh(buildMesh, buildBaseMesh, context, nodeContext))

View file

@ -21,6 +21,9 @@
#include <nel/misc/debug.h> #include <nel/misc/debug.h>
#include <nel/misc/tool_logger.h> #include <nel/misc/tool_logger.h>
#include <nel/misc/sstring.h> #include <nel/misc/sstring.h>
#include <nel/misc/file.h>
#include <nel/3d/shape.h>
#include "database_config.h" #include "database_config.h"
#include "scene_meta.h" #include "scene_meta.h"
@ -217,6 +220,34 @@ void flagExpandedBones(CMeshUtilsContext &context)
} }
} }
void exportShapes(CMeshUtilsContext &context)
{
for (TNodeContextMap::iterator it(context.Nodes.begin()), end(context.Nodes.end()); it != end; ++it)
{
CNodeContext &nodeContext = it->second;
if (nodeContext.Shape)
{
std::string shapePath = context.Settings.DestinationDirectoryPath + "/" + it->first + ".shape";
context.ToolLogger.writeDepend(NLMISC::BUILD, shapePath.c_str(), "*");
NLMISC::COFile f;
if (f.open(shapePath, false, false, true))
{
try
{
NL3D::CShapeStream shapeStream(nodeContext.Shape);
shapeStream.serial(f);
f.close();
}
catch (...)
{
tlerror(context.ToolLogger, context.Settings.SourceFilePath.c_str(),
"Shape '%s' serialization failed!", it->first.c_str());
}
}
}
}
}
// 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)
{ {
@ -277,6 +308,9 @@ int exportScene(const CMeshUtilsSettings &settings)
// Import shapes // Import shapes
importShapes(context, context.InternalScene->mRootNode); importShapes(context, context.InternalScene->mRootNode);
// Export shapes
exportShapes(context);
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }