Extended OBJ loader to parse specular and normal maps
This commit is contained in:
+1
-1
@@ -18,7 +18,7 @@ Model::Model(OBJ &obj, ResourceManager* rm)
|
||||
{
|
||||
currentMaterial = face.Material;
|
||||
// Load texture
|
||||
auto texture = std::shared_ptr<Texture>(rm->Load<Texture>("Texture", currentMaterial->TextureFile));
|
||||
auto texture = std::shared_ptr<Texture>(rm->Load<Texture>("Texture", currentMaterial->DiffuseTexture.FileName));
|
||||
// TODO: Load material parameters
|
||||
// Create new texture group (start index of new group is upcoming index)
|
||||
TextureGroup texGroup = { texture, index, index };
|
||||
|
||||
+172
-19
@@ -126,9 +126,11 @@ void OBJ::ParseMaterial()
|
||||
std::string currentMaterialName;
|
||||
MaterialInfo* currentMaterial = nullptr;
|
||||
|
||||
unsigned int currentLine = 0;
|
||||
std::string line;
|
||||
while (std::getline(file, line))
|
||||
{
|
||||
currentLine++;
|
||||
if (line.length() == 0)
|
||||
continue;
|
||||
|
||||
@@ -140,19 +142,7 @@ void OBJ::ParseMaterial()
|
||||
// Create a new material definition
|
||||
if (prefix == "newmtl")
|
||||
{
|
||||
MaterialInfo mat =
|
||||
{
|
||||
"",
|
||||
std::make_tuple(0.2f, 0.2f, 0.2f),
|
||||
std::make_tuple(0.8f, 0.8f, 0.8f),
|
||||
std::make_tuple(1.0f, 1.0f, 1.0f),
|
||||
std::make_tuple(1.0f, 1.0f, 1.0f),
|
||||
1.0f,
|
||||
1.0f,
|
||||
0.0f,
|
||||
0,
|
||||
};
|
||||
|
||||
MaterialInfo mat;
|
||||
ss >> currentMaterialName;
|
||||
LOG_INFO("Parsing material %s", currentMaterialName.c_str());
|
||||
Materials[currentMaterialName] = mat;
|
||||
@@ -243,14 +233,177 @@ void OBJ::ParseMaterial()
|
||||
currentMaterial->IlluminationModel = illum;
|
||||
continue;
|
||||
}
|
||||
// Texture file
|
||||
// TODO:
|
||||
if (prefix == "map_Ka" || prefix == "map_Kd")
|
||||
// Diffuse texture
|
||||
if (prefix == "map_Kd")
|
||||
{
|
||||
std::string textureFile;
|
||||
ss >> textureFile;
|
||||
currentMaterial->TextureFile = (m_MaterialPath.branch_path() / textureFile).string();
|
||||
MaterialInfo::ColorMap colorMap;
|
||||
|
||||
std::string fileName;
|
||||
std::string arg;
|
||||
while (ss >> arg)
|
||||
{
|
||||
ParseColorMap(currentLine, ss, prefix, arg, colorMap);
|
||||
}
|
||||
|
||||
// HACK: Should we really have to specify the full path here?
|
||||
colorMap.FileName = (m_MaterialPath.branch_path() / colorMap.FileName).string();
|
||||
currentMaterial->DiffuseTexture = colorMap;
|
||||
continue;
|
||||
}
|
||||
// Specular map
|
||||
if (prefix == "map_Ks")
|
||||
{
|
||||
MaterialInfo::ColorMap colorMap;
|
||||
|
||||
std::string fileName;
|
||||
std::string arg;
|
||||
while (ss >> arg)
|
||||
{
|
||||
ParseColorMap(currentLine, ss, prefix, arg, colorMap);
|
||||
}
|
||||
|
||||
// HACK: Should we really have to specify the full path here?
|
||||
colorMap.FileName = (m_MaterialPath.branch_path() / colorMap.FileName).string();
|
||||
currentMaterial->SpecularMap = colorMap;
|
||||
continue;
|
||||
}
|
||||
// Normal map (bump map)
|
||||
if (prefix == "bump")
|
||||
{
|
||||
MaterialInfo::BumpMap bumpMap;
|
||||
|
||||
std::string fileName;
|
||||
std::string arg;
|
||||
while (ss >> arg)
|
||||
{
|
||||
ParseBumpMap(currentLine, ss, prefix, arg, bumpMap);
|
||||
}
|
||||
|
||||
// HACK: Should we really have to specify the full path here?
|
||||
bumpMap.FileName = (m_MaterialPath.branch_path() / bumpMap.FileName).string();
|
||||
currentMaterial->NormalMap = bumpMap;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OBJ::ParseTextureMap(unsigned int line, std::stringstream &ss, std::string prefix, std::string arg, MaterialInfo::TextureMap &textureMap)
|
||||
{
|
||||
if (arg == "-blendu")
|
||||
{
|
||||
std::string val;
|
||||
ss >> val;
|
||||
if (val == "off")
|
||||
textureMap.blendu = false;
|
||||
else if (val == "on")
|
||||
textureMap.blendu = true;
|
||||
else
|
||||
LOG_ERROR("Unrecognized MTL value \"%s\" to argument \"%s %s\" on line %i", val.c_str(), prefix.c_str(), arg.c_str(), line);
|
||||
}
|
||||
else if (arg == "-blendv")
|
||||
{
|
||||
std::string val;
|
||||
ss >> val;
|
||||
if (val == "off")
|
||||
textureMap.blendv = false;
|
||||
else if (val == "on")
|
||||
textureMap.blendv = true;
|
||||
else
|
||||
LOG_ERROR("Unrecognized MTL value \"%s\" to argument \"%s %s\" on line %i", val.c_str(), prefix.c_str(), arg.c_str(), line);
|
||||
}
|
||||
else if (arg == "-clamp")
|
||||
{
|
||||
std::string val;
|
||||
ss >> val;
|
||||
if (val == "off")
|
||||
textureMap.clamp = false;
|
||||
else if (val == "on")
|
||||
textureMap.clamp = true;
|
||||
else
|
||||
LOG_ERROR("Unrecognized MTL value \"%s\" to argument \"%s %s\" on line %i", val.c_str(), prefix.c_str(), arg.c_str(), line);
|
||||
}
|
||||
else if (arg == "-o")
|
||||
{
|
||||
float u, v, w;
|
||||
if (ss >> u >> v >> w)
|
||||
{
|
||||
textureMap.o = std::make_tuple(u, v, w);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_ERROR("Unrecognized MTL value to argument \"%s %s\" on line %i", prefix.c_str(), arg.c_str(), line);
|
||||
}
|
||||
}
|
||||
else if (arg == "-s")
|
||||
{
|
||||
float u, v, w;
|
||||
if (ss >> u >> v >> w)
|
||||
{
|
||||
textureMap.s = std::make_tuple(u, v, w);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_ERROR("Unrecognized MTL value to argument \"%s %s\" on line %i", prefix.c_str(), arg.c_str(), line);
|
||||
}
|
||||
}
|
||||
// Assume unrecognized options is part of the file name
|
||||
else
|
||||
{
|
||||
if (!textureMap.FileName.empty())
|
||||
textureMap.FileName += " ";
|
||||
textureMap.FileName += arg;
|
||||
}
|
||||
}
|
||||
|
||||
void OBJ::ParseColorMap(unsigned int line, std::stringstream &ss, std::string prefix, std::string arg, MaterialInfo::ColorMap &colorMap)
|
||||
{
|
||||
if (arg == "-cc")
|
||||
{
|
||||
if (prefix != "map_Kd" || prefix != "map_Ks")
|
||||
{
|
||||
LOG_ERROR("Invalid MTL argument \"%s\" to option \"%s\" on line %i", arg.c_str(), prefix.c_str(), line);
|
||||
return;
|
||||
}
|
||||
|
||||
std::string val;
|
||||
if (ss >> val)
|
||||
{
|
||||
if (val == "off")
|
||||
colorMap.cc = false;
|
||||
else if (val == "on")
|
||||
colorMap.cc = true;
|
||||
else
|
||||
LOG_ERROR("Unrecognized MTL value \"%s\" to argument \"%s %s\" on line %i", val.c_str(), prefix.c_str(), arg.c_str(), line);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_ERROR("Unrecognized MTL value to argument \"%s %s\" on line %i", prefix.c_str(), arg.c_str(), line);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ParseTextureMap(line, ss, prefix, arg, colorMap);
|
||||
}
|
||||
}
|
||||
|
||||
void OBJ::ParseBumpMap(unsigned int line, std::stringstream &ss, std::string prefix, std::string arg, MaterialInfo::BumpMap &bumpMap)
|
||||
{
|
||||
if (arg == "-bm")
|
||||
{
|
||||
if (prefix != "bump")
|
||||
{
|
||||
LOG_ERROR("Invalid MTL argument \"%s\" to option \"%s\" on line %i", arg.c_str(), prefix.c_str(), line);
|
||||
return;
|
||||
}
|
||||
|
||||
float val;
|
||||
if (ss >> val)
|
||||
bumpMap.bm = val;
|
||||
else
|
||||
LOG_ERROR("Unrecognized MTL value to argument \"%s %s\" on line %i", prefix.c_str(), arg.c_str(), line);
|
||||
}
|
||||
else
|
||||
{
|
||||
ParseTextureMap(line, ss, prefix, arg, bumpMap);
|
||||
}
|
||||
}
|
||||
@@ -10,21 +10,78 @@
|
||||
#include <map>
|
||||
|
||||
#include <boost/filesystem/path.hpp>
|
||||
#include <boost/program_options.hpp>
|
||||
|
||||
class OBJ
|
||||
{
|
||||
public:
|
||||
struct MaterialInfo
|
||||
{
|
||||
std::string TextureFile;
|
||||
std::tuple<float, float, float> AmbientColor;
|
||||
std::tuple<float, float, float> DiffuseColor;
|
||||
std::tuple<float, float, float> SpecularColor;
|
||||
std::tuple<float, float, float> TransmissionFilter;
|
||||
float OpticalDensity;
|
||||
float Alpha;
|
||||
float Shininess;
|
||||
int IlluminationModel;
|
||||
struct TextureMap
|
||||
{
|
||||
TextureMap()
|
||||
: blendu(true)
|
||||
, blendv(true)
|
||||
, clamp(false)
|
||||
, o(std::make_tuple(0.f, 0.f, 0.f))
|
||||
, s(std::make_tuple(1.f, 1.f, 1.f)) { }
|
||||
|
||||
std::string FileName;
|
||||
|
||||
// http://paulbourke.net/dataformats/mtl/
|
||||
// "These options are described in detail in 'Options for texture map statements' on page 5-18."
|
||||
|
||||
// Horizontal texture blending
|
||||
bool blendu; // = true
|
||||
// Vertical texture blending
|
||||
bool blendv; // = true
|
||||
// Clamping
|
||||
bool clamp; // = false
|
||||
// Offset
|
||||
std::tuple<float, float, float> o; // = (0, 0, 0)
|
||||
// Scale
|
||||
std::tuple<float, float, float> s; // = (1, 1, 1)
|
||||
};
|
||||
|
||||
struct ColorMap : public TextureMap
|
||||
{
|
||||
ColorMap()
|
||||
: cc(false) { }
|
||||
|
||||
// Color correction
|
||||
bool cc; // = false
|
||||
};
|
||||
|
||||
struct BumpMap : public TextureMap
|
||||
{
|
||||
BumpMap()
|
||||
: bm(1.f) { }
|
||||
|
||||
// Bump multiplier
|
||||
float bm; // = 1?
|
||||
};
|
||||
|
||||
MaterialInfo()
|
||||
: AmbientColor(std::make_tuple(0.2f, 0.2f, 0.2f))
|
||||
, DiffuseColor(std::make_tuple(0.8f, 0.8f, 0.8f))
|
||||
, SpecularColor(std::make_tuple(1.0f, 1.0f, 1.0f))
|
||||
, TransmissionFilter(std::make_tuple(1.0f, 1.0f, 1.0f))
|
||||
, OpticalDensity(1.0f)
|
||||
, Alpha(1.0f)
|
||||
, Shininess(0.0f)
|
||||
, IlluminationModel(0) { }
|
||||
|
||||
ColorMap DiffuseTexture;
|
||||
ColorMap SpecularMap;
|
||||
BumpMap NormalMap;
|
||||
std::tuple<float, float, float> AmbientColor; // = (0.2, 0.2, 0.2)
|
||||
std::tuple<float, float, float> DiffuseColor; // = (0.8, 0.8, 0.8)
|
||||
std::tuple<float, float, float> SpecularColor; // = (1, 1, 1)
|
||||
std::tuple<float, float, float> TransmissionFilter; // = (1, 1, 1)
|
||||
float OpticalDensity; // = 1
|
||||
float Alpha; // = 1
|
||||
float Shininess; // = 0
|
||||
int IlluminationModel; // = 0
|
||||
};
|
||||
|
||||
struct FaceDefinition
|
||||
@@ -59,6 +116,9 @@ private:
|
||||
MaterialInfo* m_CurrentMaterial;
|
||||
|
||||
void ParseMaterial();
|
||||
void ParseTextureMap(unsigned int line, std::stringstream &ss, std::string prefix, std::string arg, MaterialInfo::TextureMap &textureMap);
|
||||
void ParseColorMap(unsigned int line, std::stringstream &ss, std::string prefix, std::string arg, MaterialInfo::ColorMap &textureMap);
|
||||
void ParseBumpMap(unsigned int line, std::stringstream &ss, std::string prefix, std::string arg, MaterialInfo::BumpMap &textureMap);
|
||||
};
|
||||
|
||||
#endif // OBJ_h__
|
||||
Reference in New Issue
Block a user