Model can no longer be animated (SkeletalModel will)
Former-commit-id: e203a3dddf74bb171d8abe961e8a2f28df13bcad
This commit is contained in:
parent
c901b5808e
commit
fa5b1ab000
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
Loading…
Reference in New Issue