Merge branch 'master' into vulkan
Former-commit-id: e2aa8425da79e895900639e75c19e6155ae1681e [formerly e85202803b75ef6526f537bb1c8baab5a02c63db] Former-commit-id: 08e921b9afd2e004413b5777e9371593d42815ee
This commit is contained in:
commit
cccf5ae36b
|
|
@ -1,2 +1,4 @@
|
||||||
# Auto detect text files and perform LF normalization
|
# Auto detect text files and perform LF normalization
|
||||||
* text=auto
|
* text=auto
|
||||||
|
extlibs/* linguist-vendored
|
||||||
|
NazaraModuleTemplate/* linguist-vendored
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
EXAMPLE.Name = "HardwareInfo"
|
EXAMPLE.Name = "HardwareInfo"
|
||||||
|
|
||||||
EXAMPLE.Console = true
|
EXAMPLE.EnableConsole = true
|
||||||
|
|
||||||
EXAMPLE.Defines = {
|
EXAMPLE.Defines = {
|
||||||
"NAZARA_RENDERER_OPENGL"
|
"NAZARA_RENDERER_OPENGL"
|
||||||
|
|
|
||||||
|
|
@ -84,7 +84,7 @@ namespace Nz
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!file.Open(OpenMode_WriteOnly))
|
if (!file.Open(OpenMode_WriteOnly | OpenMode_Truncate))
|
||||||
{
|
{
|
||||||
NazaraError("Failed to save to file: unable to open \"" + filePath + "\" in write mode");
|
NazaraError("Failed to save to file: unable to open \"" + filePath + "\" in write mode");
|
||||||
return false;
|
return false;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// This file was automatically generated on 17 Nov 2015 at 13:20:45
|
// This file was automatically generated on 12 Jul 2016 at 17:44:43
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Nazara Engine - Graphics module
|
Nazara Engine - Graphics module
|
||||||
|
|
@ -47,6 +47,8 @@
|
||||||
#include <Nazara/Graphics/DeferredRenderPass.hpp>
|
#include <Nazara/Graphics/DeferredRenderPass.hpp>
|
||||||
#include <Nazara/Graphics/DeferredRenderQueue.hpp>
|
#include <Nazara/Graphics/DeferredRenderQueue.hpp>
|
||||||
#include <Nazara/Graphics/DeferredRenderTechnique.hpp>
|
#include <Nazara/Graphics/DeferredRenderTechnique.hpp>
|
||||||
|
#include <Nazara/Graphics/DepthRenderQueue.hpp>
|
||||||
|
#include <Nazara/Graphics/DepthRenderTechnique.hpp>
|
||||||
#include <Nazara/Graphics/Drawable.hpp>
|
#include <Nazara/Graphics/Drawable.hpp>
|
||||||
#include <Nazara/Graphics/Enums.hpp>
|
#include <Nazara/Graphics/Enums.hpp>
|
||||||
#include <Nazara/Graphics/ForwardRenderQueue.hpp>
|
#include <Nazara/Graphics/ForwardRenderQueue.hpp>
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
// This file was automatically generated on 17 Nov 2015 at 13:20:45
|
// This file was automatically generated on 12 Jul 2016 at 17:44:43
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Nazara Engine - Noise module
|
Nazara Engine - Noise module
|
||||||
|
|
||||||
Copyright (C) 2015 Rémi "Overdrivr" Bèges (remi.beges@laposte.net)
|
Copyright (C) 2016 Rémi "Overdrivr" Bèges (remi.beges@laposte.net)
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
this software and associated documentation files (the "Software"), to deal in
|
this software and associated documentation files (the "Software"), to deal in
|
||||||
|
|
@ -29,25 +29,16 @@
|
||||||
#ifndef NAZARA_GLOBAL_NOISE_HPP
|
#ifndef NAZARA_GLOBAL_NOISE_HPP
|
||||||
#define NAZARA_GLOBAL_NOISE_HPP
|
#define NAZARA_GLOBAL_NOISE_HPP
|
||||||
|
|
||||||
#include <Nazara/Noise/Abstract2DNoise.hpp>
|
|
||||||
#include <Nazara/Noise/Abstract3DNoise.hpp>
|
|
||||||
#include <Nazara/Noise/Abstract4DNoise.hpp>
|
|
||||||
#include <Nazara/Noise/ComplexNoiseBase.hpp>
|
|
||||||
#include <Nazara/Noise/Config.hpp>
|
#include <Nazara/Noise/Config.hpp>
|
||||||
#include <Nazara/Noise/FBM2D.hpp>
|
#include <Nazara/Noise/Enums.hpp>
|
||||||
#include <Nazara/Noise/FBM3D.hpp>
|
#include <Nazara/Noise/FBM.hpp>
|
||||||
#include <Nazara/Noise/FBM4D.hpp>
|
#include <Nazara/Noise/HybridMultiFractal.hpp>
|
||||||
#include <Nazara/Noise/HybridMultiFractal2D.hpp>
|
#include <Nazara/Noise/MixerBase.hpp>
|
||||||
#include <Nazara/Noise/HybridMultiFractal3D.hpp>
|
|
||||||
#include <Nazara/Noise/HybridMultiFractal4D.hpp>
|
|
||||||
#include <Nazara/Noise/MappedNoiseBase.hpp>
|
|
||||||
#include <Nazara/Noise/Noise.hpp>
|
#include <Nazara/Noise/Noise.hpp>
|
||||||
#include <Nazara/Noise/NoiseBase.hpp>
|
#include <Nazara/Noise/NoiseBase.hpp>
|
||||||
#include <Nazara/Noise/Perlin2D.hpp>
|
#include <Nazara/Noise/NoiseTools.hpp>
|
||||||
#include <Nazara/Noise/Perlin3D.hpp>
|
#include <Nazara/Noise/Perlin.hpp>
|
||||||
#include <Nazara/Noise/Perlin4D.hpp>
|
#include <Nazara/Noise/Simplex.hpp>
|
||||||
#include <Nazara/Noise/Simplex2D.hpp>
|
#include <Nazara/Noise/Worley.hpp>
|
||||||
#include <Nazara/Noise/Simplex3D.hpp>
|
|
||||||
#include <Nazara/Noise/Simplex4D.hpp>
|
|
||||||
|
|
||||||
#endif // NAZARA_GLOBAL_NOISE_HPP
|
#endif // NAZARA_GLOBAL_NOISE_HPP
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// This file was automatically generated on 24 Jun 2015 at 13:55:50
|
// This file was automatically generated on 12 Jul 2016 at 17:44:43
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Nazara Engine - Utility module
|
Nazara Engine - Utility module
|
||||||
|
|
@ -54,6 +54,7 @@
|
||||||
#include <Nazara/Utility/Joint.hpp>
|
#include <Nazara/Utility/Joint.hpp>
|
||||||
#include <Nazara/Utility/Joystick.hpp>
|
#include <Nazara/Utility/Joystick.hpp>
|
||||||
#include <Nazara/Utility/Keyboard.hpp>
|
#include <Nazara/Utility/Keyboard.hpp>
|
||||||
|
#include <Nazara/Utility/MaterialData.hpp>
|
||||||
#include <Nazara/Utility/Mesh.hpp>
|
#include <Nazara/Utility/Mesh.hpp>
|
||||||
#include <Nazara/Utility/MeshData.hpp>
|
#include <Nazara/Utility/MeshData.hpp>
|
||||||
#include <Nazara/Utility/Mouse.hpp>
|
#include <Nazara/Utility/Mouse.hpp>
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,22 @@ namespace Nz
|
||||||
class NAZARA_UTILITY_API MTLParser
|
class NAZARA_UTILITY_API MTLParser
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
struct Material;
|
||||||
|
|
||||||
|
MTLParser() = default;
|
||||||
|
~MTLParser() = default;
|
||||||
|
|
||||||
|
inline Material* AddMaterial(const String& matName);
|
||||||
|
|
||||||
|
inline void Clear();
|
||||||
|
|
||||||
|
inline const Material* GetMaterial(const String& materialName) const;
|
||||||
|
inline const std::unordered_map<String, Material>& GetMaterials() const;
|
||||||
|
|
||||||
|
bool Parse(Stream& stream);
|
||||||
|
|
||||||
|
bool Save(Stream& stream) const;
|
||||||
|
|
||||||
struct Material
|
struct Material
|
||||||
{
|
{
|
||||||
Color ambient = Color::White;
|
Color ambient = Color::White;
|
||||||
|
|
@ -39,27 +55,26 @@ namespace Nz
|
||||||
unsigned int illumModel = 0;
|
unsigned int illumModel = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
MTLParser(Stream& stream$);
|
|
||||||
~MTLParser();
|
|
||||||
|
|
||||||
const Material* GetMaterial(const String& materialName) const;
|
|
||||||
const std::unordered_map<String, Material>& GetMaterials() const;
|
|
||||||
|
|
||||||
bool Parse();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool Advance(bool required = true);
|
bool Advance(bool required = true);
|
||||||
void Error(const String& message);
|
template<typename T> void Emit(const T& text) const;
|
||||||
void Warning(const String& message);
|
inline void EmitLine() const;
|
||||||
void UnrecognizedLine(bool error = false);
|
template<typename T> void EmitLine(const T& line) const;
|
||||||
|
inline void Error(const String& message);
|
||||||
|
inline void Flush() const;
|
||||||
|
inline void Warning(const String& message);
|
||||||
|
inline void UnrecognizedLine(bool error = false);
|
||||||
|
|
||||||
std::unordered_map<String, Material> m_materials;
|
std::unordered_map<String, Material> m_materials;
|
||||||
Stream& m_stream;
|
mutable Stream* m_currentStream;
|
||||||
String m_currentLine;
|
String m_currentLine;
|
||||||
|
mutable StringStream m_outputStream;
|
||||||
bool m_keepLastLine;
|
bool m_keepLastLine;
|
||||||
unsigned int m_lineCount;
|
unsigned int m_lineCount;
|
||||||
unsigned int m_streamFlags;
|
unsigned int m_streamFlags;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include <Nazara/Utility/Formats/MTLParser.inl>
|
||||||
|
|
||||||
#endif // NAZARA_FORMATS_MTLPARSER_HPP
|
#endif // NAZARA_FORMATS_MTLPARSER_HPP
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,83 @@
|
||||||
|
// Copyright (C) 2016 Jérôme Leclercq
|
||||||
|
// This file is part of the "Nazara Engine - Utility module"
|
||||||
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||||
|
|
||||||
|
#include <Nazara/Utility/Formats/MTLParser.hpp>
|
||||||
|
#include <Nazara/Core/Error.hpp>
|
||||||
|
#include <Nazara/Utility/Debug.hpp>
|
||||||
|
|
||||||
|
namespace Nz
|
||||||
|
{
|
||||||
|
inline MTLParser::Material* MTLParser::AddMaterial(const String& matName)
|
||||||
|
{
|
||||||
|
return &m_materials[matName];
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void MTLParser::Clear()
|
||||||
|
{
|
||||||
|
m_materials.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const MTLParser::Material* MTLParser::GetMaterial(const String& materialName) const
|
||||||
|
{
|
||||||
|
auto it = m_materials.find(materialName);
|
||||||
|
if (it != m_materials.end())
|
||||||
|
return &it->second;
|
||||||
|
else
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const std::unordered_map<String, MTLParser::Material>& MTLParser::GetMaterials() const
|
||||||
|
{
|
||||||
|
return m_materials;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void MTLParser::Emit(const T& text) const
|
||||||
|
{
|
||||||
|
m_outputStream << text;
|
||||||
|
if (m_outputStream.GetBufferSize() > 1024 * 1024)
|
||||||
|
Flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void MTLParser::EmitLine() const
|
||||||
|
{
|
||||||
|
Emit('\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void MTLParser::EmitLine(const T& line) const
|
||||||
|
{
|
||||||
|
Emit(line);
|
||||||
|
Emit('\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void MTLParser::Error(const String& message)
|
||||||
|
{
|
||||||
|
NazaraError(message + " at line #" + String::Number(m_lineCount));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void MTLParser::Flush() const
|
||||||
|
{
|
||||||
|
m_currentStream->Write(m_outputStream);
|
||||||
|
m_outputStream.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void MTLParser::Warning(const String& message)
|
||||||
|
{
|
||||||
|
NazaraWarning(message + " at line #" + String::Number(m_lineCount));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void MTLParser::UnrecognizedLine(bool error)
|
||||||
|
{
|
||||||
|
String message = "Unrecognized \"" + m_currentLine + '"';
|
||||||
|
|
||||||
|
if (error)
|
||||||
|
Error(message);
|
||||||
|
else
|
||||||
|
Warning(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#include <Nazara/Utility/DebugOff.hpp>
|
||||||
|
#include "MTLParser.hpp"
|
||||||
|
|
@ -52,6 +52,7 @@ namespace Nz
|
||||||
|
|
||||||
inline String* SetMaterialCount(std::size_t materialCount);
|
inline String* SetMaterialCount(std::size_t materialCount);
|
||||||
inline Mesh* SetMeshCount(std::size_t meshCount);
|
inline Mesh* SetMeshCount(std::size_t meshCount);
|
||||||
|
inline void SetMtlLib(const String& mtlLib);
|
||||||
inline Vector3f* SetNormalCount(std::size_t normalCount);
|
inline Vector3f* SetNormalCount(std::size_t normalCount);
|
||||||
inline Vector4f* SetPositionCount(std::size_t positionCount);
|
inline Vector4f* SetPositionCount(std::size_t positionCount);
|
||||||
inline Vector3f* SetTexCoordCount(std::size_t texCoordCount);
|
inline Vector3f* SetTexCoordCount(std::size_t texCoordCount);
|
||||||
|
|
|
||||||
|
|
@ -109,6 +109,11 @@ namespace Nz
|
||||||
return m_meshes.data();
|
return m_meshes.data();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void OBJParser::SetMtlLib(const String& mtlLib)
|
||||||
|
{
|
||||||
|
m_mtlLib = mtlLib;
|
||||||
|
}
|
||||||
|
|
||||||
inline Vector3f* OBJParser::SetNormalCount(std::size_t normalCount)
|
inline Vector3f* OBJParser::SetNormalCount(std::size_t normalCount)
|
||||||
{
|
{
|
||||||
m_normals.resize(normalCount);
|
m_normals.resize(normalCount);
|
||||||
|
|
|
||||||
|
|
@ -1,20 +0,0 @@
|
||||||
// Copyright (C) 2015 Jérôme Leclercq
|
|
||||||
// This file is part of the "Nazara Engine - Utility module"
|
|
||||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
#include <Nazara/Utility/Debug.hpp>
|
|
||||||
|
|
||||||
namespace Nz
|
|
||||||
{
|
|
||||||
template<typename... Args>
|
|
||||||
ImageRef Image::New(Args&&... args)
|
|
||||||
{
|
|
||||||
std::unique_ptr<Image> object(new Image(std::forward<Args>(args)...));
|
|
||||||
object->SetPersistent(false);
|
|
||||||
|
|
||||||
return object.release();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#include <Nazara/Utility/DebugOff.hpp>
|
|
||||||
|
|
@ -71,6 +71,7 @@ namespace Nz
|
||||||
friend MeshLibrary;
|
friend MeshLibrary;
|
||||||
friend MeshLoader;
|
friend MeshLoader;
|
||||||
friend MeshManager;
|
friend MeshManager;
|
||||||
|
friend MeshSaver;
|
||||||
friend class Utility;
|
friend class Utility;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
@ -126,6 +127,9 @@ namespace Nz
|
||||||
void RemoveSubMesh(const String& identifier);
|
void RemoveSubMesh(const String& identifier);
|
||||||
void RemoveSubMesh(unsigned int index);
|
void RemoveSubMesh(unsigned int index);
|
||||||
|
|
||||||
|
bool SaveToFile(const String& filePath, const MeshParams& params = MeshParams());
|
||||||
|
bool SaveToStream(Stream& stream, const String& format, const MeshParams& params = MeshParams());
|
||||||
|
|
||||||
void SetAnimation(const String& animationPath);
|
void SetAnimation(const String& animationPath);
|
||||||
void SetMaterialCount(unsigned int matCount);
|
void SetMaterialCount(unsigned int matCount);
|
||||||
void SetMaterialData(unsigned int matIndex, ParameterList data);
|
void SetMaterialData(unsigned int matIndex, ParameterList data);
|
||||||
|
|
|
||||||
|
|
@ -102,7 +102,8 @@ namespace Nz
|
||||||
stream.Read(skin, 68*sizeof(char));
|
stream.Read(skin, 68*sizeof(char));
|
||||||
|
|
||||||
ParameterList matData;
|
ParameterList matData;
|
||||||
matData.SetParameter(MaterialData::FilePath, baseDir + skin);
|
matData.SetParameter(MaterialData::CustomDefined);
|
||||||
|
matData.SetParameter(MaterialData::DiffuseTexturePath, baseDir + skin);
|
||||||
|
|
||||||
mesh->SetMaterialData(i, std::move(matData));
|
mesh->SetMaterialData(i, std::move(matData));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||||
|
|
||||||
#include <Nazara/Utility/Formats/MTLParser.hpp>
|
#include <Nazara/Utility/Formats/MTLParser.hpp>
|
||||||
|
#include <Nazara/Core/CallOnExit.hpp>
|
||||||
#include <Nazara/Core/Error.hpp>
|
#include <Nazara/Core/Error.hpp>
|
||||||
#include <Nazara/Core/Log.hpp>
|
#include <Nazara/Core/Log.hpp>
|
||||||
#include <Nazara/Utility/Config.hpp>
|
#include <Nazara/Utility/Config.hpp>
|
||||||
|
|
@ -12,36 +13,22 @@
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
MTLParser::MTLParser(Stream& stream) :
|
bool MTLParser::Parse(Stream& stream)
|
||||||
m_stream(stream),
|
|
||||||
m_streamFlags(stream.GetStreamOptions()) //< Saves stream flags
|
|
||||||
{
|
{
|
||||||
m_stream.EnableTextMode(true);
|
m_currentStream = &stream;
|
||||||
}
|
|
||||||
|
|
||||||
MTLParser::~MTLParser()
|
// Force stream in text mode, reset it at the end
|
||||||
{
|
Nz::CallOnExit resetTextMode;
|
||||||
// Reset stream flags
|
if ((stream.GetStreamOptions() & StreamOption_Text) == 0)
|
||||||
if ((m_streamFlags & StreamOption_Text) == 0)
|
{
|
||||||
m_stream.EnableTextMode(false);
|
stream.EnableTextMode(true);
|
||||||
}
|
|
||||||
|
|
||||||
const MTLParser::Material* MTLParser::GetMaterial(const String& materialName) const
|
resetTextMode.Reset([&stream] ()
|
||||||
{
|
{
|
||||||
auto it = m_materials.find(materialName);
|
stream.EnableTextMode(false);
|
||||||
if (it != m_materials.end())
|
});
|
||||||
return &it->second;
|
}
|
||||||
else
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::unordered_map<String, MTLParser::Material>& MTLParser::GetMaterials() const
|
|
||||||
{
|
|
||||||
return m_materials;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MTLParser::Parse()
|
|
||||||
{
|
|
||||||
m_keepLastLine = false;
|
m_keepLastLine = false;
|
||||||
m_lineCount = 0;
|
m_lineCount = 0;
|
||||||
m_materials.clear();
|
m_materials.clear();
|
||||||
|
|
@ -57,7 +44,7 @@ namespace Nz
|
||||||
if (std::sscanf(&m_currentLine[3], "%f %f %f", &r, &g, &b) == 3)
|
if (std::sscanf(&m_currentLine[3], "%f %f %f", &r, &g, &b) == 3)
|
||||||
{
|
{
|
||||||
if (!currentMaterial)
|
if (!currentMaterial)
|
||||||
currentMaterial = &m_materials["default"];
|
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->ambient = Color(static_cast<UInt8>(r*255.f), static_cast<UInt8>(g*255.f), static_cast<UInt8>(b*255.f));
|
||||||
}
|
}
|
||||||
|
|
@ -72,7 +59,7 @@ namespace Nz
|
||||||
if (std::sscanf(&m_currentLine[3], "%f %f %f", &r, &g, &b) == 3)
|
if (std::sscanf(&m_currentLine[3], "%f %f %f", &r, &g, &b) == 3)
|
||||||
{
|
{
|
||||||
if (!currentMaterial)
|
if (!currentMaterial)
|
||||||
currentMaterial = &m_materials["default"];
|
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->diffuse = Color(static_cast<UInt8>(r*255.f), static_cast<UInt8>(g*255.f), static_cast<UInt8>(b*255.f));
|
||||||
}
|
}
|
||||||
|
|
@ -87,7 +74,7 @@ namespace Nz
|
||||||
if (std::sscanf(&m_currentLine[3], "%f %f %f", &r, &g, &b) == 3)
|
if (std::sscanf(&m_currentLine[3], "%f %f %f", &r, &g, &b) == 3)
|
||||||
{
|
{
|
||||||
if (!currentMaterial)
|
if (!currentMaterial)
|
||||||
currentMaterial = &m_materials["default"];
|
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->specular = Color(static_cast<UInt8>(r*255.f), static_cast<UInt8>(g*255.f), static_cast<UInt8>(b*255.f));
|
||||||
}
|
}
|
||||||
|
|
@ -102,7 +89,7 @@ namespace Nz
|
||||||
if (std::sscanf(&m_currentLine[3], "%f", &density) == 1)
|
if (std::sscanf(&m_currentLine[3], "%f", &density) == 1)
|
||||||
{
|
{
|
||||||
if (!currentMaterial)
|
if (!currentMaterial)
|
||||||
currentMaterial = &m_materials["default"];
|
currentMaterial = AddMaterial("default");
|
||||||
|
|
||||||
currentMaterial->refractionIndex = density;
|
currentMaterial->refractionIndex = density;
|
||||||
}
|
}
|
||||||
|
|
@ -117,7 +104,7 @@ namespace Nz
|
||||||
if (std::sscanf(&m_currentLine[3], "%f", &coef) == 1)
|
if (std::sscanf(&m_currentLine[3], "%f", &coef) == 1)
|
||||||
{
|
{
|
||||||
if (!currentMaterial)
|
if (!currentMaterial)
|
||||||
currentMaterial = &m_materials["default"];
|
currentMaterial = AddMaterial("default");
|
||||||
|
|
||||||
currentMaterial->shininess = coef;
|
currentMaterial->shininess = coef;
|
||||||
}
|
}
|
||||||
|
|
@ -132,7 +119,7 @@ namespace Nz
|
||||||
if (std::sscanf(&m_currentLine[(keyword[0] == 'd') ? 2 : 3], "%f", &alpha) == 1)
|
if (std::sscanf(&m_currentLine[(keyword[0] == 'd') ? 2 : 3], "%f", &alpha) == 1)
|
||||||
{
|
{
|
||||||
if (!currentMaterial)
|
if (!currentMaterial)
|
||||||
currentMaterial = &m_materials["default"];
|
currentMaterial = AddMaterial("default");
|
||||||
|
|
||||||
currentMaterial->alpha = alpha;
|
currentMaterial->alpha = alpha;
|
||||||
}
|
}
|
||||||
|
|
@ -147,7 +134,7 @@ namespace Nz
|
||||||
if (std::sscanf(&m_currentLine[(keyword[0] == 'd') ? 2 : 3], "%f", &alpha) == 1)
|
if (std::sscanf(&m_currentLine[(keyword[0] == 'd') ? 2 : 3], "%f", &alpha) == 1)
|
||||||
{
|
{
|
||||||
if (!currentMaterial)
|
if (!currentMaterial)
|
||||||
currentMaterial = &m_materials["default"];
|
currentMaterial = AddMaterial("default");
|
||||||
|
|
||||||
currentMaterial->alpha = 1.f - alpha; // tr vaut pour la "valeur de transparence", 0 = opaque
|
currentMaterial->alpha = 1.f - alpha; // tr vaut pour la "valeur de transparence", 0 = opaque
|
||||||
}
|
}
|
||||||
|
|
@ -162,7 +149,7 @@ namespace Nz
|
||||||
if (std::sscanf(&m_currentLine[6], "%u", &model) == 1)
|
if (std::sscanf(&m_currentLine[6], "%u", &model) == 1)
|
||||||
{
|
{
|
||||||
if (!currentMaterial)
|
if (!currentMaterial)
|
||||||
currentMaterial = &m_materials["default"];
|
currentMaterial = AddMaterial("default");
|
||||||
|
|
||||||
currentMaterial->illumModel = model;
|
currentMaterial->illumModel = model;
|
||||||
}
|
}
|
||||||
|
|
@ -178,7 +165,7 @@ namespace Nz
|
||||||
{
|
{
|
||||||
String map = m_currentLine.SubString(mapPos);
|
String map = m_currentLine.SubString(mapPos);
|
||||||
if (!currentMaterial)
|
if (!currentMaterial)
|
||||||
currentMaterial = &m_materials["default"];
|
currentMaterial = AddMaterial("default");
|
||||||
|
|
||||||
currentMaterial->ambientMap = map;
|
currentMaterial->ambientMap = map;
|
||||||
}
|
}
|
||||||
|
|
@ -190,7 +177,7 @@ namespace Nz
|
||||||
{
|
{
|
||||||
String map = m_currentLine.SubString(mapPos);
|
String map = m_currentLine.SubString(mapPos);
|
||||||
if (!currentMaterial)
|
if (!currentMaterial)
|
||||||
currentMaterial = &m_materials["default"];
|
currentMaterial = AddMaterial("default");
|
||||||
|
|
||||||
currentMaterial->diffuseMap = map;
|
currentMaterial->diffuseMap = map;
|
||||||
}
|
}
|
||||||
|
|
@ -202,7 +189,7 @@ namespace Nz
|
||||||
{
|
{
|
||||||
String map = m_currentLine.SubString(mapPos);
|
String map = m_currentLine.SubString(mapPos);
|
||||||
if (!currentMaterial)
|
if (!currentMaterial)
|
||||||
currentMaterial = &m_materials["default"];
|
currentMaterial = AddMaterial("default");
|
||||||
|
|
||||||
currentMaterial->specularMap = map;
|
currentMaterial->specularMap = map;
|
||||||
}
|
}
|
||||||
|
|
@ -214,7 +201,7 @@ namespace Nz
|
||||||
{
|
{
|
||||||
String map = m_currentLine.SubString(mapPos);
|
String map = m_currentLine.SubString(mapPos);
|
||||||
if (!currentMaterial)
|
if (!currentMaterial)
|
||||||
currentMaterial = &m_materials["default"];
|
currentMaterial = AddMaterial("default");
|
||||||
|
|
||||||
currentMaterial->bumpMap = map;
|
currentMaterial->bumpMap = map;
|
||||||
}
|
}
|
||||||
|
|
@ -226,7 +213,7 @@ namespace Nz
|
||||||
{
|
{
|
||||||
String map = m_currentLine.SubString(mapPos);
|
String map = m_currentLine.SubString(mapPos);
|
||||||
if (!currentMaterial)
|
if (!currentMaterial)
|
||||||
currentMaterial = &m_materials["default"];
|
currentMaterial = AddMaterial("default");
|
||||||
|
|
||||||
currentMaterial->alphaMap = map;
|
currentMaterial->alphaMap = map;
|
||||||
}
|
}
|
||||||
|
|
@ -238,7 +225,7 @@ namespace Nz
|
||||||
{
|
{
|
||||||
String map = m_currentLine.SubString(mapPos);
|
String map = m_currentLine.SubString(mapPos);
|
||||||
if (!currentMaterial)
|
if (!currentMaterial)
|
||||||
currentMaterial = &m_materials["default"];
|
currentMaterial = AddMaterial("default");
|
||||||
|
|
||||||
currentMaterial->decalMap = map;
|
currentMaterial->decalMap = map;
|
||||||
}
|
}
|
||||||
|
|
@ -250,7 +237,7 @@ namespace Nz
|
||||||
{
|
{
|
||||||
String map = m_currentLine.SubString(mapPos);
|
String map = m_currentLine.SubString(mapPos);
|
||||||
if (!currentMaterial)
|
if (!currentMaterial)
|
||||||
currentMaterial = &m_materials["default"];
|
currentMaterial = AddMaterial("default");
|
||||||
|
|
||||||
currentMaterial->displacementMap = map;
|
currentMaterial->displacementMap = map;
|
||||||
}
|
}
|
||||||
|
|
@ -262,7 +249,7 @@ namespace Nz
|
||||||
{
|
{
|
||||||
String map = m_currentLine.SubString(mapPos);
|
String map = m_currentLine.SubString(mapPos);
|
||||||
if (!currentMaterial)
|
if (!currentMaterial)
|
||||||
currentMaterial = &m_materials["default"];
|
currentMaterial = AddMaterial("default");
|
||||||
|
|
||||||
currentMaterial->reflectionMap = map;
|
currentMaterial->reflectionMap = map;
|
||||||
}
|
}
|
||||||
|
|
@ -271,7 +258,7 @@ namespace Nz
|
||||||
{
|
{
|
||||||
String materialName = m_currentLine.SubString(m_currentLine.GetWordPosition(1));
|
String materialName = m_currentLine.SubString(m_currentLine.GetWordPosition(1));
|
||||||
if (!materialName.IsEmpty())
|
if (!materialName.IsEmpty())
|
||||||
currentMaterial = &m_materials[materialName];
|
currentMaterial = AddMaterial(materialName);
|
||||||
#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
|
#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
|
||||||
else
|
else
|
||||||
UnrecognizedLine();
|
UnrecognizedLine();
|
||||||
|
|
@ -286,13 +273,150 @@ namespace Nz
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool MTLParser::Save(Stream& stream) const
|
||||||
|
{
|
||||||
|
m_currentStream = &stream;
|
||||||
|
|
||||||
|
// Force stream in text mode, reset it at the end
|
||||||
|
Nz::CallOnExit resetTextMode;
|
||||||
|
if ((stream.GetStreamOptions() & StreamOption_Text) == 0)
|
||||||
|
{
|
||||||
|
stream.EnableTextMode(true);
|
||||||
|
|
||||||
|
resetTextMode.Reset([&stream] ()
|
||||||
|
{
|
||||||
|
stream.EnableTextMode(false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
m_outputStream.Clear();
|
||||||
|
|
||||||
|
EmitLine("# Exported by Nazara Engine");
|
||||||
|
EmitLine();
|
||||||
|
|
||||||
|
Emit("# material count: ");
|
||||||
|
Emit(m_materials.size());
|
||||||
|
EmitLine();
|
||||||
|
|
||||||
|
for (auto& pair : m_materials)
|
||||||
|
{
|
||||||
|
const String& matName = pair.first;
|
||||||
|
const Material& mat = pair.second;
|
||||||
|
|
||||||
|
Emit("newmtl ");
|
||||||
|
EmitLine(pair.first);
|
||||||
|
EmitLine();
|
||||||
|
|
||||||
|
Emit("Ka ");
|
||||||
|
Emit(mat.ambient.r / 255.f);
|
||||||
|
Emit(' ');
|
||||||
|
Emit(mat.ambient.g / 255.f);
|
||||||
|
Emit(' ');
|
||||||
|
Emit(mat.ambient.b / 255.f);
|
||||||
|
EmitLine();
|
||||||
|
|
||||||
|
Emit("Kd ");
|
||||||
|
Emit(mat.diffuse.r / 255.f);
|
||||||
|
Emit(' ');
|
||||||
|
Emit(mat.diffuse.g / 255.f);
|
||||||
|
Emit(' ');
|
||||||
|
Emit(mat.diffuse.b / 255.f);
|
||||||
|
EmitLine();
|
||||||
|
|
||||||
|
Emit("Ks ");
|
||||||
|
Emit(mat.specular.r / 255.f);
|
||||||
|
Emit(' ');
|
||||||
|
Emit(mat.specular.g / 255.f);
|
||||||
|
Emit(' ');
|
||||||
|
Emit(mat.specular.b / 255.f);
|
||||||
|
EmitLine();
|
||||||
|
|
||||||
|
if (mat.alpha != 1.f)
|
||||||
|
{
|
||||||
|
Emit("d ");
|
||||||
|
EmitLine(mat.alpha);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mat.refractionIndex != 1.f)
|
||||||
|
{
|
||||||
|
Emit("ni ");
|
||||||
|
EmitLine(mat.refractionIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mat.shininess != 1.f)
|
||||||
|
{
|
||||||
|
Emit("ns ");
|
||||||
|
EmitLine(mat.shininess);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mat.illumModel != 0)
|
||||||
|
{
|
||||||
|
Emit("illum ");
|
||||||
|
EmitLine(mat.illumModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mat.ambientMap.IsEmpty())
|
||||||
|
{
|
||||||
|
Emit("map_Ka ");
|
||||||
|
EmitLine(mat.ambientMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mat.diffuseMap.IsEmpty())
|
||||||
|
{
|
||||||
|
Emit("map_Kd ");
|
||||||
|
EmitLine(mat.diffuseMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mat.specularMap.IsEmpty())
|
||||||
|
{
|
||||||
|
Emit("map_Ks ");
|
||||||
|
EmitLine(mat.specularMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mat.bumpMap.IsEmpty())
|
||||||
|
{
|
||||||
|
Emit("map_bump ");
|
||||||
|
EmitLine(mat.bumpMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mat.alphaMap.IsEmpty())
|
||||||
|
{
|
||||||
|
Emit("map_d ");
|
||||||
|
EmitLine(mat.alphaMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mat.decalMap.IsEmpty())
|
||||||
|
{
|
||||||
|
Emit("map_decal ");
|
||||||
|
EmitLine(mat.decalMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mat.displacementMap.IsEmpty())
|
||||||
|
{
|
||||||
|
Emit("map_disp ");
|
||||||
|
EmitLine(mat.displacementMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mat.reflectionMap.IsEmpty())
|
||||||
|
{
|
||||||
|
Emit("map_refl ");
|
||||||
|
EmitLine(mat.reflectionMap);
|
||||||
|
}
|
||||||
|
EmitLine();
|
||||||
|
}
|
||||||
|
|
||||||
|
Flush();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool MTLParser::Advance(bool required)
|
bool MTLParser::Advance(bool required)
|
||||||
{
|
{
|
||||||
if (!m_keepLastLine)
|
if (!m_keepLastLine)
|
||||||
{
|
{
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
if (m_stream.EndOfStream())
|
if (m_currentStream->EndOfStream())
|
||||||
{
|
{
|
||||||
if (required)
|
if (required)
|
||||||
Error("Incomplete MTL file");
|
Error("Incomplete MTL file");
|
||||||
|
|
@ -302,7 +426,7 @@ namespace Nz
|
||||||
|
|
||||||
m_lineCount++;
|
m_lineCount++;
|
||||||
|
|
||||||
m_currentLine = m_stream.ReadLine();
|
m_currentLine = m_currentStream->ReadLine();
|
||||||
m_currentLine = m_currentLine.SubStringTo("#"); // On ignore les commentaires
|
m_currentLine = m_currentLine.SubStringTo("#"); // On ignore les commentaires
|
||||||
m_currentLine.Simplify(); // Pour un traitement plus simple
|
m_currentLine.Simplify(); // Pour un traitement plus simple
|
||||||
}
|
}
|
||||||
|
|
@ -313,24 +437,4 @@ namespace Nz
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MTLParser::Error(const String& message)
|
|
||||||
{
|
|
||||||
NazaraError(message + " at line #" + String::Number(m_lineCount));
|
|
||||||
}
|
|
||||||
|
|
||||||
void MTLParser::Warning(const String& message)
|
|
||||||
{
|
|
||||||
NazaraWarning(message + " at line #" + String::Number(m_lineCount));
|
|
||||||
}
|
|
||||||
|
|
||||||
void MTLParser::UnrecognizedLine(bool error)
|
|
||||||
{
|
|
||||||
String message = "Unrecognized \"" + m_currentLine + '"';
|
|
||||||
|
|
||||||
if (error)
|
|
||||||
Error(message);
|
|
||||||
else
|
|
||||||
Warning(message);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -49,8 +49,8 @@ namespace Nz
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
MTLParser materialParser(file);
|
MTLParser materialParser;
|
||||||
if (!materialParser.Parse())
|
if (!materialParser.Parse(file))
|
||||||
{
|
{
|
||||||
NazaraError("MTL parser failed");
|
NazaraError("MTL parser failed");
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -90,13 +90,31 @@ namespace Nz
|
||||||
data.SetParameter(MaterialData::SpecularColor, specularColor);
|
data.SetParameter(MaterialData::SpecularColor, specularColor);
|
||||||
|
|
||||||
if (!mtlMat->alphaMap.IsEmpty())
|
if (!mtlMat->alphaMap.IsEmpty())
|
||||||
data.SetParameter(MaterialData::AlphaTexturePath, baseDir + mtlMat->alphaMap);
|
{
|
||||||
|
String fullPath = mtlMat->alphaMap;
|
||||||
|
if (!Nz::File::IsAbsolute(fullPath))
|
||||||
|
fullPath.Prepend(baseDir);
|
||||||
|
|
||||||
|
data.SetParameter(MaterialData::AlphaTexturePath, fullPath);
|
||||||
|
}
|
||||||
|
|
||||||
if (!mtlMat->diffuseMap.IsEmpty())
|
if (!mtlMat->diffuseMap.IsEmpty())
|
||||||
data.SetParameter(MaterialData::DiffuseTexturePath, baseDir + mtlMat->diffuseMap);
|
{
|
||||||
|
String fullPath = mtlMat->diffuseMap;
|
||||||
|
if (!Nz::File::IsAbsolute(fullPath))
|
||||||
|
fullPath.Prepend(baseDir);
|
||||||
|
|
||||||
|
data.SetParameter(MaterialData::DiffuseTexturePath, fullPath);
|
||||||
|
}
|
||||||
|
|
||||||
if (!mtlMat->specularMap.IsEmpty())
|
if (!mtlMat->specularMap.IsEmpty())
|
||||||
data.SetParameter(MaterialData::SpecularTexturePath, baseDir + mtlMat->specularMap);
|
{
|
||||||
|
String fullPath = mtlMat->specularMap;
|
||||||
|
if (!Nz::File::IsAbsolute(fullPath))
|
||||||
|
fullPath.Prepend(baseDir);
|
||||||
|
|
||||||
|
data.SetParameter(MaterialData::SpecularTexturePath, fullPath);
|
||||||
|
}
|
||||||
|
|
||||||
// If we either have an alpha value or an alpha map, let's configure the material for transparency
|
// 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.IsEmpty())
|
||||||
|
|
|
||||||
|
|
@ -386,10 +386,11 @@ namespace Nz
|
||||||
m_outputStream.Clear();
|
m_outputStream.Clear();
|
||||||
|
|
||||||
EmitLine("# Exported by Nazara Engine");
|
EmitLine("# Exported by Nazara Engine");
|
||||||
|
EmitLine();
|
||||||
|
|
||||||
if (!m_mtlLib.IsEmpty())
|
if (!m_mtlLib.IsEmpty())
|
||||||
{
|
{
|
||||||
Emit("mtlib ");
|
Emit("mtllib ");
|
||||||
EmitLine(m_mtlLib);
|
EmitLine(m_mtlLib);
|
||||||
EmitLine();
|
EmitLine();
|
||||||
}
|
}
|
||||||
|
|
@ -403,17 +404,15 @@ namespace Nz
|
||||||
Emit(position.x);
|
Emit(position.x);
|
||||||
Emit(' ');
|
Emit(' ');
|
||||||
Emit(position.y);
|
Emit(position.y);
|
||||||
if (!NumberEquals(position.z, 0.f) || !NumberEquals(position.w, 1.f))
|
Emit(' ');
|
||||||
|
Emit(position.z);
|
||||||
|
|
||||||
|
if (!NumberEquals(position.w, 1.f))
|
||||||
{
|
{
|
||||||
Emit(' ');
|
Emit(' ');
|
||||||
Emit(position.z);
|
Emit(position.w);
|
||||||
|
|
||||||
if (!NumberEquals(position.w, 1.f))
|
|
||||||
{
|
|
||||||
Emit(' ');
|
|
||||||
Emit(position.w);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EmitLine();
|
EmitLine();
|
||||||
}
|
}
|
||||||
EmitLine();
|
EmitLine();
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,229 @@
|
||||||
|
// Copyright (C) 2016 Jérôme Leclercq
|
||||||
|
// This file is part of the "Nazara Engine - Utility module"
|
||||||
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||||
|
|
||||||
|
#include <Nazara/Utility/Formats/OBJLoader.hpp>
|
||||||
|
#include <Nazara/Core/Algorithm.hpp>
|
||||||
|
#include <Nazara/Core/ErrorFlags.hpp>
|
||||||
|
#include <Nazara/Utility/BufferMapper.hpp>
|
||||||
|
#include <Nazara/Utility/IndexMapper.hpp>
|
||||||
|
#include <Nazara/Utility/MaterialData.hpp>
|
||||||
|
#include <Nazara/Utility/Mesh.hpp>
|
||||||
|
#include <Nazara/Utility/StaticMesh.hpp>
|
||||||
|
#include <Nazara/Utility/TriangleIterator.hpp>
|
||||||
|
#include <Nazara/Utility/VertexMapper.hpp>
|
||||||
|
#include <Nazara/Utility/Formats/MTLParser.hpp>
|
||||||
|
#include <Nazara/Utility/Formats/OBJParser.hpp>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <limits>
|
||||||
|
#include <map>
|
||||||
|
#include <memory>
|
||||||
|
#include <unordered_set>
|
||||||
|
#include <Nazara/Utility/Debug.hpp>
|
||||||
|
|
||||||
|
namespace Nz
|
||||||
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
template<typename T>
|
||||||
|
class VertexCache
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
VertexCache(T* ptr) :
|
||||||
|
m_count(0),
|
||||||
|
m_buffer(ptr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t GetCount() const
|
||||||
|
{
|
||||||
|
return m_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t Insert(const T& data)
|
||||||
|
{
|
||||||
|
auto it = m_cache.find(data);
|
||||||
|
if (it == m_cache.end())
|
||||||
|
{
|
||||||
|
it = m_cache.insert(std::make_pair(data, m_count)).first;
|
||||||
|
m_buffer[m_count] = data;
|
||||||
|
m_count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return it->second + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::size_t m_count;
|
||||||
|
std::map<T, std::size_t> m_cache;
|
||||||
|
T* m_buffer;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool IsSupported(const String& extension)
|
||||||
|
{
|
||||||
|
return (extension == "obj");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SaveToStream(const Mesh& mesh, const String& format, Stream& stream, const MeshParams& parameters)
|
||||||
|
{
|
||||||
|
if (!mesh.IsValid())
|
||||||
|
{
|
||||||
|
NazaraError("Invalid mesh");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mesh.IsAnimable())
|
||||||
|
{
|
||||||
|
NazaraError("An animated mesh cannot be saved to " + format + " format");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t worstCacheVertexCount = mesh.GetVertexCount();
|
||||||
|
OBJParser objFormat;
|
||||||
|
objFormat.SetNormalCount(worstCacheVertexCount);
|
||||||
|
objFormat.SetPositionCount(worstCacheVertexCount);
|
||||||
|
objFormat.SetTexCoordCount(worstCacheVertexCount);
|
||||||
|
|
||||||
|
String mtlPath = stream.GetPath();
|
||||||
|
if (!mtlPath.IsEmpty())
|
||||||
|
{
|
||||||
|
mtlPath.Replace(".obj", ".mtl");
|
||||||
|
String fileName = mtlPath.SubStringFrom(NAZARA_DIRECTORY_SEPARATOR, -1, true);
|
||||||
|
if (!fileName.IsEmpty())
|
||||||
|
objFormat.SetMtlLib(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
VertexCache<Vector3f> normalCache(objFormat.GetNormals());
|
||||||
|
VertexCache<Vector4f> positionCache(objFormat.GetPositions());
|
||||||
|
VertexCache<Vector3f> texCoordsCache(objFormat.GetTexCoords());
|
||||||
|
|
||||||
|
// Materials
|
||||||
|
MTLParser mtlFormat;
|
||||||
|
std::unordered_set<String> registredMaterials;
|
||||||
|
|
||||||
|
std::size_t matCount = mesh.GetMaterialCount();
|
||||||
|
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);
|
||||||
|
|
||||||
|
// Makes sure we only have one material of that name
|
||||||
|
while (registredMaterials.find(name) != registredMaterials.end())
|
||||||
|
name += '_';
|
||||||
|
|
||||||
|
registredMaterials.insert(name);
|
||||||
|
materialNames[i] = name;
|
||||||
|
|
||||||
|
MTLParser::Material* material = mtlFormat.AddMaterial(name);
|
||||||
|
|
||||||
|
bool bValue;
|
||||||
|
String strVal;
|
||||||
|
if (matData.HasParameter(MaterialData::CustomDefined))
|
||||||
|
{
|
||||||
|
Color colorVal;
|
||||||
|
float fValue;
|
||||||
|
|
||||||
|
if (matData.GetColorParameter(MaterialData::AmbientColor, &colorVal))
|
||||||
|
material->ambient = colorVal;
|
||||||
|
|
||||||
|
if (matData.GetColorParameter(MaterialData::DiffuseColor, &colorVal))
|
||||||
|
material->diffuse = colorVal;
|
||||||
|
|
||||||
|
if (matData.GetColorParameter(MaterialData::SpecularColor, &colorVal))
|
||||||
|
material->specular = colorVal;
|
||||||
|
|
||||||
|
if (matData.GetFloatParameter(MaterialData::Shininess, &fValue))
|
||||||
|
material->shininess = fValue;
|
||||||
|
|
||||||
|
if (matData.GetStringParameter(MaterialData::AlphaTexturePath, &strVal))
|
||||||
|
material->alphaMap = strVal;
|
||||||
|
|
||||||
|
if (matData.GetStringParameter(MaterialData::DiffuseTexturePath, &strVal))
|
||||||
|
material->diffuseMap = strVal;
|
||||||
|
|
||||||
|
if (matData.GetStringParameter(MaterialData::SpecularTexturePath, &strVal))
|
||||||
|
material->specularMap = strVal;
|
||||||
|
}
|
||||||
|
else if (matData.GetStringParameter(MaterialData::FilePath, &strVal))
|
||||||
|
material->diffuseMap = strVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Meshes
|
||||||
|
std::size_t meshCount = mesh.GetSubMeshCount();
|
||||||
|
OBJParser::Mesh* meshes = objFormat.SetMeshCount(meshCount);
|
||||||
|
for (std::size_t i = 0; i < meshCount; ++i)
|
||||||
|
{
|
||||||
|
const StaticMesh* staticMesh = static_cast<const StaticMesh*>(mesh.GetSubMesh(i));
|
||||||
|
|
||||||
|
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].vertices.resize(triangleCount * 3);
|
||||||
|
|
||||||
|
{
|
||||||
|
VertexMapper vertexMapper(staticMesh);
|
||||||
|
|
||||||
|
SparsePtr<Vector3f> normalPtr = vertexMapper.GetComponentPtr<Vector3f>(VertexComponent_Normal);
|
||||||
|
SparsePtr<Vector3f> positionPtr = vertexMapper.GetComponentPtr<Vector3f>(VertexComponent_Position);
|
||||||
|
SparsePtr<Vector2f> texCoordsPtr = vertexMapper.GetComponentPtr<Vector2f>(VertexComponent_TexCoord);
|
||||||
|
|
||||||
|
std::size_t faceIndex = 0;
|
||||||
|
TriangleIterator triangle(staticMesh);
|
||||||
|
do
|
||||||
|
{
|
||||||
|
OBJParser::Face& face = meshes[i].faces[faceIndex];
|
||||||
|
face.firstVertex = faceIndex * 3;
|
||||||
|
face.vertexCount = 3;
|
||||||
|
|
||||||
|
for (std::size_t j = 0; j < 3; ++j)
|
||||||
|
{
|
||||||
|
OBJParser::FaceVertex& vertexIndices = meshes[i].vertices[face.firstVertex + 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]);
|
||||||
|
}
|
||||||
|
|
||||||
|
faceIndex++;
|
||||||
|
}
|
||||||
|
while (triangle.Advance());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
objFormat.SetNormalCount(normalCache.GetCount());
|
||||||
|
objFormat.SetPositionCount(positionCache.GetCount());
|
||||||
|
objFormat.SetTexCoordCount(texCoordsCache.GetCount());
|
||||||
|
|
||||||
|
objFormat.Save(stream);
|
||||||
|
|
||||||
|
if (!mtlPath.IsEmpty())
|
||||||
|
{
|
||||||
|
File mtlFile(mtlPath, OpenMode_WriteOnly | OpenMode_Truncate);
|
||||||
|
if (mtlFile.IsOpen())
|
||||||
|
mtlFormat.Save(mtlFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Loaders
|
||||||
|
{
|
||||||
|
void RegisterOBJSaver()
|
||||||
|
{
|
||||||
|
MeshSaver::RegisterSaver(IsSupported, SaveToStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UnregisterOBJSaver()
|
||||||
|
{
|
||||||
|
MeshSaver::UnregisterSaver(IsSupported, SaveToStream);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
// 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_FORMATS_OBJSAVER_HPP
|
||||||
|
#define NAZARA_FORMATS_OBJSAVER_HPP
|
||||||
|
|
||||||
|
#include <Nazara/Prerequesites.hpp>
|
||||||
|
|
||||||
|
namespace Nz
|
||||||
|
{
|
||||||
|
namespace Loaders
|
||||||
|
{
|
||||||
|
void RegisterOBJSaver();
|
||||||
|
void UnregisterOBJSaver();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // NAZARA_FORMATS_OBJSAVER_HPP
|
||||||
|
|
@ -606,6 +606,16 @@ namespace Nz
|
||||||
InvalidateAABB();
|
InvalidateAABB();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Mesh::SaveToFile(const String& filePath, const MeshParams& params)
|
||||||
|
{
|
||||||
|
return MeshSaver::SaveToFile(*this, filePath, params);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Mesh::SaveToStream(Stream& stream, const String& format, const MeshParams& params)
|
||||||
|
{
|
||||||
|
return MeshSaver::SaveToStream(*this, stream, format, params);
|
||||||
|
}
|
||||||
|
|
||||||
void Mesh::SetAnimation(const String& animationPath)
|
void Mesh::SetAnimation(const String& animationPath)
|
||||||
{
|
{
|
||||||
NazaraAssert(m_impl, "Mesh should be created first");
|
NazaraAssert(m_impl, "Mesh should be created first");
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@
|
||||||
#include <Nazara/Utility/Formats/MD5AnimLoader.hpp>
|
#include <Nazara/Utility/Formats/MD5AnimLoader.hpp>
|
||||||
#include <Nazara/Utility/Formats/MD5MeshLoader.hpp>
|
#include <Nazara/Utility/Formats/MD5MeshLoader.hpp>
|
||||||
#include <Nazara/Utility/Formats/OBJLoader.hpp>
|
#include <Nazara/Utility/Formats/OBJLoader.hpp>
|
||||||
|
#include <Nazara/Utility/Formats/OBJSaver.hpp>
|
||||||
#include <Nazara/Utility/Formats/PCXLoader.hpp>
|
#include <Nazara/Utility/Formats/PCXLoader.hpp>
|
||||||
#include <Nazara/Utility/Formats/STBLoader.hpp>
|
#include <Nazara/Utility/Formats/STBLoader.hpp>
|
||||||
#include <Nazara/Utility/Formats/STBSaver.hpp>
|
#include <Nazara/Utility/Formats/STBSaver.hpp>
|
||||||
|
|
@ -125,10 +126,12 @@ namespace Nz
|
||||||
|
|
||||||
// Mesh (text)
|
// Mesh (text)
|
||||||
Loaders::RegisterOBJLoader();
|
Loaders::RegisterOBJLoader();
|
||||||
|
Loaders::RegisterOBJSaver();
|
||||||
|
|
||||||
// Mesh
|
// Mesh
|
||||||
Loaders::RegisterMD2(); // Loader de fichiers .md2 (v8)
|
Loaders::RegisterMD2(); // Loader de fichiers .md2 (v8)
|
||||||
Loaders::RegisterMD5Mesh(); // Loader de fichiers .md5mesh (v10)
|
Loaders::RegisterMD5Mesh(); // Loader de fichiers .md5mesh (v10)
|
||||||
|
Loaders::RegisterOBJLoader(); // Loader de fichiers .md5mesh (v10)
|
||||||
|
|
||||||
// Image
|
// Image
|
||||||
Loaders::RegisterPCX(); // Loader de fichiers .pcx (1, 4, 8, 24 bits)
|
Loaders::RegisterPCX(); // Loader de fichiers .pcx (1, 4, 8, 24 bits)
|
||||||
|
|
@ -163,6 +166,7 @@ namespace Nz
|
||||||
Loaders::UnregisterMD5Anim();
|
Loaders::UnregisterMD5Anim();
|
||||||
Loaders::UnregisterMD5Mesh();
|
Loaders::UnregisterMD5Mesh();
|
||||||
Loaders::UnregisterOBJLoader();
|
Loaders::UnregisterOBJLoader();
|
||||||
|
Loaders::UnregisterOBJSaver();
|
||||||
Loaders::UnregisterPCX();
|
Loaders::UnregisterPCX();
|
||||||
Loaders::UnregisterSTBLoader();
|
Loaders::UnregisterSTBLoader();
|
||||||
Loaders::UnregisterSTBSaver();
|
Loaders::UnregisterSTBSaver();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue