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/3D/SceneNode.hpp>
|
||||
#include <Nazara/Core/ResourceLoader.hpp>
|
||||
#include <Nazara/Core/Updatable.hpp>
|
||||
#include <Nazara/Renderer/Material.hpp>
|
||||
#include <Nazara/Utility/Animation.hpp>
|
||||
#include <Nazara/Utility/Mesh.hpp>
|
||||
|
||||
struct NzModelParameters
|
||||
struct NAZARA_API NzModelParameters
|
||||
{
|
||||
bool loadAnimation = true;
|
||||
bool loadMaterials = true;
|
||||
NzAnimationParams animation;
|
||||
NzMaterialParams material;
|
||||
NzMeshParams mesh;
|
||||
|
||||
bool IsValid() const;
|
||||
};
|
||||
|
||||
class NzModel;
|
||||
|
||||
using NzModelLoader = NzResourceLoader<NzModel, NzModelParameters>;
|
||||
|
||||
class NAZARA_API NzModel : public NzSceneNode, public NzUpdatable
|
||||
{
|
||||
friend NzModelLoader;
|
||||
friend class NzScene;
|
||||
|
||||
public:
|
||||
|
|
@ -56,16 +64,16 @@ class NAZARA_API NzModel : public NzSceneNode, public NzUpdatable
|
|||
bool IsAnimationEnabled() const;
|
||||
bool IsDrawEnabled() const;
|
||||
|
||||
bool LoadFromFile(const NzString& meshPath, const NzModelParameters& modelParameters = NzModelParameters());
|
||||
bool LoadFromMemory(const void* data, std::size_t size, const NzModelParameters& modelParameters = NzModelParameters());
|
||||
bool LoadFromStream(NzInputStream& stream, const NzModelParameters& modelParameters = NzModelParameters());
|
||||
bool LoadFromFile(const NzString& filePath, const NzModelParameters& params = NzModelParameters());
|
||||
bool LoadFromMemory(const void* data, std::size_t size, const NzModelParameters& params = NzModelParameters());
|
||||
bool LoadFromStream(NzInputStream& stream, const NzModelParameters& params = NzModelParameters());
|
||||
|
||||
void Reset();
|
||||
|
||||
bool SetAnimation(NzAnimation* animation);
|
||||
void SetMaterial(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);
|
||||
void SetSequence(unsigned int sequenceIndex);
|
||||
void SetSkin(unsigned int skin);
|
||||
|
|
@ -97,6 +105,8 @@ class NAZARA_API NzModel : public NzSceneNode, public NzUpdatable
|
|||
unsigned int m_nextFrame;
|
||||
unsigned int m_skin;
|
||||
unsigned int m_skinCount;
|
||||
|
||||
static NzModelLoader::LoaderList s_loaders;
|
||||
};
|
||||
|
||||
#endif // NAZARA_MODEL_HPP
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
#include <Nazara/3D/3D.hpp>
|
||||
#include <Nazara/2D/2D.hpp>
|
||||
#include <Nazara/3D/Config.hpp>
|
||||
#include <Nazara/3D/Loaders/Mesh.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Core/Log.hpp>
|
||||
#include <Nazara/Renderer/Renderer.hpp>
|
||||
|
|
@ -26,6 +27,9 @@ bool Nz3D::Initialize()
|
|||
|
||||
// Initialisation du module
|
||||
|
||||
// Loaders
|
||||
NzLoaders_Mesh_Register();
|
||||
|
||||
NazaraNotice("Initialized: 3D module");
|
||||
|
||||
return true;
|
||||
|
|
@ -50,6 +54,9 @@ void Nz3D::Uninitialize()
|
|||
// Libération du module
|
||||
s_moduleReferenceCounter = 0;
|
||||
|
||||
// Loaders
|
||||
NzLoaders_Mesh_Unregister();
|
||||
|
||||
NazaraNotice("Uninitialized: 3D module");
|
||||
|
||||
// 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 <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() :
|
||||
m_currentSequence(nullptr),
|
||||
m_animationEnabled(true),
|
||||
m_boundingBoxUpdated(false),
|
||||
m_boundingBoxUpdated(true),
|
||||
m_drawEnabled(true),
|
||||
m_matCount(0),
|
||||
m_skin(0),
|
||||
|
|
@ -250,50 +261,19 @@ bool NzModel::IsDrawEnabled() const
|
|||
return m_drawEnabled;
|
||||
}
|
||||
|
||||
bool NzModel::LoadFromFile(const NzString& meshPath, const NzModelParameters& modelParameters)
|
||||
bool NzModel::LoadFromFile(const NzString& filePath, const NzModelParameters& params)
|
||||
{
|
||||
///TODO: ResourceManager
|
||||
std::unique_ptr<NzMesh> mesh(new NzMesh);
|
||||
if (!mesh->LoadFromFile(meshPath, modelParameters.mesh))
|
||||
{
|
||||
NazaraError("Failed to load mesh");
|
||||
return false;
|
||||
}
|
||||
|
||||
mesh->SetPersistent(false, false);
|
||||
SetMesh(mesh.release(), modelParameters);
|
||||
|
||||
return true;
|
||||
return NzModelLoader::LoadFromFile(this, filePath, params);
|
||||
}
|
||||
|
||||
bool NzModel::LoadFromMemory(const void* data, std::size_t size, const NzModelParameters& modelParameters)
|
||||
bool NzModel::LoadFromMemory(const void* data, std::size_t size, const NzModelParameters& params)
|
||||
{
|
||||
std::unique_ptr<NzMesh> mesh(new NzMesh);
|
||||
if (!mesh->LoadFromMemory(data, size, modelParameters.mesh))
|
||||
{
|
||||
NazaraError("Failed to load mesh");
|
||||
return false;
|
||||
}
|
||||
|
||||
mesh->SetPersistent(false, false);
|
||||
SetMesh(mesh.release(), modelParameters);
|
||||
|
||||
return true;
|
||||
return NzModelLoader::LoadFromMemory(this, data, size, params);
|
||||
}
|
||||
|
||||
bool NzModel::LoadFromStream(NzInputStream& stream, const NzModelParameters& modelParameters)
|
||||
bool NzModel::LoadFromStream(NzInputStream& stream, const NzModelParameters& params)
|
||||
{
|
||||
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;
|
||||
return NzModelLoader::LoadFromStream(this, stream, params);
|
||||
}
|
||||
|
||||
void NzModel::Reset()
|
||||
|
|
@ -404,58 +384,39 @@ void NzModel::SetMaterial(unsigned int skinIndex, unsigned int matIndex, NzMater
|
|||
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_mesh = mesh;
|
||||
|
||||
if (m_mesh->GetAnimationType() == nzAnimationType_Skeletal)
|
||||
m_skeleton = *mesh->GetSkeleton(); // Copie du squelette template
|
||||
|
||||
if (modelParameters.loadAnimation && m_mesh->IsAnimable())
|
||||
if (m_animation)
|
||||
{
|
||||
NzString animationPath = m_mesh->GetAnimation();
|
||||
if (!animationPath.IsEmpty())
|
||||
if (m_animation->GetJointCount() != m_mesh->GetJointCount())
|
||||
{
|
||||
std::unique_ptr<NzAnimation> animation(new NzAnimation);
|
||||
if (animation->LoadFromFile(animationPath, modelParameters.animation) && SetAnimation(animation.get()))
|
||||
{
|
||||
animation->SetPersistent(false);
|
||||
animation.release();
|
||||
}
|
||||
else
|
||||
NazaraWarning("Failed to load animation");
|
||||
NazaraWarning("Animation joint count is not matching new mesh joint count");
|
||||
SetAnimation(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
m_matCount = mesh->GetMaterialCount();
|
||||
m_materials.reserve(m_matCount);
|
||||
if (modelParameters.loadMaterials)
|
||||
{
|
||||
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
|
||||
{
|
||||
NazaraWarning("Failed to load material #" + NzString::Number(i));
|
||||
m_materials.resize(m_matCount, NzMaterial::GetDefault());
|
||||
m_skinCount = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
NzModelLoader::LoaderList NzModel::s_loaders;
|
||||
|
|
|
|||
Loading…
Reference in New Issue