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/TextureSampler.hpp>
|
||||
#include <Nazara/Renderer/UberShader.hpp>
|
||||
#include <Nazara/Utility/MaterialData.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
|
|
@ -62,6 +63,8 @@ namespace Nz
|
|||
|
||||
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 EnableAlphaTest(bool alphaTest);
|
||||
void EnableDepthSorting(bool depthSorting);
|
||||
|
|
|
|||
|
|
@ -19,40 +19,6 @@ namespace Nz
|
|||
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
|
||||
{
|
||||
GpuQueryCondition_Region_NoWait,
|
||||
|
|
@ -124,59 +90,6 @@ namespace Nz
|
|||
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
|
||||
{
|
||||
ShaderUniform_InvProjMatrix,
|
||||
|
|
@ -205,20 +118,6 @@ namespace Nz
|
|||
|
||||
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
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
#ifndef NAZARA_RENDERSTATES_HPP
|
||||
#define NAZARA_RENDERSTATES_HPP
|
||||
|
||||
#include <Nazara/Renderer/Enums.hpp>
|
||||
#include <Nazara/Utility/Enums.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
#include <Nazara/Prerequesites.hpp>
|
||||
#include <Nazara/Renderer/Config.hpp>
|
||||
#include <Nazara/Renderer/Enums.hpp>
|
||||
#include <Nazara/Utility/Enums.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
|
|
|
|||
|
|
@ -17,6 +17,22 @@ namespace Nz
|
|||
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
|
||||
{
|
||||
BufferAccess_DiscardAndWrite,
|
||||
|
|
@ -87,6 +103,24 @@ namespace Nz
|
|||
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
|
||||
{
|
||||
ImageType_1D,
|
||||
|
|
@ -211,6 +245,73 @@ namespace Nz
|
|||
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
|
||||
{
|
||||
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;
|
||||
AnimationType GetAnimationType() 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;
|
||||
Skeleton* GetSkeleton();
|
||||
const Skeleton* GetSkeleton() const;
|
||||
|
|
@ -124,8 +125,8 @@ namespace Nz
|
|||
void RemoveSubMesh(unsigned int index);
|
||||
|
||||
void SetAnimation(const String& animationPath);
|
||||
void SetMaterial(unsigned int matIndex, const String& materialPath);
|
||||
void SetMaterialCount(unsigned int matCount);
|
||||
void SetMaterialData(unsigned int matIndex, ParameterList data);
|
||||
|
||||
void Transform(const Matrix4f& matrix);
|
||||
|
||||
|
|
|
|||
|
|
@ -3,9 +3,11 @@
|
|||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Graphics/Formats/MeshLoader.hpp>
|
||||
#include <Nazara/Core/ErrorFlags.hpp>
|
||||
#include <Nazara/Graphics/Material.hpp>
|
||||
#include <Nazara/Graphics/Model.hpp>
|
||||
#include <Nazara/Graphics/SkeletalModel.hpp>
|
||||
#include <Nazara/Utility/MaterialData.hpp>
|
||||
#include <Nazara/Utility/Mesh.hpp>
|
||||
#include <memory>
|
||||
#include <Nazara/Graphics/Debug.hpp>
|
||||
|
|
@ -14,6 +16,33 @@ namespace Nz
|
|||
{
|
||||
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)
|
||||
{
|
||||
NazaraUnused(stream);
|
||||
|
|
@ -46,22 +75,7 @@ namespace Nz
|
|||
model->SetMesh(mesh);
|
||||
|
||||
if (parameters.loadMaterials)
|
||||
{
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
LoadMaterials(model, parameters);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -98,22 +112,7 @@ namespace Nz
|
|||
model->SetMesh(mesh);
|
||||
|
||||
if (parameters.loadMaterials)
|
||||
{
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
LoadMaterials(model, parameters);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@
|
|||
#include <Nazara/Graphics/SkyboxBackground.hpp>
|
||||
#include <Nazara/Graphics/Sprite.hpp>
|
||||
#include <Nazara/Graphics/Formats/MeshLoader.hpp>
|
||||
#include <Nazara/Graphics/Formats/OBJLoader.hpp>
|
||||
#include <Nazara/Graphics/Formats/TextureLoader.hpp>
|
||||
#include <Nazara/Renderer/Renderer.hpp>
|
||||
#include <Nazara/Utility/Font.hpp>
|
||||
|
|
@ -96,9 +95,6 @@ namespace Nz
|
|||
return false;
|
||||
}
|
||||
|
||||
// Loaders
|
||||
Loaders::RegisterOBJ();
|
||||
|
||||
// Loaders génériques
|
||||
Loaders::RegisterMesh();
|
||||
Loaders::RegisterTexture();
|
||||
|
|
@ -176,7 +172,6 @@ namespace Nz
|
|||
|
||||
// Loaders
|
||||
Loaders::UnregisterMesh();
|
||||
Loaders::UnregisterOBJ();
|
||||
Loaders::UnregisterTexture();
|
||||
|
||||
DeferredRenderTechnique::Uninitialize();
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
#endif
|
||||
|
||||
#include <Nazara/Graphics/Material.hpp>
|
||||
#include <Nazara/Core/ErrorFlags.hpp>
|
||||
#include <Nazara/Renderer/OpenGL.hpp>
|
||||
#include <Nazara/Renderer/Renderer.hpp>
|
||||
#include <Nazara/Renderer/UberShaderPreprocessor.hpp>
|
||||
|
|
@ -139,6 +140,166 @@ namespace Nz
|
|||
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)
|
||||
{
|
||||
#ifdef NAZARA_DEBUG
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
#include <Nazara/Math/Algorithm.hpp>
|
||||
#include <Nazara/Math/Quaternion.hpp>
|
||||
#include <Nazara/Utility/BufferMapper.hpp>
|
||||
#include <Nazara/Utility/MaterialData.hpp>
|
||||
#include <Nazara/Utility/Mesh.hpp>
|
||||
#include <Nazara/Utility/StaticMesh.hpp>
|
||||
#include <Nazara/Utility/Formats/MD2Constants.hpp>
|
||||
|
|
@ -99,7 +100,11 @@ namespace Nz
|
|||
for (unsigned int i = 0; i < header.num_skins; ++i)
|
||||
{
|
||||
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/IndexIterator.hpp>
|
||||
#include <Nazara/Utility/IndexMapper.hpp>
|
||||
#include <Nazara/Utility/MaterialData.hpp>
|
||||
#include <Nazara/Utility/SkeletalMesh.hpp>
|
||||
#include <Nazara/Utility/StaticMesh.hpp>
|
||||
#include <Nazara/Utility/Formats/MD5MeshParser.hpp>
|
||||
|
|
@ -189,7 +190,10 @@ namespace Nz
|
|||
vertexMapper.Unmap();
|
||||
|
||||
// Material
|
||||
mesh->SetMaterial(i, baseDir + md5Mesh.shader);
|
||||
ParameterList matData;
|
||||
matData.SetParameter(MaterialData::FilePath, baseDir + md5Mesh.shader);
|
||||
|
||||
mesh->SetMaterialData(i, std::move(matData));
|
||||
|
||||
// Submesh
|
||||
SkeletalMeshRef subMesh = SkeletalMesh::New(mesh);
|
||||
|
|
@ -285,7 +289,10 @@ namespace Nz
|
|||
mesh->AddSubMesh(subMesh);
|
||||
|
||||
// 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)
|
||||
|
|
|
|||
|
|
@ -1,14 +1,13 @@
|
|||
// Copyright (C) 2015 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Graphics module"
|
||||
// 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/Graphics/Formats/OBJLoader.hpp>
|
||||
#include <Nazara/Utility/Formats/OBJLoader.hpp>
|
||||
#include <Nazara/Core/Algorithm.hpp>
|
||||
#include <Nazara/Core/ErrorFlags.hpp>
|
||||
#include <Nazara/Graphics/Material.hpp>
|
||||
#include <Nazara/Graphics/Model.hpp>
|
||||
#include <Nazara/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/Formats/MTLParser.hpp>
|
||||
|
|
@ -17,7 +16,7 @@
|
|||
#include <limits>
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
#include <Nazara/Graphics/Debug.hpp>
|
||||
#include <Nazara/Utility/Debug.hpp>
|
||||
|
||||
///TODO: N'avoir qu'un seul VertexBuffer communs à tous les meshes
|
||||
|
||||
|
|
@ -30,7 +29,7 @@ namespace Nz
|
|||
return (extension == "obj");
|
||||
}
|
||||
|
||||
Ternary Check(Stream& stream, const ModelParameters& parameters)
|
||||
Ternary Check(Stream& stream, const MeshParams& parameters)
|
||||
{
|
||||
NazaraUnused(stream);
|
||||
|
||||
|
|
@ -41,7 +40,7 @@ namespace Nz
|
|||
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);
|
||||
if (!file.Open(OpenMode_ReadOnly | OpenMode_Text))
|
||||
|
|
@ -57,7 +56,7 @@ namespace Nz
|
|||
return false;
|
||||
}
|
||||
|
||||
std::unordered_map<String, MaterialRef> materialCache;
|
||||
std::unordered_map<String, ParameterList> materialCache;
|
||||
String baseDir = file.GetDirectory();
|
||||
for (unsigned int i = 0; i < meshCount; ++i)
|
||||
{
|
||||
|
|
@ -72,8 +71,9 @@ namespace Nz
|
|||
auto it = materialCache.find(matName);
|
||||
if (it == materialCache.end())
|
||||
{
|
||||
MaterialRef material = Material::New();
|
||||
material->SetShader(parameters.shaderName);
|
||||
ParameterList data;
|
||||
|
||||
data.SetParameter(MaterialData::CustomDefined);
|
||||
|
||||
UInt8 alphaValue = static_cast<UInt8>(mtlMat->alpha*255.f);
|
||||
|
||||
|
|
@ -84,54 +84,40 @@ namespace Nz
|
|||
diffuseColor.a = alphaValue;
|
||||
specularColor.a = alphaValue;
|
||||
|
||||
material->SetAmbientColor(ambientColor);
|
||||
material->SetDiffuseColor(diffuseColor);
|
||||
material->SetSpecularColor(specularColor);
|
||||
material->SetShininess(mtlMat->shininess);
|
||||
data.SetParameter(MaterialData::AmbientColor, ambientColor);
|
||||
data.SetParameter(MaterialData::DiffuseColor, diffuseColor);
|
||||
data.SetParameter(MaterialData::Shininess, 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))
|
||||
isTranslucent = true; // Une alpha map indique de la transparence
|
||||
else
|
||||
NazaraWarning("Failed to load alpha map (" + mtlMat->alphaMap + ')');
|
||||
// Some default settings
|
||||
data.SetParameter(MaterialData::Blending, true);
|
||||
data.SetParameter(MaterialData::DepthWrite, true);
|
||||
data.SetParameter(MaterialData::DstBlend, static_cast<int>(BlendFunc_InvSrcAlpha));
|
||||
data.SetParameter(MaterialData::SrcBlend, static_cast<int>(BlendFunc_SrcAlpha));
|
||||
}
|
||||
|
||||
if (parameters.loadDiffuseMap && !mtlMat->diffuseMap.IsEmpty())
|
||||
{
|
||||
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;
|
||||
it = materialCache.emplace(matName, std::move(data)).first;
|
||||
}
|
||||
|
||||
model->SetMaterial(meshes[i].material, it->second);
|
||||
mesh->SetMaterialData(meshes[i].material, it->second);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Load(Model* model, Stream& stream, const ModelParameters& parameters)
|
||||
bool Load(Mesh* mesh, Stream& stream, const MeshParams& parameters)
|
||||
{
|
||||
int reservedVertexCount;
|
||||
if (!parameters.custom.GetIntegerParameter("NativeOBJLoader_VertexCount", &reservedVertexCount))
|
||||
|
|
@ -144,12 +130,7 @@ namespace Nz
|
|||
return false;
|
||||
}
|
||||
|
||||
MeshRef mesh = Mesh::New();
|
||||
if (!mesh->CreateStatic()) // Ne devrait jamais échouer
|
||||
{
|
||||
NazaraInternalError("Failed to create mesh");
|
||||
return false;
|
||||
}
|
||||
mesh->CreateStatic();
|
||||
|
||||
const String* materials = parser.GetMaterials();
|
||||
const Vector4f* positions = parser.GetPositions();
|
||||
|
|
@ -160,8 +141,8 @@ namespace Nz
|
|||
unsigned int meshCount = parser.GetMeshCount();
|
||||
|
||||
NazaraAssert(materials != nullptr && positions != nullptr && normals != nullptr &&
|
||||
texCoords != nullptr && meshes != nullptr && meshCount > 0,
|
||||
"Invalid OBJParser output");
|
||||
texCoords != nullptr && meshes != nullptr && meshCount > 0,
|
||||
"Invalid OBJParser output");
|
||||
|
||||
// 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
|
||||
|
|
@ -197,8 +178,8 @@ namespace Nz
|
|||
bool operator()(const OBJParser::FaceVertex& lhs, const OBJParser::FaceVertex& rhs) const
|
||||
{
|
||||
return lhs.normal == rhs.normal &&
|
||||
lhs.position == rhs.position &&
|
||||
lhs.texCoord == rhs.texCoord;
|
||||
lhs.position == rhs.position &&
|
||||
lhs.texCoord == rhs.texCoord;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -230,8 +211,8 @@ namespace Nz
|
|||
}
|
||||
|
||||
// Création des buffers
|
||||
IndexBufferRef indexBuffer = IndexBuffer::New(vertexCount > std::numeric_limits<UInt16>::max(), indices.size(), parameters.mesh.storage, BufferUsage_Static);
|
||||
VertexBufferRef vertexBuffer = VertexBuffer::New(VertexDeclaration::Get(VertexLayout_XYZ_Normal_UV_Tangent), vertexCount, 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.storage, BufferUsage_Static);
|
||||
|
||||
// Remplissage des indices
|
||||
IndexMapper indexMapper(indexBuffer, BufferAccess_WriteOnly);
|
||||
|
|
@ -254,7 +235,7 @@ namespace Nz
|
|||
|
||||
const Vector4f& vec = positions[vertexIndices.position];
|
||||
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)
|
||||
vertex.normal = normals[vertexIndices.normal];
|
||||
|
|
@ -264,7 +245,7 @@ namespace Nz
|
|||
if (vertexIndices.texCoord >= 0)
|
||||
{
|
||||
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
|
||||
hasTexCoords = false;
|
||||
|
|
@ -279,7 +260,7 @@ namespace Nz
|
|||
continue;
|
||||
}
|
||||
|
||||
if (parameters.mesh.optimizeIndexBuffers)
|
||||
if (parameters.optimizeIndexBuffers)
|
||||
indexBuffer->Optimize();
|
||||
|
||||
subMesh->GenerateAABB();
|
||||
|
|
@ -299,17 +280,15 @@ namespace Nz
|
|||
}
|
||||
mesh->SetMaterialCount(parser.GetMaterialCount());
|
||||
|
||||
if (parameters.mesh.center)
|
||||
if (parameters.center)
|
||||
mesh->Recenter();
|
||||
|
||||
model->SetMesh(mesh);
|
||||
|
||||
// On charge les matériaux si demandé
|
||||
String mtlLib = parser.GetMtlLib();
|
||||
if (parameters.loadMaterials && !mtlLib.IsEmpty())
|
||||
if (!mtlLib.IsEmpty())
|
||||
{
|
||||
ErrorFlags flags(ErrorFlag_ThrowExceptionDisabled);
|
||||
LoadMaterials(model, stream.GetDirectory() + mtlLib, parameters.material, materials, meshes, meshCount);
|
||||
ParseMTL(mesh, stream.GetDirectory() + mtlLib, materials, meshes, meshCount);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
@ -320,12 +299,12 @@ namespace Nz
|
|||
{
|
||||
void RegisterOBJ()
|
||||
{
|
||||
ModelLoader::RegisterLoader(IsSupported, Check, Load);
|
||||
MeshLoader::RegisterLoader(IsSupported, Check, Load);
|
||||
}
|
||||
|
||||
void UnregisterOBJ()
|
||||
{
|
||||
ModelLoader::UnregisterLoader(IsSupported, Check, Load);
|
||||
MeshLoader::UnregisterLoader(IsSupported, Check, Load);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -52,11 +52,11 @@ namespace Nz
|
|||
{
|
||||
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::vector<String> materials;
|
||||
std::vector<ParameterList> materialData;
|
||||
std::vector<SubMeshRef> subMeshes;
|
||||
AnimationType animationType;
|
||||
Boxf aabb;
|
||||
|
|
@ -75,93 +75,36 @@ namespace Nz
|
|||
|
||||
void Mesh::AddSubMesh(SubMesh* subMesh)
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Mesh not created");
|
||||
return;
|
||||
}
|
||||
NazaraAssert(m_impl, "Mesh should be created first");
|
||||
NazaraAssert(subMesh, "Invalid submesh");
|
||||
NazaraAssert(subMesh->GetAnimationType() == m_impl->animationType, "Submesh animation type doesn't match mesh animation type");
|
||||
|
||||
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);
|
||||
|
||||
InvalidateAABB();
|
||||
}
|
||||
|
||||
void Mesh::AddSubMesh(const String& identifier, SubMesh* subMesh)
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Mesh not created");
|
||||
return;
|
||||
}
|
||||
|
||||
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
|
||||
NazaraAssert(m_impl, "Mesh should be created first");
|
||||
NazaraAssert(!identifier.IsEmpty(), "Identifier is empty");
|
||||
NazaraAssert(m_impl->subMeshMap.find(identifier) == m_impl->subMeshMap.end(), "SubMesh identifier \"" + identifier + "\" is already in use");
|
||||
NazaraAssert(subMesh, "Invalid submesh");
|
||||
NazaraAssert(subMesh->GetAnimationType() == m_impl->animationType, "Submesh animation type doesn't match mesh animation type");
|
||||
|
||||
int index = m_impl->subMeshes.size();
|
||||
|
||||
m_impl->aabbUpdated = false; // On invalide l'AABB
|
||||
m_impl->subMeshes.push_back(subMesh);
|
||||
m_impl->subMeshMap[identifier] = index;
|
||||
|
||||
InvalidateAABB();
|
||||
}
|
||||
|
||||
SubMesh* Mesh::BuildSubMesh(const Primitive& primitive, const MeshParams& params)
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
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
|
||||
NazaraAssert(m_impl, "Mesh should be created first");
|
||||
NazaraAssert(m_impl->animationType == AnimationType_Static, "Submesh building only works for static meshes");
|
||||
NazaraAssert(params.IsValid(), "Invalid parameters");
|
||||
|
||||
Boxf aabb;
|
||||
IndexBufferRef indexBuffer;
|
||||
|
|
@ -333,17 +276,7 @@ namespace Nz
|
|||
|
||||
void Mesh::BuildSubMeshes(const PrimitiveList& list, const MeshParams& params)
|
||||
{
|
||||
unsigned int primitiveCount = list.GetSize();
|
||||
|
||||
#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)
|
||||
for (unsigned int i = 0; i < list.GetSize(); ++i)
|
||||
BuildSubMesh(list.GetPrimitive(i), params);
|
||||
}
|
||||
|
||||
|
|
@ -351,18 +284,17 @@ namespace Nz
|
|||
{
|
||||
Destroy();
|
||||
|
||||
m_impl = new MeshImpl;
|
||||
m_impl->animationType = AnimationType_Skeletal;
|
||||
m_impl->jointCount = jointCount;
|
||||
if (!m_impl->skeleton.Create(jointCount))
|
||||
std::unique_ptr<MeshImpl> impl(new MeshImpl);
|
||||
impl->animationType = AnimationType_Skeletal;
|
||||
impl->jointCount = jointCount;
|
||||
if (!impl->skeleton.Create(jointCount))
|
||||
{
|
||||
delete m_impl;
|
||||
m_impl = nullptr;
|
||||
|
||||
NazaraError("Failed to create skeleton");
|
||||
return false;
|
||||
}
|
||||
|
||||
m_impl = impl.release();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -389,13 +321,7 @@ namespace Nz
|
|||
|
||||
void Mesh::GenerateNormals()
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Mesh not created");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
NazaraAssert(m_impl, "Mesh should be created first");
|
||||
|
||||
for (SubMesh* subMesh : m_impl->subMeshes)
|
||||
subMesh->GenerateNormals();
|
||||
|
|
@ -403,13 +329,7 @@ namespace Nz
|
|||
|
||||
void Mesh::GenerateNormalsAndTangents()
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Mesh not created");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
NazaraAssert(m_impl, "Mesh should be created first");
|
||||
|
||||
for (SubMesh* subMesh : m_impl->subMeshes)
|
||||
subMesh->GenerateNormalsAndTangents();
|
||||
|
|
@ -417,13 +337,7 @@ namespace Nz
|
|||
|
||||
void Mesh::GenerateTangents()
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Mesh not created");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
NazaraAssert(m_impl, "Mesh should be created first");
|
||||
|
||||
for (SubMesh* subMesh : m_impl->subMeshes)
|
||||
subMesh->GenerateTangents();
|
||||
|
|
@ -431,15 +345,7 @@ namespace Nz
|
|||
|
||||
const Boxf& Mesh::GetAABB() const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Mesh not created");
|
||||
|
||||
static Boxf dummy;
|
||||
return dummy;
|
||||
}
|
||||
#endif
|
||||
NazaraAssert(m_impl, "Mesh should be created first");
|
||||
|
||||
if (!m_impl->aabbUpdated)
|
||||
{
|
||||
|
|
@ -461,248 +367,121 @@ namespace Nz
|
|||
|
||||
String Mesh::GetAnimation() const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Mesh not created");
|
||||
return String();
|
||||
}
|
||||
#endif
|
||||
NazaraAssert(m_impl, "Mesh should be created first");
|
||||
|
||||
return m_impl->animationPath;
|
||||
}
|
||||
|
||||
AnimationType Mesh::GetAnimationType() const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Mesh not created");
|
||||
return AnimationType_Static;
|
||||
}
|
||||
#endif
|
||||
NazaraAssert(m_impl, "Mesh should be created first");
|
||||
|
||||
return m_impl->animationType;
|
||||
}
|
||||
|
||||
unsigned int Mesh::GetJointCount() const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Mesh not created");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (m_impl->animationType != AnimationType_Skeletal)
|
||||
{
|
||||
NazaraError("Mesh's animation type is not skeletal");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
NazaraAssert(m_impl, "Mesh should be created first");
|
||||
NazaraAssert(m_impl->animationType == AnimationType_Skeletal, "Mesh is not skeletal");
|
||||
|
||||
return m_impl->jointCount;
|
||||
}
|
||||
|
||||
String Mesh::GetMaterial(unsigned int index) const
|
||||
ParameterList& Mesh::GetMaterialData(unsigned int index)
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Mesh not created");
|
||||
return String();
|
||||
}
|
||||
NazaraAssert(m_impl, "Mesh should be created first");
|
||||
NazaraAssert(index < m_impl->materialData.size(), "Material index out of range");
|
||||
|
||||
if (index >= m_impl->materials.size())
|
||||
{
|
||||
NazaraError("Material index out of range (" + String::Number(index) + " >= " + String::Number(m_impl->materials.size()) + ')');
|
||||
return String();
|
||||
}
|
||||
#endif
|
||||
return m_impl->materialData[index];
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Mesh not created");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
NazaraAssert(m_impl, "Mesh should be created first");
|
||||
|
||||
return m_impl->materials.size();
|
||||
return m_impl->materialData.size();
|
||||
}
|
||||
|
||||
Skeleton* Mesh::GetSkeleton()
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Animation not created");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (m_impl->animationType != AnimationType_Skeletal)
|
||||
{
|
||||
NazaraError("Mesh's animation type is not skeletal");
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
NazaraAssert(m_impl, "Mesh should be created first");
|
||||
NazaraAssert(m_impl->animationType == AnimationType_Skeletal, "Mesh is not skeletal");
|
||||
|
||||
return &m_impl->skeleton;
|
||||
}
|
||||
|
||||
const Skeleton* Mesh::GetSkeleton() const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Animation not created");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (m_impl->animationType != AnimationType_Skeletal)
|
||||
{
|
||||
NazaraError("Mesh's animation type is not skeletal");
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
NazaraAssert(m_impl, "Mesh should be created first");
|
||||
NazaraAssert(m_impl->animationType == AnimationType_Skeletal, "Mesh is not skeletal");
|
||||
|
||||
return &m_impl->skeleton;
|
||||
}
|
||||
|
||||
SubMesh* Mesh::GetSubMesh(const String& identifier)
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Mesh not created");
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
NazaraAssert(m_impl, "Mesh should be created first");
|
||||
|
||||
auto it = m_impl->subMeshMap.find(identifier);
|
||||
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (it == m_impl->subMeshMap.end())
|
||||
{
|
||||
NazaraError("SubMesh not found");
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
NazaraAssert(it != m_impl->subMeshMap.end(), "SubMesh " + identifier + " not found");
|
||||
|
||||
return m_impl->subMeshes[it->second];
|
||||
}
|
||||
|
||||
SubMesh* Mesh::GetSubMesh(unsigned int index)
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
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
|
||||
NazaraAssert(m_impl, "Mesh should be created first");
|
||||
NazaraAssert(index < m_impl->subMeshes.size(), "Submesh index out of range");
|
||||
|
||||
return m_impl->subMeshes[index];
|
||||
}
|
||||
|
||||
const SubMesh* Mesh::GetSubMesh(const String& identifier) const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Mesh not created");
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
NazaraAssert(m_impl, "Mesh should be created first");
|
||||
|
||||
auto it = m_impl->subMeshMap.find(identifier);
|
||||
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (it == m_impl->subMeshMap.end())
|
||||
{
|
||||
NazaraError("SubMesh not found");
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
NazaraAssert(it != m_impl->subMeshMap.end(), "SubMesh " + identifier + " not found");
|
||||
|
||||
return m_impl->subMeshes[it->second];
|
||||
}
|
||||
|
||||
const SubMesh* Mesh::GetSubMesh(unsigned int index) const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
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
|
||||
NazaraAssert(m_impl, "Mesh should be created first");
|
||||
NazaraAssert(index < m_impl->subMeshes.size(), "Submesh index out of range");
|
||||
|
||||
return m_impl->subMeshes[index];
|
||||
}
|
||||
|
||||
unsigned int Mesh::GetSubMeshCount() const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Mesh not created");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
NazaraAssert(m_impl, "Mesh should be created first");
|
||||
|
||||
return m_impl->subMeshes.size();
|
||||
}
|
||||
|
||||
int Mesh::GetSubMeshIndex(const String& identifier) const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Mesh not created");
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
NazaraAssert(m_impl, "Mesh should be created first");
|
||||
|
||||
auto it = m_impl->subMeshMap.find(identifier);
|
||||
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (it == m_impl->subMeshMap.end())
|
||||
{
|
||||
NazaraError("SubMesh not found");
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
NazaraAssert(it != m_impl->subMeshMap.end(), "SubMesh " + identifier + " not found");
|
||||
|
||||
return it->second;
|
||||
}
|
||||
|
||||
unsigned int Mesh::GetTriangleCount() const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Mesh not created");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
NazaraAssert(m_impl, "Mesh should be created first");
|
||||
|
||||
unsigned int triangleCount = 0;
|
||||
for (SubMesh* subMesh : m_impl->subMeshes)
|
||||
|
|
@ -713,13 +492,7 @@ namespace Nz
|
|||
|
||||
unsigned int Mesh::GetVertexCount() const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Mesh not created");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
NazaraAssert(m_impl, "Mesh should be created first");
|
||||
|
||||
unsigned int vertexCount = 0;
|
||||
for (SubMesh* subMesh : m_impl->subMeshes)
|
||||
|
|
@ -730,52 +503,28 @@ namespace Nz
|
|||
|
||||
void Mesh::InvalidateAABB() const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Mesh not created");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
NazaraAssert(m_impl, "Mesh should be created first");
|
||||
|
||||
m_impl->aabbUpdated = false;
|
||||
}
|
||||
|
||||
bool Mesh::HasSubMesh(const String& identifier) const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Mesh not created");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
NazaraAssert(m_impl, "Mesh should be created first");
|
||||
|
||||
return m_impl->subMeshMap.find(identifier) != m_impl->subMeshMap.end();
|
||||
}
|
||||
|
||||
bool Mesh::HasSubMesh(unsigned int index) const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Mesh not created");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
NazaraAssert(m_impl, "Mesh should be created first");
|
||||
|
||||
return index < m_impl->subMeshes.size();
|
||||
}
|
||||
|
||||
bool Mesh::IsAnimable() const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Mesh not created");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
NazaraAssert(m_impl, "Mesh should be created first");
|
||||
|
||||
return m_impl->animationType != AnimationType_Static;
|
||||
}
|
||||
|
|
@ -802,21 +551,10 @@ namespace Nz
|
|||
|
||||
void Mesh::Recenter()
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Mesh not created");
|
||||
return;
|
||||
}
|
||||
NazaraAssert(m_impl, "Mesh should be created first");
|
||||
NazaraAssert(m_impl->animationType == AnimationType_Static, "Mesh is not static");
|
||||
|
||||
if (m_impl->animationType != AnimationType_Static)
|
||||
{
|
||||
NazaraError("Mesh must be static");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Le centre de notre mesh est le centre de l'AABB *globale*
|
||||
// The center of our mesh is the center of our *global* AABB
|
||||
Vector3f center = GetAABB().GetCenter();
|
||||
|
||||
for (SubMesh* subMesh : m_impl->subMeshes)
|
||||
|
|
@ -833,119 +571,62 @@ namespace Nz
|
|||
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();
|
||||
aabb.Translate(-center);
|
||||
|
||||
staticMesh->SetAABB(aabb);
|
||||
}
|
||||
|
||||
// Il ne faut pas oublier d'invalider notre AABB
|
||||
m_impl->aabbUpdated = false;
|
||||
InvalidateAABB();
|
||||
}
|
||||
|
||||
void Mesh::RemoveSubMesh(const String& identifier)
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
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
|
||||
unsigned int index = GetSubMeshIndex(identifier);
|
||||
|
||||
// On déplace l'itérateur du début d'une distance de x
|
||||
auto it2 = m_impl->subMeshes.begin();
|
||||
std::advance(it2, index);
|
||||
m_impl->subMeshes.erase(it2);
|
||||
|
||||
m_impl->aabbUpdated = false; // On invalide l'AABB
|
||||
InvalidateAABB();
|
||||
}
|
||||
|
||||
void Mesh::RemoveSubMesh(unsigned int index)
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
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
|
||||
NazaraAssert(m_impl, "Mesh should be created first");
|
||||
NazaraAssert(index < m_impl->subMeshes.size(), "Submesh index out of range");
|
||||
|
||||
// On déplace l'itérateur du début de x
|
||||
auto it = m_impl->subMeshes.begin();
|
||||
std::advance(it, index);
|
||||
m_impl->subMeshes.erase(it);
|
||||
|
||||
m_impl->aabbUpdated = false; // On invalide l'AABB
|
||||
InvalidateAABB();
|
||||
}
|
||||
|
||||
void Mesh::SetAnimation(const String& animationPath)
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Mesh not created");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
NazaraAssert(m_impl, "Mesh should be created first");
|
||||
|
||||
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
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Mesh not created");
|
||||
return;
|
||||
}
|
||||
NazaraAssert(m_impl, "Mesh should be created first");
|
||||
NazaraAssert(matIndex < m_impl->materialData.size(), "Material index out of range");
|
||||
|
||||
if (matIndex >= m_impl->materials.size())
|
||||
{
|
||||
NazaraError("Material index out of range (" + String::Number(matIndex) + " >= " + String::Number(m_impl->materials.size()) + ')');
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
m_impl->materials[matIndex] = materialPath;
|
||||
m_impl->materialData[matIndex] = std::move(data);
|
||||
}
|
||||
|
||||
void Mesh::SetMaterialCount(unsigned int matCount)
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Mesh not created");
|
||||
return;
|
||||
}
|
||||
NazaraAssert(m_impl, "Mesh should be created first");
|
||||
NazaraAssert(matCount > 0, "A mesh should have at least a material");
|
||||
|
||||
if (matCount == 0)
|
||||
{
|
||||
NazaraError("A mesh should have at least a material");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
m_impl->materials.resize(matCount);
|
||||
m_impl->materialData.resize(matCount);
|
||||
|
||||
#ifdef NAZARA_DEBUG
|
||||
for (SubMesh* subMesh : m_impl->subMeshes)
|
||||
|
|
@ -953,7 +634,7 @@ namespace Nz
|
|||
unsigned int matIndex = subMesh->GetMaterialIndex();
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
|
@ -962,22 +643,8 @@ namespace Nz
|
|||
|
||||
void Mesh::Transform(const Matrix4f& matrix)
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Mesh not created");
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_impl->animationType != AnimationType_Static)
|
||||
{
|
||||
NazaraError("Mesh must be static");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (matrix.IsIdentity())
|
||||
return;
|
||||
NazaraAssert(m_impl, "Mesh should be created first");
|
||||
NazaraAssert(m_impl->animationType == AnimationType_Static, "Mesh is not static");
|
||||
|
||||
for (SubMesh* subMesh : m_impl->subMeshes)
|
||||
{
|
||||
|
|
@ -1000,8 +667,7 @@ namespace Nz
|
|||
staticMesh->SetAABB(aabb);
|
||||
}
|
||||
|
||||
// Il ne faut pas oublier d'invalider notre AABB
|
||||
m_impl->aabbUpdated = false;
|
||||
InvalidateAABB();
|
||||
}
|
||||
|
||||
bool Mesh::Initialize()
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
#include <Nazara/Utility/Formats/MD2Loader.hpp>
|
||||
#include <Nazara/Utility/Formats/MD5AnimLoader.hpp>
|
||||
#include <Nazara/Utility/Formats/MD5MeshLoader.hpp>
|
||||
#include <Nazara/Utility/Formats/OBJLoader.hpp>
|
||||
#include <Nazara/Utility/Formats/PCXLoader.hpp>
|
||||
#include <Nazara/Utility/Formats/STBLoader.hpp>
|
||||
#include <Nazara/Utility/Formats/STBSaver.hpp>
|
||||
|
|
@ -114,7 +115,7 @@ namespace Nz
|
|||
Loaders::RegisterFreeType();
|
||||
|
||||
// Image
|
||||
Loaders::RegisterDDSLoader(); // Generic loader (STB)
|
||||
Loaders::RegisterDDSLoader(); // DDS Loader (DirectX format)
|
||||
Loaders::RegisterSTBLoader(); // Generic loader (STB)
|
||||
Loaders::RegisterSTBSaver(); // Generic saver (STB)
|
||||
|
||||
|
|
@ -122,6 +123,9 @@ namespace Nz
|
|||
// Animation
|
||||
Loaders::RegisterMD5Anim(); // Loader de fichiers .md5anim (v10)
|
||||
|
||||
// Mesh (text)
|
||||
Loaders::RegisterOBJ();
|
||||
|
||||
// Mesh
|
||||
Loaders::RegisterMD2(); // Loader de fichiers .md2 (v8)
|
||||
Loaders::RegisterMD5Mesh(); // Loader de fichiers .md5mesh (v10)
|
||||
|
|
@ -158,6 +162,7 @@ namespace Nz
|
|||
Loaders::UnregisterMD2();
|
||||
Loaders::UnregisterMD5Anim();
|
||||
Loaders::UnregisterMD5Mesh();
|
||||
Loaders::UnregisterOBJ();
|
||||
Loaders::UnregisterPCX();
|
||||
Loaders::UnregisterSTBLoader();
|
||||
Loaders::UnregisterSTBSaver();
|
||||
|
|
|
|||
Loading…
Reference in New Issue