From 50f4afda07bfee9383ebcc772b279af75c7a98c6 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Sun, 20 Sep 2015 21:08:30 +0200 Subject: [PATCH] Import basic material options --- .../tools/3d/mesh_utils/assimp_material.cpp | 143 ++++++++++++++++++ .../nel/tools/3d/mesh_utils/assimp_material.h | 24 +++ code/nel/tools/3d/mesh_utils/mesh_utils.cpp | 7 +- code/nel/tools/3d/mesh_utils/scene_context.h | 5 +- code/nel/tools/3d/mesh_utils/scene_meta.cpp | 7 +- code/nel/tools/3d/mesh_utils/scene_meta.h | 13 +- 6 files changed, 193 insertions(+), 6 deletions(-) create mode 100644 code/nel/tools/3d/mesh_utils/assimp_material.cpp create mode 100644 code/nel/tools/3d/mesh_utils/assimp_material.h diff --git a/code/nel/tools/3d/mesh_utils/assimp_material.cpp b/code/nel/tools/3d/mesh_utils/assimp_material.cpp new file mode 100644 index 000000000..6a786d63b --- /dev/null +++ b/code/nel/tools/3d/mesh_utils/assimp_material.cpp @@ -0,0 +1,143 @@ +// 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 "assimp_shape.h" + +#include +#include +#include + +#define NL_NODE_INTERNAL_TYPE aiNode +#define NL_SCENE_INTERNAL_TYPE aiScene +#include "scene_context.h" + +#include +#include +#include + +#include + +using namespace std; +using namespace NLMISC; +using namespace NL3D; + +// http://assimp.sourceforge.net/lib_html/materials.html + +inline CRGBA convColor(const aiColor3D &ac) +{ + return CRGBA(ac.r * 255.99f, ac.g * 255.99f, ac.b * 255.99f); +} + +inline CRGBA convColor(const aiColor4D &ac) +{ + return CRGBA(ac.r * 255.99f, ac.g * 255.99f, ac.b * 255.99f, ac.a * 255.99f); +} + +CSmartPtr assimpMaterial(CMeshUtilsContext &context, const aiMaterial *am) +{ + CSmartPtr matp = new CMaterial(); + CMaterial &mat = *matp; + mat.initLighted(); + mat.setShader(CMaterial::Normal); + + int i; + float f; + aiColor3D c3; + aiColor4D c4; + + if (am->Get(AI_MATKEY_TWOSIDED, i) == aiReturn_SUCCESS) + mat.setDoubleSided(i != 0); + + if (am->Get(AI_MATKEY_BLEND_FUNC, i) == aiReturn_SUCCESS) switch ((aiBlendMode)i) + { + case aiBlendMode_Default: + mat.setSrcBlend(CMaterial::srcalpha); + mat.setDstBlend(CMaterial::invsrcalpha); + break; + case aiBlendMode_Additive: + mat.setSrcBlend(CMaterial::one); + mat.setDstBlend(CMaterial::one); + break; + } + + if (am->Get(AI_MATKEY_OPACITY, f) == aiReturn_SUCCESS) + mat.setOpacity(f * 255.99f); + + if (am->Get(AI_MATKEY_SHININESS, f) == aiReturn_SUCCESS) + mat.setShininess(f); // OR (float)pow(2.0, shininess * 10.0) * 4.f ?? + + if (am->Get(AI_MATKEY_COLOR_DIFFUSE, c3) == aiReturn_SUCCESS) + { + CRGBA diffuse = convColor(c3); + diffuse.A = mat.getOpacity(); + mat.setDiffuse(diffuse); + } + + if (am->Get(AI_MATKEY_COLOR_AMBIENT, c3) == aiReturn_SUCCESS) + mat.setAmbient(convColor(c3)); + + if (am->Get(AI_MATKEY_COLOR_SPECULAR, c3) == aiReturn_SUCCESS) + { + CRGBA specular = convColor(c3); + if (am->Get(AI_MATKEY_SHININESS_STRENGTH, f) == aiReturn_SUCCESS) + { + CRGBAF fColor = specular; + fColor *= f; + uint8 a = specular.A; + specular = fColor; + specular.A = a; + } + mat.setSpecular(specular); + } + + if (am->Get(AI_MATKEY_COLOR_EMISSIVE, c3) == aiReturn_SUCCESS) + mat.setEmissive(convColor(c3)); + + return matp; +} + +void assimpMaterials(CMeshUtilsContext &context) +{ + const aiScene *scene = context.InternalScene; + for (unsigned int mi = 0; mi < scene->mNumMaterials; ++mi) + { + const aiMaterial *am = scene->mMaterials[mi]; + + for (unsigned int pi = 0; pi < am->mNumProperties; ++pi) // DEBUG + { // DEBUG + const aiMaterialProperty *amp = am->mProperties[pi]; + printf("%s\n", amp->mKey.C_Str()); + } // DEBUG + + aiString amname; + if (am->Get(AI_MATKEY_NAME, amname) != aiReturn_SUCCESS) + { + tlerror(context.ToolLogger, context.Settings.SourceFilePath.c_str(), + "Material has no name"); + continue; + } + + if (context.SceneMeta.Materials.find(amname.C_Str()) + == context.SceneMeta.Materials.end()) + { + context.SceneMeta.Materials[amname.C_Str()] = assimpMaterial(context, am); + } + } +} + +/* end of file */ diff --git a/code/nel/tools/3d/mesh_utils/assimp_material.h b/code/nel/tools/3d/mesh_utils/assimp_material.h new file mode 100644 index 000000000..eac083573 --- /dev/null +++ b/code/nel/tools/3d/mesh_utils/assimp_material.h @@ -0,0 +1,24 @@ +// 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 + +struct CMeshUtilsContext; + +void assimpMaterials(CMeshUtilsContext &context); + +/* end of file */ diff --git a/code/nel/tools/3d/mesh_utils/mesh_utils.cpp b/code/nel/tools/3d/mesh_utils/mesh_utils.cpp index f6313fc98..66454c984 100644 --- a/code/nel/tools/3d/mesh_utils/mesh_utils.cpp +++ b/code/nel/tools/3d/mesh_utils/mesh_utils.cpp @@ -32,6 +32,8 @@ #define NL_NODE_INTERNAL_TYPE aiNode #define NL_SCENE_INTERNAL_TYPE aiScene #include "scene_context.h" + +#include "assimp_material.h" #include "assimp_shape.h" CMeshUtilsSettings::CMeshUtilsSettings() @@ -269,9 +271,10 @@ int exportScene(const CMeshUtilsSettings &settings) // ] // -- SKEL FLAG -- - // TODO - // First import materials... + // First import materials + assimpMaterials(context); + // Import shapes importShapes(context, context.InternalScene->mRootNode); return EXIT_SUCCESS; diff --git a/code/nel/tools/3d/mesh_utils/scene_context.h b/code/nel/tools/3d/mesh_utils/scene_context.h index 737800d6f..714e3ff54 100644 --- a/code/nel/tools/3d/mesh_utils/scene_context.h +++ b/code/nel/tools/3d/mesh_utils/scene_context.h @@ -27,6 +27,8 @@ #include #include +#include + #ifndef NL_NODE_INTERNAL_TYPE #define NL_NODE_INTERNAL_TYPE void #endif @@ -36,6 +38,7 @@ namespace NL3D { class IShape; + class CMaterial; } struct CNodeContext @@ -51,7 +54,7 @@ struct CNodeContext bool IsBone; // NLMISC::CMatrix Transform; // TODO - NLMISC::CRefPtr Shape; + NLMISC::CSmartPtr Shape; }; typedef std::map TNodeContextMap; diff --git a/code/nel/tools/3d/mesh_utils/scene_meta.cpp b/code/nel/tools/3d/mesh_utils/scene_meta.cpp index a81505492..3c72207cf 100644 --- a/code/nel/tools/3d/mesh_utils/scene_meta.cpp +++ b/code/nel/tools/3d/mesh_utils/scene_meta.cpp @@ -22,6 +22,8 @@ #include #include +#include + using namespace std; using namespace NLMISC; @@ -47,7 +49,7 @@ void CNodeMeta::serial(NLMISC::IStream &s) } CSceneMeta::CSceneMeta() : - DefaultInstanceGroup(false), + ExportDefaultIG(false), SkeletonMode(TSkelRoot) { @@ -77,10 +79,11 @@ void CSceneMeta::serial(NLMISC::IStream &s) { uint version = s.serialVersion(1); - s.serial(DefaultInstanceGroup); + s.serial(ExportDefaultIG); s.serial((uint32 &)SkeletonMode); s.serialCont(Nodes); + s.serialPtrCont(Materials); } /* 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 index 972132fbc..43f309557 100644 --- a/code/nel/tools/3d/mesh_utils/scene_meta.h +++ b/code/nel/tools/3d/mesh_utils/scene_meta.h @@ -20,11 +20,18 @@ #include #include +#include + +#include namespace NLMISC { class IStream; } +namespace NL3D { + class CMaterial; +} + enum TMesh { TMeshDisabled = 0, @@ -56,6 +63,7 @@ struct CNodeMeta std::string InstanceGroupName; bool AutoAnim; + // std::vector Materials; // In case there's an issue with nameless materials in some format... Map to material entirely in the meta editor. void serial(NLMISC::IStream &s); }; @@ -67,13 +75,16 @@ enum TSkel TSkelFull = 2, // Include all connected child nodes in the skeleton }; +typedef std::map > TMaterialMap; struct CSceneMeta { CSceneMeta(); - bool DefaultInstanceGroup; // Export a default instance group from nodes the scene that do not have an instance group set + bool ExportDefaultIG; // Export a default instance group from nodes the scene that do not have an instance group set TSkel SkeletonMode; + std::map Nodes; + TMaterialMap Materials; const std::string &metaFilePath() const { return m_MetaFilePath; }