Added ModelLoader
Changed Model::SetMesh behavior Former-commit-id: b1c937b22bcebeef8b8fc42ff061dbf8ece8d2f1
This commit is contained in:
parent
be894c5555
commit
b5d73ce389
|
|
@ -9,22 +9,30 @@
|
||||||
|
|
||||||
#include <Nazara/Prerequesites.hpp>
|
#include <Nazara/Prerequesites.hpp>
|
||||||
#include <Nazara/3D/SceneNode.hpp>
|
#include <Nazara/3D/SceneNode.hpp>
|
||||||
|
#include <Nazara/Core/ResourceLoader.hpp>
|
||||||
#include <Nazara/Core/Updatable.hpp>
|
#include <Nazara/Core/Updatable.hpp>
|
||||||
#include <Nazara/Renderer/Material.hpp>
|
#include <Nazara/Renderer/Material.hpp>
|
||||||
#include <Nazara/Utility/Animation.hpp>
|
#include <Nazara/Utility/Animation.hpp>
|
||||||
#include <Nazara/Utility/Mesh.hpp>
|
#include <Nazara/Utility/Mesh.hpp>
|
||||||
|
|
||||||
struct NzModelParameters
|
struct NAZARA_API NzModelParameters
|
||||||
{
|
{
|
||||||
bool loadAnimation = true;
|
bool loadAnimation = true;
|
||||||
bool loadMaterials = true;
|
bool loadMaterials = true;
|
||||||
NzAnimationParams animation;
|
NzAnimationParams animation;
|
||||||
NzMaterialParams material;
|
NzMaterialParams material;
|
||||||
NzMeshParams mesh;
|
NzMeshParams mesh;
|
||||||
|
|
||||||
|
bool IsValid() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class NzModel;
|
||||||
|
|
||||||
|
using NzModelLoader = NzResourceLoader<NzModel, NzModelParameters>;
|
||||||
|
|
||||||
class NAZARA_API NzModel : public NzSceneNode, public NzUpdatable
|
class NAZARA_API NzModel : public NzSceneNode, public NzUpdatable
|
||||||
{
|
{
|
||||||
|
friend NzModelLoader;
|
||||||
friend class NzScene;
|
friend class NzScene;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
@ -56,16 +64,16 @@ class NAZARA_API NzModel : public NzSceneNode, public NzUpdatable
|
||||||
bool IsAnimationEnabled() const;
|
bool IsAnimationEnabled() const;
|
||||||
bool IsDrawEnabled() const;
|
bool IsDrawEnabled() const;
|
||||||
|
|
||||||
bool LoadFromFile(const NzString& meshPath, const NzModelParameters& modelParameters = NzModelParameters());
|
bool LoadFromFile(const NzString& filePath, const NzModelParameters& params = NzModelParameters());
|
||||||
bool LoadFromMemory(const void* data, std::size_t size, const NzModelParameters& modelParameters = NzModelParameters());
|
bool LoadFromMemory(const void* data, std::size_t size, const NzModelParameters& params = NzModelParameters());
|
||||||
bool LoadFromStream(NzInputStream& stream, const NzModelParameters& modelParameters = NzModelParameters());
|
bool LoadFromStream(NzInputStream& stream, const NzModelParameters& params = NzModelParameters());
|
||||||
|
|
||||||
void Reset();
|
void Reset();
|
||||||
|
|
||||||
bool SetAnimation(NzAnimation* animation);
|
bool SetAnimation(NzAnimation* animation);
|
||||||
void SetMaterial(unsigned int matIndex, NzMaterial* material);
|
void SetMaterial(unsigned int matIndex, NzMaterial* material);
|
||||||
void SetMaterial(unsigned int skinIndex, unsigned int matIndex, NzMaterial* material);
|
void SetMaterial(unsigned int skinIndex, unsigned int matIndex, NzMaterial* material);
|
||||||
void SetMesh(NzMesh* mesh, const NzModelParameters& parameters = NzModelParameters());
|
void SetMesh(NzMesh* mesh);
|
||||||
bool SetSequence(const NzString& sequenceName);
|
bool SetSequence(const NzString& sequenceName);
|
||||||
void SetSequence(unsigned int sequenceIndex);
|
void SetSequence(unsigned int sequenceIndex);
|
||||||
void SetSkin(unsigned int skin);
|
void SetSkin(unsigned int skin);
|
||||||
|
|
@ -97,6 +105,8 @@ class NAZARA_API NzModel : public NzSceneNode, public NzUpdatable
|
||||||
unsigned int m_nextFrame;
|
unsigned int m_nextFrame;
|
||||||
unsigned int m_skin;
|
unsigned int m_skin;
|
||||||
unsigned int m_skinCount;
|
unsigned int m_skinCount;
|
||||||
|
|
||||||
|
static NzModelLoader::LoaderList s_loaders;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // NAZARA_MODEL_HPP
|
#endif // NAZARA_MODEL_HPP
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
#include <Nazara/3D/3D.hpp>
|
#include <Nazara/3D/3D.hpp>
|
||||||
#include <Nazara/2D/2D.hpp>
|
#include <Nazara/2D/2D.hpp>
|
||||||
#include <Nazara/3D/Config.hpp>
|
#include <Nazara/3D/Config.hpp>
|
||||||
|
#include <Nazara/3D/Loaders/Mesh.hpp>
|
||||||
#include <Nazara/Core/Error.hpp>
|
#include <Nazara/Core/Error.hpp>
|
||||||
#include <Nazara/Core/Log.hpp>
|
#include <Nazara/Core/Log.hpp>
|
||||||
#include <Nazara/Renderer/Renderer.hpp>
|
#include <Nazara/Renderer/Renderer.hpp>
|
||||||
|
|
@ -26,6 +27,9 @@ bool Nz3D::Initialize()
|
||||||
|
|
||||||
// Initialisation du module
|
// Initialisation du module
|
||||||
|
|
||||||
|
// Loaders
|
||||||
|
NzLoaders_Mesh_Register();
|
||||||
|
|
||||||
NazaraNotice("Initialized: 3D module");
|
NazaraNotice("Initialized: 3D module");
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -50,6 +54,9 @@ void Nz3D::Uninitialize()
|
||||||
// Libération du module
|
// Libération du module
|
||||||
s_moduleReferenceCounter = 0;
|
s_moduleReferenceCounter = 0;
|
||||||
|
|
||||||
|
// Loaders
|
||||||
|
NzLoaders_Mesh_Unregister();
|
||||||
|
|
||||||
NazaraNotice("Uninitialized: 3D module");
|
NazaraNotice("Uninitialized: 3D module");
|
||||||
|
|
||||||
// Libération des dépendances
|
// Libération des dépendances
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
// Copyright (C) 2013 Jérôme Leclercq
|
||||||
|
// This file is part of the "Nazara Engine - 3D module"
|
||||||
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifndef NAZARA_LOADERS_MESH_HPP
|
||||||
|
#define NAZARA_LOADERS_MESH_HPP
|
||||||
|
|
||||||
|
#include <Nazara/Prerequesites.hpp>
|
||||||
|
|
||||||
|
void NzLoaders_Mesh_Register();
|
||||||
|
void NzLoaders_Mesh_Unregister();
|
||||||
|
|
||||||
|
#endif // NAZARA_LOADERS_MESH_HPP
|
||||||
|
|
@ -0,0 +1,89 @@
|
||||||
|
// Copyright (C) 2013 Jérôme Leclercq
|
||||||
|
// This file is part of the "Nazara Engine - 3D module"
|
||||||
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||||
|
|
||||||
|
#include <Nazara/3D/Loaders/Mesh.hpp>
|
||||||
|
#include <Nazara/3D/Model.hpp>
|
||||||
|
#include <Nazara/Renderer/Material.hpp>
|
||||||
|
#include <Nazara/Utility/Mesh.hpp>
|
||||||
|
#include <memory>
|
||||||
|
#include <Nazara/3D/Debug.hpp>
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
bool Check(NzInputStream& stream, const NzModelParameters& parameters)
|
||||||
|
{
|
||||||
|
NazaraUnused(stream);
|
||||||
|
NazaraUnused(parameters);
|
||||||
|
|
||||||
|
return true; ///FIXME: Pas bon
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Load(NzModel* model, NzInputStream& stream, const NzModelParameters& parameters)
|
||||||
|
{
|
||||||
|
NazaraUnused(parameters);
|
||||||
|
|
||||||
|
std::unique_ptr<NzMesh> mesh(new NzMesh);
|
||||||
|
mesh->SetPersistent(false, false);
|
||||||
|
if (!mesh->LoadFromStream(stream))
|
||||||
|
{
|
||||||
|
NazaraError("Failed to load model mesh");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Nous ne pouvons plus avoir recours au smart pointeur à partir d'ici si nous voulons être exception-safe
|
||||||
|
NzMesh* meshPtr = mesh.get();
|
||||||
|
|
||||||
|
model->Reset();
|
||||||
|
model->SetMesh(meshPtr);
|
||||||
|
mesh.release();
|
||||||
|
|
||||||
|
if (parameters.loadAnimation && meshPtr->IsAnimable())
|
||||||
|
{
|
||||||
|
NzString animationPath = meshPtr->GetAnimation();
|
||||||
|
if (!animationPath.IsEmpty())
|
||||||
|
{
|
||||||
|
std::unique_ptr<NzAnimation> animation(new NzAnimation);
|
||||||
|
animation->SetPersistent(false, false);
|
||||||
|
if (animation->LoadFromFile(animationPath, parameters.animation) && model->SetAnimation(animation.get()))
|
||||||
|
animation.release();
|
||||||
|
else
|
||||||
|
NazaraWarning("Failed to load animation");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parameters.loadMaterials)
|
||||||
|
{
|
||||||
|
unsigned int matCount = model->GetMaterialCount();
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < matCount; ++i)
|
||||||
|
{
|
||||||
|
NzString mat = meshPtr->GetMaterial(i);
|
||||||
|
if (!mat.IsEmpty())
|
||||||
|
{
|
||||||
|
std::unique_ptr<NzMaterial> material(new NzMaterial);
|
||||||
|
material->SetPersistent(false, false);
|
||||||
|
if (material->LoadFromFile(mat, parameters.material))
|
||||||
|
{
|
||||||
|
model->SetMaterial(i, material.get());
|
||||||
|
material.release();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
NazaraWarning("Failed to load material #" + NzString::Number(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NzLoaders_Mesh_Register()
|
||||||
|
{
|
||||||
|
NzModelLoader::RegisterLoader(NzMeshLoader::IsExtensionSupported, Check, Load);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NzLoaders_Mesh_Unregister()
|
||||||
|
{
|
||||||
|
NzModelLoader::UnregisterLoader(NzMeshLoader::IsExtensionSupported, Check, Load);
|
||||||
|
}
|
||||||
|
|
@ -10,10 +10,21 @@
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include <Nazara/3D/Debug.hpp>
|
#include <Nazara/3D/Debug.hpp>
|
||||||
|
|
||||||
|
bool NzModelParameters::IsValid() const
|
||||||
|
{
|
||||||
|
if (loadAnimation && !animation.IsValid())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (loadMaterials && !material.IsValid())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return mesh.IsValid();
|
||||||
|
}
|
||||||
|
|
||||||
NzModel::NzModel() :
|
NzModel::NzModel() :
|
||||||
m_currentSequence(nullptr),
|
m_currentSequence(nullptr),
|
||||||
m_animationEnabled(true),
|
m_animationEnabled(true),
|
||||||
m_boundingBoxUpdated(false),
|
m_boundingBoxUpdated(true),
|
||||||
m_drawEnabled(true),
|
m_drawEnabled(true),
|
||||||
m_matCount(0),
|
m_matCount(0),
|
||||||
m_skin(0),
|
m_skin(0),
|
||||||
|
|
@ -250,50 +261,19 @@ bool NzModel::IsDrawEnabled() const
|
||||||
return m_drawEnabled;
|
return m_drawEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NzModel::LoadFromFile(const NzString& meshPath, const NzModelParameters& modelParameters)
|
bool NzModel::LoadFromFile(const NzString& filePath, const NzModelParameters& params)
|
||||||
{
|
{
|
||||||
///TODO: ResourceManager
|
return NzModelLoader::LoadFromFile(this, filePath, params);
|
||||||
std::unique_ptr<NzMesh> mesh(new NzMesh);
|
|
||||||
if (!mesh->LoadFromFile(meshPath, modelParameters.mesh))
|
|
||||||
{
|
|
||||||
NazaraError("Failed to load mesh");
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mesh->SetPersistent(false, false);
|
bool NzModel::LoadFromMemory(const void* data, std::size_t size, const NzModelParameters& params)
|
||||||
SetMesh(mesh.release(), modelParameters);
|
{
|
||||||
|
return NzModelLoader::LoadFromMemory(this, data, size, params);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NzModel::LoadFromMemory(const void* data, std::size_t size, const NzModelParameters& modelParameters)
|
bool NzModel::LoadFromStream(NzInputStream& stream, const NzModelParameters& params)
|
||||||
{
|
{
|
||||||
std::unique_ptr<NzMesh> mesh(new NzMesh);
|
return NzModelLoader::LoadFromStream(this, stream, params);
|
||||||
if (!mesh->LoadFromMemory(data, size, modelParameters.mesh))
|
|
||||||
{
|
|
||||||
NazaraError("Failed to load mesh");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
mesh->SetPersistent(false, false);
|
|
||||||
SetMesh(mesh.release(), modelParameters);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool NzModel::LoadFromStream(NzInputStream& stream, const NzModelParameters& modelParameters)
|
|
||||||
{
|
|
||||||
std::unique_ptr<NzMesh> mesh(new NzMesh);
|
|
||||||
if (!mesh->LoadFromStream(stream, modelParameters.mesh))
|
|
||||||
{
|
|
||||||
NazaraError("Failed to load mesh");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
mesh->SetPersistent(false, false);
|
|
||||||
SetMesh(mesh.release(), modelParameters);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void NzModel::Reset()
|
void NzModel::Reset()
|
||||||
|
|
@ -404,58 +384,39 @@ void NzModel::SetMaterial(unsigned int skinIndex, unsigned int matIndex, NzMater
|
||||||
m_materials[index] = NzMaterial::GetDefault();
|
m_materials[index] = NzMaterial::GetDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
void NzModel::SetMesh(NzMesh* mesh, const NzModelParameters& modelParameters)
|
void NzModel::SetMesh(NzMesh* mesh)
|
||||||
{
|
{
|
||||||
Reset();
|
m_mesh = mesh;
|
||||||
|
|
||||||
if (mesh)
|
if (m_mesh)
|
||||||
{
|
{
|
||||||
m_boundingBoxUpdated = false;
|
m_boundingBoxUpdated = false;
|
||||||
m_mesh = mesh;
|
|
||||||
|
|
||||||
if (m_mesh->GetAnimationType() == nzAnimationType_Skeletal)
|
if (m_mesh->GetAnimationType() == nzAnimationType_Skeletal)
|
||||||
m_skeleton = *mesh->GetSkeleton(); // Copie du squelette template
|
m_skeleton = *mesh->GetSkeleton(); // Copie du squelette template
|
||||||
|
|
||||||
if (modelParameters.loadAnimation && m_mesh->IsAnimable())
|
if (m_animation)
|
||||||
{
|
{
|
||||||
NzString animationPath = m_mesh->GetAnimation();
|
if (m_animation->GetJointCount() != m_mesh->GetJointCount())
|
||||||
if (!animationPath.IsEmpty())
|
|
||||||
{
|
{
|
||||||
std::unique_ptr<NzAnimation> animation(new NzAnimation);
|
NazaraWarning("Animation joint count is not matching new mesh joint count");
|
||||||
if (animation->LoadFromFile(animationPath, modelParameters.animation) && SetAnimation(animation.get()))
|
SetAnimation(nullptr);
|
||||||
{
|
|
||||||
animation->SetPersistent(false);
|
|
||||||
animation.release();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
NazaraWarning("Failed to load animation");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_matCount = mesh->GetMaterialCount();
|
m_matCount = mesh->GetMaterialCount();
|
||||||
m_materials.reserve(m_matCount);
|
m_materials.resize(m_matCount, NzMaterial::GetDefault());
|
||||||
if (modelParameters.loadMaterials)
|
m_skinCount = 1;
|
||||||
{
|
|
||||||
for (unsigned int i = 0; i < m_matCount; ++i)
|
|
||||||
{
|
|
||||||
NzString mat = mesh->GetMaterial(i);
|
|
||||||
if (!mat.IsEmpty())
|
|
||||||
{
|
|
||||||
std::unique_ptr<NzMaterial> material(new NzMaterial);
|
|
||||||
if (material->LoadFromFile(mat, modelParameters.material))
|
|
||||||
{
|
|
||||||
material->SetPersistent(false, false); // Pas de vérification des références car nous n'y avons pas encore accroché de référence
|
|
||||||
m_materials.push_back(material.release());
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
NazaraWarning("Failed to load material #" + NzString::Number(i));
|
m_boundingBox.MakeNull();
|
||||||
|
m_boundingBoxUpdated = true;
|
||||||
|
m_matCount = 0;
|
||||||
|
m_skinCount = 0;
|
||||||
|
m_materials.clear();
|
||||||
|
|
||||||
m_materials.push_back(NzMaterial::GetDefault());
|
SetAnimation(nullptr);
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -642,3 +603,5 @@ bool NzModel::VisibilityTest(const NzFrustumf& frustum)
|
||||||
|
|
||||||
return frustum.Contains(m_boundingBox);
|
return frustum.Contains(m_boundingBox);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NzModelLoader::LoaderList NzModel::s_loaders;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue