Rename and move loaders, expose parsers
Former-commit-id: 932ae2aab020f956d3fdb91107f6842ff292aa08
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
// This file is part of the "Nazara Engine - Graphics module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Graphics/Loaders/Mesh.hpp>
|
||||
#include <Nazara/Graphics/Formats/MeshLoader.hpp>
|
||||
#include <Nazara/Graphics/Material.hpp>
|
||||
#include <Nazara/Graphics/Model.hpp>
|
||||
#include <Nazara/Graphics/SkeletalModel.hpp>
|
||||
@@ -2,13 +2,13 @@
|
||||
// This file is part of the "Nazara Engine - Graphics module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Graphics/Loaders/OBJ.hpp>
|
||||
#include <Nazara/Graphics/Formats/OBJLoader.hpp>
|
||||
#include <Nazara/Core/Algorithm.hpp>
|
||||
#include <Nazara/Core/ErrorFlags.hpp>
|
||||
#include <Nazara/Graphics/Material.hpp>
|
||||
#include <Nazara/Graphics/Model.hpp>
|
||||
#include <Nazara/Graphics/Loaders/OBJ/MTLParser.hpp>
|
||||
#include <Nazara/Graphics/Loaders/OBJ/OBJParser.hpp>
|
||||
#include <Nazara/Graphics/Formats/MTLParser.hpp>
|
||||
#include <Nazara/Graphics/Formats/OBJParser.hpp>
|
||||
#include <Nazara/Utility/BufferMapper.hpp>
|
||||
#include <Nazara/Utility/IndexMapper.hpp>
|
||||
#include <Nazara/Utility/Mesh.hpp>
|
||||
@@ -2,7 +2,7 @@
|
||||
// This file is part of the "Nazara Engine - Graphics module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Graphics/Loaders/Texture.hpp>
|
||||
#include <Nazara/Graphics/Formats/TextureLoader.hpp>
|
||||
#include <Nazara/Graphics/Material.hpp>
|
||||
#include <Nazara/Renderer/Texture.hpp>
|
||||
#include <memory>
|
||||
@@ -17,9 +17,9 @@
|
||||
#include <Nazara/Graphics/ParticleRenderer.hpp>
|
||||
#include <Nazara/Graphics/RenderTechniques.hpp>
|
||||
#include <Nazara/Graphics/SkinningManager.hpp>
|
||||
#include <Nazara/Graphics/Loaders/Mesh.hpp>
|
||||
#include <Nazara/Graphics/Loaders/OBJ.hpp>
|
||||
#include <Nazara/Graphics/Loaders/Texture.hpp>
|
||||
#include <Nazara/Graphics/Formats/MeshLoader.hpp>
|
||||
#include <Nazara/Graphics/Formats/OBJLoader.hpp>
|
||||
#include <Nazara/Graphics/Formats/TextureLoader.hpp>
|
||||
#include <Nazara/Renderer/Renderer.hpp>
|
||||
#include <Nazara/Utility/Font.hpp>
|
||||
#include <Nazara/Graphics/Debug.hpp>
|
||||
|
||||
@@ -1,328 +0,0 @@
|
||||
// Copyright (C) 2015 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Graphics module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Graphics/Loaders/OBJ/MTLParser.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Core/Log.hpp>
|
||||
#include <Nazara/Utility/Config.hpp>
|
||||
#include <cstdio>
|
||||
#include <memory>
|
||||
#include <Nazara/Graphics/Debug.hpp>
|
||||
|
||||
NzMTLParser::NzMTLParser(NzInputStream& stream) :
|
||||
m_stream(stream),
|
||||
m_streamFlags(stream.GetStreamOptions())
|
||||
{
|
||||
if ((m_streamFlags & nzStreamOption_Text) == 0)
|
||||
m_stream.SetStreamOptions(m_streamFlags | nzStreamOption_Text);
|
||||
}
|
||||
|
||||
NzMTLParser::~NzMTLParser()
|
||||
{
|
||||
if ((m_streamFlags & nzStreamOption_Text) == 0)
|
||||
m_stream.SetStreamOptions(m_streamFlags);
|
||||
}
|
||||
|
||||
const NzMTLParser::Material* NzMTLParser::GetMaterial(const NzString& materialName) const
|
||||
{
|
||||
auto it = m_materials.find(materialName);
|
||||
if (it != m_materials.end())
|
||||
return &it->second;
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool NzMTLParser::Parse()
|
||||
{
|
||||
m_keepLastLine = false;
|
||||
m_lineCount = 0;
|
||||
m_materials.clear();
|
||||
|
||||
Material* currentMaterial = nullptr;
|
||||
|
||||
while (Advance(false))
|
||||
{
|
||||
NzString keyword = m_currentLine.GetWord(0).ToLower();
|
||||
if (keyword == "ka")
|
||||
{
|
||||
float r, g, b;
|
||||
if (std::sscanf(&m_currentLine[3], "%f %f %f", &r, &g, &b) == 3)
|
||||
{
|
||||
if (!currentMaterial)
|
||||
currentMaterial = &m_materials["default"];
|
||||
|
||||
currentMaterial->ambient = NzColor(static_cast<nzUInt8>(r*255.f), static_cast<nzUInt8>(g*255.f), static_cast<nzUInt8>(b*255.f));
|
||||
}
|
||||
#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)
|
||||
{
|
||||
if (!currentMaterial)
|
||||
currentMaterial = &m_materials["default"];
|
||||
|
||||
currentMaterial->diffuse = NzColor(static_cast<nzUInt8>(r*255.f), static_cast<nzUInt8>(g*255.f), static_cast<nzUInt8>(b*255.f));
|
||||
}
|
||||
#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)
|
||||
{
|
||||
if (!currentMaterial)
|
||||
currentMaterial = &m_materials["default"];
|
||||
|
||||
currentMaterial->specular = NzColor(static_cast<nzUInt8>(r*255.f), static_cast<nzUInt8>(g*255.f), static_cast<nzUInt8>(b*255.f));
|
||||
}
|
||||
#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
|
||||
else
|
||||
UnrecognizedLine();
|
||||
#endif
|
||||
}
|
||||
else if (keyword == "ni")
|
||||
{
|
||||
float density;
|
||||
if (std::sscanf(&m_currentLine[3], "%f", &density) == 1)
|
||||
{
|
||||
if (!currentMaterial)
|
||||
currentMaterial = &m_materials["default"];
|
||||
|
||||
currentMaterial->refractionIndex = density;
|
||||
}
|
||||
#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
|
||||
else
|
||||
UnrecognizedLine();
|
||||
#endif
|
||||
}
|
||||
else if (keyword == "ns")
|
||||
{
|
||||
float coef;
|
||||
if (std::sscanf(&m_currentLine[3], "%f", &coef) == 1)
|
||||
{
|
||||
if (!currentMaterial)
|
||||
currentMaterial = &m_materials["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 = &m_materials["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 = &m_materials["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 = &m_materials["default"];
|
||||
|
||||
currentMaterial->illumModel = model;
|
||||
}
|
||||
#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
|
||||
else
|
||||
UnrecognizedLine();
|
||||
#endif
|
||||
}
|
||||
else if (keyword == "map_ka")
|
||||
{
|
||||
unsigned int mapPos = m_currentLine.GetWordPosition(1);
|
||||
if (mapPos != NzString::npos)
|
||||
{
|
||||
NzString map = m_currentLine.SubString(mapPos);
|
||||
if (!currentMaterial)
|
||||
currentMaterial = &m_materials["default"];
|
||||
|
||||
currentMaterial->ambientMap = map;
|
||||
}
|
||||
}
|
||||
else if (keyword == "map_kd")
|
||||
{
|
||||
unsigned int mapPos = m_currentLine.GetWordPosition(1);
|
||||
if (mapPos != NzString::npos)
|
||||
{
|
||||
NzString map = m_currentLine.SubString(mapPos);
|
||||
if (!currentMaterial)
|
||||
currentMaterial = &m_materials["default"];
|
||||
|
||||
currentMaterial->diffuseMap = map;
|
||||
}
|
||||
}
|
||||
else if (keyword == "map_ks")
|
||||
{
|
||||
unsigned int mapPos = m_currentLine.GetWordPosition(1);
|
||||
if (mapPos != NzString::npos)
|
||||
{
|
||||
NzString map = m_currentLine.SubString(mapPos);
|
||||
if (!currentMaterial)
|
||||
currentMaterial = &m_materials["default"];
|
||||
|
||||
currentMaterial->specularMap = map;
|
||||
}
|
||||
}
|
||||
else if (keyword == "map_bump" || keyword == "bump")
|
||||
{
|
||||
unsigned int mapPos = m_currentLine.GetWordPosition(1);
|
||||
if (mapPos != NzString::npos)
|
||||
{
|
||||
NzString map = m_currentLine.SubString(mapPos);
|
||||
if (!currentMaterial)
|
||||
currentMaterial = &m_materials["default"];
|
||||
|
||||
currentMaterial->bumpMap = map;
|
||||
}
|
||||
}
|
||||
else if (keyword == "map_d")
|
||||
{
|
||||
unsigned int mapPos = m_currentLine.GetWordPosition(1);
|
||||
if (mapPos != NzString::npos)
|
||||
{
|
||||
NzString map = m_currentLine.SubString(mapPos);
|
||||
if (!currentMaterial)
|
||||
currentMaterial = &m_materials["default"];
|
||||
|
||||
currentMaterial->alphaMap = map;
|
||||
}
|
||||
}
|
||||
else if (keyword == "map_decal" || keyword == "decal")
|
||||
{
|
||||
unsigned int mapPos = m_currentLine.GetWordPosition(1);
|
||||
if (mapPos != NzString::npos)
|
||||
{
|
||||
NzString map = m_currentLine.SubString(mapPos);
|
||||
if (!currentMaterial)
|
||||
currentMaterial = &m_materials["default"];
|
||||
|
||||
currentMaterial->decalMap = map;
|
||||
}
|
||||
}
|
||||
else if (keyword == "map_disp" || keyword == "disp")
|
||||
{
|
||||
unsigned int mapPos = m_currentLine.GetWordPosition(1);
|
||||
if (mapPos != NzString::npos)
|
||||
{
|
||||
NzString map = m_currentLine.SubString(mapPos);
|
||||
if (!currentMaterial)
|
||||
currentMaterial = &m_materials["default"];
|
||||
|
||||
currentMaterial->displacementMap = map;
|
||||
}
|
||||
}
|
||||
else if (keyword == "map_refl" || keyword == "refl")
|
||||
{
|
||||
unsigned int mapPos = m_currentLine.GetWordPosition(1);
|
||||
if (mapPos != NzString::npos)
|
||||
{
|
||||
NzString map = m_currentLine.SubString(mapPos);
|
||||
if (!currentMaterial)
|
||||
currentMaterial = &m_materials["default"];
|
||||
|
||||
currentMaterial->reflectionMap = map;
|
||||
}
|
||||
}
|
||||
else if (keyword == "newmtl")
|
||||
{
|
||||
NzString materialName = m_currentLine.SubString(m_currentLine.GetWordPosition(1));
|
||||
if (!materialName.IsEmpty())
|
||||
currentMaterial = &m_materials[materialName];
|
||||
#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
|
||||
else
|
||||
UnrecognizedLine();
|
||||
#endif
|
||||
}
|
||||
#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
|
||||
else
|
||||
UnrecognizedLine();
|
||||
#endif
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NzMTLParser::Advance(bool required)
|
||||
{
|
||||
if (!m_keepLastLine)
|
||||
{
|
||||
do
|
||||
{
|
||||
if (m_stream.EndOfStream())
|
||||
{
|
||||
if (required)
|
||||
Error("Incomplete MTL file");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
m_lineCount++;
|
||||
|
||||
m_currentLine = m_stream.ReadLine();
|
||||
m_currentLine = m_currentLine.SubStringTo("#"); // On ignore les commentaires
|
||||
m_currentLine.Simplify(); // Pour un traitement plus simple
|
||||
}
|
||||
while (m_currentLine.IsEmpty());
|
||||
}
|
||||
else
|
||||
m_keepLastLine = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void NzMTLParser::Error(const NzString& message)
|
||||
{
|
||||
NazaraError(message + " at line #" + NzString::Number(m_lineCount));
|
||||
}
|
||||
|
||||
void NzMTLParser::Warning(const NzString& message)
|
||||
{
|
||||
NazaraWarning(message + " at line #" + NzString::Number(m_lineCount));
|
||||
}
|
||||
|
||||
void NzMTLParser::UnrecognizedLine(bool error)
|
||||
{
|
||||
NzString message = "Unrecognized \"" + m_currentLine + '"';
|
||||
|
||||
if (error)
|
||||
Error(message);
|
||||
else
|
||||
Warning(message);
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
// Copyright (C) 2015 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Graphics module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_LOADERS_OBJ_MTLPARSER_HPP
|
||||
#define NAZARA_LOADERS_OBJ_MTLPARSER_HPP
|
||||
|
||||
#include <Nazara/Prerequesites.hpp>
|
||||
#include <Nazara/Core/Color.hpp>
|
||||
#include <Nazara/Core/InputStream.hpp>
|
||||
#include <Nazara/Core/String.hpp>
|
||||
#include <unordered_map>
|
||||
|
||||
class NzMTLParser
|
||||
{
|
||||
public:
|
||||
struct Material
|
||||
{
|
||||
NzColor ambient = NzColor::White;
|
||||
NzColor diffuse = NzColor::White;
|
||||
NzColor specular = NzColor::White;
|
||||
NzString alphaMap;
|
||||
NzString ambientMap;
|
||||
NzString bumpMap;
|
||||
NzString decalMap;
|
||||
NzString diffuseMap;
|
||||
NzString displacementMap;
|
||||
NzString reflectionMap;
|
||||
NzString shininessMap;
|
||||
NzString specularMap;
|
||||
float alpha = 1.f;
|
||||
float refractionIndex = 1.f;
|
||||
float shininess = 1.f;
|
||||
unsigned int illumModel = 0;
|
||||
};
|
||||
|
||||
NzMTLParser(NzInputStream& stream$);
|
||||
~NzMTLParser();
|
||||
|
||||
const Material* GetMaterial(const NzString& materialName) const;
|
||||
|
||||
bool Parse();
|
||||
|
||||
private:
|
||||
bool Advance(bool required = true);
|
||||
void Error(const NzString& message);
|
||||
void Warning(const NzString& message);
|
||||
void UnrecognizedLine(bool error = false);
|
||||
|
||||
std::unordered_map<NzString, Material> m_materials;
|
||||
NzInputStream& m_stream;
|
||||
NzString m_currentLine;
|
||||
bool m_keepLastLine;
|
||||
unsigned int m_lineCount;
|
||||
unsigned int m_streamFlags;
|
||||
};
|
||||
|
||||
#endif // NAZARA_LOADERS_OBJ_MTLPARSER_HPP
|
||||
@@ -1,439 +0,0 @@
|
||||
// Copyright (C) 2015 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Graphics module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Graphics/Loaders/OBJ/OBJParser.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Core/Log.hpp>
|
||||
#include <Nazara/Utility/Config.hpp>
|
||||
#include <cctype>
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
#include <Nazara/Graphics/Debug.hpp>
|
||||
|
||||
NzOBJParser::NzOBJParser(NzInputStream& stream) :
|
||||
m_stream(stream),
|
||||
m_streamFlags(stream.GetStreamOptions())
|
||||
{
|
||||
if ((m_streamFlags & nzStreamOption_Text) == 0)
|
||||
m_stream.SetStreamOptions(m_streamFlags | nzStreamOption_Text);
|
||||
}
|
||||
|
||||
NzOBJParser::~NzOBJParser()
|
||||
{
|
||||
if ((m_streamFlags & nzStreamOption_Text) == 0)
|
||||
m_stream.SetStreamOptions(m_streamFlags);
|
||||
}
|
||||
|
||||
const NzString* NzOBJParser::GetMaterials() const
|
||||
{
|
||||
return m_materials.data();
|
||||
}
|
||||
|
||||
unsigned int NzOBJParser::GetMaterialCount() const
|
||||
{
|
||||
return m_materials.size();
|
||||
}
|
||||
|
||||
const NzOBJParser::Mesh* NzOBJParser::GetMeshes() const
|
||||
{
|
||||
return m_meshes.data();
|
||||
}
|
||||
|
||||
unsigned int NzOBJParser::GetMeshCount() const
|
||||
{
|
||||
return m_meshes.size();
|
||||
}
|
||||
|
||||
const NzString& NzOBJParser::GetMtlLib() const
|
||||
{
|
||||
return m_mtlLib;
|
||||
}
|
||||
|
||||
const NzVector3f* NzOBJParser::GetNormals() const
|
||||
{
|
||||
return m_normals.data();
|
||||
}
|
||||
|
||||
unsigned int NzOBJParser::GetNormalCount() const
|
||||
{
|
||||
return m_normals.size();
|
||||
}
|
||||
|
||||
const NzVector4f* NzOBJParser::GetPositions() const
|
||||
{
|
||||
return m_positions.data();
|
||||
}
|
||||
|
||||
unsigned int NzOBJParser::GetPositionCount() const
|
||||
{
|
||||
return m_positions.size();
|
||||
}
|
||||
|
||||
const NzVector3f* NzOBJParser::GetTexCoords() const
|
||||
{
|
||||
return m_texCoords.data();
|
||||
}
|
||||
|
||||
unsigned int NzOBJParser::GetTexCoordCount() const
|
||||
{
|
||||
return m_texCoords.size();
|
||||
}
|
||||
|
||||
bool NzOBJParser::Parse()
|
||||
{
|
||||
NzString matName, meshName;
|
||||
matName = meshName = "default";
|
||||
m_keepLastLine = false;
|
||||
m_lineCount = 0;
|
||||
m_meshes.clear();
|
||||
m_mtlLib.Clear();
|
||||
|
||||
m_normals.clear();
|
||||
m_positions.clear();
|
||||
m_texCoords.clear();
|
||||
|
||||
// Beaucoup de meshs font plus de 100 sommets, préparons le terrain
|
||||
m_normals.reserve(100);
|
||||
m_positions.reserve(100);
|
||||
m_texCoords.reserve(100);
|
||||
|
||||
// On va regrouper les meshs par nom et par matériau
|
||||
std::unordered_map<NzString, std::unordered_map<NzString, std::vector<Face>>> meshes;
|
||||
|
||||
// On prépare le mesh par défaut
|
||||
std::vector<Face>* currentMesh = &meshes[meshName][matName];
|
||||
|
||||
while (Advance(false))
|
||||
{
|
||||
switch (std::tolower(m_currentLine[0]))
|
||||
{
|
||||
case 'f': // Une face
|
||||
{
|
||||
if (m_currentLine.GetSize() < 7) // Le minimum syndical pour définir une face de trois sommets (f 1 2 3)
|
||||
{
|
||||
#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
|
||||
UnrecognizedLine();
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
unsigned int vertexCount = m_currentLine.Count(' ');
|
||||
if (vertexCount < 3)
|
||||
{
|
||||
#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
|
||||
UnrecognizedLine();
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
Face face;
|
||||
face.vertices.resize(vertexCount);
|
||||
|
||||
bool error = false;
|
||||
unsigned int pos = 2;
|
||||
for (unsigned int i = 0; i < vertexCount; ++i)
|
||||
{
|
||||
int offset;
|
||||
int& n = face.vertices[i].normal;
|
||||
int& p = face.vertices[i].position;
|
||||
int& t = face.vertices[i].texCoord;
|
||||
|
||||
if (std::sscanf(&m_currentLine[pos], "%d/%d/%d%n", &p, &t, &n, &offset) != 3)
|
||||
{
|
||||
if (std::sscanf(&m_currentLine[pos], "%d//%d%n", &p, &n, &offset) != 2)
|
||||
{
|
||||
if (std::sscanf(&m_currentLine[pos], "%d/%d%n", &p, &t, &offset) != 2)
|
||||
{
|
||||
if (std::sscanf(&m_currentLine[pos], "%d%n", &p, &offset) != 1)
|
||||
{
|
||||
#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
|
||||
UnrecognizedLine();
|
||||
#endif
|
||||
error = true;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
n = 0;
|
||||
t = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
n = 0;
|
||||
}
|
||||
else
|
||||
t = 0;
|
||||
}
|
||||
|
||||
if (p < 0)
|
||||
{
|
||||
p += m_positions.size();
|
||||
if (p < 0)
|
||||
{
|
||||
Error("Vertex index out of range (" + NzString::Number(p) + " < 0");
|
||||
error = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
p--;
|
||||
|
||||
if (n < 0)
|
||||
{
|
||||
n += m_normals.size();
|
||||
if (n < 0)
|
||||
{
|
||||
Error("Vertex index out of range (" + NzString::Number(n) + " < 0");
|
||||
error = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
n--;
|
||||
|
||||
if (t < 0)
|
||||
{
|
||||
t += m_texCoords.size();
|
||||
if (t < 0)
|
||||
{
|
||||
Error("Vertex index out of range (" + NzString::Number(t) + " < 0");
|
||||
error = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
t--;
|
||||
|
||||
if (static_cast<unsigned int>(p) >= m_positions.size())
|
||||
{
|
||||
Error("Vertex index out of range (" + NzString::Number(p) + " >= " + NzString::Number(m_positions.size()) + ')');
|
||||
error = true;
|
||||
break;
|
||||
}
|
||||
else if (n >= 0 && static_cast<unsigned int>(n) >= m_normals.size())
|
||||
{
|
||||
Error("Normal index out of range (" + NzString::Number(n) + " >= " + NzString::Number(m_normals.size()) + ')');
|
||||
error = true;
|
||||
break;
|
||||
}
|
||||
else if (t >= 0 && static_cast<unsigned int>(t) >= m_texCoords.size())
|
||||
{
|
||||
Error("TexCoord index out of range (" + NzString::Number(t) + " >= " + NzString::Number(m_texCoords.size()) + ')');
|
||||
error = true;
|
||||
break;
|
||||
}
|
||||
|
||||
pos += offset;
|
||||
}
|
||||
|
||||
if (!error)
|
||||
currentMesh->push_back(std::move(face));
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 'm':
|
||||
#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
|
||||
if (m_currentLine.GetWord(0).ToLower() != "mtllib")
|
||||
UnrecognizedLine();
|
||||
#endif
|
||||
|
||||
m_mtlLib = m_currentLine.SubString(m_currentLine.GetWordPosition(1));
|
||||
break;
|
||||
|
||||
case 'g':
|
||||
case 'o':
|
||||
{
|
||||
if (m_currentLine.GetSize() <= 2 || m_currentLine[1] != ' ')
|
||||
{
|
||||
#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
|
||||
UnrecognizedLine();
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
NzString objectName = m_currentLine.SubString(m_currentLine.GetWordPosition(1));
|
||||
if (objectName.IsEmpty())
|
||||
{
|
||||
#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
|
||||
UnrecognizedLine();
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
meshName = objectName;
|
||||
currentMesh = &meshes[meshName][matName];
|
||||
break;
|
||||
}
|
||||
|
||||
#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
|
||||
case 's':
|
||||
if (m_currentLine.GetSize() <= 2 || m_currentLine[1] == ' ')
|
||||
{
|
||||
NzString param = m_currentLine.SubString(2);
|
||||
if (param != "all" && param != "on" && param != "off" && !param.IsNumber())
|
||||
UnrecognizedLine();
|
||||
}
|
||||
else
|
||||
UnrecognizedLine();
|
||||
break;
|
||||
#endif
|
||||
|
||||
case 'u':
|
||||
#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
|
||||
if (m_currentLine.GetWord(0) != "usemtl")
|
||||
UnrecognizedLine();
|
||||
#endif
|
||||
|
||||
matName = m_currentLine.SubString(m_currentLine.GetWordPosition(1));
|
||||
if (matName.IsEmpty())
|
||||
{
|
||||
#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
|
||||
UnrecognizedLine();
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
currentMesh = &meshes[meshName][matName];
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
{
|
||||
NzString word = m_currentLine.GetWord(0).ToLower();
|
||||
if (word == 'v')
|
||||
{
|
||||
NzVector4f vertex(NzVector3f::Zero(), 1.f);
|
||||
unsigned int paramCount = std::sscanf(&m_currentLine[2], "%f %f %f %f", &vertex.x, &vertex.y, &vertex.z, &vertex.w);
|
||||
if (paramCount >= 3)
|
||||
m_positions.push_back(vertex);
|
||||
#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
|
||||
else
|
||||
UnrecognizedLine();
|
||||
#endif
|
||||
}
|
||||
else if (word == "vn")
|
||||
{
|
||||
NzVector3f normal(NzVector3f::Zero());
|
||||
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
|
||||
else
|
||||
UnrecognizedLine();
|
||||
#endif
|
||||
}
|
||||
else if (word == "vt")
|
||||
{
|
||||
NzVector3f uvw(NzVector3f::Zero());
|
||||
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
|
||||
else
|
||||
UnrecognizedLine();
|
||||
#endif
|
||||
}
|
||||
#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
|
||||
else
|
||||
UnrecognizedLine();
|
||||
#endif
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
|
||||
UnrecognizedLine();
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
std::unordered_map<NzString, unsigned int> materials;
|
||||
unsigned int matCount = 0;
|
||||
|
||||
for (auto& meshIt : meshes)
|
||||
{
|
||||
for (auto& matIt : meshIt.second)
|
||||
{
|
||||
if (!matIt.second.empty())
|
||||
{
|
||||
Mesh mesh;
|
||||
mesh.faces = std::move(matIt.second);
|
||||
mesh.name = meshIt.first;
|
||||
|
||||
auto it = materials.find(matIt.first);
|
||||
if (it == materials.end())
|
||||
{
|
||||
mesh.material = matCount;
|
||||
materials[matIt.first] = matCount++;
|
||||
}
|
||||
else
|
||||
mesh.material = it->second;
|
||||
|
||||
m_meshes.push_back(std::move(mesh));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (m_meshes.empty())
|
||||
{
|
||||
NazaraError("No meshes");
|
||||
return false;
|
||||
}
|
||||
|
||||
m_materials.resize(matCount);
|
||||
for (const std::pair<NzString, unsigned int>& pair : materials)
|
||||
m_materials[pair.second] = pair.first;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NzOBJParser::Advance(bool required)
|
||||
{
|
||||
if (!m_keepLastLine)
|
||||
{
|
||||
do
|
||||
{
|
||||
if (m_stream.EndOfStream())
|
||||
{
|
||||
if (required)
|
||||
Error("Incomplete OBJ file");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
m_lineCount++;
|
||||
|
||||
m_currentLine = m_stream.ReadLine();
|
||||
m_currentLine = m_currentLine.SubStringTo("#"); // On ignore les commentaires
|
||||
m_currentLine.Simplify(); // Pour un traitement plus simple
|
||||
}
|
||||
while (m_currentLine.IsEmpty());
|
||||
}
|
||||
else
|
||||
m_keepLastLine = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void NzOBJParser::Error(const NzString& message)
|
||||
{
|
||||
NazaraError(message + " at line #" + NzString::Number(m_lineCount));
|
||||
}
|
||||
|
||||
void NzOBJParser::Warning(const NzString& message)
|
||||
{
|
||||
NazaraWarning(message + " at line #" + NzString::Number(m_lineCount));
|
||||
}
|
||||
|
||||
void NzOBJParser::UnrecognizedLine(bool error)
|
||||
{
|
||||
NzString message = "Unrecognized \"" + m_currentLine + '"';
|
||||
|
||||
if (error)
|
||||
Error(message);
|
||||
else
|
||||
Warning(message);
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
// Copyright (C) 2015 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Graphics module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_LOADERS_OBJ_OBJPARSER_HPP
|
||||
#define NAZARA_LOADERS_OBJ_OBJPARSER_HPP
|
||||
|
||||
#include <Nazara/Prerequesites.hpp>
|
||||
#include <Nazara/Core/InputStream.hpp>
|
||||
#include <Nazara/Core/String.hpp>
|
||||
#include <Nazara/Math/Vector3.hpp>
|
||||
#include <Nazara/Math/Vector4.hpp>
|
||||
#include <vector>
|
||||
|
||||
class NzOBJParser
|
||||
{
|
||||
public:
|
||||
struct FaceVertex
|
||||
{
|
||||
int normal;
|
||||
int position;
|
||||
int texCoord;
|
||||
};
|
||||
|
||||
struct Face
|
||||
{
|
||||
std::vector<FaceVertex> vertices;
|
||||
};
|
||||
|
||||
struct Mesh
|
||||
{
|
||||
std::vector<Face> faces;
|
||||
NzString name;
|
||||
unsigned int material;
|
||||
};
|
||||
|
||||
NzOBJParser(NzInputStream& stream$);
|
||||
~NzOBJParser();
|
||||
|
||||
const NzString* GetMaterials() const;
|
||||
unsigned int GetMaterialCount() const;
|
||||
const Mesh* GetMeshes() const;
|
||||
unsigned int GetMeshCount() const;
|
||||
const NzString& GetMtlLib() const;
|
||||
const NzVector3f* GetNormals() const;
|
||||
unsigned int GetNormalCount() const;
|
||||
const NzVector4f* GetPositions() const;
|
||||
unsigned int GetPositionCount() const;
|
||||
const NzVector3f* GetTexCoords() const;
|
||||
unsigned int GetTexCoordCount() const;
|
||||
|
||||
bool Parse();
|
||||
|
||||
private:
|
||||
bool Advance(bool required = true);
|
||||
void Error(const NzString& message);
|
||||
void Warning(const NzString& message);
|
||||
void UnrecognizedLine(bool error = false);
|
||||
|
||||
std::vector<Mesh> m_meshes;
|
||||
std::vector<NzString> m_materials;
|
||||
std::vector<NzVector3f> m_normals;
|
||||
std::vector<NzVector4f> m_positions;
|
||||
std::vector<NzVector3f> m_texCoords;
|
||||
NzInputStream& m_stream;
|
||||
NzString m_currentLine;
|
||||
NzString m_mtlLib;
|
||||
bool m_keepLastLine;
|
||||
unsigned int m_lineCount;
|
||||
unsigned int m_streamFlags;
|
||||
};
|
||||
|
||||
#endif // NAZARA_LOADERS_OBJ_OBJPARSER_HPP
|
||||
Reference in New Issue
Block a user