Import material texture

This commit is contained in:
kaetemi 2015-09-21 18:11:35 +02:00
parent a3c8b2f89c
commit 6c8a8d7b48
4 changed files with 128 additions and 3 deletions

View file

@ -31,6 +31,7 @@
#include <nel/misc/tool_logger.h>
#include <nel/3d/mesh.h>
#include <nel/3d/texture_file.h>
using namespace std;
using namespace NLMISC;
@ -50,6 +51,10 @@ inline CRGBA convColor(const aiColor4D &ac)
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.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)
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)

View file

@ -22,8 +22,11 @@
#include <nel/misc/tool_logger.h>
#include <nel/misc/sstring.h>
#include <nel/misc/file.h>
#include <nel/misc/path.h>
#include <nel/3d/shape.h>
#include <nel/3d/mesh.h>
#include <nel/3d/texture_file.h>
#include "database_config.h"
#include "scene_meta.h"
@ -227,7 +230,7 @@ void exportShapes(CMeshUtilsContext &context)
CNodeContext &nodeContext = it->second;
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(), "*");
NLMISC::COFile f;
if (f.open(shapePath, false, false, true))
@ -244,6 +247,34 @@ void exportShapes(CMeshUtilsContext &context)
"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);
if (!settings.ToolErrorLog.empty())
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
CDatabaseConfig::init(settings.SourceFilePath);

View file

@ -49,6 +49,11 @@ void CNodeMeta::serial(NLMISC::IStream &s)
}
CSceneMeta::CSceneMeta() :
ImportShape(true),
ImportSkel(true),
ImportAnim(true),
ImportCmb(true),
ImportIG(true),
ExportDefaultIG(false),
SkeletonMode(TSkelRoot)
{
@ -57,7 +62,7 @@ CSceneMeta::CSceneMeta() :
bool CSceneMeta::load(const std::string &filePath)
{
m_MetaFilePath = filePath + ".nelmeta";
m_MetaFilePath = NLMISC::CPath::standardizePath(filePath + ".nelmeta", false);
if (CFile::fileExists(m_MetaFilePath))
{
CIFile f(m_MetaFilePath);
@ -79,6 +84,12 @@ void CSceneMeta::serial(NLMISC::IStream &s)
{
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((uint32 &)SkeletonMode);

View file

@ -80,6 +80,12 @@ struct 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
TSkel SkeletonMode;