Big f***ing cleanup part 1
This commit is contained in:
@@ -18,7 +18,7 @@ namespace Nz
|
||||
DDSLoader() = delete;
|
||||
~DDSLoader() = delete;
|
||||
|
||||
static bool IsSupported(const String& extension)
|
||||
static bool IsSupported(const std::string& extension)
|
||||
{
|
||||
return (extension == "dds");
|
||||
}
|
||||
|
||||
@@ -320,9 +320,9 @@ namespace Nz
|
||||
return characterSize/15.f; // Joker ?
|
||||
}
|
||||
|
||||
bool SetFile(const String& filePath)
|
||||
bool SetFile(const std::filesystem::path& filePath)
|
||||
{
|
||||
std::unique_ptr<File> file(new File);
|
||||
std::unique_ptr<File> file = std::make_unique<File>();
|
||||
if (!file->Open(filePath, OpenMode_ReadOnly))
|
||||
{
|
||||
NazaraError("Failed to open stream from file: " + Error::GetLastError());
|
||||
@@ -336,7 +336,7 @@ namespace Nz
|
||||
|
||||
void SetMemory(const void* data, std::size_t size)
|
||||
{
|
||||
m_ownedStream.reset(new MemoryView(data, size));
|
||||
m_ownedStream = std::make_unique<MemoryView>(data, size);
|
||||
SetStream(*m_ownedStream);
|
||||
}
|
||||
|
||||
@@ -349,14 +349,14 @@ namespace Nz
|
||||
m_stream.pos = 0;
|
||||
m_stream.size = static_cast<unsigned long>(stream.GetSize());
|
||||
|
||||
m_args.driver = 0;
|
||||
m_args.driver = nullptr;
|
||||
m_args.flags = FT_OPEN_STREAM;
|
||||
m_args.stream = &m_stream;
|
||||
}
|
||||
|
||||
bool SupportsOutline(float /*outlineThickness*/) const override
|
||||
{
|
||||
return s_stroker != 0;
|
||||
return s_stroker != nullptr;
|
||||
}
|
||||
|
||||
bool SupportsStyle(TextStyleFlags style) const override
|
||||
@@ -383,10 +383,10 @@ namespace Nz
|
||||
mutable unsigned int m_characterSize;
|
||||
};
|
||||
|
||||
bool IsSupported(const String& extension)
|
||||
bool IsSupported(const std::string& extension)
|
||||
{
|
||||
///FIXME: Je suppose qu'il en manque quelques unes..
|
||||
static std::set<String> supportedExtensions = {
|
||||
static std::set<std::string> supportedExtensions = {
|
||||
"afm", "bdf", "cff", "cid", "dfont", "fnt", "fon", "otf", "pfa", "pfb", "pfm", "pfr", "sfnt", "ttc", "tte", "ttf"
|
||||
};
|
||||
|
||||
@@ -408,12 +408,11 @@ namespace Nz
|
||||
return Ternary_False;
|
||||
}
|
||||
|
||||
FontRef LoadFile(const String& filePath, const FontParams& parameters)
|
||||
FontRef LoadFile(const std::filesystem::path& filePath, const FontParams& parameters)
|
||||
{
|
||||
NazaraUnused(parameters);
|
||||
|
||||
std::unique_ptr<FreeTypeStream> face(new FreeTypeStream);
|
||||
|
||||
std::unique_ptr<FreeTypeStream> face = std::make_unique<FreeTypeStream>();
|
||||
if (!face->SetFile(filePath))
|
||||
{
|
||||
NazaraError("Failed to open file");
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace Nz
|
||||
{
|
||||
namespace
|
||||
{
|
||||
bool IsSupported(const String& extension)
|
||||
bool IsSupported(const std::string& extension)
|
||||
{
|
||||
return (extension == "md2");
|
||||
}
|
||||
@@ -93,14 +93,14 @@ namespace Nz
|
||||
mesh->SetMaterialCount(header.num_skins);
|
||||
stream.SetCursorPos(header.offset_skins);
|
||||
{
|
||||
String baseDir = stream.GetDirectory();
|
||||
std::filesystem::path baseDir = stream.GetDirectory();
|
||||
char skin[68];
|
||||
for (unsigned int i = 0; i < header.num_skins; ++i)
|
||||
{
|
||||
stream.Read(skin, 68*sizeof(char));
|
||||
|
||||
ParameterList matData;
|
||||
matData.SetParameter(MaterialData::DiffuseTexturePath, baseDir + skin);
|
||||
matData.SetParameter(MaterialData::DiffuseTexturePath, (baseDir / skin).generic_u8string());
|
||||
|
||||
mesh->SetMaterialData(i, std::move(matData));
|
||||
}
|
||||
@@ -196,10 +196,8 @@ namespace Nz
|
||||
Vector2f invSkinSize(1.f / header.skinwidth, 1.f / header.skinheight);
|
||||
for (unsigned int i = 0; i < header.num_tris; ++i)
|
||||
{
|
||||
for (unsigned int j = 0; j < 3; ++j)
|
||||
for (unsigned int fixedIndex : indexFix) //< Reverse winding order
|
||||
{
|
||||
const unsigned int fixedIndex = indexFix[j]; //< Reverse winding order
|
||||
|
||||
const MD2_TexCoord& texC = texCoords[triangles[i].texCoords[fixedIndex]];
|
||||
Vector2f uv(texC.u, texC.v);
|
||||
uv *= invSkinSize;
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Utility/Formats/MD5AnimLoader.hpp>
|
||||
#include <Nazara/Core/Directory.hpp>
|
||||
#include <Nazara/Utility/Formats/MD5AnimParser.hpp>
|
||||
#include <Nazara/Utility/Animation.hpp>
|
||||
#include <Nazara/Utility/Sequence.hpp>
|
||||
@@ -13,7 +12,7 @@ namespace Nz
|
||||
{
|
||||
namespace
|
||||
{
|
||||
bool IsSupported(const String& extension)
|
||||
bool IsSupported(const std::string& extension)
|
||||
{
|
||||
return (extension == "md5anim");
|
||||
}
|
||||
@@ -40,10 +39,10 @@ namespace Nz
|
||||
}
|
||||
|
||||
const MD5AnimParser::Frame* frames = parser.GetFrames();
|
||||
UInt32 frameCount = parser.GetFrameCount();
|
||||
UInt32 frameRate = parser.GetFrameRate();
|
||||
std::size_t frameCount = parser.GetFrameCount();
|
||||
std::size_t frameRate = parser.GetFrameRate();
|
||||
const MD5AnimParser::Joint* joints = parser.GetJoints();
|
||||
UInt32 jointCount = parser.GetJointCount();
|
||||
std::size_t jointCount = parser.GetJointCount();
|
||||
|
||||
// À ce stade, nous sommes censés avoir assez d'informations pour créer l'animation
|
||||
AnimationRef animation = Animation::New();
|
||||
@@ -53,7 +52,7 @@ namespace Nz
|
||||
sequence.firstFrame = 0;
|
||||
sequence.frameCount = frameCount;
|
||||
sequence.frameRate = frameRate;
|
||||
sequence.name = stream.GetPath().SubStringFrom(NAZARA_DIRECTORY_SEPARATOR, -1, true);
|
||||
sequence.name = stream.GetPath().filename().generic_u8string();
|
||||
|
||||
animation->AddSequence(sequence);
|
||||
|
||||
@@ -63,10 +62,10 @@ namespace Nz
|
||||
Quaternionf rotationQuat = Quaternionf::RotationBetween(Vector3f::UnitX(), Vector3f::Forward()) *
|
||||
Quaternionf::RotationBetween(Vector3f::UnitZ(), Vector3f::Up());
|
||||
|
||||
for (UInt32 i = 0; i < jointCount; ++i)
|
||||
for (std::size_t i = 0; i < jointCount; ++i)
|
||||
{
|
||||
int parent = joints[i].parent;
|
||||
for (UInt32 j = 0; j < frameCount; ++j)
|
||||
for (std::size_t j = 0; j < frameCount; ++j)
|
||||
{
|
||||
SequenceJoint& sequenceJoint = sequenceJoints[j*jointCount + i];
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace Nz
|
||||
{
|
||||
namespace
|
||||
{
|
||||
bool IsSupported(const String& extension)
|
||||
bool IsSupported(const std::string& extension)
|
||||
{
|
||||
return (extension == "md5mesh");
|
||||
}
|
||||
@@ -48,7 +48,7 @@ namespace Nz
|
||||
Quaternionf rotationQuat = Quaternionf::RotationBetween(Vector3f::UnitX(), Vector3f::Forward()) *
|
||||
Quaternionf::RotationBetween(Vector3f::UnitZ(), Vector3f::Up());
|
||||
|
||||
String baseDir = stream.GetDirectory();
|
||||
std::filesystem::path baseDir = stream.GetDirectory();
|
||||
|
||||
// Le hellknight de Doom 3 fait ~120 unités, et il est dit qu'il fait trois mètres
|
||||
// Nous réduisons donc la taille générale des fichiers MD5 de 1/40
|
||||
@@ -198,7 +198,7 @@ namespace Nz
|
||||
|
||||
// Material
|
||||
ParameterList matData;
|
||||
matData.SetParameter(MaterialData::FilePath, baseDir + md5Mesh.shader);
|
||||
matData.SetParameter(MaterialData::FilePath, (baseDir / md5Mesh.shader).generic_u8string());
|
||||
|
||||
mesh->SetMaterialData(i, std::move(matData));
|
||||
|
||||
@@ -211,11 +211,11 @@ namespace Nz
|
||||
|
||||
// Animation
|
||||
// Il est peut-être éventuellement possible que la probabilité que l'animation ait le même nom soit non-nulle.
|
||||
String path = stream.GetPath();
|
||||
if (!path.IsEmpty())
|
||||
std::filesystem::path path = stream.GetPath();
|
||||
if (!path.empty())
|
||||
{
|
||||
path.Replace(".md5mesh", ".md5anim", -8, String::CaseInsensitive);
|
||||
if (File::Exists(path))
|
||||
path.replace_extension(".md5anim");
|
||||
if (std::filesystem::exists(path))
|
||||
mesh->SetAnimation(path);
|
||||
}
|
||||
}
|
||||
@@ -306,7 +306,7 @@ namespace Nz
|
||||
|
||||
// Material
|
||||
ParameterList matData;
|
||||
matData.SetParameter(MaterialData::FilePath, baseDir + md5Mesh.shader);
|
||||
matData.SetParameter(MaterialData::FilePath, (baseDir / md5Mesh.shader).generic_u8string());
|
||||
|
||||
mesh->SetMaterialData(i, std::move(matData));
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#include <Nazara/Utility/Formats/MD5MeshParser.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Core/StringExt.hpp>
|
||||
#include <Nazara/Utility/Config.hpp>
|
||||
#include <cstdio>
|
||||
#include <memory>
|
||||
@@ -71,19 +72,19 @@ namespace Nz
|
||||
{
|
||||
#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
|
||||
case 'M': // MD5Version
|
||||
if (m_currentLine.GetWord(0) != "MD5Version")
|
||||
if (!StartsWith(m_currentLine, "MD5Version "))
|
||||
UnrecognizedLine();
|
||||
break;
|
||||
|
||||
case 'c': // commandline
|
||||
if (m_currentLine.GetWord(0) != "commandline")
|
||||
if (!StartsWith(m_currentLine, "commandline "))
|
||||
UnrecognizedLine();
|
||||
break;
|
||||
#endif
|
||||
|
||||
case 'j': // joints
|
||||
#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
|
||||
if (!m_currentLine.StartsWith("joints {"))
|
||||
if (!StartsWith(m_currentLine, "joints {"))
|
||||
{
|
||||
UnrecognizedLine();
|
||||
break;
|
||||
@@ -100,7 +101,7 @@ namespace Nz
|
||||
case 'm': // mesh
|
||||
{
|
||||
#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
|
||||
if (m_currentLine != "mesh {")
|
||||
if (!StartsWith(m_currentLine, "mesh {"))
|
||||
{
|
||||
UnrecognizedLine();
|
||||
break;
|
||||
@@ -113,7 +114,7 @@ namespace Nz
|
||||
Warning("More meshes than registred");
|
||||
#endif
|
||||
|
||||
m_meshes.push_back(Mesh());
|
||||
m_meshes.emplace_back();
|
||||
}
|
||||
|
||||
if (!ParseMesh())
|
||||
@@ -182,14 +183,25 @@ namespace Nz
|
||||
m_lineCount++;
|
||||
|
||||
m_currentLine = m_stream.ReadLine();
|
||||
if (m_currentLine.IsEmpty())
|
||||
continue;
|
||||
|
||||
m_currentLine = m_currentLine.SubStringTo("//"); // On ignore les commentaires
|
||||
m_currentLine.Simplify(); // Pour un traitement plus simple
|
||||
m_currentLine.Trim();
|
||||
if (std::size_t p = m_currentLine.find("//"); p != m_currentLine.npos)
|
||||
{
|
||||
if (p > 0)
|
||||
m_currentLine = m_currentLine.substr(0, p - 1);
|
||||
else
|
||||
m_currentLine.clear();
|
||||
}
|
||||
|
||||
// Trim left
|
||||
m_currentLine.erase(m_currentLine.begin(), std::find_if(m_currentLine.begin(), m_currentLine.end(), [](char c)
|
||||
{
|
||||
return !std::isspace(c);
|
||||
}));
|
||||
|
||||
if (m_currentLine.empty())
|
||||
continue;
|
||||
}
|
||||
while (m_currentLine.IsEmpty());
|
||||
while (m_currentLine.empty());
|
||||
}
|
||||
else
|
||||
m_keepLastLine = false;
|
||||
@@ -197,9 +209,9 @@ namespace Nz
|
||||
return true;
|
||||
}
|
||||
|
||||
void MD5MeshParser::Error(const String& message)
|
||||
void MD5MeshParser::Error(const std::string& message)
|
||||
{
|
||||
NazaraError(message + " at line #" + String::Number(m_lineCount));
|
||||
NazaraError(message + " at line #" + std::to_string(m_lineCount));
|
||||
}
|
||||
|
||||
bool MD5MeshParser::ParseJoints()
|
||||
@@ -216,7 +228,7 @@ namespace Nz
|
||||
if (!Advance())
|
||||
return false;
|
||||
|
||||
std::size_t pos = m_currentLine.Find(' ');
|
||||
std::size_t pos = m_currentLine.find(' ');
|
||||
if (pos == String::npos)
|
||||
{
|
||||
UnrecognizedLine(true);
|
||||
@@ -231,8 +243,8 @@ namespace Nz
|
||||
|
||||
char name[64];
|
||||
if (std::sscanf(&m_currentLine[0], "%63s %d ( %f %f %f ) ( %f %f %f )", &name[0], &m_joints[i].parent,
|
||||
&m_joints[i].bindPos.x, &m_joints[i].bindPos.y, &m_joints[i].bindPos.z,
|
||||
&m_joints[i].bindOrient.x, &m_joints[i].bindOrient.y, &m_joints[i].bindOrient.z) != 8)
|
||||
&m_joints[i].bindPos.x, &m_joints[i].bindPos.y, &m_joints[i].bindPos.z,
|
||||
&m_joints[i].bindOrient.x, &m_joints[i].bindOrient.y, &m_joints[i].bindOrient.z) != 8)
|
||||
{
|
||||
UnrecognizedLine(true);
|
||||
return false;
|
||||
@@ -246,7 +258,7 @@ namespace Nz
|
||||
{
|
||||
if (static_cast<std::size_t>(parent) >= jointCount)
|
||||
{
|
||||
Error("Joint's parent is out of bounds (" + String::Number(parent) + " >= " + String::Number(jointCount) + ')');
|
||||
Error("Joint's parent is out of bounds (" + std::to_string(parent) + " >= " + std::to_string(jointCount) + ')');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -257,7 +269,7 @@ namespace Nz
|
||||
if (!Advance())
|
||||
return false;
|
||||
|
||||
if (m_currentLine != '}')
|
||||
if (m_currentLine != "}")
|
||||
{
|
||||
#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
|
||||
Warning("Hierarchy braces closing not found");
|
||||
@@ -282,17 +294,42 @@ namespace Nz
|
||||
break;
|
||||
|
||||
case 's': // shader
|
||||
{
|
||||
#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
|
||||
if (!m_currentLine.StartsWith("shader "))
|
||||
if (!StartsWith(m_currentLine, "shader "))
|
||||
{
|
||||
UnrecognizedLine();
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
m_meshes[m_meshIndex].shader = m_currentLine.SubString(7);
|
||||
m_meshes[m_meshIndex].shader.Trim('"');
|
||||
std::string_view shader = m_currentLine;
|
||||
shader = shader.substr(7);
|
||||
if (shader.empty())
|
||||
{
|
||||
#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
|
||||
UnrecognizedLine();
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
if (shader.front() == '"')
|
||||
shader.remove_prefix(1);
|
||||
|
||||
if (shader.empty())
|
||||
{
|
||||
#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
|
||||
UnrecognizedLine();
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
if (shader.back() == '"')
|
||||
shader.remove_prefix(1);
|
||||
|
||||
m_meshes[m_meshIndex].shader = shader;
|
||||
break;
|
||||
}
|
||||
|
||||
case 'n': // num[tris/verts]
|
||||
{
|
||||
@@ -315,7 +352,7 @@ namespace Nz
|
||||
|
||||
if (index != i)
|
||||
{
|
||||
Error("Unexpected triangle index (expected " + String::Number(i) + ", got " + String::Number(index) + ')');
|
||||
Error("Unexpected triangle index (expected " + std::to_string(i) + ", got " + std::to_string(index) + ')');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -338,7 +375,7 @@ namespace Nz
|
||||
|
||||
if (index != i)
|
||||
{
|
||||
Error("Unexpected vertex index (expected " + String::Number(i) + ", got " + String::Number(index) + ')');
|
||||
Error("Unexpected vertex index (expected " + std::to_string(i) + ", got " + std::to_string(index) + ')');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -354,7 +391,7 @@ namespace Nz
|
||||
Weight& weight = m_meshes[m_meshIndex].weights[i];
|
||||
unsigned int index;
|
||||
if (std::sscanf(&m_currentLine[0], "weight %u %u %f ( %f %f %f )", &index, &weight.joint, &weight.bias,
|
||||
&weight.pos.x, &weight.pos.y, &weight.pos.z) != 6)
|
||||
&weight.pos.x, &weight.pos.y, &weight.pos.z) != 6)
|
||||
{
|
||||
UnrecognizedLine(true);
|
||||
return false;
|
||||
@@ -362,7 +399,7 @@ namespace Nz
|
||||
|
||||
if (index != i)
|
||||
{
|
||||
Error("Unexpected weight index (expected " + String::Number(i) + ", got " + String::Number(index) + ')');
|
||||
Error("Unexpected weight index (expected " + std::to_string(i) + ", got " + std::to_string(index) + ')');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -408,14 +445,14 @@ namespace Nz
|
||||
return true;
|
||||
}
|
||||
|
||||
void MD5MeshParser::Warning(const String& message)
|
||||
void MD5MeshParser::Warning(const std::string& message)
|
||||
{
|
||||
NazaraWarning(message + " at line #" + String::Number(m_lineCount));
|
||||
NazaraWarning(message + " at line #" + std::to_string(m_lineCount));
|
||||
}
|
||||
|
||||
void MD5MeshParser::UnrecognizedLine(bool error)
|
||||
{
|
||||
String message = "Unrecognized \"" + m_currentLine + '"';
|
||||
std::string message = "Unrecognized \"" + m_currentLine + '"';
|
||||
|
||||
if (error)
|
||||
Error(message);
|
||||
|
||||
@@ -4,12 +4,31 @@
|
||||
|
||||
#include <Nazara/Utility/Formats/MTLParser.hpp>
|
||||
#include <Nazara/Core/CallOnExit.hpp>
|
||||
#include <Nazara/Core/StringExt.hpp>
|
||||
#include <Nazara/Utility/Config.hpp>
|
||||
#include <cstdio>
|
||||
#include <Nazara/Utility/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
namespace
|
||||
{
|
||||
template<std::size_t N>
|
||||
bool TestKeyword(const std::string& currentLine, const char(&keyword)[N], std::size_t& offset)
|
||||
{
|
||||
if (currentLine.size() > N && StartsWith(currentLine, keyword, CaseIndependent{}) && std::isspace(currentLine[N - 1]))
|
||||
{
|
||||
offset = N;
|
||||
while (offset < currentLine.size() && std::isspace(currentLine[offset]))
|
||||
offset++;
|
||||
|
||||
return offset < currentLine.size();
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool MTLParser::Parse(Stream& stream)
|
||||
{
|
||||
m_currentStream = &stream;
|
||||
@@ -31,266 +50,434 @@ namespace Nz
|
||||
m_materials.clear();
|
||||
|
||||
Material* currentMaterial = nullptr;
|
||||
std::size_t offset;
|
||||
|
||||
while (Advance(false))
|
||||
{
|
||||
String keyword = m_currentLine.GetWord(0).ToLower();
|
||||
if (keyword == "ka")
|
||||
switch (std::tolower(m_currentLine[0]))
|
||||
{
|
||||
float r, g, b;
|
||||
if (std::sscanf(&m_currentLine[3], "%f %f %f", &r, &g, &b) == 3)
|
||||
case 'b':
|
||||
{
|
||||
if (!currentMaterial)
|
||||
currentMaterial = AddMaterial("default");
|
||||
if (TestKeyword(m_currentLine, "bump", offset))
|
||||
{
|
||||
std::string map = m_currentLine.substr(offset);
|
||||
if (!map.empty())
|
||||
{
|
||||
if (!currentMaterial)
|
||||
currentMaterial = AddMaterial("default");
|
||||
|
||||
currentMaterial->ambient = Color(static_cast<UInt8>(r*255.f), static_cast<UInt8>(g*255.f), static_cast<UInt8>(b*255.f));
|
||||
currentMaterial->bumpMap = map;
|
||||
}
|
||||
#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
|
||||
else
|
||||
UnrecognizedLine();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
|
||||
else
|
||||
UnrecognizedLine();
|
||||
#endif
|
||||
}
|
||||
else if (keyword == "kd")
|
||||
{
|
||||
float r, g, b;
|
||||
if (std::sscanf(&m_currentLine[3], "%f %f %f", &r, &g, &b) == 3)
|
||||
|
||||
case 'd':
|
||||
{
|
||||
if (!currentMaterial)
|
||||
currentMaterial = AddMaterial("default");
|
||||
if (TestKeyword(m_currentLine, "d", offset))
|
||||
{
|
||||
float alpha;
|
||||
if (std::sscanf(&m_currentLine[2], "%f", &alpha) == 1)
|
||||
{
|
||||
if (!currentMaterial)
|
||||
currentMaterial = AddMaterial("default");
|
||||
|
||||
currentMaterial->diffuse = Color(static_cast<UInt8>(r*255.f), static_cast<UInt8>(g*255.f), static_cast<UInt8>(b*255.f));
|
||||
currentMaterial->alpha = alpha;
|
||||
}
|
||||
#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
|
||||
else
|
||||
UnrecognizedLine();
|
||||
#endif
|
||||
}
|
||||
else if (TestKeyword(m_currentLine, "decal", offset))
|
||||
{
|
||||
std::string map = m_currentLine.substr(offset);
|
||||
if (!map.empty())
|
||||
{
|
||||
if (!currentMaterial)
|
||||
currentMaterial = AddMaterial("default");
|
||||
|
||||
currentMaterial->decalMap = map;
|
||||
}
|
||||
#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
|
||||
else
|
||||
UnrecognizedLine();
|
||||
#endif
|
||||
}
|
||||
else if (TestKeyword(m_currentLine, "disp", offset))
|
||||
{
|
||||
std::string map = m_currentLine.substr(offset);
|
||||
if (!map.empty())
|
||||
{
|
||||
if (!currentMaterial)
|
||||
currentMaterial = AddMaterial("default");
|
||||
|
||||
currentMaterial->displacementMap = map;
|
||||
}
|
||||
#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
|
||||
else
|
||||
UnrecognizedLine();
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
}
|
||||
#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
|
||||
else
|
||||
UnrecognizedLine();
|
||||
#endif
|
||||
}
|
||||
else if (keyword == "ks")
|
||||
{
|
||||
float r, g, b;
|
||||
if (std::sscanf(&m_currentLine[3], "%f %f %f", &r, &g, &b) == 3)
|
||||
|
||||
case 'e':
|
||||
{
|
||||
if (!currentMaterial)
|
||||
currentMaterial = AddMaterial("default");
|
||||
if (TestKeyword(m_currentLine, "emissive", offset))
|
||||
{
|
||||
// <!> This is a custom keyword
|
||||
std::string map = m_currentLine.substr(offset);
|
||||
if (!map.empty())
|
||||
{
|
||||
if (!currentMaterial)
|
||||
currentMaterial = AddMaterial("default");
|
||||
|
||||
currentMaterial->specular = Color(static_cast<UInt8>(r*255.f), static_cast<UInt8>(g*255.f), static_cast<UInt8>(b*255.f));
|
||||
currentMaterial->emissiveMap = map;
|
||||
}
|
||||
#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
|
||||
else
|
||||
UnrecognizedLine();
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
}
|
||||
#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
|
||||
else
|
||||
UnrecognizedLine();
|
||||
#endif
|
||||
}
|
||||
else if (keyword == "ni")
|
||||
{
|
||||
float density;
|
||||
if (std::sscanf(&m_currentLine[3], "%f", &density) == 1)
|
||||
|
||||
case 'k':
|
||||
{
|
||||
if (!currentMaterial)
|
||||
currentMaterial = AddMaterial("default");
|
||||
if (TestKeyword(m_currentLine, "ka", offset))
|
||||
{
|
||||
float r, g, b;
|
||||
if (std::sscanf(&m_currentLine[offset], "%f %f %f", &r, &g, &b) == 3)
|
||||
{
|
||||
if (!currentMaterial)
|
||||
currentMaterial = AddMaterial("default");
|
||||
|
||||
currentMaterial->refractionIndex = density;
|
||||
currentMaterial->ambient = Color(static_cast<UInt8>(r * 255.f), static_cast<UInt8>(g * 255.f), static_cast<UInt8>(b * 255.f));
|
||||
}
|
||||
#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
|
||||
else
|
||||
UnrecognizedLine();
|
||||
#endif
|
||||
}
|
||||
else if (TestKeyword(m_currentLine, "kd", offset))
|
||||
{
|
||||
float r, g, b;
|
||||
if (std::sscanf(&m_currentLine[offset], "%f %f %f", &r, &g, &b) == 3)
|
||||
{
|
||||
if (!currentMaterial)
|
||||
currentMaterial = AddMaterial("default");
|
||||
|
||||
currentMaterial->diffuse = Color(static_cast<UInt8>(r * 255.f), static_cast<UInt8>(g * 255.f), static_cast<UInt8>(b * 255.f));
|
||||
}
|
||||
#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
|
||||
else
|
||||
UnrecognizedLine();
|
||||
#endif
|
||||
}
|
||||
else if (TestKeyword(m_currentLine, "ks", offset))
|
||||
{
|
||||
float r, g, b;
|
||||
if (std::sscanf(&m_currentLine[offset], "%f %f %f", &r, &g, &b) == 3)
|
||||
{
|
||||
if (!currentMaterial)
|
||||
currentMaterial = AddMaterial("default");
|
||||
|
||||
currentMaterial->specular = Color(static_cast<UInt8>(r * 255.f), static_cast<UInt8>(g * 255.f), static_cast<UInt8>(b * 255.f));
|
||||
}
|
||||
#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
|
||||
else
|
||||
UnrecognizedLine();
|
||||
#endif
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
|
||||
else
|
||||
UnrecognizedLine();
|
||||
#endif
|
||||
}
|
||||
else if (keyword == "ns")
|
||||
{
|
||||
float coef;
|
||||
if (std::sscanf(&m_currentLine[3], "%f", &coef) == 1)
|
||||
|
||||
case 'i':
|
||||
{
|
||||
if (!currentMaterial)
|
||||
currentMaterial = AddMaterial("default");
|
||||
if (TestKeyword(m_currentLine, "illum", offset))
|
||||
{
|
||||
unsigned int model;
|
||||
if (std::sscanf(&m_currentLine[offset], "%u", &model) == 1)
|
||||
{
|
||||
if (!currentMaterial)
|
||||
currentMaterial = AddMaterial("default");
|
||||
|
||||
currentMaterial->shininess = coef;
|
||||
}
|
||||
#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
|
||||
else
|
||||
UnrecognizedLine();
|
||||
#endif
|
||||
}
|
||||
else if (keyword == 'd')
|
||||
{
|
||||
float alpha;
|
||||
if (std::sscanf(&m_currentLine[(keyword[0] == 'd') ? 2 : 3], "%f", &alpha) == 1)
|
||||
{
|
||||
if (!currentMaterial)
|
||||
currentMaterial = AddMaterial("default");
|
||||
|
||||
currentMaterial->alpha = alpha;
|
||||
}
|
||||
#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
|
||||
else
|
||||
UnrecognizedLine();
|
||||
#endif
|
||||
}
|
||||
else if (keyword == "tr")
|
||||
{
|
||||
float alpha;
|
||||
if (std::sscanf(&m_currentLine[(keyword[0] == 'd') ? 2 : 3], "%f", &alpha) == 1)
|
||||
{
|
||||
if (!currentMaterial)
|
||||
currentMaterial = AddMaterial("default");
|
||||
|
||||
currentMaterial->alpha = 1.f - alpha; // tr vaut pour la "valeur de transparence", 0 = opaque
|
||||
}
|
||||
#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
|
||||
else
|
||||
UnrecognizedLine();
|
||||
#endif
|
||||
}
|
||||
else if (keyword == "illum")
|
||||
{
|
||||
unsigned int model;
|
||||
if (std::sscanf(&m_currentLine[6], "%u", &model) == 1)
|
||||
{
|
||||
if (!currentMaterial)
|
||||
currentMaterial = AddMaterial("default");
|
||||
|
||||
currentMaterial->illumModel = model;
|
||||
}
|
||||
#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
|
||||
else
|
||||
UnrecognizedLine();
|
||||
#endif
|
||||
}
|
||||
else if (keyword == "map_ka")
|
||||
{
|
||||
std::size_t mapPos = m_currentLine.GetWordPosition(1);
|
||||
if (mapPos != String::npos)
|
||||
{
|
||||
String map = m_currentLine.SubString(mapPos);
|
||||
if (!currentMaterial)
|
||||
currentMaterial = AddMaterial("default");
|
||||
|
||||
currentMaterial->ambientMap = map;
|
||||
}
|
||||
}
|
||||
else if (keyword == "map_kd")
|
||||
{
|
||||
std::size_t mapPos = m_currentLine.GetWordPosition(1);
|
||||
if (mapPos != String::npos)
|
||||
{
|
||||
String map = m_currentLine.SubString(mapPos);
|
||||
if (!currentMaterial)
|
||||
currentMaterial = AddMaterial("default");
|
||||
|
||||
currentMaterial->diffuseMap = map;
|
||||
}
|
||||
}
|
||||
else if (keyword == "map_ks")
|
||||
{
|
||||
std::size_t mapPos = m_currentLine.GetWordPosition(1);
|
||||
if (mapPos != String::npos)
|
||||
{
|
||||
String map = m_currentLine.SubString(mapPos);
|
||||
if (!currentMaterial)
|
||||
currentMaterial = AddMaterial("default");
|
||||
|
||||
currentMaterial->specularMap = map;
|
||||
}
|
||||
}
|
||||
else if (keyword == "map_bump" || keyword == "bump")
|
||||
{
|
||||
std::size_t mapPos = m_currentLine.GetWordPosition(1);
|
||||
if (mapPos != String::npos)
|
||||
{
|
||||
String map = m_currentLine.SubString(mapPos);
|
||||
if (!currentMaterial)
|
||||
currentMaterial = AddMaterial("default");
|
||||
|
||||
currentMaterial->bumpMap = map;
|
||||
}
|
||||
}
|
||||
else if (keyword == "map_d")
|
||||
{
|
||||
std::size_t mapPos = m_currentLine.GetWordPosition(1);
|
||||
if (mapPos != String::npos)
|
||||
{
|
||||
String map = m_currentLine.SubString(mapPos);
|
||||
if (!currentMaterial)
|
||||
currentMaterial = AddMaterial("default");
|
||||
|
||||
currentMaterial->alphaMap = map;
|
||||
}
|
||||
}
|
||||
else if (keyword == "map_decal" || keyword == "decal")
|
||||
{
|
||||
std::size_t mapPos = m_currentLine.GetWordPosition(1);
|
||||
if (mapPos != String::npos)
|
||||
{
|
||||
String map = m_currentLine.SubString(mapPos);
|
||||
if (!currentMaterial)
|
||||
currentMaterial = AddMaterial("default");
|
||||
|
||||
currentMaterial->decalMap = map;
|
||||
}
|
||||
}
|
||||
else if (keyword == "map_disp" || keyword == "disp")
|
||||
{
|
||||
std::size_t mapPos = m_currentLine.GetWordPosition(1);
|
||||
if (mapPos != String::npos)
|
||||
{
|
||||
String map = m_currentLine.SubString(mapPos);
|
||||
if (!currentMaterial)
|
||||
currentMaterial = AddMaterial("default");
|
||||
|
||||
currentMaterial->displacementMap = map;
|
||||
}
|
||||
}
|
||||
else if (keyword == "map_refl" || keyword == "refl")
|
||||
{
|
||||
std::size_t mapPos = m_currentLine.GetWordPosition(1);
|
||||
if (mapPos != String::npos)
|
||||
{
|
||||
String map = m_currentLine.SubString(mapPos);
|
||||
if (!currentMaterial)
|
||||
currentMaterial = AddMaterial("default");
|
||||
|
||||
currentMaterial->reflectionMap = map;
|
||||
}
|
||||
}
|
||||
else if (keyword == "map_normal" || keyword == "normal")
|
||||
{
|
||||
// <!> This is a custom keyword
|
||||
std::size_t mapPos = m_currentLine.GetWordPosition(1);
|
||||
if (mapPos != String::npos)
|
||||
{
|
||||
String map = m_currentLine.SubString(mapPos);
|
||||
if (!currentMaterial)
|
||||
currentMaterial = AddMaterial("default");
|
||||
|
||||
currentMaterial->normalMap = map;
|
||||
}
|
||||
}
|
||||
else if (keyword == "map_emissive" || keyword == "emissive")
|
||||
{
|
||||
// <!> This is a custom keyword
|
||||
std::size_t mapPos = m_currentLine.GetWordPosition(1);
|
||||
if (mapPos != String::npos)
|
||||
{
|
||||
String map = m_currentLine.SubString(mapPos);
|
||||
if (!currentMaterial)
|
||||
currentMaterial = AddMaterial("default");
|
||||
|
||||
currentMaterial->emissiveMap = map;
|
||||
}
|
||||
}
|
||||
else if (keyword == "newmtl")
|
||||
{
|
||||
String materialName = m_currentLine.SubString(m_currentLine.GetWordPosition(1));
|
||||
if (!materialName.IsEmpty())
|
||||
currentMaterial = AddMaterial(materialName);
|
||||
#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
|
||||
else
|
||||
UnrecognizedLine();
|
||||
#endif
|
||||
}
|
||||
currentMaterial->illumModel = model;
|
||||
}
|
||||
#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
|
||||
else
|
||||
UnrecognizedLine();
|
||||
else
|
||||
UnrecognizedLine();
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 'm':
|
||||
{
|
||||
if (TestKeyword(m_currentLine, "map_ka", offset))
|
||||
{
|
||||
std::string map = m_currentLine.substr(offset);
|
||||
if (!map.empty())
|
||||
{
|
||||
if (!currentMaterial)
|
||||
currentMaterial = AddMaterial("default");
|
||||
|
||||
currentMaterial->ambientMap = map;
|
||||
}
|
||||
#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
|
||||
else
|
||||
UnrecognizedLine();
|
||||
#endif
|
||||
}
|
||||
else if (TestKeyword(m_currentLine, "map_kd", offset))
|
||||
{
|
||||
std::string map = m_currentLine.substr(offset);
|
||||
if (!map.empty())
|
||||
{
|
||||
if (!currentMaterial)
|
||||
currentMaterial = AddMaterial("default");
|
||||
|
||||
currentMaterial->diffuseMap = map;
|
||||
}
|
||||
#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
|
||||
else
|
||||
UnrecognizedLine();
|
||||
#endif
|
||||
}
|
||||
else if (TestKeyword(m_currentLine, "map_ks", offset))
|
||||
{
|
||||
std::string map = m_currentLine.substr(offset);
|
||||
if (!map.empty())
|
||||
{
|
||||
if (!currentMaterial)
|
||||
currentMaterial = AddMaterial("default");
|
||||
|
||||
currentMaterial->specularMap = map;
|
||||
}
|
||||
#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
|
||||
else
|
||||
UnrecognizedLine();
|
||||
#endif
|
||||
}
|
||||
else if (TestKeyword(m_currentLine, "map_bump", offset))
|
||||
{
|
||||
std::string map = m_currentLine.substr(offset);
|
||||
if (!map.empty())
|
||||
{
|
||||
if (!currentMaterial)
|
||||
currentMaterial = AddMaterial("default");
|
||||
|
||||
currentMaterial->bumpMap = map;
|
||||
}
|
||||
#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
|
||||
else
|
||||
UnrecognizedLine();
|
||||
#endif
|
||||
}
|
||||
else if (TestKeyword(m_currentLine, "map_d", offset))
|
||||
{
|
||||
std::string map = m_currentLine.substr(offset);
|
||||
if (!map.empty())
|
||||
{
|
||||
if (!currentMaterial)
|
||||
currentMaterial = AddMaterial("default");
|
||||
|
||||
currentMaterial->alphaMap = map;
|
||||
}
|
||||
#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
|
||||
else
|
||||
UnrecognizedLine();
|
||||
#endif
|
||||
}
|
||||
else if (TestKeyword(m_currentLine, "map_decal", offset))
|
||||
{
|
||||
std::string map = m_currentLine.substr(offset);
|
||||
if (!map.empty())
|
||||
{
|
||||
if (!currentMaterial)
|
||||
currentMaterial = AddMaterial("default");
|
||||
|
||||
currentMaterial->decalMap = map;
|
||||
}
|
||||
#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
|
||||
else
|
||||
UnrecognizedLine();
|
||||
#endif
|
||||
}
|
||||
else if (TestKeyword(m_currentLine, "map_disp", offset))
|
||||
{
|
||||
std::string map = m_currentLine.substr(offset);
|
||||
if (!map.empty())
|
||||
{
|
||||
if (!currentMaterial)
|
||||
currentMaterial = AddMaterial("default");
|
||||
|
||||
currentMaterial->displacementMap = map;
|
||||
}
|
||||
#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
|
||||
else
|
||||
UnrecognizedLine();
|
||||
#endif
|
||||
}
|
||||
else if (TestKeyword(m_currentLine, "map_refl", offset))
|
||||
{
|
||||
std::string map = m_currentLine.substr(offset);
|
||||
if (!map.empty())
|
||||
{
|
||||
if (!currentMaterial)
|
||||
currentMaterial = AddMaterial("default");
|
||||
|
||||
currentMaterial->reflectionMap = map;
|
||||
}
|
||||
#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
|
||||
else
|
||||
UnrecognizedLine();
|
||||
#endif
|
||||
}
|
||||
else if (TestKeyword(m_currentLine, "map_normal", offset))
|
||||
{
|
||||
std::string map = m_currentLine.substr(offset);
|
||||
if (!map.empty())
|
||||
{
|
||||
if (!currentMaterial)
|
||||
currentMaterial = AddMaterial("default");
|
||||
|
||||
currentMaterial->normalMap = map;
|
||||
}
|
||||
#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
|
||||
else
|
||||
UnrecognizedLine();
|
||||
#endif
|
||||
}
|
||||
else if (TestKeyword(m_currentLine, "map_emissive", offset))
|
||||
{
|
||||
// <!> This is a custom keyword
|
||||
std::string map = m_currentLine.substr(offset);
|
||||
if (!map.empty())
|
||||
{
|
||||
if (!currentMaterial)
|
||||
currentMaterial = AddMaterial("default");
|
||||
|
||||
currentMaterial->emissiveMap = map;
|
||||
}
|
||||
#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
|
||||
else
|
||||
UnrecognizedLine();
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 'n':
|
||||
{
|
||||
if (TestKeyword(m_currentLine, "ni", offset))
|
||||
{
|
||||
float density;
|
||||
if (std::sscanf(&m_currentLine[offset], "%f", &density) == 1)
|
||||
{
|
||||
if (!currentMaterial)
|
||||
currentMaterial = AddMaterial("default");
|
||||
|
||||
currentMaterial->refractionIndex = density;
|
||||
}
|
||||
#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
|
||||
else
|
||||
UnrecognizedLine();
|
||||
#endif
|
||||
}
|
||||
else if (TestKeyword(m_currentLine, "ns", offset))
|
||||
{
|
||||
float coef;
|
||||
if (std::sscanf(&m_currentLine[offset], "%f", &coef) == 1)
|
||||
{
|
||||
if (!currentMaterial)
|
||||
currentMaterial = AddMaterial("default");
|
||||
|
||||
currentMaterial->shininess = coef;
|
||||
}
|
||||
#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
|
||||
else
|
||||
UnrecognizedLine();
|
||||
#endif
|
||||
}
|
||||
else if (TestKeyword(m_currentLine, "normal", offset))
|
||||
{
|
||||
std::string map = m_currentLine.substr(offset);
|
||||
if (!map.empty())
|
||||
{
|
||||
if (!currentMaterial)
|
||||
currentMaterial = AddMaterial("default");
|
||||
|
||||
currentMaterial->normalMap = map;
|
||||
}
|
||||
#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
|
||||
else
|
||||
UnrecognizedLine();
|
||||
#endif
|
||||
}
|
||||
else if (TestKeyword(m_currentLine, "newmtl", offset))
|
||||
{
|
||||
std::string materialName = m_currentLine.substr(offset);
|
||||
if (!materialName.empty())
|
||||
currentMaterial = AddMaterial(materialName);
|
||||
#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
|
||||
else
|
||||
UnrecognizedLine();
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 'r':
|
||||
{
|
||||
if (TestKeyword(m_currentLine, "refl", offset))
|
||||
{
|
||||
std::string map = m_currentLine.substr(offset);
|
||||
if (!map.empty())
|
||||
{
|
||||
if (!currentMaterial)
|
||||
currentMaterial = AddMaterial("default");
|
||||
|
||||
currentMaterial->reflectionMap = map;
|
||||
}
|
||||
#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
|
||||
else
|
||||
UnrecognizedLine();
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 't':
|
||||
{
|
||||
if (TestKeyword(m_currentLine, "tr", offset))
|
||||
{
|
||||
float alpha;
|
||||
if (std::sscanf(&m_currentLine[offset], "%f", &alpha) == 1)
|
||||
{
|
||||
if (!currentMaterial)
|
||||
currentMaterial = AddMaterial("default");
|
||||
|
||||
currentMaterial->alpha = 1.f - alpha; // tr vaut pour la "valeur de transparence", 0 = opaque
|
||||
}
|
||||
#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
|
||||
else
|
||||
UnrecognizedLine();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
|
||||
UnrecognizedLine();
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -378,49 +565,49 @@ namespace Nz
|
||||
EmitLine(mat.illumModel);
|
||||
}
|
||||
|
||||
if (!mat.ambientMap.IsEmpty())
|
||||
if (!mat.ambientMap.empty())
|
||||
{
|
||||
Emit("map_Ka ");
|
||||
EmitLine(mat.ambientMap);
|
||||
}
|
||||
|
||||
if (!mat.diffuseMap.IsEmpty())
|
||||
if (!mat.diffuseMap.empty())
|
||||
{
|
||||
Emit("map_Kd ");
|
||||
EmitLine(mat.diffuseMap);
|
||||
}
|
||||
|
||||
if (!mat.specularMap.IsEmpty())
|
||||
if (!mat.specularMap.empty())
|
||||
{
|
||||
Emit("map_Ks ");
|
||||
EmitLine(mat.specularMap);
|
||||
}
|
||||
|
||||
if (!mat.bumpMap.IsEmpty())
|
||||
if (!mat.bumpMap.empty())
|
||||
{
|
||||
Emit("map_bump ");
|
||||
EmitLine(mat.bumpMap);
|
||||
}
|
||||
|
||||
if (!mat.alphaMap.IsEmpty())
|
||||
if (!mat.alphaMap.empty())
|
||||
{
|
||||
Emit("map_d ");
|
||||
EmitLine(mat.alphaMap);
|
||||
}
|
||||
|
||||
if (!mat.decalMap.IsEmpty())
|
||||
if (!mat.decalMap.empty())
|
||||
{
|
||||
Emit("map_decal ");
|
||||
EmitLine(mat.decalMap);
|
||||
}
|
||||
|
||||
if (!mat.displacementMap.IsEmpty())
|
||||
if (!mat.displacementMap.empty())
|
||||
{
|
||||
Emit("map_disp ");
|
||||
EmitLine(mat.displacementMap);
|
||||
}
|
||||
|
||||
if (!mat.reflectionMap.IsEmpty())
|
||||
if (!mat.reflectionMap.empty())
|
||||
{
|
||||
Emit("map_refl ");
|
||||
EmitLine(mat.reflectionMap);
|
||||
@@ -450,13 +637,18 @@ namespace Nz
|
||||
m_lineCount++;
|
||||
|
||||
m_currentLine = m_currentStream->ReadLine();
|
||||
if (m_currentLine.IsEmpty())
|
||||
continue;
|
||||
if (std::size_t p = m_currentLine.find('#'); p != m_currentLine.npos)
|
||||
{
|
||||
if (p > 0)
|
||||
m_currentLine = m_currentLine.substr(0, p - 1);
|
||||
else
|
||||
m_currentLine.clear();
|
||||
}
|
||||
|
||||
m_currentLine = m_currentLine.SubStringTo("#"); // On ignore les commentaires
|
||||
m_currentLine.Simplify(); // Pour un traitement plus simple
|
||||
if (m_currentLine.empty())
|
||||
continue;
|
||||
}
|
||||
while (m_currentLine.IsEmpty());
|
||||
while (m_currentLine.empty());
|
||||
}
|
||||
else
|
||||
m_keepLastLine = false;
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace Nz
|
||||
{
|
||||
namespace
|
||||
{
|
||||
bool IsSupported(const String& extension)
|
||||
bool IsSupported(const std::string& extension)
|
||||
{
|
||||
return (extension == "obj");
|
||||
}
|
||||
@@ -42,12 +42,12 @@ namespace Nz
|
||||
return Ternary_Unknown;
|
||||
}
|
||||
|
||||
bool ParseMTL(Mesh* mesh, const String& filePath, const String* materials, const OBJParser::Mesh* meshes, UInt32 meshCount)
|
||||
bool ParseMTL(Mesh* mesh, const std::filesystem::path& filePath, const std::string* materials, const OBJParser::Mesh* meshes, std::size_t meshCount)
|
||||
{
|
||||
File file(filePath);
|
||||
if (!file.Open(OpenMode_ReadOnly | OpenMode_Text))
|
||||
{
|
||||
NazaraError("Failed to open MTL file (" + file.GetPath() + ')');
|
||||
NazaraError("Failed to open MTL file (" + file.GetPath().generic_u8string() + ')');
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -59,10 +59,10 @@ namespace Nz
|
||||
}
|
||||
|
||||
std::unordered_map<String, ParameterList> materialCache;
|
||||
String baseDir = file.GetDirectory();
|
||||
for (UInt32 i = 0; i < meshCount; ++i)
|
||||
std::filesystem::path baseDir = file.GetDirectory();
|
||||
for (std::size_t i = 0; i < meshCount; ++i)
|
||||
{
|
||||
const String& matName = materials[meshes[i].material];
|
||||
const std::string& matName = materials[meshes[i].material];
|
||||
const MTLParser::Material* mtlMat = materialParser.GetMaterial(matName);
|
||||
if (!mtlMat)
|
||||
{
|
||||
@@ -89,53 +89,53 @@ namespace Nz
|
||||
data.SetParameter(MaterialData::Shininess, mtlMat->shininess);
|
||||
data.SetParameter(MaterialData::SpecularColor, specularColor);
|
||||
|
||||
if (!mtlMat->alphaMap.IsEmpty())
|
||||
if (!mtlMat->alphaMap.empty())
|
||||
{
|
||||
String fullPath = mtlMat->alphaMap;
|
||||
if (!Nz::File::IsAbsolute(fullPath))
|
||||
fullPath.Prepend(baseDir);
|
||||
std::filesystem::path fullPath = mtlMat->alphaMap;
|
||||
if (!fullPath.is_absolute())
|
||||
fullPath = baseDir / fullPath;
|
||||
|
||||
data.SetParameter(MaterialData::AlphaTexturePath, fullPath);
|
||||
data.SetParameter(MaterialData::AlphaTexturePath, fullPath.generic_u8string());
|
||||
}
|
||||
|
||||
if (!mtlMat->diffuseMap.IsEmpty())
|
||||
if (!mtlMat->diffuseMap.empty())
|
||||
{
|
||||
String fullPath = mtlMat->diffuseMap;
|
||||
if (!Nz::File::IsAbsolute(fullPath))
|
||||
fullPath.Prepend(baseDir);
|
||||
std::filesystem::path fullPath = mtlMat->diffuseMap;
|
||||
if (!fullPath.is_absolute())
|
||||
fullPath = baseDir / fullPath;
|
||||
|
||||
data.SetParameter(MaterialData::DiffuseTexturePath, fullPath);
|
||||
data.SetParameter(MaterialData::DiffuseTexturePath, fullPath.generic_u8string());
|
||||
}
|
||||
|
||||
if (!mtlMat->emissiveMap.IsEmpty())
|
||||
if (!mtlMat->emissiveMap.empty())
|
||||
{
|
||||
String fullPath = mtlMat->emissiveMap;
|
||||
if (!Nz::File::IsAbsolute(fullPath))
|
||||
fullPath.Prepend(baseDir);
|
||||
std::filesystem::path fullPath = mtlMat->emissiveMap;
|
||||
if (!fullPath.is_absolute())
|
||||
fullPath = baseDir / fullPath;
|
||||
|
||||
data.SetParameter(MaterialData::EmissiveTexturePath, fullPath);
|
||||
data.SetParameter(MaterialData::EmissiveTexturePath, fullPath.generic_u8string());
|
||||
}
|
||||
|
||||
if (!mtlMat->normalMap.IsEmpty())
|
||||
if (!mtlMat->normalMap.empty())
|
||||
{
|
||||
String fullPath = mtlMat->normalMap;
|
||||
if (!Nz::File::IsAbsolute(fullPath))
|
||||
fullPath.Prepend(baseDir);
|
||||
std::filesystem::path fullPath = mtlMat->normalMap;
|
||||
if (!fullPath.is_absolute())
|
||||
fullPath = baseDir / fullPath;
|
||||
|
||||
data.SetParameter(MaterialData::NormalTexturePath, fullPath);
|
||||
data.SetParameter(MaterialData::NormalTexturePath, fullPath.generic_u8string());
|
||||
}
|
||||
|
||||
if (!mtlMat->specularMap.IsEmpty())
|
||||
if (!mtlMat->specularMap.empty())
|
||||
{
|
||||
String fullPath = mtlMat->specularMap;
|
||||
if (!Nz::File::IsAbsolute(fullPath))
|
||||
fullPath.Prepend(baseDir);
|
||||
std::filesystem::path fullPath = mtlMat->specularMap;
|
||||
if (!fullPath.is_absolute())
|
||||
fullPath = baseDir / fullPath;
|
||||
|
||||
data.SetParameter(MaterialData::SpecularTexturePath, fullPath);
|
||||
data.SetParameter(MaterialData::SpecularTexturePath, fullPath.generic_u8string());
|
||||
}
|
||||
|
||||
// If we either have an alpha value or an alpha map, let's configure the material for transparency
|
||||
if (alphaValue != 255 || !mtlMat->alphaMap.IsEmpty())
|
||||
if (alphaValue != 255 || !mtlMat->alphaMap.empty())
|
||||
{
|
||||
// Some default settings
|
||||
data.SetParameter(MaterialData::Blending, true);
|
||||
@@ -169,27 +169,27 @@ namespace Nz
|
||||
MeshRef mesh = Mesh::New();
|
||||
mesh->CreateStatic();
|
||||
|
||||
const String* materials = parser.GetMaterials();
|
||||
const std::string* materials = parser.GetMaterials();
|
||||
const Vector4f* positions = parser.GetPositions();
|
||||
const Vector3f* normals = parser.GetNormals();
|
||||
const Vector3f* texCoords = parser.GetTexCoords();
|
||||
|
||||
const OBJParser::Mesh* meshes = parser.GetMeshes();
|
||||
UInt32 meshCount = parser.GetMeshCount();
|
||||
std::size_t meshCount = parser.GetMeshCount();
|
||||
|
||||
NazaraAssert(materials != nullptr && positions != nullptr && normals != nullptr &&
|
||||
texCoords != nullptr && meshes != nullptr && meshCount > 0,
|
||||
"Invalid OBJParser output");
|
||||
|
||||
// Un conteneur temporaire pour contenir les indices de face avant triangulation
|
||||
std::vector<UInt32> faceIndices(3); // Comme il y aura au moins trois sommets
|
||||
for (UInt32 i = 0; i < meshCount; ++i)
|
||||
std::vector<std::size_t> faceIndices(3); // Comme il y aura au moins trois sommets
|
||||
for (std::size_t i = 0; i < meshCount; ++i)
|
||||
{
|
||||
std::size_t faceCount = meshes[i].faces.size();
|
||||
if (faceCount == 0)
|
||||
continue;
|
||||
|
||||
std::vector<UInt32> indices;
|
||||
std::vector<std::size_t> indices;
|
||||
indices.reserve(faceCount*3); // Pire cas si les faces sont des triangles
|
||||
|
||||
// Afin d'utiliser OBJParser::FaceVertex comme clé dans un unordered_map,
|
||||
@@ -226,10 +226,10 @@ namespace Nz
|
||||
unsigned int vertexCount = 0;
|
||||
for (unsigned int j = 0; j < faceCount; ++j)
|
||||
{
|
||||
UInt32 faceVertexCount = meshes[i].faces[j].vertexCount;
|
||||
std::size_t faceVertexCount = meshes[i].faces[j].vertexCount;
|
||||
faceIndices.resize(faceVertexCount);
|
||||
|
||||
for (UInt32 k = 0; k < faceVertexCount; ++k)
|
||||
for (std::size_t k = 0; k < faceVertexCount; ++k)
|
||||
{
|
||||
const OBJParser::FaceVertex& vertex = meshes[i].vertices[meshes[i].faces[j].firstVertex + k];
|
||||
|
||||
@@ -241,7 +241,7 @@ namespace Nz
|
||||
}
|
||||
|
||||
// Triangulation
|
||||
for (UInt32 k = 1; k < faceVertexCount-1; ++k)
|
||||
for (std::size_t k = 1; k < faceVertexCount-1; ++k)
|
||||
{
|
||||
indices.push_back(faceIndices[0]);
|
||||
indices.push_back(faceIndices[k]);
|
||||
@@ -250,13 +250,13 @@ namespace Nz
|
||||
}
|
||||
|
||||
// Création des buffers
|
||||
IndexBufferRef indexBuffer = IndexBuffer::New(vertexCount > std::numeric_limits<UInt16>::max(), UInt32(indices.size()), parameters.storage, parameters.indexBufferFlags);
|
||||
VertexBufferRef vertexBuffer = VertexBuffer::New(parameters.vertexDeclaration, UInt32(vertexCount), parameters.storage, parameters.vertexBufferFlags);
|
||||
IndexBufferRef indexBuffer = IndexBuffer::New(vertexCount > std::numeric_limits<UInt16>::max(), std::size_t(indices.size()), parameters.storage, parameters.indexBufferFlags);
|
||||
VertexBufferRef vertexBuffer = VertexBuffer::New(parameters.vertexDeclaration, std::size_t(vertexCount), parameters.storage, parameters.vertexBufferFlags);
|
||||
|
||||
// Remplissage des indices
|
||||
IndexMapper indexMapper(indexBuffer, BufferAccess_WriteOnly);
|
||||
for (std::size_t j = 0; j < indices.size(); ++j)
|
||||
indexMapper.Set(j, indices[j]);
|
||||
indexMapper.Set(j, UInt32(indices[j]));
|
||||
|
||||
indexMapper.Unmap(); // Pour laisser les autres tâches affecter l'index buffer
|
||||
|
||||
@@ -337,11 +337,11 @@ namespace Nz
|
||||
mesh->Recenter();
|
||||
|
||||
// On charge les matériaux si demandé
|
||||
String mtlLib = parser.GetMtlLib();
|
||||
if (!mtlLib.IsEmpty())
|
||||
std::filesystem::path mtlLib = parser.GetMtlLib();
|
||||
if (!mtlLib.empty())
|
||||
{
|
||||
ErrorFlags flags(ErrorFlag_ThrowExceptionDisabled);
|
||||
ParseMTL(mesh, stream.GetDirectory() + mtlLib, materials, meshes, meshCount);
|
||||
ParseMTL(mesh, stream.GetDirectory() / mtlLib, materials, meshes, meshCount);
|
||||
}
|
||||
|
||||
return mesh;
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#include <Nazara/Utility/Formats/OBJParser.hpp>
|
||||
#include <Nazara/Core/CallOnExit.hpp>
|
||||
#include <Nazara/Core/StringExt.hpp>
|
||||
#include <Nazara/Utility/Config.hpp>
|
||||
#include <cctype>
|
||||
#include <memory>
|
||||
@@ -45,32 +46,29 @@ namespace Nz
|
||||
case 'o': //< Object (defines a mesh)
|
||||
case 's': //< Smooth
|
||||
{
|
||||
if (m_currentLine.GetSize() > 1 && m_currentLine[1] == ' ')
|
||||
if (m_currentLine.size() > 1 && m_currentLine[1] == ' ')
|
||||
return true;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 'm': //< MTLLib
|
||||
if (m_currentLine.GetWord(0).ToLower() == "mtllib")
|
||||
if (StartsWith(m_currentLine, "mtllib "))
|
||||
return true;
|
||||
|
||||
break;
|
||||
|
||||
case 'u': //< Usemtl
|
||||
if (m_currentLine.GetWord(0).ToLower() == "usemtl")
|
||||
if (StartsWith(m_currentLine, "usemtl "))
|
||||
return true;
|
||||
|
||||
break;
|
||||
|
||||
case 'v': //< Position/Normal/Texcoords
|
||||
{
|
||||
String word = m_currentLine.GetWord(0).ToLower();
|
||||
if (word == 'v')
|
||||
return true;
|
||||
else if (word == "vn")
|
||||
return true;
|
||||
else if (word == "vt")
|
||||
if (StartsWith(m_currentLine, "v ") ||
|
||||
StartsWith(m_currentLine, "vn ") ||
|
||||
StartsWith(m_currentLine, "vt "))
|
||||
return true;
|
||||
|
||||
break;
|
||||
@@ -87,7 +85,7 @@ namespace Nz
|
||||
return false;
|
||||
}
|
||||
|
||||
bool OBJParser::Parse(Nz::Stream& stream, UInt32 reservedVertexCount)
|
||||
bool OBJParser::Parse(Nz::Stream& stream, std::size_t reservedVertexCount)
|
||||
{
|
||||
m_currentStream = &stream;
|
||||
m_errorCount = 0;
|
||||
@@ -106,10 +104,10 @@ namespace Nz
|
||||
});
|
||||
}
|
||||
|
||||
String matName, meshName;
|
||||
std::string matName, meshName;
|
||||
matName = meshName = "default";
|
||||
m_meshes.clear();
|
||||
m_mtlLib.Clear();
|
||||
m_mtlLib.clear();
|
||||
|
||||
m_normals.clear();
|
||||
m_positions.clear();
|
||||
@@ -122,12 +120,12 @@ namespace Nz
|
||||
|
||||
// Sort meshes by material and group
|
||||
using MatPair = std::pair<Mesh, unsigned int>;
|
||||
std::unordered_map<String, std::unordered_map<String, MatPair>> meshesByName;
|
||||
std::unordered_map<std::string, std::unordered_map<std::string, MatPair>> meshesByName;
|
||||
|
||||
UInt32 faceReserve = 0;
|
||||
UInt32 vertexReserve = 0;
|
||||
unsigned int matCount = 0;
|
||||
auto GetMaterial = [&] (const String& mesh, const String& mat) -> Mesh*
|
||||
auto GetMaterial = [&] (const std::string& mesh, const std::string& mat) -> Mesh*
|
||||
{
|
||||
auto& map = meshesByName[mesh];
|
||||
auto it = map.find(mat);
|
||||
@@ -154,22 +152,22 @@ namespace Nz
|
||||
case '#': //< Comment
|
||||
// Some softwares write comments to gives the number of vertex/faces an importer can expect
|
||||
unsigned int data;
|
||||
if (std::sscanf(m_currentLine.GetConstBuffer(), "# position count: %u", &data) == 1)
|
||||
if (std::sscanf(m_currentLine.data(), "# position count: %u", &data) == 1)
|
||||
m_positions.reserve(data);
|
||||
else if (std::sscanf(m_currentLine.GetConstBuffer(), "# normal count: %u", &data) == 1)
|
||||
else if (std::sscanf(m_currentLine.data(), "# normal count: %u", &data) == 1)
|
||||
m_normals.reserve(data);
|
||||
else if (std::sscanf(m_currentLine.GetConstBuffer(), "# texcoords count: %u", &data) == 1)
|
||||
else if (std::sscanf(m_currentLine.data(), "# texcoords count: %u", &data) == 1)
|
||||
m_texCoords.reserve(data);
|
||||
else if (std::sscanf(m_currentLine.GetConstBuffer(), "# face count: %u", &data) == 1)
|
||||
else if (std::sscanf(m_currentLine.data(), "# face count: %u", &data) == 1)
|
||||
faceReserve = data;
|
||||
else if (std::sscanf(m_currentLine.GetConstBuffer(), "# vertex count: %u", &data) == 1)
|
||||
else if (std::sscanf(m_currentLine.data(), "# vertex count: %u", &data) == 1)
|
||||
vertexReserve = data;
|
||||
|
||||
break;
|
||||
|
||||
case 'f': //< Face
|
||||
{
|
||||
if (m_currentLine.GetSize() < 7) // Since we only treat triangles, this is the minimum length of a face line (f 1 2 3)
|
||||
if (m_currentLine.size() < 7) // Since we only treat triangles, this is the minimum length of a face line (f 1 2 3)
|
||||
{
|
||||
#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
|
||||
if (!UnrecognizedLine())
|
||||
@@ -178,7 +176,7 @@ namespace Nz
|
||||
break;
|
||||
}
|
||||
|
||||
unsigned int vertexCount = m_currentLine.Count(' ');
|
||||
std::size_t vertexCount = std::count(m_currentLine.begin(), m_currentLine.end(), ' ');
|
||||
if (vertexCount < 3)
|
||||
{
|
||||
#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
|
||||
@@ -192,8 +190,8 @@ namespace Nz
|
||||
currentMesh = GetMaterial(meshName, matName);
|
||||
|
||||
Face face;
|
||||
face.firstVertex = static_cast<UInt32>(currentMesh->vertices.size());
|
||||
face.vertexCount = static_cast<UInt32>(vertexCount);
|
||||
face.firstVertex = currentMesh->vertices.size();
|
||||
face.vertexCount = vertexCount;
|
||||
|
||||
currentMesh->vertices.resize(face.firstVertex + vertexCount, FaceVertex{0, 0, 0});
|
||||
|
||||
@@ -230,7 +228,7 @@ namespace Nz
|
||||
p += static_cast<int>(m_positions.size());
|
||||
if (p < 0)
|
||||
{
|
||||
Error("Vertex index out of range (" + String::Number(p) + " < 0");
|
||||
Error("Vertex index out of range (" + std::to_string(p) + " < 0");
|
||||
error = true;
|
||||
break;
|
||||
}
|
||||
@@ -243,7 +241,7 @@ namespace Nz
|
||||
n += static_cast<int>(m_normals.size());
|
||||
if (n < 0)
|
||||
{
|
||||
Error("Normal index out of range (" + String::Number(n) + " < 0");
|
||||
Error("Normal index out of range (" + std::to_string(n) + " < 0");
|
||||
error = true;
|
||||
break;
|
||||
}
|
||||
@@ -256,7 +254,7 @@ namespace Nz
|
||||
t += static_cast<int>(m_texCoords.size());
|
||||
if (t < 0)
|
||||
{
|
||||
Error("Texture coordinates index out of range (" + String::Number(t) + " < 0");
|
||||
Error("Texture coordinates index out of range (" + std::to_string(t) + " < 0");
|
||||
error = true;
|
||||
break;
|
||||
}
|
||||
@@ -266,19 +264,19 @@ namespace Nz
|
||||
|
||||
if (static_cast<std::size_t>(p) > m_positions.size())
|
||||
{
|
||||
Error("Vertex index out of range (" + String::Number(p) + " >= " + String::Number(m_positions.size()) + ')');
|
||||
Error("Vertex index out of range (" + std::to_string(p) + " >= " + std::to_string(m_positions.size()) + ')');
|
||||
error = true;
|
||||
break;
|
||||
}
|
||||
else if (n != 0 && static_cast<std::size_t>(n) > m_normals.size())
|
||||
{
|
||||
Error("Normal index out of range (" + String::Number(n) + " >= " + String::Number(m_normals.size()) + ')');
|
||||
Error("Normal index out of range (" + std::to_string(n) + " >= " + std::to_string(m_normals.size()) + ')');
|
||||
error = true;
|
||||
break;
|
||||
}
|
||||
else if (t != 0 && static_cast<std::size_t>(t) > m_texCoords.size())
|
||||
{
|
||||
Error("TexCoord index out of range (" + String::Number(t) + " >= " + String::Number(m_texCoords.size()) + ')');
|
||||
Error("TexCoord index out of range (" + std::to_string(t) + " >= " + std::to_string(m_texCoords.size()) + ')');
|
||||
error = true;
|
||||
break;
|
||||
}
|
||||
@@ -299,29 +297,36 @@ namespace Nz
|
||||
}
|
||||
|
||||
case 'm': //< MTLLib
|
||||
#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
|
||||
if (m_currentLine.GetWord(0).ToLower() != "mtllib")
|
||||
{
|
||||
const char prefix[] = "mtllib ";
|
||||
if (!StartsWith(m_currentLine, prefix))
|
||||
{
|
||||
#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
|
||||
if (!UnrecognizedLine())
|
||||
return false;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
m_mtlLib = m_currentLine.SubString(m_currentLine.GetWordPosition(1));
|
||||
break;
|
||||
}
|
||||
|
||||
m_mtlLib = m_currentLine.substr(sizeof(prefix) - 1);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'g': //< Group (inside a mesh)
|
||||
case 'o': //< Object (defines a mesh)
|
||||
{
|
||||
if (m_currentLine.GetSize() <= 2 || m_currentLine[1] != ' ')
|
||||
if (m_currentLine.size() <= 2 || m_currentLine[1] != ' ')
|
||||
{
|
||||
#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
|
||||
#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
|
||||
if (!UnrecognizedLine())
|
||||
return false;
|
||||
#endif
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
String objectName = m_currentLine.SubString(m_currentLine.GetWordPosition(1));
|
||||
if (objectName.IsEmpty())
|
||||
std::string objectName = m_currentLine.substr(2);
|
||||
if (objectName.empty())
|
||||
{
|
||||
#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
|
||||
if (!UnrecognizedLine())
|
||||
@@ -335,12 +340,12 @@ namespace Nz
|
||||
break;
|
||||
}
|
||||
|
||||
#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
|
||||
#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
|
||||
case 's': //< Smooth
|
||||
if (m_currentLine.GetSize() <= 2 || m_currentLine[1] == ' ')
|
||||
if (m_currentLine.size() <= 2 || m_currentLine[1] == ' ')
|
||||
{
|
||||
String param = m_currentLine.SubString(2);
|
||||
if (param != "all" && param != "on" && param != "off" && !param.IsNumber())
|
||||
std::string param = m_currentLine.substr(2);
|
||||
if (param != "all" && param != "on" && param != "off" && !IsNumber(param))
|
||||
{
|
||||
if (!UnrecognizedLine())
|
||||
return false;
|
||||
@@ -349,33 +354,51 @@ namespace Nz
|
||||
else if (!UnrecognizedLine())
|
||||
return false;
|
||||
break;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
case 'u': //< Usemtl
|
||||
#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
|
||||
if (m_currentLine.GetWord(0) != "usemtl" && !UnrecognizedLine())
|
||||
return false;
|
||||
#endif
|
||||
|
||||
matName = m_currentLine.SubString(m_currentLine.GetWordPosition(1));
|
||||
currentMesh = nullptr;
|
||||
if (matName.IsEmpty())
|
||||
{
|
||||
const char prefix[] = "usemtl ";
|
||||
if (!StartsWith(m_currentLine, prefix))
|
||||
{
|
||||
#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
|
||||
#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
|
||||
if (!UnrecognizedLine())
|
||||
return false;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
std::string newMatName = m_currentLine.substr(sizeof(prefix) - 1);
|
||||
if (newMatName.empty())
|
||||
{
|
||||
#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
|
||||
if (!UnrecognizedLine())
|
||||
return false;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
matName = std::move(newMatName);
|
||||
currentMesh = nullptr;
|
||||
break;
|
||||
}
|
||||
|
||||
case 'v': //< Position/Normal/Texcoords
|
||||
{
|
||||
String word = m_currentLine.GetWord(0).ToLower();
|
||||
if (word == 'v')
|
||||
if (m_currentLine.size() < 7)
|
||||
{
|
||||
#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
|
||||
if (!UnrecognizedLine())
|
||||
return false;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
if (std::isspace(m_currentLine[1]))
|
||||
{
|
||||
Vector4f vertex(Vector3f::Zero(), 1.f);
|
||||
unsigned int paramCount = std::sscanf(&m_currentLine[2], "%f %f %f %f", &vertex.x, &vertex.y, &vertex.z, &vertex.w);
|
||||
unsigned int paramCount = std::sscanf(&m_currentLine[2], " %f %f %f %f", &vertex.x, &vertex.y, &vertex.z, &vertex.w);
|
||||
if (paramCount >= 1)
|
||||
m_positions.push_back(vertex);
|
||||
#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
|
||||
@@ -383,10 +406,10 @@ namespace Nz
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
else if (word == "vn")
|
||||
else if (m_currentLine[1] == 'n' && std::isspace(m_currentLine[2]))
|
||||
{
|
||||
Vector3f normal(Vector3f::Zero());
|
||||
unsigned int paramCount = std::sscanf(&m_currentLine[3], "%f %f %f", &normal.x, &normal.y, &normal.z);
|
||||
unsigned int paramCount = std::sscanf(&m_currentLine[3], " %f %f %f", &normal.x, &normal.y, &normal.z);
|
||||
if (paramCount == 3)
|
||||
m_normals.push_back(normal);
|
||||
#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
|
||||
@@ -394,10 +417,10 @@ namespace Nz
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
else if (word == "vt")
|
||||
else if (m_currentLine[1] == 't' && std::isspace(m_currentLine[2]))
|
||||
{
|
||||
Vector3f uvw(Vector3f::Zero());
|
||||
unsigned int paramCount = std::sscanf(&m_currentLine[3], "%f %f %f", &uvw.x, &uvw.y, &uvw.z);
|
||||
unsigned int paramCount = std::sscanf(&m_currentLine[3], " %f %f %f", &uvw.x, &uvw.y, &uvw.z);
|
||||
if (paramCount >= 2)
|
||||
m_texCoords.push_back(uvw);
|
||||
#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
|
||||
@@ -422,7 +445,7 @@ namespace Nz
|
||||
}
|
||||
}
|
||||
|
||||
std::unordered_map<String, unsigned int> materials;
|
||||
std::unordered_map<std::string, unsigned int> materials;
|
||||
m_materials.resize(matCount);
|
||||
|
||||
for (auto& meshPair : meshesByName)
|
||||
@@ -480,10 +503,10 @@ namespace Nz
|
||||
EmitLine("# Exported by Nazara Engine");
|
||||
EmitLine();
|
||||
|
||||
if (!m_mtlLib.IsEmpty())
|
||||
if (!m_mtlLib.empty())
|
||||
{
|
||||
Emit("mtllib ");
|
||||
EmitLine(m_mtlLib);
|
||||
EmitLine(m_mtlLib.generic_u8string());
|
||||
EmitLine();
|
||||
}
|
||||
|
||||
@@ -617,12 +640,18 @@ namespace Nz
|
||||
m_lineCount++;
|
||||
|
||||
m_currentLine = m_currentStream->ReadLine();
|
||||
if (m_currentLine.IsEmpty())
|
||||
continue;
|
||||
if (std::size_t p = m_currentLine.find('#'); p != m_currentLine.npos)
|
||||
{
|
||||
if (p > 0)
|
||||
m_currentLine = m_currentLine.substr(0, p - 1);
|
||||
else
|
||||
m_currentLine.clear();
|
||||
}
|
||||
|
||||
m_currentLine.Simplify(); // Simplify lines (convert multiple blanks into a single space and trims)
|
||||
if (m_currentLine.empty())
|
||||
continue;
|
||||
}
|
||||
while (m_currentLine.IsEmpty());
|
||||
while (m_currentLine.empty());
|
||||
}
|
||||
else
|
||||
m_keepLastLine = false;
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
// This file is part of the "Nazara Engine - Utility module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Core/Directory.hpp>
|
||||
#include <Nazara/Utility/MaterialData.hpp>
|
||||
#include <Nazara/Utility/Mesh.hpp>
|
||||
#include <Nazara/Utility/StaticMesh.hpp>
|
||||
@@ -28,12 +27,12 @@ namespace Nz
|
||||
{
|
||||
}
|
||||
|
||||
UInt32 GetCount() const
|
||||
std::size_t GetCount() const
|
||||
{
|
||||
return m_count;
|
||||
}
|
||||
|
||||
UInt32 Insert(const T& data)
|
||||
std::size_t Insert(const T& data)
|
||||
{
|
||||
auto it = m_cache.find(data);
|
||||
if (it == m_cache.end())
|
||||
@@ -47,17 +46,17 @@ namespace Nz
|
||||
}
|
||||
|
||||
private:
|
||||
UInt32 m_count;
|
||||
std::map<T, UInt32> m_cache;
|
||||
std::size_t m_count;
|
||||
std::map<T, std::size_t> m_cache;
|
||||
T* m_buffer;
|
||||
};
|
||||
|
||||
bool IsSupported(const String& extension)
|
||||
bool IsSupported(const std::string& extension)
|
||||
{
|
||||
return (extension == "obj");
|
||||
}
|
||||
|
||||
bool SaveToStream(const Mesh& mesh, const String& format, Stream& stream, const MeshParams& parameters)
|
||||
bool SaveToStream(const Mesh& mesh, const std::string& format, Stream& stream, const MeshParams& parameters)
|
||||
{
|
||||
NazaraUnused(parameters);
|
||||
|
||||
@@ -73,18 +72,18 @@ namespace Nz
|
||||
return false;
|
||||
}
|
||||
|
||||
UInt32 worstCacheVertexCount = mesh.GetVertexCount();
|
||||
std::size_t worstCacheVertexCount = mesh.GetVertexCount();
|
||||
OBJParser objFormat;
|
||||
objFormat.SetNormalCount(worstCacheVertexCount);
|
||||
objFormat.SetPositionCount(worstCacheVertexCount);
|
||||
objFormat.SetTexCoordCount(worstCacheVertexCount);
|
||||
|
||||
String mtlPath = stream.GetPath();
|
||||
if (!mtlPath.IsEmpty())
|
||||
std::filesystem::path mtlPath = stream.GetPath();
|
||||
if (!mtlPath.empty())
|
||||
{
|
||||
mtlPath.Replace(".obj", ".mtl");
|
||||
String fileName = mtlPath.SubStringFrom(NAZARA_DIRECTORY_SEPARATOR, -1, true);
|
||||
if (!fileName.IsEmpty())
|
||||
mtlPath.replace_extension(".mtl");
|
||||
std::filesystem::path fileName = mtlPath.filename();
|
||||
if (!fileName.empty())
|
||||
objFormat.SetMtlLib(fileName);
|
||||
}
|
||||
|
||||
@@ -94,17 +93,20 @@ namespace Nz
|
||||
|
||||
// Materials
|
||||
MTLParser mtlFormat;
|
||||
std::unordered_set<String> registredMaterials;
|
||||
std::unordered_set<std::string> registredMaterials;
|
||||
|
||||
UInt32 matCount = mesh.GetMaterialCount();
|
||||
String* materialNames = objFormat.SetMaterialCount(matCount);
|
||||
for (UInt32 i = 0; i < matCount; ++i)
|
||||
std::size_t matCount = mesh.GetMaterialCount();
|
||||
std::string* materialNames = objFormat.SetMaterialCount(matCount);
|
||||
for (std::size_t i = 0; i < matCount; ++i)
|
||||
{
|
||||
const ParameterList& matData = mesh.GetMaterialData(i);
|
||||
|
||||
String name;
|
||||
if (!matData.GetStringParameter(MaterialData::Name, &name))
|
||||
name = "material_" + String::Number(i);
|
||||
String nzname;
|
||||
std::string name;
|
||||
if (matData.GetStringParameter(MaterialData::Name, &nzname))
|
||||
name = nzname.ToStdString();
|
||||
else
|
||||
name = "material_" + std::to_string(i);
|
||||
|
||||
// Makes sure we only have one material of that name
|
||||
while (registredMaterials.find(name) != registredMaterials.end())
|
||||
@@ -117,7 +119,7 @@ namespace Nz
|
||||
|
||||
String strVal;
|
||||
if (matData.GetStringParameter(MaterialData::FilePath, &strVal))
|
||||
material->diffuseMap = strVal;
|
||||
material->diffuseMap = strVal.ToStdString();
|
||||
else
|
||||
{
|
||||
Color colorVal;
|
||||
@@ -136,28 +138,28 @@ namespace Nz
|
||||
material->shininess = float(dValue);
|
||||
|
||||
if (matData.GetStringParameter(MaterialData::AlphaTexturePath, &strVal))
|
||||
material->alphaMap = strVal;
|
||||
material->alphaMap = strVal.ToStdString();
|
||||
|
||||
if (matData.GetStringParameter(MaterialData::DiffuseTexturePath, &strVal))
|
||||
material->diffuseMap = strVal;
|
||||
material->diffuseMap = strVal.ToStdString();
|
||||
|
||||
if (matData.GetStringParameter(MaterialData::SpecularTexturePath, &strVal))
|
||||
material->specularMap = strVal;
|
||||
material->specularMap = strVal.ToStdString();
|
||||
}
|
||||
}
|
||||
|
||||
// Meshes
|
||||
UInt32 meshCount = mesh.GetSubMeshCount();
|
||||
std::size_t meshCount = mesh.GetSubMeshCount();
|
||||
OBJParser::Mesh* meshes = objFormat.SetMeshCount(meshCount);
|
||||
for (UInt32 i = 0; i < meshCount; ++i)
|
||||
for (std::size_t i = 0; i < meshCount; ++i)
|
||||
{
|
||||
const StaticMesh* staticMesh = static_cast<const StaticMesh*>(mesh.GetSubMesh(i));
|
||||
|
||||
UInt32 triangleCount = staticMesh->GetTriangleCount();
|
||||
std::size_t triangleCount = staticMesh->GetTriangleCount();
|
||||
|
||||
meshes[i].faces.resize(triangleCount);
|
||||
meshes[i].material = staticMesh->GetMaterialIndex();
|
||||
meshes[i].name = "mesh_" + String::Number(i);
|
||||
meshes[i].name = "mesh_" + std::to_string(i);
|
||||
meshes[i].vertices.resize(triangleCount * 3);
|
||||
|
||||
{
|
||||
@@ -167,7 +169,7 @@ namespace Nz
|
||||
SparsePtr<Vector3f> positionPtr = vertexMapper.GetComponentPtr<Vector3f>(VertexComponent_Position);
|
||||
SparsePtr<Vector2f> texCoordsPtr = vertexMapper.GetComponentPtr<Vector2f>(VertexComponent_TexCoord);
|
||||
|
||||
UInt32 faceIndex = 0;
|
||||
std::size_t faceIndex = 0;
|
||||
TriangleIterator triangle(staticMesh);
|
||||
do
|
||||
{
|
||||
@@ -179,7 +181,7 @@ namespace Nz
|
||||
{
|
||||
OBJParser::FaceVertex& vertexIndices = meshes[i].vertices[face.firstVertex + j];
|
||||
|
||||
UInt32 index = triangle[j];
|
||||
std::size_t index = triangle[j];
|
||||
vertexIndices.normal = normalCache.Insert(normalPtr[index]);
|
||||
vertexIndices.position = positionCache.Insert(positionPtr[index]);
|
||||
vertexIndices.texCoord = texCoordsCache.Insert(texCoordsPtr[index]);
|
||||
@@ -197,7 +199,7 @@ namespace Nz
|
||||
|
||||
objFormat.Save(stream);
|
||||
|
||||
if (!mtlPath.IsEmpty())
|
||||
if (!mtlPath.empty())
|
||||
{
|
||||
File mtlFile(mtlPath, OpenMode_WriteOnly | OpenMode_Truncate);
|
||||
if (mtlFile.IsOpen())
|
||||
|
||||
@@ -40,7 +40,7 @@ namespace Nz
|
||||
|
||||
static_assert(sizeof(pcx_header) == (6+48+54)*sizeof(UInt8) + 10*sizeof(UInt16), "pcx_header struct must be packed");
|
||||
|
||||
bool IsSupported(const String& extension)
|
||||
bool IsSupported(const std::string& extension)
|
||||
{
|
||||
return (extension == "pcx");
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace Nz
|
||||
|
||||
static stbi_io_callbacks callbacks = {Read, Skip, Eof};
|
||||
|
||||
bool IsSupported(const String& extension)
|
||||
bool IsSupported(const std::string& extension)
|
||||
{
|
||||
static std::set<String> supportedExtensions = {"bmp", "gif", "hdr", "jpg", "jpeg", "pic", "png", "ppm", "pgm", "psd", "tga"};
|
||||
return supportedExtensions.find(extension) != supportedExtensions.end();
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace Nz
|
||||
{
|
||||
using FormatHandler = bool(*)(const Image& image, const ImageParams& parameters, Stream& stream);
|
||||
|
||||
std::map<String, FormatHandler> s_formatHandlers;
|
||||
std::map<std::string, FormatHandler> s_formatHandlers;
|
||||
|
||||
int ConvertToFloatFormat(Image& image)
|
||||
{
|
||||
@@ -102,12 +102,12 @@ namespace Nz
|
||||
throw std::runtime_error("Failed to write to stream");
|
||||
}
|
||||
|
||||
bool FormatQuerier(const String& extension)
|
||||
bool FormatQuerier(const std::string& extension)
|
||||
{
|
||||
return s_formatHandlers.find(extension) != s_formatHandlers.end();
|
||||
}
|
||||
|
||||
bool SaveToStream(const Image& image, const String& format, Stream& stream, const ImageParams& parameters)
|
||||
bool SaveToStream(const Image& image, const std::string& format, Stream& stream, const ImageParams& parameters)
|
||||
{
|
||||
NazaraUnused(parameters);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user