Make mesh able to carry material informations
- Move OBJ Loader to Utility module, where it belongs - Change Mesh material informations from a path to a parameterlist - Improve Mesh code Former-commit-id: f16f48f8b6399188a09797cec3707ab6726bdbca
This commit is contained in:
parent
9aab369791
commit
3b5d6e9cde
|
|
@ -24,6 +24,7 @@
|
||||||
#include <Nazara/Renderer/Texture.hpp>
|
#include <Nazara/Renderer/Texture.hpp>
|
||||||
#include <Nazara/Renderer/TextureSampler.hpp>
|
#include <Nazara/Renderer/TextureSampler.hpp>
|
||||||
#include <Nazara/Renderer/UberShader.hpp>
|
#include <Nazara/Renderer/UberShader.hpp>
|
||||||
|
#include <Nazara/Utility/MaterialData.hpp>
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
|
|
@ -62,6 +63,8 @@ namespace Nz
|
||||||
|
|
||||||
const Shader* Apply(UInt32 shaderFlags = 0, UInt8 textureUnit = 0, UInt8* lastUsedUnit = nullptr) const;
|
const Shader* Apply(UInt32 shaderFlags = 0, UInt8 textureUnit = 0, UInt8* lastUsedUnit = nullptr) const;
|
||||||
|
|
||||||
|
void BuildFromParameters(const ParameterList& matData, const MaterialParams& matParams = MaterialParams());
|
||||||
|
|
||||||
void Enable(RendererParameter renderParameter, bool enable);
|
void Enable(RendererParameter renderParameter, bool enable);
|
||||||
void EnableAlphaTest(bool alphaTest);
|
void EnableAlphaTest(bool alphaTest);
|
||||||
void EnableDepthSorting(bool depthSorting);
|
void EnableDepthSorting(bool depthSorting);
|
||||||
|
|
|
||||||
|
|
@ -19,40 +19,6 @@ namespace Nz
|
||||||
AttachmentPoint_Max = AttachmentPoint_Stencil
|
AttachmentPoint_Max = AttachmentPoint_Stencil
|
||||||
};
|
};
|
||||||
|
|
||||||
enum BlendFunc
|
|
||||||
{
|
|
||||||
BlendFunc_DestAlpha,
|
|
||||||
BlendFunc_DestColor,
|
|
||||||
BlendFunc_SrcAlpha,
|
|
||||||
BlendFunc_SrcColor,
|
|
||||||
BlendFunc_InvDestAlpha,
|
|
||||||
BlendFunc_InvDestColor,
|
|
||||||
BlendFunc_InvSrcAlpha,
|
|
||||||
BlendFunc_InvSrcColor,
|
|
||||||
BlendFunc_One,
|
|
||||||
BlendFunc_Zero,
|
|
||||||
|
|
||||||
BlendFunc_Max = BlendFunc_Zero
|
|
||||||
};
|
|
||||||
|
|
||||||
enum FaceFilling
|
|
||||||
{
|
|
||||||
FaceFilling_Fill,
|
|
||||||
FaceFilling_Line,
|
|
||||||
FaceFilling_Point,
|
|
||||||
|
|
||||||
FaceFilling_Max = FaceFilling_Point
|
|
||||||
};
|
|
||||||
|
|
||||||
enum FaceSide
|
|
||||||
{
|
|
||||||
FaceSide_Back,
|
|
||||||
FaceSide_Front,
|
|
||||||
FaceSide_FrontAndBack,
|
|
||||||
|
|
||||||
FaceSide_Max = FaceSide_FrontAndBack
|
|
||||||
};
|
|
||||||
|
|
||||||
enum GpuQueryCondition
|
enum GpuQueryCondition
|
||||||
{
|
{
|
||||||
GpuQueryCondition_Region_NoWait,
|
GpuQueryCondition_Region_NoWait,
|
||||||
|
|
@ -124,59 +90,6 @@ namespace Nz
|
||||||
RendererBuffer_Max = RendererBuffer_Stencil*2-1
|
RendererBuffer_Max = RendererBuffer_Stencil*2-1
|
||||||
};
|
};
|
||||||
|
|
||||||
enum RendererComparison
|
|
||||||
{
|
|
||||||
RendererComparison_Always,
|
|
||||||
RendererComparison_Equal,
|
|
||||||
RendererComparison_Greater,
|
|
||||||
RendererComparison_GreaterOrEqual,
|
|
||||||
RendererComparison_Less,
|
|
||||||
RendererComparison_LessOrEqual,
|
|
||||||
RendererComparison_Never,
|
|
||||||
RendererComparison_NotEqual,
|
|
||||||
|
|
||||||
RendererComparison_Max = RendererComparison_NotEqual
|
|
||||||
};
|
|
||||||
|
|
||||||
enum RendererParameter
|
|
||||||
{
|
|
||||||
RendererParameter_Blend,
|
|
||||||
RendererParameter_ColorWrite,
|
|
||||||
RendererParameter_DepthBuffer,
|
|
||||||
RendererParameter_DepthWrite,
|
|
||||||
RendererParameter_FaceCulling,
|
|
||||||
RendererParameter_ScissorTest,
|
|
||||||
RendererParameter_StencilTest,
|
|
||||||
|
|
||||||
RendererParameter_Max = RendererParameter_StencilTest
|
|
||||||
};
|
|
||||||
|
|
||||||
enum SamplerFilter
|
|
||||||
{
|
|
||||||
SamplerFilter_Unknown = -1,
|
|
||||||
|
|
||||||
SamplerFilter_Bilinear,
|
|
||||||
SamplerFilter_Nearest,
|
|
||||||
SamplerFilter_Trilinear,
|
|
||||||
|
|
||||||
SamplerFilter_Default,
|
|
||||||
|
|
||||||
SamplerFilter_Max = SamplerFilter_Default
|
|
||||||
};
|
|
||||||
|
|
||||||
enum SamplerWrap
|
|
||||||
{
|
|
||||||
SamplerWrap_Unknown = -1,
|
|
||||||
|
|
||||||
SamplerWrap_Clamp,
|
|
||||||
SamplerWrap_MirroredRepeat,
|
|
||||||
SamplerWrap_Repeat,
|
|
||||||
|
|
||||||
SamplerWrap_Default,
|
|
||||||
|
|
||||||
SamplerWrap_Max = SamplerWrap_Repeat
|
|
||||||
};
|
|
||||||
|
|
||||||
enum ShaderUniform
|
enum ShaderUniform
|
||||||
{
|
{
|
||||||
ShaderUniform_InvProjMatrix,
|
ShaderUniform_InvProjMatrix,
|
||||||
|
|
@ -205,20 +118,6 @@ namespace Nz
|
||||||
|
|
||||||
ShaderStageType_Max = ShaderStageType_Vertex
|
ShaderStageType_Max = ShaderStageType_Vertex
|
||||||
};
|
};
|
||||||
|
|
||||||
enum StencilOperation
|
|
||||||
{
|
|
||||||
StencilOperation_Decrement,
|
|
||||||
StencilOperation_DecrementNoClamp,
|
|
||||||
StencilOperation_Increment,
|
|
||||||
StencilOperation_IncrementNoClamp,
|
|
||||||
StencilOperation_Invert,
|
|
||||||
StencilOperation_Keep,
|
|
||||||
StencilOperation_Replace,
|
|
||||||
StencilOperation_Zero,
|
|
||||||
|
|
||||||
StencilOperation_Max = StencilOperation_Zero
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // NAZARA_ENUMS_RENDERER_HPP
|
#endif // NAZARA_ENUMS_RENDERER_HPP
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
#ifndef NAZARA_RENDERSTATES_HPP
|
#ifndef NAZARA_RENDERSTATES_HPP
|
||||||
#define NAZARA_RENDERSTATES_HPP
|
#define NAZARA_RENDERSTATES_HPP
|
||||||
|
|
||||||
#include <Nazara/Renderer/Enums.hpp>
|
#include <Nazara/Utility/Enums.hpp>
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
#include <Nazara/Prerequesites.hpp>
|
#include <Nazara/Prerequesites.hpp>
|
||||||
#include <Nazara/Renderer/Config.hpp>
|
#include <Nazara/Renderer/Config.hpp>
|
||||||
#include <Nazara/Renderer/Enums.hpp>
|
#include <Nazara/Utility/Enums.hpp>
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,22 @@ namespace Nz
|
||||||
AnimationType_Max = AnimationType_Static
|
AnimationType_Max = AnimationType_Static
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum BlendFunc
|
||||||
|
{
|
||||||
|
BlendFunc_DestAlpha,
|
||||||
|
BlendFunc_DestColor,
|
||||||
|
BlendFunc_SrcAlpha,
|
||||||
|
BlendFunc_SrcColor,
|
||||||
|
BlendFunc_InvDestAlpha,
|
||||||
|
BlendFunc_InvDestColor,
|
||||||
|
BlendFunc_InvSrcAlpha,
|
||||||
|
BlendFunc_InvSrcColor,
|
||||||
|
BlendFunc_One,
|
||||||
|
BlendFunc_Zero,
|
||||||
|
|
||||||
|
BlendFunc_Max = BlendFunc_Zero
|
||||||
|
};
|
||||||
|
|
||||||
enum BufferAccess
|
enum BufferAccess
|
||||||
{
|
{
|
||||||
BufferAccess_DiscardAndWrite,
|
BufferAccess_DiscardAndWrite,
|
||||||
|
|
@ -87,6 +103,24 @@ namespace Nz
|
||||||
DataStorage_Max = DataStorage_Software*2-1
|
DataStorage_Max = DataStorage_Software*2-1
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum FaceFilling
|
||||||
|
{
|
||||||
|
FaceFilling_Fill,
|
||||||
|
FaceFilling_Line,
|
||||||
|
FaceFilling_Point,
|
||||||
|
|
||||||
|
FaceFilling_Max = FaceFilling_Point
|
||||||
|
};
|
||||||
|
|
||||||
|
enum FaceSide
|
||||||
|
{
|
||||||
|
FaceSide_Back,
|
||||||
|
FaceSide_Front,
|
||||||
|
FaceSide_FrontAndBack,
|
||||||
|
|
||||||
|
FaceSide_Max = FaceSide_FrontAndBack
|
||||||
|
};
|
||||||
|
|
||||||
enum ImageType
|
enum ImageType
|
||||||
{
|
{
|
||||||
ImageType_1D,
|
ImageType_1D,
|
||||||
|
|
@ -211,6 +245,73 @@ namespace Nz
|
||||||
PrimitiveMode_Max = PrimitiveMode_TriangleFan
|
PrimitiveMode_Max = PrimitiveMode_TriangleFan
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum RendererComparison
|
||||||
|
{
|
||||||
|
RendererComparison_Always,
|
||||||
|
RendererComparison_Equal,
|
||||||
|
RendererComparison_Greater,
|
||||||
|
RendererComparison_GreaterOrEqual,
|
||||||
|
RendererComparison_Less,
|
||||||
|
RendererComparison_LessOrEqual,
|
||||||
|
RendererComparison_Never,
|
||||||
|
RendererComparison_NotEqual,
|
||||||
|
|
||||||
|
RendererComparison_Max = RendererComparison_NotEqual
|
||||||
|
};
|
||||||
|
|
||||||
|
enum RendererParameter
|
||||||
|
{
|
||||||
|
RendererParameter_Blend,
|
||||||
|
RendererParameter_ColorWrite,
|
||||||
|
RendererParameter_DepthBuffer,
|
||||||
|
RendererParameter_DepthWrite,
|
||||||
|
RendererParameter_FaceCulling,
|
||||||
|
RendererParameter_ScissorTest,
|
||||||
|
RendererParameter_StencilTest,
|
||||||
|
|
||||||
|
RendererParameter_Max = RendererParameter_StencilTest
|
||||||
|
};
|
||||||
|
|
||||||
|
enum SamplerFilter
|
||||||
|
{
|
||||||
|
SamplerFilter_Unknown = -1,
|
||||||
|
|
||||||
|
SamplerFilter_Bilinear,
|
||||||
|
SamplerFilter_Nearest,
|
||||||
|
SamplerFilter_Trilinear,
|
||||||
|
|
||||||
|
SamplerFilter_Default,
|
||||||
|
|
||||||
|
SamplerFilter_Max = SamplerFilter_Default
|
||||||
|
};
|
||||||
|
|
||||||
|
enum SamplerWrap
|
||||||
|
{
|
||||||
|
SamplerWrap_Unknown = -1,
|
||||||
|
|
||||||
|
SamplerWrap_Clamp,
|
||||||
|
SamplerWrap_MirroredRepeat,
|
||||||
|
SamplerWrap_Repeat,
|
||||||
|
|
||||||
|
SamplerWrap_Default,
|
||||||
|
|
||||||
|
SamplerWrap_Max = SamplerWrap_Repeat
|
||||||
|
};
|
||||||
|
|
||||||
|
enum StencilOperation
|
||||||
|
{
|
||||||
|
StencilOperation_Decrement,
|
||||||
|
StencilOperation_DecrementNoClamp,
|
||||||
|
StencilOperation_Increment,
|
||||||
|
StencilOperation_IncrementNoClamp,
|
||||||
|
StencilOperation_Invert,
|
||||||
|
StencilOperation_Keep,
|
||||||
|
StencilOperation_Replace,
|
||||||
|
StencilOperation_Zero,
|
||||||
|
|
||||||
|
StencilOperation_Max = StencilOperation_Zero
|
||||||
|
};
|
||||||
|
|
||||||
enum TextAlign
|
enum TextAlign
|
||||||
{
|
{
|
||||||
TextAlign_Left,
|
TextAlign_Left,
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,65 @@
|
||||||
|
// 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
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifndef NAZARA_MATERIALDATA_HPP
|
||||||
|
#define NAZARA_MATERIALDATA_HPP
|
||||||
|
|
||||||
|
namespace Nz
|
||||||
|
{
|
||||||
|
struct MaterialData
|
||||||
|
{
|
||||||
|
static constexpr const char* AlphaTest = "MatAlphaTest";
|
||||||
|
static constexpr const char* AlphaTexturePath = "MatAlphaTexturePath";
|
||||||
|
static constexpr const char* AlphaThreshold = "MatAlphaThreshold";
|
||||||
|
static constexpr const char* AmbientColor = "MatAmbientColor";
|
||||||
|
static constexpr const char* BackFaceStencilCompare = "MatBackFaceStencilCompare";
|
||||||
|
static constexpr const char* BackFaceStencilFail = "MatBackFaceStencilFail";
|
||||||
|
static constexpr const char* BackFaceStencilMask = "MatBackFaceStencilMask";
|
||||||
|
static constexpr const char* BackFaceStencilPass = "MatBackFaceStencilPass";
|
||||||
|
static constexpr const char* BackFaceStencilReference = "MatBackFaceStencilReference";
|
||||||
|
static constexpr const char* BackFaceStencilZFail = "MatBackFaceStencilZFail";
|
||||||
|
static constexpr const char* Blending = "MatBlending";
|
||||||
|
static constexpr const char* CustomDefined = "MatCustomDefined";
|
||||||
|
static constexpr const char* ColorWrite = "MatColorWrite";
|
||||||
|
static constexpr const char* DepthBuffer = "MatDepthBuffer";
|
||||||
|
static constexpr const char* DepthFunc = "MatDepthfunc";
|
||||||
|
static constexpr const char* DepthSorting = "MatDepthSorting";
|
||||||
|
static constexpr const char* DepthWrite = "MatDepthWrite";
|
||||||
|
static constexpr const char* DiffuseAnisotropyLevel = "MatDiffuseAnisotropyLevel";
|
||||||
|
static constexpr const char* DiffuseColor = "MatDiffuseColor";
|
||||||
|
static constexpr const char* DiffuseFilter = "MatDiffuseFilter";
|
||||||
|
static constexpr const char* DiffuseTexturePath = "MatDiffuseTexturePath";
|
||||||
|
static constexpr const char* DiffuseWrap = "MatDiffuseWrap";
|
||||||
|
static constexpr const char* DstBlend = "MatDstBlend";
|
||||||
|
static constexpr const char* EmissiveTexturePath = "MatEmissiveTexturePath";
|
||||||
|
static constexpr const char* FaceCulling = "MatFaceCulling";
|
||||||
|
static constexpr const char* FaceFilling = "MatFaceFilling";
|
||||||
|
static constexpr const char* FilePath = "MatFilePath";
|
||||||
|
static constexpr const char* HeightTexturePath = "MatHeightTexturePath";
|
||||||
|
static constexpr const char* Lighting = "MatLighting";
|
||||||
|
static constexpr const char* LineWidth = "MatLineWidth";
|
||||||
|
static constexpr const char* NormalTexturePath = "MatNormalTexturePath";
|
||||||
|
static constexpr const char* PointSize = "MatPointSize";
|
||||||
|
static constexpr const char* ScissorTest = "MatScissorTest";
|
||||||
|
static constexpr const char* Shininess = "MatShininess";
|
||||||
|
static constexpr const char* SpecularAnisotropyLevel = "MatSpecularAnisotropyLevel";
|
||||||
|
static constexpr const char* SpecularColor = "MatSpecularColor";
|
||||||
|
static constexpr const char* SpecularFilter = "MatSpecularFilter";
|
||||||
|
static constexpr const char* SpecularTexturePath = "MatSpecularTexturePath";
|
||||||
|
static constexpr const char* SpecularWrap = "MatSpecularWrap";
|
||||||
|
static constexpr const char* SrcBlend = "MatSrcBlend";
|
||||||
|
static constexpr const char* StencilCompare = "MatStencilCompare";
|
||||||
|
static constexpr const char* StencilFail = "MatStencilFail";
|
||||||
|
static constexpr const char* StencilMask = "MatStencilMask";
|
||||||
|
static constexpr const char* StencilPass = "MatStencilPass";
|
||||||
|
static constexpr const char* StencilReference = "MatStencilReference";
|
||||||
|
static constexpr const char* StencilTest = "MatStencilTest";
|
||||||
|
static constexpr const char* StencilZFail = "MatStencilZFail";
|
||||||
|
static constexpr const char* Transform = "MatTransform";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // NAZARA_MATERIALDATA_HPP
|
||||||
|
|
@ -93,7 +93,8 @@ namespace Nz
|
||||||
String GetAnimation() const;
|
String GetAnimation() const;
|
||||||
AnimationType GetAnimationType() const;
|
AnimationType GetAnimationType() const;
|
||||||
unsigned int GetJointCount() const;
|
unsigned int GetJointCount() const;
|
||||||
String GetMaterial(unsigned int index) const;
|
ParameterList& GetMaterialData(unsigned int index);
|
||||||
|
const ParameterList& GetMaterialData(unsigned int index) const;
|
||||||
unsigned int GetMaterialCount() const;
|
unsigned int GetMaterialCount() const;
|
||||||
Skeleton* GetSkeleton();
|
Skeleton* GetSkeleton();
|
||||||
const Skeleton* GetSkeleton() const;
|
const Skeleton* GetSkeleton() const;
|
||||||
|
|
@ -124,8 +125,8 @@ namespace Nz
|
||||||
void RemoveSubMesh(unsigned int index);
|
void RemoveSubMesh(unsigned int index);
|
||||||
|
|
||||||
void SetAnimation(const String& animationPath);
|
void SetAnimation(const String& animationPath);
|
||||||
void SetMaterial(unsigned int matIndex, const String& materialPath);
|
|
||||||
void SetMaterialCount(unsigned int matCount);
|
void SetMaterialCount(unsigned int matCount);
|
||||||
|
void SetMaterialData(unsigned int matIndex, ParameterList data);
|
||||||
|
|
||||||
void Transform(const Matrix4f& matrix);
|
void Transform(const Matrix4f& matrix);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,9 +3,11 @@
|
||||||
// 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/Graphics/Formats/MeshLoader.hpp>
|
#include <Nazara/Graphics/Formats/MeshLoader.hpp>
|
||||||
|
#include <Nazara/Core/ErrorFlags.hpp>
|
||||||
#include <Nazara/Graphics/Material.hpp>
|
#include <Nazara/Graphics/Material.hpp>
|
||||||
#include <Nazara/Graphics/Model.hpp>
|
#include <Nazara/Graphics/Model.hpp>
|
||||||
#include <Nazara/Graphics/SkeletalModel.hpp>
|
#include <Nazara/Graphics/SkeletalModel.hpp>
|
||||||
|
#include <Nazara/Utility/MaterialData.hpp>
|
||||||
#include <Nazara/Utility/Mesh.hpp>
|
#include <Nazara/Utility/Mesh.hpp>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <Nazara/Graphics/Debug.hpp>
|
#include <Nazara/Graphics/Debug.hpp>
|
||||||
|
|
@ -14,6 +16,33 @@ namespace Nz
|
||||||
{
|
{
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
void LoadMaterials(Model* model, const ModelParameters& parameters)
|
||||||
|
{
|
||||||
|
unsigned int matCount = model->GetMaterialCount();
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < matCount; ++i)
|
||||||
|
{
|
||||||
|
const ParameterList& matData = model->GetMesh()->GetMaterialData(i);
|
||||||
|
|
||||||
|
String filePath;
|
||||||
|
if (matData.GetStringParameter(MaterialData::FilePath, &filePath))
|
||||||
|
{
|
||||||
|
MaterialRef material = Material::New();
|
||||||
|
if (material->LoadFromFile(filePath, parameters.material))
|
||||||
|
model->SetMaterial(i, std::move(material));
|
||||||
|
else
|
||||||
|
NazaraWarning("Failed to load material from file " + String::Number(i));
|
||||||
|
}
|
||||||
|
else if (matData.HasParameter(MaterialData::CustomDefined))
|
||||||
|
{
|
||||||
|
MaterialRef material = Material::New();
|
||||||
|
material->BuildFromParameters(matData, parameters.material);
|
||||||
|
|
||||||
|
model->SetMaterial(i, std::move(material));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Ternary CheckStatic(Stream& stream, const ModelParameters& parameters)
|
Ternary CheckStatic(Stream& stream, const ModelParameters& parameters)
|
||||||
{
|
{
|
||||||
NazaraUnused(stream);
|
NazaraUnused(stream);
|
||||||
|
|
@ -46,22 +75,7 @@ namespace Nz
|
||||||
model->SetMesh(mesh);
|
model->SetMesh(mesh);
|
||||||
|
|
||||||
if (parameters.loadMaterials)
|
if (parameters.loadMaterials)
|
||||||
{
|
LoadMaterials(model, parameters);
|
||||||
unsigned int matCount = model->GetMaterialCount();
|
|
||||||
|
|
||||||
for (unsigned int i = 0; i < matCount; ++i)
|
|
||||||
{
|
|
||||||
String mat = mesh->GetMaterial(i);
|
|
||||||
if (!mat.IsEmpty())
|
|
||||||
{
|
|
||||||
MaterialRef material = Material::New();
|
|
||||||
if (material->LoadFromFile(mat, parameters.material))
|
|
||||||
model->SetMaterial(i, material);
|
|
||||||
else
|
|
||||||
NazaraWarning("Failed to load material #" + String::Number(i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -98,22 +112,7 @@ namespace Nz
|
||||||
model->SetMesh(mesh);
|
model->SetMesh(mesh);
|
||||||
|
|
||||||
if (parameters.loadMaterials)
|
if (parameters.loadMaterials)
|
||||||
{
|
LoadMaterials(model, parameters);
|
||||||
unsigned int matCount = model->GetMaterialCount();
|
|
||||||
|
|
||||||
for (unsigned int i = 0; i < matCount; ++i)
|
|
||||||
{
|
|
||||||
String mat = mesh->GetMaterial(i);
|
|
||||||
if (!mat.IsEmpty())
|
|
||||||
{
|
|
||||||
MaterialRef material = Material::New();
|
|
||||||
if (material->LoadFromFile(mat, parameters.material))
|
|
||||||
model->SetMaterial(i, material);
|
|
||||||
else
|
|
||||||
NazaraWarning("Failed to load material #" + String::Number(i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,6 @@
|
||||||
#include <Nazara/Graphics/SkyboxBackground.hpp>
|
#include <Nazara/Graphics/SkyboxBackground.hpp>
|
||||||
#include <Nazara/Graphics/Sprite.hpp>
|
#include <Nazara/Graphics/Sprite.hpp>
|
||||||
#include <Nazara/Graphics/Formats/MeshLoader.hpp>
|
#include <Nazara/Graphics/Formats/MeshLoader.hpp>
|
||||||
#include <Nazara/Graphics/Formats/OBJLoader.hpp>
|
|
||||||
#include <Nazara/Graphics/Formats/TextureLoader.hpp>
|
#include <Nazara/Graphics/Formats/TextureLoader.hpp>
|
||||||
#include <Nazara/Renderer/Renderer.hpp>
|
#include <Nazara/Renderer/Renderer.hpp>
|
||||||
#include <Nazara/Utility/Font.hpp>
|
#include <Nazara/Utility/Font.hpp>
|
||||||
|
|
@ -96,9 +95,6 @@ namespace Nz
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Loaders
|
|
||||||
Loaders::RegisterOBJ();
|
|
||||||
|
|
||||||
// Loaders génériques
|
// Loaders génériques
|
||||||
Loaders::RegisterMesh();
|
Loaders::RegisterMesh();
|
||||||
Loaders::RegisterTexture();
|
Loaders::RegisterTexture();
|
||||||
|
|
@ -176,7 +172,6 @@ namespace Nz
|
||||||
|
|
||||||
// Loaders
|
// Loaders
|
||||||
Loaders::UnregisterMesh();
|
Loaders::UnregisterMesh();
|
||||||
Loaders::UnregisterOBJ();
|
|
||||||
Loaders::UnregisterTexture();
|
Loaders::UnregisterTexture();
|
||||||
|
|
||||||
DeferredRenderTechnique::Uninitialize();
|
DeferredRenderTechnique::Uninitialize();
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <Nazara/Graphics/Material.hpp>
|
#include <Nazara/Graphics/Material.hpp>
|
||||||
|
#include <Nazara/Core/ErrorFlags.hpp>
|
||||||
#include <Nazara/Renderer/OpenGL.hpp>
|
#include <Nazara/Renderer/OpenGL.hpp>
|
||||||
#include <Nazara/Renderer/Renderer.hpp>
|
#include <Nazara/Renderer/Renderer.hpp>
|
||||||
#include <Nazara/Renderer/UberShaderPreprocessor.hpp>
|
#include <Nazara/Renderer/UberShaderPreprocessor.hpp>
|
||||||
|
|
@ -139,6 +140,166 @@ namespace Nz
|
||||||
return instance.shader;
|
return instance.shader;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Material::BuildFromParameters(const ParameterList& matData, const MaterialParams& matParams)
|
||||||
|
{
|
||||||
|
Color color;
|
||||||
|
bool isEnabled;
|
||||||
|
float fValue;
|
||||||
|
int iValue;
|
||||||
|
String path;
|
||||||
|
|
||||||
|
ErrorFlags errFlags(ErrorFlag_Silent | ErrorFlag_ThrowExceptionDisabled, true);
|
||||||
|
|
||||||
|
|
||||||
|
if (matData.GetFloatParameter(MaterialData::AlphaThreshold, &fValue))
|
||||||
|
SetAlphaThreshold(fValue);
|
||||||
|
|
||||||
|
if (matData.GetBooleanParameter(MaterialData::AlphaTest, &isEnabled))
|
||||||
|
EnableAlphaTest(isEnabled);
|
||||||
|
|
||||||
|
if (matData.GetColorParameter(MaterialData::AmbientColor, &color))
|
||||||
|
SetAmbientColor(color);
|
||||||
|
|
||||||
|
if (matData.GetIntegerParameter(MaterialData::DepthFunc, &iValue))
|
||||||
|
SetDepthFunc(static_cast<RendererComparison>(iValue));
|
||||||
|
|
||||||
|
if (matData.GetBooleanParameter(MaterialData::DepthSorting, &isEnabled))
|
||||||
|
EnableDepthSorting(isEnabled);
|
||||||
|
|
||||||
|
if (matData.GetColorParameter(MaterialData::DiffuseColor, &color))
|
||||||
|
SetDiffuseColor(color);
|
||||||
|
|
||||||
|
if (matData.GetIntegerParameter(MaterialData::DstBlend, &iValue))
|
||||||
|
SetDstBlend(static_cast<BlendFunc>(iValue));
|
||||||
|
|
||||||
|
if (matData.GetIntegerParameter(MaterialData::FaceCulling, &iValue))
|
||||||
|
SetFaceCulling(static_cast<FaceSide>(iValue));
|
||||||
|
|
||||||
|
if (matData.GetIntegerParameter(MaterialData::FaceFilling, &iValue))
|
||||||
|
SetFaceFilling(static_cast<FaceFilling>(iValue));
|
||||||
|
|
||||||
|
if (matData.GetBooleanParameter(MaterialData::Lighting, &isEnabled))
|
||||||
|
EnableLighting(isEnabled);
|
||||||
|
|
||||||
|
if (matData.GetFloatParameter(MaterialData::LineWidth, &fValue))
|
||||||
|
m_states.lineWidth = fValue;
|
||||||
|
|
||||||
|
if (matData.GetFloatParameter(MaterialData::PointSize, &fValue))
|
||||||
|
m_states.pointSize = fValue;
|
||||||
|
|
||||||
|
if (matData.GetColorParameter(MaterialData::SpecularColor, &color))
|
||||||
|
SetSpecularColor(color);
|
||||||
|
|
||||||
|
if (matData.GetFloatParameter(MaterialData::Shininess, &fValue))
|
||||||
|
SetShininess(fValue);
|
||||||
|
|
||||||
|
if (matData.GetIntegerParameter(MaterialData::SrcBlend, &iValue))
|
||||||
|
SetSrcBlend(static_cast<BlendFunc>(iValue));
|
||||||
|
|
||||||
|
if (matData.GetBooleanParameter(MaterialData::Transform, &isEnabled))
|
||||||
|
EnableTransform(isEnabled);
|
||||||
|
|
||||||
|
// RendererParameter
|
||||||
|
if (matData.GetBooleanParameter(MaterialData::Blending, &isEnabled))
|
||||||
|
Enable(RendererParameter_Blend, isEnabled);
|
||||||
|
|
||||||
|
if (matData.GetBooleanParameter(MaterialData::ColorWrite, &isEnabled))
|
||||||
|
Enable(RendererParameter_ColorWrite, isEnabled);
|
||||||
|
|
||||||
|
if (matData.GetBooleanParameter(MaterialData::DepthBuffer, &isEnabled))
|
||||||
|
Enable(RendererParameter_DepthBuffer, isEnabled);
|
||||||
|
|
||||||
|
if (matData.GetBooleanParameter(MaterialData::DepthWrite, &isEnabled))
|
||||||
|
Enable(RendererParameter_DepthWrite, isEnabled);
|
||||||
|
|
||||||
|
if (matData.GetBooleanParameter(MaterialData::FaceCulling, &isEnabled))
|
||||||
|
Enable(RendererParameter_FaceCulling, isEnabled);
|
||||||
|
|
||||||
|
if (matData.GetBooleanParameter(MaterialData::ScissorTest, &isEnabled))
|
||||||
|
Enable(RendererParameter_ScissorTest, isEnabled);
|
||||||
|
|
||||||
|
if (matData.GetBooleanParameter(MaterialData::StencilTest, &isEnabled))
|
||||||
|
Enable(RendererParameter_StencilTest, isEnabled);
|
||||||
|
|
||||||
|
// Samplers
|
||||||
|
if (matData.GetIntegerParameter(MaterialData::DiffuseAnisotropyLevel, &iValue))
|
||||||
|
m_diffuseSampler.SetAnisotropyLevel(static_cast<UInt8>(iValue));
|
||||||
|
|
||||||
|
if (matData.GetIntegerParameter(MaterialData::DiffuseFilter, &iValue))
|
||||||
|
m_diffuseSampler.SetFilterMode(static_cast<SamplerFilter>(iValue));
|
||||||
|
|
||||||
|
if (matData.GetIntegerParameter(MaterialData::DiffuseWrap, &iValue))
|
||||||
|
m_diffuseSampler.SetWrapMode(static_cast<SamplerWrap>(iValue));
|
||||||
|
|
||||||
|
if (matData.GetIntegerParameter(MaterialData::SpecularAnisotropyLevel, &iValue))
|
||||||
|
m_specularSampler.SetAnisotropyLevel(static_cast<UInt8>(iValue));
|
||||||
|
|
||||||
|
if (matData.GetIntegerParameter(MaterialData::SpecularFilter, &iValue))
|
||||||
|
m_specularSampler.SetFilterMode(static_cast<SamplerFilter>(iValue));
|
||||||
|
|
||||||
|
if (matData.GetIntegerParameter(MaterialData::SpecularWrap, &iValue))
|
||||||
|
m_specularSampler.SetWrapMode(static_cast<SamplerWrap>(iValue));
|
||||||
|
|
||||||
|
// Stencil
|
||||||
|
if (matData.GetIntegerParameter(MaterialData::StencilCompare, &iValue))
|
||||||
|
m_states.frontFace.stencilCompare = static_cast<RendererComparison>(iValue);
|
||||||
|
|
||||||
|
if (matData.GetIntegerParameter(MaterialData::StencilFail, &iValue))
|
||||||
|
m_states.frontFace.stencilFail = static_cast<StencilOperation>(iValue);
|
||||||
|
|
||||||
|
if (matData.GetIntegerParameter(MaterialData::StencilPass, &iValue))
|
||||||
|
m_states.frontFace.stencilPass = static_cast<StencilOperation>(iValue);
|
||||||
|
|
||||||
|
if (matData.GetIntegerParameter(MaterialData::StencilZFail, &iValue))
|
||||||
|
m_states.frontFace.stencilZFail = static_cast<StencilOperation>(iValue);
|
||||||
|
|
||||||
|
if (matData.GetIntegerParameter(MaterialData::StencilMask, &iValue))
|
||||||
|
m_states.frontFace.stencilMask = static_cast<UInt32>(iValue);
|
||||||
|
|
||||||
|
if (matData.GetIntegerParameter(MaterialData::StencilReference, &iValue))
|
||||||
|
m_states.frontFace.stencilReference = static_cast<unsigned int>(iValue);
|
||||||
|
|
||||||
|
// Stencil (back)
|
||||||
|
if (matData.GetIntegerParameter(MaterialData::BackFaceStencilCompare, &iValue))
|
||||||
|
m_states.backFace.stencilCompare = static_cast<RendererComparison>(iValue);
|
||||||
|
|
||||||
|
if (matData.GetIntegerParameter(MaterialData::BackFaceStencilFail, &iValue))
|
||||||
|
m_states.backFace.stencilFail = static_cast<StencilOperation>(iValue);
|
||||||
|
|
||||||
|
if (matData.GetIntegerParameter(MaterialData::BackFaceStencilPass, &iValue))
|
||||||
|
m_states.backFace.stencilPass = static_cast<StencilOperation>(iValue);
|
||||||
|
|
||||||
|
if (matData.GetIntegerParameter(MaterialData::BackFaceStencilZFail, &iValue))
|
||||||
|
m_states.backFace.stencilZFail = static_cast<StencilOperation>(iValue);
|
||||||
|
|
||||||
|
if (matData.GetIntegerParameter(MaterialData::BackFaceStencilMask, &iValue))
|
||||||
|
m_states.backFace.stencilMask = static_cast<UInt32>(iValue);
|
||||||
|
|
||||||
|
if (matData.GetIntegerParameter(MaterialData::BackFaceStencilReference, &iValue))
|
||||||
|
m_states.backFace.stencilReference = static_cast<unsigned int>(iValue);
|
||||||
|
|
||||||
|
// Textures
|
||||||
|
if (matParams.loadAlphaMap && matData.GetStringParameter(MaterialData::AlphaTexturePath, &path))
|
||||||
|
SetAlphaMap(path);
|
||||||
|
|
||||||
|
if (matParams.loadDiffuseMap && matData.GetStringParameter(MaterialData::DiffuseTexturePath, &path))
|
||||||
|
SetDiffuseMap(path);
|
||||||
|
|
||||||
|
if (matParams.loadEmissiveMap && matData.GetStringParameter(MaterialData::EmissiveTexturePath, &path))
|
||||||
|
SetEmissiveMap(path);
|
||||||
|
|
||||||
|
if (matParams.loadHeightMap && matData.GetStringParameter(MaterialData::HeightTexturePath, &path))
|
||||||
|
SetHeightMap(path);
|
||||||
|
|
||||||
|
if (matParams.loadNormalMap && matData.GetStringParameter(MaterialData::NormalTexturePath, &path))
|
||||||
|
SetNormalMap(path);
|
||||||
|
|
||||||
|
if (matParams.loadSpecularMap && matData.GetStringParameter(MaterialData::SpecularTexturePath, &path))
|
||||||
|
SetSpecularMap(path);
|
||||||
|
|
||||||
|
SetShader(matParams.shaderName);
|
||||||
|
}
|
||||||
|
|
||||||
void Material::Enable(RendererParameter renderParameter, bool enable)
|
void Material::Enable(RendererParameter renderParameter, bool enable)
|
||||||
{
|
{
|
||||||
#ifdef NAZARA_DEBUG
|
#ifdef NAZARA_DEBUG
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@
|
||||||
#include <Nazara/Math/Algorithm.hpp>
|
#include <Nazara/Math/Algorithm.hpp>
|
||||||
#include <Nazara/Math/Quaternion.hpp>
|
#include <Nazara/Math/Quaternion.hpp>
|
||||||
#include <Nazara/Utility/BufferMapper.hpp>
|
#include <Nazara/Utility/BufferMapper.hpp>
|
||||||
|
#include <Nazara/Utility/MaterialData.hpp>
|
||||||
#include <Nazara/Utility/Mesh.hpp>
|
#include <Nazara/Utility/Mesh.hpp>
|
||||||
#include <Nazara/Utility/StaticMesh.hpp>
|
#include <Nazara/Utility/StaticMesh.hpp>
|
||||||
#include <Nazara/Utility/Formats/MD2Constants.hpp>
|
#include <Nazara/Utility/Formats/MD2Constants.hpp>
|
||||||
|
|
@ -99,7 +100,11 @@ namespace Nz
|
||||||
for (unsigned int i = 0; i < header.num_skins; ++i)
|
for (unsigned int i = 0; i < header.num_skins; ++i)
|
||||||
{
|
{
|
||||||
stream.Read(skin, 68*sizeof(char));
|
stream.Read(skin, 68*sizeof(char));
|
||||||
mesh->SetMaterial(i, baseDir + skin);
|
|
||||||
|
ParameterList matData;
|
||||||
|
matData.SetParameter(MaterialData::FilePath, baseDir + skin);
|
||||||
|
|
||||||
|
mesh->SetMaterialData(i, std::move(matData));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
#include <Nazara/Utility/Formats/MD5MeshLoader.hpp>
|
#include <Nazara/Utility/Formats/MD5MeshLoader.hpp>
|
||||||
#include <Nazara/Utility/IndexIterator.hpp>
|
#include <Nazara/Utility/IndexIterator.hpp>
|
||||||
#include <Nazara/Utility/IndexMapper.hpp>
|
#include <Nazara/Utility/IndexMapper.hpp>
|
||||||
|
#include <Nazara/Utility/MaterialData.hpp>
|
||||||
#include <Nazara/Utility/SkeletalMesh.hpp>
|
#include <Nazara/Utility/SkeletalMesh.hpp>
|
||||||
#include <Nazara/Utility/StaticMesh.hpp>
|
#include <Nazara/Utility/StaticMesh.hpp>
|
||||||
#include <Nazara/Utility/Formats/MD5MeshParser.hpp>
|
#include <Nazara/Utility/Formats/MD5MeshParser.hpp>
|
||||||
|
|
@ -189,7 +190,10 @@ namespace Nz
|
||||||
vertexMapper.Unmap();
|
vertexMapper.Unmap();
|
||||||
|
|
||||||
// Material
|
// Material
|
||||||
mesh->SetMaterial(i, baseDir + md5Mesh.shader);
|
ParameterList matData;
|
||||||
|
matData.SetParameter(MaterialData::FilePath, baseDir + md5Mesh.shader);
|
||||||
|
|
||||||
|
mesh->SetMaterialData(i, std::move(matData));
|
||||||
|
|
||||||
// Submesh
|
// Submesh
|
||||||
SkeletalMeshRef subMesh = SkeletalMesh::New(mesh);
|
SkeletalMeshRef subMesh = SkeletalMesh::New(mesh);
|
||||||
|
|
@ -285,7 +289,10 @@ namespace Nz
|
||||||
mesh->AddSubMesh(subMesh);
|
mesh->AddSubMesh(subMesh);
|
||||||
|
|
||||||
// Material
|
// Material
|
||||||
mesh->SetMaterial(i, baseDir + md5Mesh.shader);
|
ParameterList matData;
|
||||||
|
matData.SetParameter(MaterialData::FilePath, baseDir + md5Mesh.shader);
|
||||||
|
|
||||||
|
mesh->SetMaterialData(i, std::move(matData));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parameters.center)
|
if (parameters.center)
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,13 @@
|
||||||
// Copyright (C) 2015 Jérôme Leclercq
|
// Copyright (C) 2016 Jérôme Leclercq
|
||||||
// This file is part of the "Nazara Engine - Graphics module"
|
// This file is part of the "Nazara Engine - Utility module"
|
||||||
// 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/Graphics/Formats/OBJLoader.hpp>
|
#include <Nazara/Utility/Formats/OBJLoader.hpp>
|
||||||
#include <Nazara/Core/Algorithm.hpp>
|
#include <Nazara/Core/Algorithm.hpp>
|
||||||
#include <Nazara/Core/ErrorFlags.hpp>
|
#include <Nazara/Core/ErrorFlags.hpp>
|
||||||
#include <Nazara/Graphics/Material.hpp>
|
|
||||||
#include <Nazara/Graphics/Model.hpp>
|
|
||||||
#include <Nazara/Utility/BufferMapper.hpp>
|
#include <Nazara/Utility/BufferMapper.hpp>
|
||||||
#include <Nazara/Utility/IndexMapper.hpp>
|
#include <Nazara/Utility/IndexMapper.hpp>
|
||||||
|
#include <Nazara/Utility/MaterialData.hpp>
|
||||||
#include <Nazara/Utility/Mesh.hpp>
|
#include <Nazara/Utility/Mesh.hpp>
|
||||||
#include <Nazara/Utility/StaticMesh.hpp>
|
#include <Nazara/Utility/StaticMesh.hpp>
|
||||||
#include <Nazara/Utility/Formats/MTLParser.hpp>
|
#include <Nazara/Utility/Formats/MTLParser.hpp>
|
||||||
|
|
@ -17,7 +16,7 @@
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <Nazara/Graphics/Debug.hpp>
|
#include <Nazara/Utility/Debug.hpp>
|
||||||
|
|
||||||
///TODO: N'avoir qu'un seul VertexBuffer communs à tous les meshes
|
///TODO: N'avoir qu'un seul VertexBuffer communs à tous les meshes
|
||||||
|
|
||||||
|
|
@ -30,7 +29,7 @@ namespace Nz
|
||||||
return (extension == "obj");
|
return (extension == "obj");
|
||||||
}
|
}
|
||||||
|
|
||||||
Ternary Check(Stream& stream, const ModelParameters& parameters)
|
Ternary Check(Stream& stream, const MeshParams& parameters)
|
||||||
{
|
{
|
||||||
NazaraUnused(stream);
|
NazaraUnused(stream);
|
||||||
|
|
||||||
|
|
@ -41,7 +40,7 @@ namespace Nz
|
||||||
return Ternary_Unknown;
|
return Ternary_Unknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LoadMaterials(Model* model, const String& filePath, const MaterialParams& parameters, const String* materials, const OBJParser::Mesh* meshes, unsigned int meshCount)
|
bool ParseMTL(Mesh* mesh, const String& filePath, const String* materials, const OBJParser::Mesh* meshes, unsigned int meshCount)
|
||||||
{
|
{
|
||||||
File file(filePath);
|
File file(filePath);
|
||||||
if (!file.Open(OpenMode_ReadOnly | OpenMode_Text))
|
if (!file.Open(OpenMode_ReadOnly | OpenMode_Text))
|
||||||
|
|
@ -57,7 +56,7 @@ namespace Nz
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unordered_map<String, MaterialRef> materialCache;
|
std::unordered_map<String, ParameterList> materialCache;
|
||||||
String baseDir = file.GetDirectory();
|
String baseDir = file.GetDirectory();
|
||||||
for (unsigned int i = 0; i < meshCount; ++i)
|
for (unsigned int i = 0; i < meshCount; ++i)
|
||||||
{
|
{
|
||||||
|
|
@ -72,8 +71,9 @@ namespace Nz
|
||||||
auto it = materialCache.find(matName);
|
auto it = materialCache.find(matName);
|
||||||
if (it == materialCache.end())
|
if (it == materialCache.end())
|
||||||
{
|
{
|
||||||
MaterialRef material = Material::New();
|
ParameterList data;
|
||||||
material->SetShader(parameters.shaderName);
|
|
||||||
|
data.SetParameter(MaterialData::CustomDefined);
|
||||||
|
|
||||||
UInt8 alphaValue = static_cast<UInt8>(mtlMat->alpha*255.f);
|
UInt8 alphaValue = static_cast<UInt8>(mtlMat->alpha*255.f);
|
||||||
|
|
||||||
|
|
@ -84,54 +84,40 @@ namespace Nz
|
||||||
diffuseColor.a = alphaValue;
|
diffuseColor.a = alphaValue;
|
||||||
specularColor.a = alphaValue;
|
specularColor.a = alphaValue;
|
||||||
|
|
||||||
material->SetAmbientColor(ambientColor);
|
data.SetParameter(MaterialData::AmbientColor, ambientColor);
|
||||||
material->SetDiffuseColor(diffuseColor);
|
data.SetParameter(MaterialData::DiffuseColor, diffuseColor);
|
||||||
material->SetSpecularColor(specularColor);
|
data.SetParameter(MaterialData::Shininess, mtlMat->shininess);
|
||||||
material->SetShininess(mtlMat->shininess);
|
data.SetParameter(MaterialData::SpecularColor, specularColor);
|
||||||
|
|
||||||
bool isTranslucent = (alphaValue != 255);
|
if (!mtlMat->alphaMap.IsEmpty())
|
||||||
|
data.SetParameter(MaterialData::AlphaTexturePath, baseDir + mtlMat->alphaMap);
|
||||||
|
|
||||||
if (parameters.loadAlphaMap && !mtlMat->alphaMap.IsEmpty())
|
if (!mtlMat->diffuseMap.IsEmpty())
|
||||||
|
data.SetParameter(MaterialData::DiffuseTexturePath, baseDir + mtlMat->diffuseMap);
|
||||||
|
|
||||||
|
if (!mtlMat->specularMap.IsEmpty())
|
||||||
|
data.SetParameter(MaterialData::SpecularTexturePath, baseDir + mtlMat->specularMap);
|
||||||
|
|
||||||
|
// 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 (material->SetAlphaMap(baseDir + mtlMat->alphaMap))
|
// Some default settings
|
||||||
isTranslucent = true; // Une alpha map indique de la transparence
|
data.SetParameter(MaterialData::Blending, true);
|
||||||
else
|
data.SetParameter(MaterialData::DepthWrite, true);
|
||||||
NazaraWarning("Failed to load alpha map (" + mtlMat->alphaMap + ')');
|
data.SetParameter(MaterialData::DstBlend, static_cast<int>(BlendFunc_InvSrcAlpha));
|
||||||
|
data.SetParameter(MaterialData::SrcBlend, static_cast<int>(BlendFunc_SrcAlpha));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parameters.loadDiffuseMap && !mtlMat->diffuseMap.IsEmpty())
|
it = materialCache.emplace(matName, std::move(data)).first;
|
||||||
{
|
|
||||||
if (!material->SetDiffuseMap(baseDir + mtlMat->diffuseMap))
|
|
||||||
NazaraWarning("Failed to load diffuse map (" + mtlMat->diffuseMap + ')');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (parameters.loadSpecularMap && !mtlMat->specularMap.IsEmpty())
|
|
||||||
{
|
|
||||||
if (!material->SetSpecularMap(baseDir + mtlMat->specularMap))
|
|
||||||
NazaraWarning("Failed to load specular map (" + mtlMat->specularMap + ')');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Si nous avons une alpha map ou des couleurs transparentes,
|
|
||||||
// nous devons configurer le matériau pour accepter la transparence au mieux
|
|
||||||
if (isTranslucent)
|
|
||||||
{
|
|
||||||
// On paramètre le matériau pour accepter la transparence au mieux
|
|
||||||
material->Enable(RendererParameter_Blend, true);
|
|
||||||
material->Enable(RendererParameter_DepthWrite, false);
|
|
||||||
material->SetDstBlend(BlendFunc_InvSrcAlpha);
|
|
||||||
material->SetSrcBlend(BlendFunc_SrcAlpha);
|
|
||||||
}
|
|
||||||
|
|
||||||
it = materialCache.emplace(matName, std::move(material)).first;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
model->SetMaterial(meshes[i].material, it->second);
|
mesh->SetMaterialData(meshes[i].material, it->second);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Load(Model* model, Stream& stream, const ModelParameters& parameters)
|
bool Load(Mesh* mesh, Stream& stream, const MeshParams& parameters)
|
||||||
{
|
{
|
||||||
int reservedVertexCount;
|
int reservedVertexCount;
|
||||||
if (!parameters.custom.GetIntegerParameter("NativeOBJLoader_VertexCount", &reservedVertexCount))
|
if (!parameters.custom.GetIntegerParameter("NativeOBJLoader_VertexCount", &reservedVertexCount))
|
||||||
|
|
@ -144,12 +130,7 @@ namespace Nz
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
MeshRef mesh = Mesh::New();
|
mesh->CreateStatic();
|
||||||
if (!mesh->CreateStatic()) // Ne devrait jamais échouer
|
|
||||||
{
|
|
||||||
NazaraInternalError("Failed to create mesh");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const String* materials = parser.GetMaterials();
|
const String* materials = parser.GetMaterials();
|
||||||
const Vector4f* positions = parser.GetPositions();
|
const Vector4f* positions = parser.GetPositions();
|
||||||
|
|
@ -160,8 +141,8 @@ namespace Nz
|
||||||
unsigned int meshCount = parser.GetMeshCount();
|
unsigned int meshCount = parser.GetMeshCount();
|
||||||
|
|
||||||
NazaraAssert(materials != nullptr && positions != nullptr && normals != nullptr &&
|
NazaraAssert(materials != nullptr && positions != nullptr && normals != nullptr &&
|
||||||
texCoords != nullptr && meshes != nullptr && meshCount > 0,
|
texCoords != nullptr && meshes != nullptr && meshCount > 0,
|
||||||
"Invalid OBJParser output");
|
"Invalid OBJParser output");
|
||||||
|
|
||||||
// Un conteneur temporaire pour contenir les indices de face avant triangulation
|
// Un conteneur temporaire pour contenir les indices de face avant triangulation
|
||||||
std::vector<unsigned int> faceIndices(3); // Comme il y aura au moins trois sommets
|
std::vector<unsigned int> faceIndices(3); // Comme il y aura au moins trois sommets
|
||||||
|
|
@ -197,8 +178,8 @@ namespace Nz
|
||||||
bool operator()(const OBJParser::FaceVertex& lhs, const OBJParser::FaceVertex& rhs) const
|
bool operator()(const OBJParser::FaceVertex& lhs, const OBJParser::FaceVertex& rhs) const
|
||||||
{
|
{
|
||||||
return lhs.normal == rhs.normal &&
|
return lhs.normal == rhs.normal &&
|
||||||
lhs.position == rhs.position &&
|
lhs.position == rhs.position &&
|
||||||
lhs.texCoord == rhs.texCoord;
|
lhs.texCoord == rhs.texCoord;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -230,8 +211,8 @@ namespace Nz
|
||||||
}
|
}
|
||||||
|
|
||||||
// Création des buffers
|
// Création des buffers
|
||||||
IndexBufferRef indexBuffer = IndexBuffer::New(vertexCount > std::numeric_limits<UInt16>::max(), indices.size(), parameters.mesh.storage, BufferUsage_Static);
|
IndexBufferRef indexBuffer = IndexBuffer::New(vertexCount > std::numeric_limits<UInt16>::max(), indices.size(), parameters.storage, BufferUsage_Static);
|
||||||
VertexBufferRef vertexBuffer = VertexBuffer::New(VertexDeclaration::Get(VertexLayout_XYZ_Normal_UV_Tangent), vertexCount, parameters.mesh.storage, BufferUsage_Static);
|
VertexBufferRef vertexBuffer = VertexBuffer::New(VertexDeclaration::Get(VertexLayout_XYZ_Normal_UV_Tangent), vertexCount, parameters.storage, BufferUsage_Static);
|
||||||
|
|
||||||
// Remplissage des indices
|
// Remplissage des indices
|
||||||
IndexMapper indexMapper(indexBuffer, BufferAccess_WriteOnly);
|
IndexMapper indexMapper(indexBuffer, BufferAccess_WriteOnly);
|
||||||
|
|
@ -254,7 +235,7 @@ namespace Nz
|
||||||
|
|
||||||
const Vector4f& vec = positions[vertexIndices.position];
|
const Vector4f& vec = positions[vertexIndices.position];
|
||||||
vertex.position.Set(vec.x, vec.y, vec.z);
|
vertex.position.Set(vec.x, vec.y, vec.z);
|
||||||
vertex.position *= parameters.mesh.scale/vec.w;
|
vertex.position *= parameters.scale/vec.w;
|
||||||
|
|
||||||
if (vertexIndices.normal >= 0)
|
if (vertexIndices.normal >= 0)
|
||||||
vertex.normal = normals[vertexIndices.normal];
|
vertex.normal = normals[vertexIndices.normal];
|
||||||
|
|
@ -264,7 +245,7 @@ namespace Nz
|
||||||
if (vertexIndices.texCoord >= 0)
|
if (vertexIndices.texCoord >= 0)
|
||||||
{
|
{
|
||||||
const Vector3f& uvw = texCoords[vertexIndices.texCoord];
|
const Vector3f& uvw = texCoords[vertexIndices.texCoord];
|
||||||
vertex.uv.Set(uvw.x, (parameters.mesh.flipUVs) ? 1.f - uvw.y : uvw.y); // Inversion des UVs si demandé
|
vertex.uv.Set(uvw.x, (parameters.flipUVs) ? 1.f - uvw.y : uvw.y); // Inversion des UVs si demandé
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
hasTexCoords = false;
|
hasTexCoords = false;
|
||||||
|
|
@ -279,7 +260,7 @@ namespace Nz
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parameters.mesh.optimizeIndexBuffers)
|
if (parameters.optimizeIndexBuffers)
|
||||||
indexBuffer->Optimize();
|
indexBuffer->Optimize();
|
||||||
|
|
||||||
subMesh->GenerateAABB();
|
subMesh->GenerateAABB();
|
||||||
|
|
@ -299,17 +280,15 @@ namespace Nz
|
||||||
}
|
}
|
||||||
mesh->SetMaterialCount(parser.GetMaterialCount());
|
mesh->SetMaterialCount(parser.GetMaterialCount());
|
||||||
|
|
||||||
if (parameters.mesh.center)
|
if (parameters.center)
|
||||||
mesh->Recenter();
|
mesh->Recenter();
|
||||||
|
|
||||||
model->SetMesh(mesh);
|
|
||||||
|
|
||||||
// On charge les matériaux si demandé
|
// On charge les matériaux si demandé
|
||||||
String mtlLib = parser.GetMtlLib();
|
String mtlLib = parser.GetMtlLib();
|
||||||
if (parameters.loadMaterials && !mtlLib.IsEmpty())
|
if (!mtlLib.IsEmpty())
|
||||||
{
|
{
|
||||||
ErrorFlags flags(ErrorFlag_ThrowExceptionDisabled);
|
ErrorFlags flags(ErrorFlag_ThrowExceptionDisabled);
|
||||||
LoadMaterials(model, stream.GetDirectory() + mtlLib, parameters.material, materials, meshes, meshCount);
|
ParseMTL(mesh, stream.GetDirectory() + mtlLib, materials, meshes, meshCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -320,12 +299,12 @@ namespace Nz
|
||||||
{
|
{
|
||||||
void RegisterOBJ()
|
void RegisterOBJ()
|
||||||
{
|
{
|
||||||
ModelLoader::RegisterLoader(IsSupported, Check, Load);
|
MeshLoader::RegisterLoader(IsSupported, Check, Load);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UnregisterOBJ()
|
void UnregisterOBJ()
|
||||||
{
|
{
|
||||||
ModelLoader::UnregisterLoader(IsSupported, Check, Load);
|
MeshLoader::UnregisterLoader(IsSupported, Check, Load);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -52,11 +52,11 @@ namespace Nz
|
||||||
{
|
{
|
||||||
MeshImpl()
|
MeshImpl()
|
||||||
{
|
{
|
||||||
materials.resize(1); // Un matériau par défaut
|
materialData.resize(1); // Un matériau par défaut
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unordered_map<String, unsigned int> subMeshMap;
|
std::unordered_map<String, unsigned int> subMeshMap;
|
||||||
std::vector<String> materials;
|
std::vector<ParameterList> materialData;
|
||||||
std::vector<SubMeshRef> subMeshes;
|
std::vector<SubMeshRef> subMeshes;
|
||||||
AnimationType animationType;
|
AnimationType animationType;
|
||||||
Boxf aabb;
|
Boxf aabb;
|
||||||
|
|
@ -75,93 +75,36 @@ namespace Nz
|
||||||
|
|
||||||
void Mesh::AddSubMesh(SubMesh* subMesh)
|
void Mesh::AddSubMesh(SubMesh* subMesh)
|
||||||
{
|
{
|
||||||
#if NAZARA_UTILITY_SAFE
|
NazaraAssert(m_impl, "Mesh should be created first");
|
||||||
if (!m_impl)
|
NazaraAssert(subMesh, "Invalid submesh");
|
||||||
{
|
NazaraAssert(subMesh->GetAnimationType() == m_impl->animationType, "Submesh animation type doesn't match mesh animation type");
|
||||||
NazaraError("Mesh not created");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!subMesh)
|
|
||||||
{
|
|
||||||
NazaraError("Invalid submesh");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (subMesh->GetAnimationType() != m_impl->animationType)
|
|
||||||
{
|
|
||||||
NazaraError("Submesh animation type must match mesh animation type");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
m_impl->aabbUpdated = false; // On invalide l'AABB
|
|
||||||
m_impl->subMeshes.push_back(subMesh);
|
m_impl->subMeshes.push_back(subMesh);
|
||||||
|
|
||||||
|
InvalidateAABB();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mesh::AddSubMesh(const String& identifier, SubMesh* subMesh)
|
void Mesh::AddSubMesh(const String& identifier, SubMesh* subMesh)
|
||||||
{
|
{
|
||||||
#if NAZARA_UTILITY_SAFE
|
NazaraAssert(m_impl, "Mesh should be created first");
|
||||||
if (!m_impl)
|
NazaraAssert(!identifier.IsEmpty(), "Identifier is empty");
|
||||||
{
|
NazaraAssert(m_impl->subMeshMap.find(identifier) == m_impl->subMeshMap.end(), "SubMesh identifier \"" + identifier + "\" is already in use");
|
||||||
NazaraError("Mesh not created");
|
NazaraAssert(subMesh, "Invalid submesh");
|
||||||
return;
|
NazaraAssert(subMesh->GetAnimationType() == m_impl->animationType, "Submesh animation type doesn't match mesh animation type");
|
||||||
}
|
|
||||||
|
|
||||||
if (identifier.IsEmpty())
|
|
||||||
{
|
|
||||||
NazaraError("Identifier is empty");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto it = m_impl->subMeshMap.find(identifier);
|
|
||||||
if (it != m_impl->subMeshMap.end())
|
|
||||||
{
|
|
||||||
NazaraError("SubMesh identifier \"" + identifier + "\" is already used");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!subMesh)
|
|
||||||
{
|
|
||||||
NazaraError("Invalid submesh");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_impl->animationType != subMesh->GetAnimationType())
|
|
||||||
{
|
|
||||||
NazaraError("Submesh animation type must match mesh animation type");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int index = m_impl->subMeshes.size();
|
int index = m_impl->subMeshes.size();
|
||||||
|
|
||||||
m_impl->aabbUpdated = false; // On invalide l'AABB
|
|
||||||
m_impl->subMeshes.push_back(subMesh);
|
m_impl->subMeshes.push_back(subMesh);
|
||||||
m_impl->subMeshMap[identifier] = index;
|
m_impl->subMeshMap[identifier] = index;
|
||||||
|
|
||||||
|
InvalidateAABB();
|
||||||
}
|
}
|
||||||
|
|
||||||
SubMesh* Mesh::BuildSubMesh(const Primitive& primitive, const MeshParams& params)
|
SubMesh* Mesh::BuildSubMesh(const Primitive& primitive, const MeshParams& params)
|
||||||
{
|
{
|
||||||
#if NAZARA_UTILITY_SAFE
|
NazaraAssert(m_impl, "Mesh should be created first");
|
||||||
if (!m_impl)
|
NazaraAssert(m_impl->animationType == AnimationType_Static, "Submesh building only works for static meshes");
|
||||||
{
|
NazaraAssert(params.IsValid(), "Invalid parameters");
|
||||||
NazaraError("Mesh not created");
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_impl->animationType != AnimationType_Static)
|
|
||||||
{
|
|
||||||
NazaraError("Mesh must be static");
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!params.IsValid())
|
|
||||||
{
|
|
||||||
NazaraError("Parameters must be valid");
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Boxf aabb;
|
Boxf aabb;
|
||||||
IndexBufferRef indexBuffer;
|
IndexBufferRef indexBuffer;
|
||||||
|
|
@ -333,17 +276,7 @@ namespace Nz
|
||||||
|
|
||||||
void Mesh::BuildSubMeshes(const PrimitiveList& list, const MeshParams& params)
|
void Mesh::BuildSubMeshes(const PrimitiveList& list, const MeshParams& params)
|
||||||
{
|
{
|
||||||
unsigned int primitiveCount = list.GetSize();
|
for (unsigned int i = 0; i < list.GetSize(); ++i)
|
||||||
|
|
||||||
#if NAZARA_UTILITY_SAFE
|
|
||||||
if (primitiveCount == 0)
|
|
||||||
{
|
|
||||||
NazaraError("PrimitiveList must have at least one primitive");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
for (unsigned int i = 0; i < primitiveCount; ++i)
|
|
||||||
BuildSubMesh(list.GetPrimitive(i), params);
|
BuildSubMesh(list.GetPrimitive(i), params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -351,18 +284,17 @@ namespace Nz
|
||||||
{
|
{
|
||||||
Destroy();
|
Destroy();
|
||||||
|
|
||||||
m_impl = new MeshImpl;
|
std::unique_ptr<MeshImpl> impl(new MeshImpl);
|
||||||
m_impl->animationType = AnimationType_Skeletal;
|
impl->animationType = AnimationType_Skeletal;
|
||||||
m_impl->jointCount = jointCount;
|
impl->jointCount = jointCount;
|
||||||
if (!m_impl->skeleton.Create(jointCount))
|
if (!impl->skeleton.Create(jointCount))
|
||||||
{
|
{
|
||||||
delete m_impl;
|
|
||||||
m_impl = nullptr;
|
|
||||||
|
|
||||||
NazaraError("Failed to create skeleton");
|
NazaraError("Failed to create skeleton");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_impl = impl.release();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -389,13 +321,7 @@ namespace Nz
|
||||||
|
|
||||||
void Mesh::GenerateNormals()
|
void Mesh::GenerateNormals()
|
||||||
{
|
{
|
||||||
#if NAZARA_UTILITY_SAFE
|
NazaraAssert(m_impl, "Mesh should be created first");
|
||||||
if (!m_impl)
|
|
||||||
{
|
|
||||||
NazaraError("Mesh not created");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
for (SubMesh* subMesh : m_impl->subMeshes)
|
for (SubMesh* subMesh : m_impl->subMeshes)
|
||||||
subMesh->GenerateNormals();
|
subMesh->GenerateNormals();
|
||||||
|
|
@ -403,13 +329,7 @@ namespace Nz
|
||||||
|
|
||||||
void Mesh::GenerateNormalsAndTangents()
|
void Mesh::GenerateNormalsAndTangents()
|
||||||
{
|
{
|
||||||
#if NAZARA_UTILITY_SAFE
|
NazaraAssert(m_impl, "Mesh should be created first");
|
||||||
if (!m_impl)
|
|
||||||
{
|
|
||||||
NazaraError("Mesh not created");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
for (SubMesh* subMesh : m_impl->subMeshes)
|
for (SubMesh* subMesh : m_impl->subMeshes)
|
||||||
subMesh->GenerateNormalsAndTangents();
|
subMesh->GenerateNormalsAndTangents();
|
||||||
|
|
@ -417,13 +337,7 @@ namespace Nz
|
||||||
|
|
||||||
void Mesh::GenerateTangents()
|
void Mesh::GenerateTangents()
|
||||||
{
|
{
|
||||||
#if NAZARA_UTILITY_SAFE
|
NazaraAssert(m_impl, "Mesh should be created first");
|
||||||
if (!m_impl)
|
|
||||||
{
|
|
||||||
NazaraError("Mesh not created");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
for (SubMesh* subMesh : m_impl->subMeshes)
|
for (SubMesh* subMesh : m_impl->subMeshes)
|
||||||
subMesh->GenerateTangents();
|
subMesh->GenerateTangents();
|
||||||
|
|
@ -431,15 +345,7 @@ namespace Nz
|
||||||
|
|
||||||
const Boxf& Mesh::GetAABB() const
|
const Boxf& Mesh::GetAABB() const
|
||||||
{
|
{
|
||||||
#if NAZARA_UTILITY_SAFE
|
NazaraAssert(m_impl, "Mesh should be created first");
|
||||||
if (!m_impl)
|
|
||||||
{
|
|
||||||
NazaraError("Mesh not created");
|
|
||||||
|
|
||||||
static Boxf dummy;
|
|
||||||
return dummy;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!m_impl->aabbUpdated)
|
if (!m_impl->aabbUpdated)
|
||||||
{
|
{
|
||||||
|
|
@ -461,248 +367,121 @@ namespace Nz
|
||||||
|
|
||||||
String Mesh::GetAnimation() const
|
String Mesh::GetAnimation() const
|
||||||
{
|
{
|
||||||
#if NAZARA_UTILITY_SAFE
|
NazaraAssert(m_impl, "Mesh should be created first");
|
||||||
if (!m_impl)
|
|
||||||
{
|
|
||||||
NazaraError("Mesh not created");
|
|
||||||
return String();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return m_impl->animationPath;
|
return m_impl->animationPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
AnimationType Mesh::GetAnimationType() const
|
AnimationType Mesh::GetAnimationType() const
|
||||||
{
|
{
|
||||||
#if NAZARA_UTILITY_SAFE
|
NazaraAssert(m_impl, "Mesh should be created first");
|
||||||
if (!m_impl)
|
|
||||||
{
|
|
||||||
NazaraError("Mesh not created");
|
|
||||||
return AnimationType_Static;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return m_impl->animationType;
|
return m_impl->animationType;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int Mesh::GetJointCount() const
|
unsigned int Mesh::GetJointCount() const
|
||||||
{
|
{
|
||||||
#if NAZARA_UTILITY_SAFE
|
NazaraAssert(m_impl, "Mesh should be created first");
|
||||||
if (!m_impl)
|
NazaraAssert(m_impl->animationType == AnimationType_Skeletal, "Mesh is not skeletal");
|
||||||
{
|
|
||||||
NazaraError("Mesh not created");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_impl->animationType != AnimationType_Skeletal)
|
|
||||||
{
|
|
||||||
NazaraError("Mesh's animation type is not skeletal");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return m_impl->jointCount;
|
return m_impl->jointCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
String Mesh::GetMaterial(unsigned int index) const
|
ParameterList& Mesh::GetMaterialData(unsigned int index)
|
||||||
{
|
{
|
||||||
#if NAZARA_UTILITY_SAFE
|
NazaraAssert(m_impl, "Mesh should be created first");
|
||||||
if (!m_impl)
|
NazaraAssert(index < m_impl->materialData.size(), "Material index out of range");
|
||||||
{
|
|
||||||
NazaraError("Mesh not created");
|
|
||||||
return String();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (index >= m_impl->materials.size())
|
return m_impl->materialData[index];
|
||||||
{
|
}
|
||||||
NazaraError("Material index out of range (" + String::Number(index) + " >= " + String::Number(m_impl->materials.size()) + ')');
|
|
||||||
return String();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return m_impl->materials[index];
|
const ParameterList& Mesh::GetMaterialData(unsigned int index) const
|
||||||
|
{
|
||||||
|
NazaraAssert(m_impl, "Mesh should be created first");
|
||||||
|
NazaraAssert(index < m_impl->materialData.size(), "Material index out of range");
|
||||||
|
|
||||||
|
return m_impl->materialData[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int Mesh::GetMaterialCount() const
|
unsigned int Mesh::GetMaterialCount() const
|
||||||
{
|
{
|
||||||
#if NAZARA_UTILITY_SAFE
|
NazaraAssert(m_impl, "Mesh should be created first");
|
||||||
if (!m_impl)
|
|
||||||
{
|
|
||||||
NazaraError("Mesh not created");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return m_impl->materials.size();
|
return m_impl->materialData.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
Skeleton* Mesh::GetSkeleton()
|
Skeleton* Mesh::GetSkeleton()
|
||||||
{
|
{
|
||||||
#if NAZARA_UTILITY_SAFE
|
NazaraAssert(m_impl, "Mesh should be created first");
|
||||||
if (!m_impl)
|
NazaraAssert(m_impl->animationType == AnimationType_Skeletal, "Mesh is not skeletal");
|
||||||
{
|
|
||||||
NazaraError("Animation not created");
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_impl->animationType != AnimationType_Skeletal)
|
|
||||||
{
|
|
||||||
NazaraError("Mesh's animation type is not skeletal");
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return &m_impl->skeleton;
|
return &m_impl->skeleton;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Skeleton* Mesh::GetSkeleton() const
|
const Skeleton* Mesh::GetSkeleton() const
|
||||||
{
|
{
|
||||||
#if NAZARA_UTILITY_SAFE
|
NazaraAssert(m_impl, "Mesh should be created first");
|
||||||
if (!m_impl)
|
NazaraAssert(m_impl->animationType == AnimationType_Skeletal, "Mesh is not skeletal");
|
||||||
{
|
|
||||||
NazaraError("Animation not created");
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_impl->animationType != AnimationType_Skeletal)
|
|
||||||
{
|
|
||||||
NazaraError("Mesh's animation type is not skeletal");
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return &m_impl->skeleton;
|
return &m_impl->skeleton;
|
||||||
}
|
}
|
||||||
|
|
||||||
SubMesh* Mesh::GetSubMesh(const String& identifier)
|
SubMesh* Mesh::GetSubMesh(const String& identifier)
|
||||||
{
|
{
|
||||||
#if NAZARA_UTILITY_SAFE
|
NazaraAssert(m_impl, "Mesh should be created first");
|
||||||
if (!m_impl)
|
|
||||||
{
|
|
||||||
NazaraError("Mesh not created");
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
auto it = m_impl->subMeshMap.find(identifier);
|
auto it = m_impl->subMeshMap.find(identifier);
|
||||||
|
NazaraAssert(it != m_impl->subMeshMap.end(), "SubMesh " + identifier + " not found");
|
||||||
#if NAZARA_UTILITY_SAFE
|
|
||||||
if (it == m_impl->subMeshMap.end())
|
|
||||||
{
|
|
||||||
NazaraError("SubMesh not found");
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return m_impl->subMeshes[it->second];
|
return m_impl->subMeshes[it->second];
|
||||||
}
|
}
|
||||||
|
|
||||||
SubMesh* Mesh::GetSubMesh(unsigned int index)
|
SubMesh* Mesh::GetSubMesh(unsigned int index)
|
||||||
{
|
{
|
||||||
#if NAZARA_UTILITY_SAFE
|
NazaraAssert(m_impl, "Mesh should be created first");
|
||||||
if (!m_impl)
|
NazaraAssert(index < m_impl->subMeshes.size(), "Submesh index out of range");
|
||||||
{
|
|
||||||
NazaraError("Mesh not created");
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (index >= m_impl->subMeshes.size())
|
|
||||||
{
|
|
||||||
NazaraError("SubMesh index out of range (" + String::Number(index) + " >= " + String::Number(m_impl->subMeshes.size()) + ')');
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return m_impl->subMeshes[index];
|
return m_impl->subMeshes[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
const SubMesh* Mesh::GetSubMesh(const String& identifier) const
|
const SubMesh* Mesh::GetSubMesh(const String& identifier) const
|
||||||
{
|
{
|
||||||
#if NAZARA_UTILITY_SAFE
|
NazaraAssert(m_impl, "Mesh should be created first");
|
||||||
if (!m_impl)
|
|
||||||
{
|
|
||||||
NazaraError("Mesh not created");
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
auto it = m_impl->subMeshMap.find(identifier);
|
auto it = m_impl->subMeshMap.find(identifier);
|
||||||
|
NazaraAssert(it != m_impl->subMeshMap.end(), "SubMesh " + identifier + " not found");
|
||||||
#if NAZARA_UTILITY_SAFE
|
|
||||||
if (it == m_impl->subMeshMap.end())
|
|
||||||
{
|
|
||||||
NazaraError("SubMesh not found");
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return m_impl->subMeshes[it->second];
|
return m_impl->subMeshes[it->second];
|
||||||
}
|
}
|
||||||
|
|
||||||
const SubMesh* Mesh::GetSubMesh(unsigned int index) const
|
const SubMesh* Mesh::GetSubMesh(unsigned int index) const
|
||||||
{
|
{
|
||||||
#if NAZARA_UTILITY_SAFE
|
NazaraAssert(m_impl, "Mesh should be created first");
|
||||||
if (!m_impl)
|
NazaraAssert(index < m_impl->subMeshes.size(), "Submesh index out of range");
|
||||||
{
|
|
||||||
NazaraError("Mesh not created");
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (index >= m_impl->subMeshes.size())
|
|
||||||
{
|
|
||||||
NazaraError("SubMesh index out of range (" + String::Number(index) + " >= " + String::Number(m_impl->subMeshes.size()) + ')');
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return m_impl->subMeshes[index];
|
return m_impl->subMeshes[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int Mesh::GetSubMeshCount() const
|
unsigned int Mesh::GetSubMeshCount() const
|
||||||
{
|
{
|
||||||
#if NAZARA_UTILITY_SAFE
|
NazaraAssert(m_impl, "Mesh should be created first");
|
||||||
if (!m_impl)
|
|
||||||
{
|
|
||||||
NazaraError("Mesh not created");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return m_impl->subMeshes.size();
|
return m_impl->subMeshes.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
int Mesh::GetSubMeshIndex(const String& identifier) const
|
int Mesh::GetSubMeshIndex(const String& identifier) const
|
||||||
{
|
{
|
||||||
#if NAZARA_UTILITY_SAFE
|
NazaraAssert(m_impl, "Mesh should be created first");
|
||||||
if (!m_impl)
|
|
||||||
{
|
|
||||||
NazaraError("Mesh not created");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
auto it = m_impl->subMeshMap.find(identifier);
|
auto it = m_impl->subMeshMap.find(identifier);
|
||||||
|
NazaraAssert(it != m_impl->subMeshMap.end(), "SubMesh " + identifier + " not found");
|
||||||
#if NAZARA_UTILITY_SAFE
|
|
||||||
if (it == m_impl->subMeshMap.end())
|
|
||||||
{
|
|
||||||
NazaraError("SubMesh not found");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return it->second;
|
return it->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int Mesh::GetTriangleCount() const
|
unsigned int Mesh::GetTriangleCount() const
|
||||||
{
|
{
|
||||||
#if NAZARA_UTILITY_SAFE
|
NazaraAssert(m_impl, "Mesh should be created first");
|
||||||
if (!m_impl)
|
|
||||||
{
|
|
||||||
NazaraError("Mesh not created");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
unsigned int triangleCount = 0;
|
unsigned int triangleCount = 0;
|
||||||
for (SubMesh* subMesh : m_impl->subMeshes)
|
for (SubMesh* subMesh : m_impl->subMeshes)
|
||||||
|
|
@ -713,13 +492,7 @@ namespace Nz
|
||||||
|
|
||||||
unsigned int Mesh::GetVertexCount() const
|
unsigned int Mesh::GetVertexCount() const
|
||||||
{
|
{
|
||||||
#if NAZARA_UTILITY_SAFE
|
NazaraAssert(m_impl, "Mesh should be created first");
|
||||||
if (!m_impl)
|
|
||||||
{
|
|
||||||
NazaraError("Mesh not created");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
unsigned int vertexCount = 0;
|
unsigned int vertexCount = 0;
|
||||||
for (SubMesh* subMesh : m_impl->subMeshes)
|
for (SubMesh* subMesh : m_impl->subMeshes)
|
||||||
|
|
@ -730,52 +503,28 @@ namespace Nz
|
||||||
|
|
||||||
void Mesh::InvalidateAABB() const
|
void Mesh::InvalidateAABB() const
|
||||||
{
|
{
|
||||||
#if NAZARA_UTILITY_SAFE
|
NazaraAssert(m_impl, "Mesh should be created first");
|
||||||
if (!m_impl)
|
|
||||||
{
|
|
||||||
NazaraError("Mesh not created");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
m_impl->aabbUpdated = false;
|
m_impl->aabbUpdated = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Mesh::HasSubMesh(const String& identifier) const
|
bool Mesh::HasSubMesh(const String& identifier) const
|
||||||
{
|
{
|
||||||
#if NAZARA_UTILITY_SAFE
|
NazaraAssert(m_impl, "Mesh should be created first");
|
||||||
if (!m_impl)
|
|
||||||
{
|
|
||||||
NazaraError("Mesh not created");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return m_impl->subMeshMap.find(identifier) != m_impl->subMeshMap.end();
|
return m_impl->subMeshMap.find(identifier) != m_impl->subMeshMap.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Mesh::HasSubMesh(unsigned int index) const
|
bool Mesh::HasSubMesh(unsigned int index) const
|
||||||
{
|
{
|
||||||
#if NAZARA_UTILITY_SAFE
|
NazaraAssert(m_impl, "Mesh should be created first");
|
||||||
if (!m_impl)
|
|
||||||
{
|
|
||||||
NazaraError("Mesh not created");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return index < m_impl->subMeshes.size();
|
return index < m_impl->subMeshes.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Mesh::IsAnimable() const
|
bool Mesh::IsAnimable() const
|
||||||
{
|
{
|
||||||
#if NAZARA_UTILITY_SAFE
|
NazaraAssert(m_impl, "Mesh should be created first");
|
||||||
if (!m_impl)
|
|
||||||
{
|
|
||||||
NazaraError("Mesh not created");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return m_impl->animationType != AnimationType_Static;
|
return m_impl->animationType != AnimationType_Static;
|
||||||
}
|
}
|
||||||
|
|
@ -802,21 +551,10 @@ namespace Nz
|
||||||
|
|
||||||
void Mesh::Recenter()
|
void Mesh::Recenter()
|
||||||
{
|
{
|
||||||
#if NAZARA_UTILITY_SAFE
|
NazaraAssert(m_impl, "Mesh should be created first");
|
||||||
if (!m_impl)
|
NazaraAssert(m_impl->animationType == AnimationType_Static, "Mesh is not static");
|
||||||
{
|
|
||||||
NazaraError("Mesh not created");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_impl->animationType != AnimationType_Static)
|
// The center of our mesh is the center of our *global* AABB
|
||||||
{
|
|
||||||
NazaraError("Mesh must be static");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Le centre de notre mesh est le centre de l'AABB *globale*
|
|
||||||
Vector3f center = GetAABB().GetCenter();
|
Vector3f center = GetAABB().GetCenter();
|
||||||
|
|
||||||
for (SubMesh* subMesh : m_impl->subMeshes)
|
for (SubMesh* subMesh : m_impl->subMeshes)
|
||||||
|
|
@ -833,119 +571,62 @@ namespace Nz
|
||||||
vertices++;
|
vertices++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// l'AABB ne change pas de dimensions mais seulement de position, appliquons-lui le même procédé
|
// Our AABB doesn't change shape, only position
|
||||||
Boxf aabb = staticMesh->GetAABB();
|
Boxf aabb = staticMesh->GetAABB();
|
||||||
aabb.Translate(-center);
|
aabb.Translate(-center);
|
||||||
|
|
||||||
staticMesh->SetAABB(aabb);
|
staticMesh->SetAABB(aabb);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Il ne faut pas oublier d'invalider notre AABB
|
InvalidateAABB();
|
||||||
m_impl->aabbUpdated = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mesh::RemoveSubMesh(const String& identifier)
|
void Mesh::RemoveSubMesh(const String& identifier)
|
||||||
{
|
{
|
||||||
#if NAZARA_UTILITY_SAFE
|
unsigned int index = GetSubMeshIndex(identifier);
|
||||||
if (!m_impl)
|
|
||||||
{
|
|
||||||
NazaraError("Mesh not created");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto it = m_impl->subMeshMap.find(identifier);
|
|
||||||
if (it == m_impl->subMeshMap.end())
|
|
||||||
{
|
|
||||||
NazaraError("SubMesh not found");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int index = it->second;
|
|
||||||
#else
|
|
||||||
unsigned int index = m_impl->subMeshMap[identifier];
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// On déplace l'itérateur du début d'une distance de x
|
// On déplace l'itérateur du début d'une distance de x
|
||||||
auto it2 = m_impl->subMeshes.begin();
|
auto it2 = m_impl->subMeshes.begin();
|
||||||
std::advance(it2, index);
|
std::advance(it2, index);
|
||||||
m_impl->subMeshes.erase(it2);
|
m_impl->subMeshes.erase(it2);
|
||||||
|
|
||||||
m_impl->aabbUpdated = false; // On invalide l'AABB
|
InvalidateAABB();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mesh::RemoveSubMesh(unsigned int index)
|
void Mesh::RemoveSubMesh(unsigned int index)
|
||||||
{
|
{
|
||||||
#if NAZARA_UTILITY_SAFE
|
NazaraAssert(m_impl, "Mesh should be created first");
|
||||||
if (!m_impl)
|
NazaraAssert(index < m_impl->subMeshes.size(), "Submesh index out of range");
|
||||||
{
|
|
||||||
NazaraError("Mesh not created");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (index >= m_impl->subMeshes.size())
|
|
||||||
{
|
|
||||||
NazaraError("SubMesh index out of range (" + String::Number(index) + " >= " + String::Number(m_impl->subMeshes.size()) + ')');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// On déplace l'itérateur du début de x
|
// On déplace l'itérateur du début de x
|
||||||
auto it = m_impl->subMeshes.begin();
|
auto it = m_impl->subMeshes.begin();
|
||||||
std::advance(it, index);
|
std::advance(it, index);
|
||||||
m_impl->subMeshes.erase(it);
|
m_impl->subMeshes.erase(it);
|
||||||
|
|
||||||
m_impl->aabbUpdated = false; // On invalide l'AABB
|
InvalidateAABB();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mesh::SetAnimation(const String& animationPath)
|
void Mesh::SetAnimation(const String& animationPath)
|
||||||
{
|
{
|
||||||
#if NAZARA_UTILITY_SAFE
|
NazaraAssert(m_impl, "Mesh should be created first");
|
||||||
if (!m_impl)
|
|
||||||
{
|
|
||||||
NazaraError("Mesh not created");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
m_impl->animationPath = animationPath;
|
m_impl->animationPath = animationPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mesh::SetMaterial(unsigned int matIndex, const String& materialPath)
|
void Mesh::SetMaterialData(unsigned int matIndex, ParameterList data)
|
||||||
{
|
{
|
||||||
#if NAZARA_UTILITY_SAFE
|
NazaraAssert(m_impl, "Mesh should be created first");
|
||||||
if (!m_impl)
|
NazaraAssert(matIndex < m_impl->materialData.size(), "Material index out of range");
|
||||||
{
|
|
||||||
NazaraError("Mesh not created");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (matIndex >= m_impl->materials.size())
|
m_impl->materialData[matIndex] = std::move(data);
|
||||||
{
|
|
||||||
NazaraError("Material index out of range (" + String::Number(matIndex) + " >= " + String::Number(m_impl->materials.size()) + ')');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
m_impl->materials[matIndex] = materialPath;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mesh::SetMaterialCount(unsigned int matCount)
|
void Mesh::SetMaterialCount(unsigned int matCount)
|
||||||
{
|
{
|
||||||
#if NAZARA_UTILITY_SAFE
|
NazaraAssert(m_impl, "Mesh should be created first");
|
||||||
if (!m_impl)
|
NazaraAssert(matCount > 0, "A mesh should have at least a material");
|
||||||
{
|
|
||||||
NazaraError("Mesh not created");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (matCount == 0)
|
m_impl->materialData.resize(matCount);
|
||||||
{
|
|
||||||
NazaraError("A mesh should have at least a material");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
m_impl->materials.resize(matCount);
|
|
||||||
|
|
||||||
#ifdef NAZARA_DEBUG
|
#ifdef NAZARA_DEBUG
|
||||||
for (SubMesh* subMesh : m_impl->subMeshes)
|
for (SubMesh* subMesh : m_impl->subMeshes)
|
||||||
|
|
@ -953,7 +634,7 @@ namespace Nz
|
||||||
unsigned int matIndex = subMesh->GetMaterialIndex();
|
unsigned int matIndex = subMesh->GetMaterialIndex();
|
||||||
if (matIndex >= matCount)
|
if (matIndex >= matCount)
|
||||||
{
|
{
|
||||||
subMesh->SetMaterialIndex(0); // Pour empêcher un crash
|
subMesh->SetMaterialIndex(0); // To prevent a crash
|
||||||
NazaraWarning("SubMesh " + String::Pointer(subMesh) + " material index is over mesh new material count (" + String::Number(matIndex) + " >= " + String::Number(matCount) + "), setting it to first material");
|
NazaraWarning("SubMesh " + String::Pointer(subMesh) + " material index is over mesh new material count (" + String::Number(matIndex) + " >= " + String::Number(matCount) + "), setting it to first material");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -962,22 +643,8 @@ namespace Nz
|
||||||
|
|
||||||
void Mesh::Transform(const Matrix4f& matrix)
|
void Mesh::Transform(const Matrix4f& matrix)
|
||||||
{
|
{
|
||||||
#if NAZARA_UTILITY_SAFE
|
NazaraAssert(m_impl, "Mesh should be created first");
|
||||||
if (!m_impl)
|
NazaraAssert(m_impl->animationType == AnimationType_Static, "Mesh is not static");
|
||||||
{
|
|
||||||
NazaraError("Mesh not created");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_impl->animationType != AnimationType_Static)
|
|
||||||
{
|
|
||||||
NazaraError("Mesh must be static");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (matrix.IsIdentity())
|
|
||||||
return;
|
|
||||||
|
|
||||||
for (SubMesh* subMesh : m_impl->subMeshes)
|
for (SubMesh* subMesh : m_impl->subMeshes)
|
||||||
{
|
{
|
||||||
|
|
@ -1000,8 +667,7 @@ namespace Nz
|
||||||
staticMesh->SetAABB(aabb);
|
staticMesh->SetAABB(aabb);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Il ne faut pas oublier d'invalider notre AABB
|
InvalidateAABB();
|
||||||
m_impl->aabbUpdated = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Mesh::Initialize()
|
bool Mesh::Initialize()
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@
|
||||||
#include <Nazara/Utility/Formats/MD2Loader.hpp>
|
#include <Nazara/Utility/Formats/MD2Loader.hpp>
|
||||||
#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/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>
|
||||||
|
|
@ -114,7 +115,7 @@ namespace Nz
|
||||||
Loaders::RegisterFreeType();
|
Loaders::RegisterFreeType();
|
||||||
|
|
||||||
// Image
|
// Image
|
||||||
Loaders::RegisterDDSLoader(); // Generic loader (STB)
|
Loaders::RegisterDDSLoader(); // DDS Loader (DirectX format)
|
||||||
Loaders::RegisterSTBLoader(); // Generic loader (STB)
|
Loaders::RegisterSTBLoader(); // Generic loader (STB)
|
||||||
Loaders::RegisterSTBSaver(); // Generic saver (STB)
|
Loaders::RegisterSTBSaver(); // Generic saver (STB)
|
||||||
|
|
||||||
|
|
@ -122,6 +123,9 @@ namespace Nz
|
||||||
// Animation
|
// Animation
|
||||||
Loaders::RegisterMD5Anim(); // Loader de fichiers .md5anim (v10)
|
Loaders::RegisterMD5Anim(); // Loader de fichiers .md5anim (v10)
|
||||||
|
|
||||||
|
// Mesh (text)
|
||||||
|
Loaders::RegisterOBJ();
|
||||||
|
|
||||||
// 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)
|
||||||
|
|
@ -158,6 +162,7 @@ namespace Nz
|
||||||
Loaders::UnregisterMD2();
|
Loaders::UnregisterMD2();
|
||||||
Loaders::UnregisterMD5Anim();
|
Loaders::UnregisterMD5Anim();
|
||||||
Loaders::UnregisterMD5Mesh();
|
Loaders::UnregisterMD5Mesh();
|
||||||
|
Loaders::UnregisterOBJ();
|
||||||
Loaders::UnregisterPCX();
|
Loaders::UnregisterPCX();
|
||||||
Loaders::UnregisterSTBLoader();
|
Loaders::UnregisterSTBLoader();
|
||||||
Loaders::UnregisterSTBSaver();
|
Loaders::UnregisterSTBSaver();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue