Model can no longer be animated (SkeletalModel will)

Former-commit-id: e203a3dddf74bb171d8abe961e8a2f28df13bcad
This commit is contained in:
Lynix 2014-05-28 01:03:59 +02:00
parent c901b5808e
commit fa5b1ab000
2 changed files with 28 additions and 267 deletions

View File

@ -9,19 +9,15 @@
#include <Nazara/Prerequesites.hpp>
#include <Nazara/Core/ResourceLoader.hpp>
#include <Nazara/Core/Updatable.hpp>
#include <Nazara/Graphics/Material.hpp>
#include <Nazara/Graphics/SceneNode.hpp>
#include <Nazara/Utility/Animation.hpp>
#include <Nazara/Utility/Mesh.hpp>
struct NAZARA_API NzModelParameters
{
NzModelParameters();
bool loadAnimation = true;
bool loadMaterials = true;
NzAnimationParams animation;
NzMaterialParams material;
NzMeshParams mesh;
@ -32,7 +28,7 @@ class NzModel;
using NzModelLoader = NzResourceLoader<NzModel, NzModelParameters>;
class NAZARA_API NzModel : public NzSceneNode, public NzUpdatable
class NAZARA_API NzModel : public NzSceneNode
{
friend NzModelLoader;
friend class NzScene;
@ -41,7 +37,7 @@ class NAZARA_API NzModel : public NzSceneNode, public NzUpdatable
NzModel();
NzModel(const NzModel& model);
NzModel(NzModel&& model);
~NzModel();
virtual ~NzModel();
void AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const override;
void AdvanceAnimation(float elapsedTime);
@ -65,6 +61,7 @@ class NAZARA_API NzModel : public NzSceneNode, public NzUpdatable
bool HasAnimation() const;
bool IsAnimationEnabled() const;
virtual bool IsAnimated() const;
bool IsDrawable() const;
void InvalidateBoundingVolume();
@ -75,12 +72,11 @@ class NAZARA_API NzModel : public NzSceneNode, public NzUpdatable
void Reset();
bool SetAnimation(NzAnimation* animation);
bool SetMaterial(const NzString& subMeshName, NzMaterial* material);
void SetMaterial(unsigned int matIndex, NzMaterial* material);
bool SetMaterial(unsigned int skinIndex, const NzString& subMeshName, NzMaterial* material);
void SetMaterial(unsigned int skinIndex, unsigned int matIndex, NzMaterial* material);
void SetMesh(NzMesh* mesh);
virtual void SetMesh(NzMesh* mesh);
bool SetSequence(const NzString& sequenceName);
void SetSequence(unsigned int sequenceIndex);
void SetSkin(unsigned int skin);
@ -89,26 +85,16 @@ class NAZARA_API NzModel : public NzSceneNode, public NzUpdatable
NzModel& operator=(const NzModel& node);
NzModel& operator=(NzModel&& node);
private:
protected:
bool FrustumCull(const NzFrustumf& frustum) override;
void InvalidateNode() override;
void Register() override;
void Unregister() override;
void Update() override;
void UpdateBoundingVolume() const;
virtual void UpdateBoundingVolume() const;
std::vector<NzMaterialRef> m_materials;
NzAnimationRef m_animation;
mutable NzBoundingVolumef m_boundingVolume;
NzMeshRef m_mesh;
NzSkeleton m_skeleton; // Uniquement pour les animations squelettiques
const NzSequence* m_currentSequence;
bool m_animationEnabled;
mutable bool m_boundingVolumeUpdated;
float m_interpolation;
unsigned int m_currentFrame;
unsigned int m_matCount;
unsigned int m_nextFrame;
unsigned int m_skin;
unsigned int m_skinCount;

View File

@ -6,7 +6,7 @@
#include <Nazara/Graphics/AbstractRenderQueue.hpp>
#include <Nazara/Graphics/Camera.hpp>
#include <Nazara/Graphics/Config.hpp>
#include <Nazara/Utility/SkeletalMesh.hpp>
#include <Nazara/Utility/MeshData.hpp>
#include <Nazara/Utility/StaticMesh.hpp>
#include <memory>
#include <Nazara/Graphics/Debug.hpp>
@ -18,9 +18,6 @@ NzModelParameters::NzModelParameters()
bool NzModelParameters::IsValid() const
{
if (loadAnimation && !animation.IsValid())
return false;
if (loadMaterials && !material.IsValid())
return false;
@ -28,8 +25,6 @@ bool NzModelParameters::IsValid() const
}
NzModel::NzModel() :
m_currentSequence(nullptr),
m_animationEnabled(true),
m_boundingVolumeUpdated(true),
m_matCount(0),
m_skin(0),
@ -41,25 +36,16 @@ NzModel::NzModel(const NzModel& model) :
NzSceneNode(model),
m_materials(model.m_materials),
m_boundingVolume(model.m_boundingVolume),
m_currentSequence(model.m_currentSequence),
m_animationEnabled(model.m_animationEnabled),
m_boundingVolumeUpdated(model.m_boundingVolumeUpdated),
m_interpolation(model.m_interpolation),
m_currentFrame(model.m_currentFrame),
m_matCount(model.m_matCount),
m_nextFrame(model.m_nextFrame),
m_skin(model.m_skin),
m_skinCount(model.m_skinCount)
{
if (model.m_mesh)
{
// Nous n'avons une animation et des matériaux que si nous avons un mesh
m_animation = model.m_animation;
// Nous n'avons des matériaux que si nous avons un mesh
m_mesh = model.m_mesh;
m_materials = model.m_materials;
if (m_mesh->GetAnimationType() == nzAnimationType_Skeletal)
m_skeleton = model.m_skeleton;
}
SetParent(model);
@ -77,64 +63,18 @@ void NzModel::AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const
unsigned int submeshCount = m_mesh->GetSubMeshCount();
for (unsigned int i = 0; i < submeshCount; ++i)
{
NzSubMesh* subMesh = m_mesh->GetSubMesh(i);
NzMaterial* material = m_materials[subMesh->GetMaterialIndex()];
const NzStaticMesh* mesh = static_cast<const NzStaticMesh*>(m_mesh->GetSubMesh(i));
NzMaterial* material = m_materials[mesh->GetMaterialIndex()];
renderQueue->AddSubMesh(material, subMesh, transformMatrix);
NzMeshData meshData;
meshData.indexBuffer = mesh->GetIndexBuffer();
meshData.primitiveMode = mesh->GetPrimitiveMode();
meshData.vertexBuffer = mesh->GetVertexBuffer();
renderQueue->AddMesh(material, meshData, mesh->GetAABB(), transformMatrix);
}
}
void NzModel::AdvanceAnimation(float elapsedTime)
{
#if NAZARA_GRAPHICS_SAFE
if (!m_animation)
{
NazaraError("Model has no animation");
return;
}
#endif
m_interpolation += m_currentSequence->frameRate * elapsedTime;
while (m_interpolation > 1.f)
{
m_interpolation -= 1.f;
unsigned lastFrame = m_currentSequence->firstFrame + m_currentSequence->frameCount - 1;
if (m_nextFrame+1 > lastFrame)
{
if (m_animation->IsLoopPointInterpolationEnabled())
{
m_currentFrame = m_nextFrame;
m_nextFrame = m_currentSequence->firstFrame;
}
else
{
m_currentFrame = m_currentSequence->firstFrame;
m_nextFrame = m_currentFrame+1;
}
}
else
{
m_currentFrame = m_nextFrame;
m_nextFrame++;
}
}
m_animation->AnimateSkeleton(&m_skeleton, m_currentFrame, m_nextFrame, m_interpolation);
m_boundingVolume.MakeNull();
m_boundingVolumeUpdated = false;
}
void NzModel::EnableAnimation(bool animation)
{
m_animationEnabled = animation;
}
NzAnimation* NzModel::GetAnimation() const
{
return m_animation;
}
const NzBoundingVolumef& NzModel::GetBoundingVolume() const
{
#if NAZARA_GRAPHICS_SAFE
@ -254,16 +194,6 @@ nzSceneNodeType NzModel::GetSceneNodeType() const
return nzSceneNodeType_Model;
}
NzSkeleton* NzModel::GetSkeleton()
{
return &m_skeleton;
}
const NzSkeleton* NzModel::GetSkeleton() const
{
return &m_skeleton;
}
unsigned int NzModel::GetSkin() const
{
return m_skin;
@ -274,14 +204,9 @@ unsigned int NzModel::GetSkinCount() const
return m_skinCount;
}
bool NzModel::HasAnimation() const
bool NzModel::IsAnimated() const
{
return m_animation != nullptr;
}
bool NzModel::IsAnimationEnabled() const
{
return m_animationEnabled;
return false;
}
bool NzModel::IsDrawable() const
@ -312,70 +237,16 @@ bool NzModel::LoadFromStream(NzInputStream& stream, const NzModelParameters& par
void NzModel::Reset()
{
if (m_scene)
m_scene->UnregisterForUpdate(this);
m_matCount = 0;
m_skinCount = 0;
if (m_mesh)
{
m_animation.Reset();
m_mesh.Reset();
m_materials.clear();
m_skeleton.Destroy();
}
}
bool NzModel::SetAnimation(NzAnimation* animation)
{
#if NAZARA_GRAPHICS_SAFE
if (!m_mesh)
{
NazaraError("Model has no animation");
return false;
}
if (animation)
{
if (!animation->IsValid())
{
NazaraError("Invalid animation");
return false;
}
if (animation->GetType() != m_mesh->GetAnimationType())
{
NazaraError("Animation type must match mesh animation type");
return false;
}
if (animation->GetType() == nzAnimationType_Skeletal && animation->GetJointCount() != m_mesh->GetJointCount())
{
NazaraError("Animation joint count must match mesh joint count");
return false;
}
}
#endif
m_animation = animation;
if (m_animation)
{
m_currentFrame = 0;
m_interpolation = 0.f;
SetSequence(0);
if (m_scene)
m_scene->RegisterForUpdate(this);
}
else if (m_scene)
m_scene->UnregisterForUpdate(this);
return true;
}
bool NzModel::SetMaterial(const NzString& subMeshName, NzMaterial* material)
{
NzSubMesh* subMesh = m_mesh->GetSubMesh(subMeshName);
@ -480,25 +351,18 @@ void NzModel::SetMaterial(unsigned int skinIndex, unsigned int matIndex, NzMater
void NzModel::SetMesh(NzMesh* mesh)
{
#if NAZARA_GRAPHICS_SAFE
if (mesh && !mesh->IsValid())
{
NazaraError("Invalid mesh");
return;
}
#endif
m_mesh = mesh;
if (m_mesh)
{
m_boundingVolume.MakeNull();
m_boundingVolumeUpdated = false;
if (m_mesh->GetAnimationType() == nzAnimationType_Skeletal)
m_skeleton = *mesh->GetSkeleton(); // Copie du squelette template
if (m_animation)
{
if (m_animation->GetJointCount() != m_mesh->GetJointCount())
{
NazaraWarning("Animation joint count is not matching new mesh joint count");
SetAnimation(nullptr);
}
}
m_matCount = mesh->GetMaterialCount();
m_materials.clear();
m_materials.resize(m_matCount, NzMaterial::GetDefault());
@ -506,61 +370,12 @@ void NzModel::SetMesh(NzMesh* mesh)
}
else
{
m_boundingVolume.MakeNull();
m_boundingVolumeUpdated = true;
m_matCount = 0;
m_materials.clear();
m_skinCount = 0;
SetAnimation(nullptr);
}
}
bool NzModel::SetSequence(const NzString& sequenceName)
{
///TODO: Rendre cette erreur "safe" avec le nouveau système de gestions d'erreur (No-log)
#if NAZARA_GRAPHICS_SAFE
if (!m_animation)
{
NazaraError("Model has no animation");
return false;
}
#endif
const NzSequence* currentSequence = m_animation->GetSequence(sequenceName);
if (!currentSequence)
{
NazaraError("Sequence not found");
return false;
}
m_currentSequence = currentSequence;
m_nextFrame = m_currentSequence->firstFrame;
return true;
}
void NzModel::SetSequence(unsigned int sequenceIndex)
{
#if NAZARA_GRAPHICS_SAFE
if (!m_animation)
{
NazaraError("Model has no animation");
return;
}
#endif
const NzSequence* currentSequence = m_animation->GetSequence(sequenceIndex);
#if NAZARA_GRAPHICS_SAFE
if (!currentSequence)
{
NazaraError("Sequence not found");
return;
}
#endif
m_currentSequence = currentSequence;
m_nextFrame = m_currentSequence->firstFrame;
InvalidateBoundingVolume();
}
void NzModel::SetSkin(unsigned int skin)
@ -594,23 +409,14 @@ NzModel& NzModel::operator=(const NzModel& node)
{
NzSceneNode::operator=(node);
m_animation = node.m_animation;
m_animationEnabled = node.m_animationEnabled;
m_boundingVolume = node.m_boundingVolume;
m_boundingVolumeUpdated = node.m_boundingVolumeUpdated;
m_currentFrame = node.m_currentFrame;
m_currentSequence = node.m_currentSequence;
m_interpolation = node.m_interpolation;
m_matCount = node.m_matCount;
m_materials = node.m_materials;
m_mesh = node.m_mesh;
m_nextFrame = node.m_nextFrame;
m_skin = node.m_skin;
m_skinCount = node.m_skinCount;
if (m_mesh->GetAnimationType() == nzAnimationType_Skeletal)
m_skeleton = node.m_skeleton;
return *this;
}
@ -619,22 +425,13 @@ NzModel& NzModel::operator=(NzModel&& node)
NzSceneNode::operator=(node);
// Ressources
m_animation = std::move(node.m_animation);
m_mesh = std::move(node.m_mesh);
m_materials = std::move(node.m_materials);
if (m_mesh->GetAnimationType() == nzAnimationType_Skeletal)
m_skeleton = std::move(node.m_skeleton);
// Paramètres
m_animationEnabled = node.m_animationEnabled;
m_boundingVolume = node.m_boundingVolume;
m_boundingVolumeUpdated = node.m_boundingVolumeUpdated;
m_currentFrame = node.m_currentFrame;
m_currentSequence = node.m_currentSequence;
m_interpolation = node.m_interpolation;
m_matCount = node.m_matCount;
m_nextFrame = node.m_nextFrame;
m_skin = node.m_skin;
m_skinCount = node.m_skinCount;
@ -656,32 +453,10 @@ void NzModel::InvalidateNode()
m_boundingVolumeUpdated = false;
}
void NzModel::Register()
{
if (m_animation)
m_scene->RegisterForUpdate(this);
}
void NzModel::Unregister()
{
m_scene->UnregisterForUpdate(this);
}
void NzModel::Update()
{
if (m_animationEnabled && m_animation)
AdvanceAnimation(m_scene->GetUpdateTime());
}
void NzModel::UpdateBoundingVolume() const
{
if (m_boundingVolume.IsNull())
{
if (m_mesh->GetAnimationType() == nzAnimationType_Skeletal)
m_boundingVolume.Set(m_skeleton.GetAABB());
else
m_boundingVolume.Set(m_mesh->GetAABB());
}
m_boundingVolume.Set(m_mesh->GetAABB());
if (!m_transformMatrixUpdated)
UpdateTransformMatrix();