Import material texture
--HG-- branch : feature-export-assimp
This commit is contained in:
parent
f8bb35c449
commit
27e7095db9
4 changed files with 128 additions and 3 deletions
|
@ -31,6 +31,7 @@
|
||||||
#include <nel/misc/tool_logger.h>
|
#include <nel/misc/tool_logger.h>
|
||||||
|
|
||||||
#include <nel/3d/mesh.h>
|
#include <nel/3d/mesh.h>
|
||||||
|
#include <nel/3d/texture_file.h>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace NLMISC;
|
using namespace NLMISC;
|
||||||
|
@ -50,6 +51,10 @@ inline CRGBA convColor(const aiColor4D &ac)
|
||||||
|
|
||||||
void assimpMaterial(NL3D::CMaterial &mat, CMeshUtilsContext &context, const aiMaterial *am)
|
void assimpMaterial(NL3D::CMaterial &mat, CMeshUtilsContext &context, const aiMaterial *am)
|
||||||
{
|
{
|
||||||
|
aiString amname;
|
||||||
|
if (am->Get(AI_MATKEY_NAME, amname) != aiReturn_SUCCESS)
|
||||||
|
amname = "";
|
||||||
|
|
||||||
mat.initLighted();
|
mat.initLighted();
|
||||||
mat.setShader(CMaterial::Normal);
|
mat.setShader(CMaterial::Normal);
|
||||||
|
|
||||||
|
@ -99,6 +104,78 @@ void assimpMaterial(NL3D::CMaterial &mat, CMeshUtilsContext &context, const aiMa
|
||||||
|
|
||||||
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));
|
||||||
|
|
||||||
|
// Textures
|
||||||
|
unsigned int texCount = am->GetTextureCount(aiTextureType_DIFFUSE);
|
||||||
|
if (texCount > IDRV_MAT_MAXTEXTURES)
|
||||||
|
{
|
||||||
|
tlwarning(context.ToolLogger, context.Settings.SourceFilePath.c_str(),
|
||||||
|
"Material '%s' has more than %i textures (%i textures found)", amname.C_Str(), IDRV_MAT_MAXTEXTURES, texCount);
|
||||||
|
texCount = IDRV_MAT_MAXTEXTURES;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned int ti = 0; ti < texCount; ++ti)
|
||||||
|
{
|
||||||
|
aiString path;
|
||||||
|
aiTextureMapping mapping;
|
||||||
|
unsigned int uvindex;
|
||||||
|
float blend; // Partially supported
|
||||||
|
aiTextureOp op;
|
||||||
|
aiTextureMapMode mapmode;
|
||||||
|
if (am->GetTexture(aiTextureType_DIFFUSE, ti, &path, &mapping, &uvindex, &blend, &op, &mapmode) != aiReturn_SUCCESS)
|
||||||
|
{
|
||||||
|
tlerror(context.ToolLogger, context.Settings.SourceFilePath.c_str(),
|
||||||
|
"Failed to get texture %i in material '%s'", ti, amname.C_Str());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string fileName = CFile::getFilename(CPath::standardizePath(path.C_Str(), false));
|
||||||
|
std::string knownPath = CPath::lookup(fileName, false, false, false);
|
||||||
|
if (knownPath.empty())
|
||||||
|
{
|
||||||
|
tlwarning(context.ToolLogger, context.Settings.SourceFilePath.c_str(),
|
||||||
|
"Texture '%s' referenced in material '%s' but not found in the database search paths", fileName.c_str(), amname.C_Str());
|
||||||
|
}
|
||||||
|
|
||||||
|
// NeL supports bitmap and cubemap, but we import only basic bitmap here. Cubemap can be inserted from the mesh editor tool
|
||||||
|
// NeL also has fancy multi-bitmap thing to switch between summer and winter and so on. Same story
|
||||||
|
CSmartPtr<CTextureFile> tex = new CTextureFile();
|
||||||
|
tex->setFileName(fileName);
|
||||||
|
tex->setWrapS(mapmode == aiTextureMapMode_Clamp ? ITexture::Clamp : ITexture::Repeat);
|
||||||
|
tex->setWrapT(mapmode == aiTextureMapMode_Clamp ? ITexture::Clamp : ITexture::Repeat);
|
||||||
|
mat.setTexture(ti, tex);
|
||||||
|
|
||||||
|
// TODO uvindex for uv routing (probably necessary during shape import - if so also need to also ask the uv channel in the editor and store in meta)
|
||||||
|
|
||||||
|
// TODO aiTextureMapping texcoordgen if useful to import
|
||||||
|
|
||||||
|
mat.texEnvArg0Alpha(ti, CMaterial::Texture, CMaterial::SrcAlpha);
|
||||||
|
mat.texEnvArg0RGB(ti, CMaterial::Texture, CMaterial::SrcColor);
|
||||||
|
mat.texEnvArg1Alpha(ti, ti == 0 ? CMaterial::Diffuse : CMaterial::Previous, CMaterial::SrcAlpha);
|
||||||
|
mat.texEnvArg1RGB(ti, ti == 0 ? CMaterial::Diffuse : CMaterial::Previous, CMaterial::SrcColor);
|
||||||
|
switch (op)
|
||||||
|
{
|
||||||
|
case aiTextureOp_Multiply:
|
||||||
|
default:
|
||||||
|
mat.texEnvOpAlpha(ti, CMaterial::Modulate);
|
||||||
|
mat.texEnvOpRGB(ti, CMaterial::Modulate);
|
||||||
|
break;
|
||||||
|
case aiTextureOp_Add:
|
||||||
|
mat.texEnvOpAlpha(ti, CMaterial::Add);
|
||||||
|
mat.texEnvOpRGB(ti, CMaterial::Add);
|
||||||
|
break;
|
||||||
|
case aiTextureOp_Subtract:
|
||||||
|
mat.texEnvArg0Alpha(ti, CMaterial::Texture, CMaterial::InvSrcAlpha);
|
||||||
|
mat.texEnvArg0RGB(ti, CMaterial::Texture, CMaterial::InvSrcColor);
|
||||||
|
mat.texEnvOpAlpha(ti, CMaterial::Add);
|
||||||
|
mat.texEnvOpRGB(ti, CMaterial::Add);
|
||||||
|
break;
|
||||||
|
case aiTextureOp_SignedAdd:
|
||||||
|
mat.texEnvOpAlpha(ti, CMaterial::AddSigned);
|
||||||
|
mat.texEnvOpRGB(ti, CMaterial::AddSigned);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CSmartPtr<CMaterial> assimpMaterial(CMeshUtilsContext &context, const aiMaterial *am)
|
CSmartPtr<CMaterial> assimpMaterial(CMeshUtilsContext &context, const aiMaterial *am)
|
||||||
|
|
|
@ -22,8 +22,11 @@
|
||||||
#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/misc/file.h>
|
||||||
|
#include <nel/misc/path.h>
|
||||||
|
|
||||||
#include <nel/3d/shape.h>
|
#include <nel/3d/shape.h>
|
||||||
|
#include <nel/3d/mesh.h>
|
||||||
|
#include <nel/3d/texture_file.h>
|
||||||
|
|
||||||
#include "database_config.h"
|
#include "database_config.h"
|
||||||
#include "scene_meta.h"
|
#include "scene_meta.h"
|
||||||
|
@ -227,7 +230,7 @@ void exportShapes(CMeshUtilsContext &context)
|
||||||
CNodeContext &nodeContext = it->second;
|
CNodeContext &nodeContext = it->second;
|
||||||
if (nodeContext.Shape)
|
if (nodeContext.Shape)
|
||||||
{
|
{
|
||||||
std::string shapePath = context.Settings.DestinationDirectoryPath + "/" + it->first + ".shape";
|
std::string shapePath = NLMISC::CPath::standardizePath(context.Settings.DestinationDirectoryPath, true) + it->first + ".shape";
|
||||||
context.ToolLogger.writeDepend(NLMISC::BUILD, shapePath.c_str(), "*");
|
context.ToolLogger.writeDepend(NLMISC::BUILD, shapePath.c_str(), "*");
|
||||||
NLMISC::COFile f;
|
NLMISC::COFile f;
|
||||||
if (f.open(shapePath, false, false, true))
|
if (f.open(shapePath, false, false, true))
|
||||||
|
@ -244,6 +247,34 @@ void exportShapes(CMeshUtilsContext &context)
|
||||||
"Shape '%s' serialization failed!", it->first.c_str());
|
"Shape '%s' serialization failed!", it->first.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (NL3D::CMesh *mesh = dynamic_cast<NL3D::CMesh *>(nodeContext.Shape.getPtr()))
|
||||||
|
{
|
||||||
|
for (uint mi = 0; mi < mesh->getNbMaterial(); ++mi)
|
||||||
|
{
|
||||||
|
NL3D::CMaterial &mat = mesh->getMaterial(mi);
|
||||||
|
for (uint ti = 0; ti < NL3D::IDRV_MAT_MAXTEXTURES; ++ti)
|
||||||
|
{
|
||||||
|
if (NL3D::ITexture *itex = mat.getTexture(ti))
|
||||||
|
{
|
||||||
|
if (NL3D::CTextureFile *tex = dynamic_cast<NL3D::CTextureFile *>(itex))
|
||||||
|
{
|
||||||
|
std::string fileName = tex->getFileName();
|
||||||
|
std::string knownPath = NLMISC::CPath::lookup(fileName, false, false, false);
|
||||||
|
if (!knownPath.empty())
|
||||||
|
{
|
||||||
|
context.ToolLogger.writeDepend(NLMISC::RUNTIME, shapePath.c_str(), knownPath.c_str());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// TODO: Move this warning into nelmeta serialization so it's shown before export
|
||||||
|
tlwarning(context.ToolLogger, context.Settings.SourceFilePath.c_str(),
|
||||||
|
"Texture '%s' referenced in material but not found in the database search paths", fileName.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -258,7 +289,7 @@ int exportScene(const CMeshUtilsSettings &settings)
|
||||||
context.ToolLogger.initDepend(settings.ToolDependLog);
|
context.ToolLogger.initDepend(settings.ToolDependLog);
|
||||||
if (!settings.ToolErrorLog.empty())
|
if (!settings.ToolErrorLog.empty())
|
||||||
context.ToolLogger.initError(settings.ToolErrorLog);
|
context.ToolLogger.initError(settings.ToolErrorLog);
|
||||||
context.ToolLogger.writeDepend(NLMISC::BUILD, "*", context.Settings.SourceFilePath.c_str()); // Base input file
|
context.ToolLogger.writeDepend(NLMISC::BUILD, "*", NLMISC::CPath::standardizePath(context.Settings.SourceFilePath, false).c_str()); // Base input file
|
||||||
|
|
||||||
// Apply database configuration
|
// Apply database configuration
|
||||||
CDatabaseConfig::init(settings.SourceFilePath);
|
CDatabaseConfig::init(settings.SourceFilePath);
|
||||||
|
|
|
@ -49,6 +49,11 @@ void CNodeMeta::serial(NLMISC::IStream &s)
|
||||||
}
|
}
|
||||||
|
|
||||||
CSceneMeta::CSceneMeta() :
|
CSceneMeta::CSceneMeta() :
|
||||||
|
ImportShape(true),
|
||||||
|
ImportSkel(true),
|
||||||
|
ImportAnim(true),
|
||||||
|
ImportCmb(true),
|
||||||
|
ImportIG(true),
|
||||||
ExportDefaultIG(false),
|
ExportDefaultIG(false),
|
||||||
SkeletonMode(TSkelRoot)
|
SkeletonMode(TSkelRoot)
|
||||||
{
|
{
|
||||||
|
@ -57,7 +62,7 @@ CSceneMeta::CSceneMeta() :
|
||||||
|
|
||||||
bool CSceneMeta::load(const std::string &filePath)
|
bool CSceneMeta::load(const std::string &filePath)
|
||||||
{
|
{
|
||||||
m_MetaFilePath = filePath + ".nelmeta";
|
m_MetaFilePath = NLMISC::CPath::standardizePath(filePath + ".nelmeta", false);
|
||||||
if (CFile::fileExists(m_MetaFilePath))
|
if (CFile::fileExists(m_MetaFilePath))
|
||||||
{
|
{
|
||||||
CIFile f(m_MetaFilePath);
|
CIFile f(m_MetaFilePath);
|
||||||
|
@ -79,6 +84,12 @@ void CSceneMeta::serial(NLMISC::IStream &s)
|
||||||
{
|
{
|
||||||
uint version = s.serialVersion(1);
|
uint version = s.serialVersion(1);
|
||||||
|
|
||||||
|
s.serial(ImportShape);
|
||||||
|
s.serial(ImportSkel);
|
||||||
|
s.serial(ImportAnim);
|
||||||
|
s.serial(ImportCmb);
|
||||||
|
s.serial(ImportIG);
|
||||||
|
|
||||||
s.serial(ExportDefaultIG);
|
s.serial(ExportDefaultIG);
|
||||||
s.serial((uint32 &)SkeletonMode);
|
s.serial((uint32 &)SkeletonMode);
|
||||||
|
|
||||||
|
|
|
@ -80,6 +80,12 @@ struct CSceneMeta
|
||||||
{
|
{
|
||||||
CSceneMeta();
|
CSceneMeta();
|
||||||
|
|
||||||
|
bool ImportShape;
|
||||||
|
bool ImportSkel;
|
||||||
|
bool ImportAnim;
|
||||||
|
bool ImportCmb;
|
||||||
|
bool ImportIG;
|
||||||
|
|
||||||
bool ExportDefaultIG; // 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;
|
TSkel SkeletonMode;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue