mirror of
https://github.com/antopilo/Nuake.git
synced 2026-09-15 20:08:54 +03:00
Animation serialization progress
This commit is contained in:
@@ -119,8 +119,9 @@ public:
|
||||
ImGui::TableNextColumn();
|
||||
}
|
||||
|
||||
if(model->GetCurrentAnimation())
|
||||
{
|
||||
ImGui::Text("Type");
|
||||
ImGui::Text("Animation");
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
uint32_t animIndex = model->GetCurrentAnimationIndex();
|
||||
@@ -131,7 +132,14 @@ public:
|
||||
for (int n = 0; n < model->GetAnimationsCount(); n++)
|
||||
{
|
||||
bool is_selected = (animIndex == n);
|
||||
if (ImGui::Selectable(animations[n]->GetName().c_str(), is_selected))
|
||||
std::string animName = animations[n]->GetName();
|
||||
|
||||
if (animName.empty())
|
||||
{
|
||||
animName = "Empty";
|
||||
}
|
||||
|
||||
if (ImGui::Selectable(animName.c_str(), is_selected))
|
||||
{
|
||||
animIndex = n;
|
||||
}
|
||||
|
||||
@@ -145,6 +145,12 @@ namespace Nuake
|
||||
v["Bitangent"]["y"] = m_Vertices[i].bitangent.y;
|
||||
v["Bitangent"]["z"] = m_Vertices[i].bitangent.z;
|
||||
|
||||
for (uint32_t b = 0; b < MAX_BONE_INFLUENCE; b++)
|
||||
{
|
||||
v["Weight"][b] = m_Vertices[i].weights[b];
|
||||
v["BoneIDs"][b] = m_Vertices[i].boneIDs[b];
|
||||
}
|
||||
|
||||
j["Vertices"][i] = v;
|
||||
}
|
||||
|
||||
@@ -177,10 +183,17 @@ namespace Nuake
|
||||
vertex.uv = { 0.0, 0.0 };
|
||||
}
|
||||
DESERIALIZE_VEC3(v["Position"], vertex.position)
|
||||
DESERIALIZE_VEC3(v["Normal"], vertex.normal)
|
||||
DESERIALIZE_VEC3(v["Tangent"], vertex.tangent)
|
||||
DESERIALIZE_VEC3(v["Bitangent"], vertex.bitangent)
|
||||
vertices.push_back(vertex);
|
||||
DESERIALIZE_VEC3(v["Normal"], vertex.normal)
|
||||
DESERIALIZE_VEC3(v["Tangent"], vertex.tangent)
|
||||
DESERIALIZE_VEC3(v["Bitangent"], vertex.bitangent)
|
||||
|
||||
for (uint32_t i = 0; i < MAX_BONE_INFLUENCE; i++)
|
||||
{
|
||||
vertex.weights[i] = v["Weight"][i];
|
||||
vertex.boneIDs[i] = v["boneIDs"][i];
|
||||
}
|
||||
|
||||
vertices.push_back(vertex);
|
||||
}
|
||||
}
|
||||
);
|
||||
@@ -190,9 +203,4 @@ namespace Nuake
|
||||
SetupMesh();
|
||||
return true;
|
||||
}
|
||||
|
||||
void SkinnedMesh::SetSkeletalAnimation(Ref<SkeletalAnimation> skeletalAnimation)
|
||||
{
|
||||
m_SkeletalAnimation = skeletalAnimation;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,6 @@ namespace Nuake
|
||||
void AddSurface(std::vector<SkinnedVertex> vertices, std::vector<uint32_t> indices, std::vector<Bone> bones);
|
||||
std::vector<SkinnedVertex>& GetVertices();
|
||||
std::vector<uint32_t>& GetIndices();
|
||||
std::vector<Bone>& GetBones();
|
||||
|
||||
Ref<Material> GetMaterial() inline const;
|
||||
void SetMaterial(Ref<Material> material);
|
||||
@@ -40,12 +39,7 @@ namespace Nuake
|
||||
json Serialize() override;
|
||||
bool Deserialize(const json& j) override;
|
||||
|
||||
void SetSkeletalAnimation(Ref<SkeletalAnimation> animation);
|
||||
Ref<SkeletalAnimation> GetSkeletalAnimation() const { return m_SkeletalAnimation; }
|
||||
|
||||
private:
|
||||
Ref<SkeletalAnimation> m_SkeletalAnimation;
|
||||
|
||||
Ref<Material> m_Material = nullptr;
|
||||
std::vector<uint32_t> m_Indices;
|
||||
std::vector<SkinnedVertex> m_Vertices;
|
||||
|
||||
@@ -67,7 +67,8 @@ namespace Nuake
|
||||
aiProcess_Triangulate |
|
||||
aiProcess_GenSmoothNormals |
|
||||
aiProcess_FixInfacingNormals |
|
||||
aiProcess_CalcTangentSpace;
|
||||
aiProcess_CalcTangentSpace |
|
||||
aiProcess_OptimizeGraph;
|
||||
|
||||
modelDir = absolute ? path + "/../" : FileSystem::Root + path + "/../";
|
||||
const std::string filePath = absolute ? path : FileSystem::Root + path;
|
||||
|
||||
@@ -82,6 +82,47 @@ namespace Nuake
|
||||
return glm::scale(glm::mat4(1.0f), finalScale);
|
||||
}
|
||||
|
||||
json BoneTransformTrack::Serialize()
|
||||
{
|
||||
BEGIN_SERIALIZE();
|
||||
for (uint32_t i = 0; i < m_PositionTimestamps.size(); i++)
|
||||
{
|
||||
j["m_PositionTimestamps"][i] = m_PositionTimestamps[i];
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < m_Positions.size(); i++)
|
||||
{
|
||||
j["m_Positions"][i] = SERIALIZE_VEC3(m_Positions[i]);
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < m_RotationTimestamps.size(); i++)
|
||||
{
|
||||
j["m_RotationTimestamps"][i] = m_RotationTimestamps[i];
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < m_Rotations.size(); i++)
|
||||
{
|
||||
j["m_Rotations"][i] = SERIALIZE_VEC4(m_Rotations[i]);
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < m_ScaleTimestamps.size(); i++)
|
||||
{
|
||||
j["m_ScaleTimestamps"][i] = m_ScaleTimestamps[i];
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < m_Scales.size(); i++)
|
||||
{
|
||||
j["m_Scales"][i] = SERIALIZE_VEC3(m_Scales[i]);
|
||||
}
|
||||
|
||||
END_SERIALIZE();
|
||||
}
|
||||
|
||||
bool BoneTransformTrack::Deserialize(const json& j)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
SkeletalAnimation::SkeletalAnimation(const std::string& name, float duration, float ticksPerSecond)
|
||||
{
|
||||
m_Name = name;
|
||||
@@ -101,4 +142,39 @@ namespace Nuake
|
||||
m_Tracks[name] = BoneTransformTrack();
|
||||
return m_Tracks[name];
|
||||
}
|
||||
|
||||
json SkeletalAnimation::Serialize()
|
||||
{
|
||||
BEGIN_SERIALIZE();
|
||||
SERIALIZE_VAL(m_Name);
|
||||
SERIALIZE_VAL(m_Duration);
|
||||
SERIALIZE_VAL(m_TicksPerSecond);
|
||||
SERIALIZE_VAL(m_CurrentTime);
|
||||
SERIALIZE_VAL(m_Loop);
|
||||
|
||||
for (auto& t : m_Tracks)
|
||||
{
|
||||
j["Tracks"][t.first] = t.second.Serialize();
|
||||
}
|
||||
|
||||
return json();
|
||||
}
|
||||
|
||||
bool SkeletalAnimation::Deserialize(const json& j)
|
||||
{
|
||||
m_Name = j["m_Name"];
|
||||
m_Duration = j["m_Duration"];
|
||||
m_TicksPerSecond = j["m_TicksPerSecond"];
|
||||
m_CurrentTime = j["m_CurrentTime"];
|
||||
m_Loop = j["m_Loop"];
|
||||
|
||||
for (auto& [trackName, trackData]: j["Tracks"].items())
|
||||
{
|
||||
BoneTransformTrack track;
|
||||
track.Deserialize(j["Tracks"][trackName]);
|
||||
m_Tracks[trackName] = std::move(track);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,6 +2,9 @@
|
||||
#include "src/Core/Core.h"
|
||||
#include <src/Rendering/Mesh/Bone.h>
|
||||
|
||||
#include "src/Resource/Serializable.h"
|
||||
#include "src/Resource/Resource.h"
|
||||
|
||||
namespace Nuake
|
||||
{
|
||||
struct SkeletonAnimationBoneAnimation
|
||||
@@ -94,9 +97,12 @@ namespace Nuake
|
||||
Matrix4 InterpolatePosition(float time);
|
||||
Matrix4 InterpolateRotation(float time);
|
||||
Matrix4 InterpolateScale(float time);
|
||||
|
||||
json Serialize();
|
||||
bool Deserialize(const json& j);
|
||||
};
|
||||
|
||||
class SkeletalAnimation
|
||||
class SkeletalAnimation : public Resource, ISerializable
|
||||
{
|
||||
private:
|
||||
std::unordered_map<std::string, BoneTransformTrack> m_Tracks;
|
||||
@@ -104,7 +110,7 @@ namespace Nuake
|
||||
float m_Duration;
|
||||
float m_TicksPerSecond;
|
||||
std::string m_Name;
|
||||
bool m_Loop;
|
||||
bool m_Loop = false;
|
||||
|
||||
public:
|
||||
SkeletalAnimation() = default;
|
||||
@@ -114,7 +120,14 @@ namespace Nuake
|
||||
|
||||
void SetCurrentTime(float time)
|
||||
{
|
||||
m_CurrentTime = fmod(time, m_Duration);
|
||||
if (m_Loop)
|
||||
{
|
||||
m_CurrentTime = fmod(time, m_Duration);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_CurrentTime = time;
|
||||
}
|
||||
}
|
||||
|
||||
float GetCurrentTime() const { return m_CurrentTime; }
|
||||
@@ -126,5 +139,8 @@ namespace Nuake
|
||||
const std::string& GetName() const { return m_Name; }
|
||||
BoneTransformTrack& GetTrack(const std::string& name);
|
||||
std::unordered_map<std::string, BoneTransformTrack>& GetTracks() { return m_Tracks; }
|
||||
|
||||
json Serialize() override;
|
||||
bool Deserialize(const json& j) override;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -78,7 +78,19 @@ namespace Nuake
|
||||
{
|
||||
j["Meshes"][i] = m_Meshes[i]->Serialize();
|
||||
}
|
||||
|
||||
j["m_CurrentAnimation"] = m_CurrentAnimation;
|
||||
j["m_NumAnimation"] = m_NumAnimation;
|
||||
|
||||
uint32_t a = 0;
|
||||
for (auto& animation : m_Animations)
|
||||
{
|
||||
j["m_Animations"][a] = animation->Serialize();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
END_SERIALIZE();
|
||||
}
|
||||
|
||||
@@ -91,6 +103,10 @@ namespace Nuake
|
||||
ModelLoader loader;
|
||||
auto otherModel = loader.LoadSkinnedModel(j["Path"], false);
|
||||
m_Meshes = otherModel->GetMeshes();
|
||||
m_Animations = otherModel->GetAnimations();
|
||||
m_SkeletonRoot = otherModel->GetSkeletonRootNode();
|
||||
m_NumAnimation = m_Animations.size();
|
||||
m_CurrentAnimation = 0;
|
||||
|
||||
this->Path = j["Path"];
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
#include "src/Core/Core.h"
|
||||
#include "src/Resource/Serializable.h"
|
||||
|
||||
|
||||
namespace Nuake
|
||||
@@ -11,5 +12,19 @@ namespace Nuake
|
||||
~BoneComponent() = default;
|
||||
|
||||
std::string Name;
|
||||
|
||||
json Serialize()
|
||||
{
|
||||
BEGIN_SERIALIZE();
|
||||
SERIALIZE_VAL(Name);
|
||||
END_SERIALIZE();
|
||||
}
|
||||
|
||||
bool Deserialize(const json& j)
|
||||
{
|
||||
Name = j["Name"];
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -16,6 +16,8 @@
|
||||
#include "src/Scene/Components/CapsuleColliderComponent.h"
|
||||
#include "src/Scene/Components/SpriteComponent.h"
|
||||
#include "src/Scene/Components/ParticleEmitterComponent.h"
|
||||
#include "src/Scene/Components/BoneComponent.h"
|
||||
#include "src/Scene/Components/SkinnedModelComponent.h"
|
||||
|
||||
namespace Nuake
|
||||
{
|
||||
@@ -69,7 +71,10 @@ namespace Nuake
|
||||
SERIALIZE_OBJECT_REF_LBL("QuakeMapComponent", GetComponent<QuakeMapComponent>())
|
||||
if (HasComponent<RigidBodyComponent>())
|
||||
SERIALIZE_OBJECT_REF_LBL("RigidBodyComponent", GetComponent<RigidBodyComponent>())
|
||||
|
||||
if (HasComponent<SkinnedModelComponent>())
|
||||
SERIALIZE_OBJECT_REF_LBL("SkinnedModelComponent", GetComponent<SkinnedModelComponent>())
|
||||
if (HasComponent<BoneComponent>())
|
||||
SERIALIZE_OBJECT_REF_LBL("BoneComponent", GetComponent<BoneComponent>())
|
||||
END_SERIALIZE();
|
||||
}
|
||||
|
||||
@@ -98,6 +103,8 @@ namespace Nuake
|
||||
DESERIALIZE_COMPONENT(SphereColliderComponent)
|
||||
DESERIALIZE_COMPONENT(RigidBodyComponent)
|
||||
DESERIALIZE_COMPONENT(BSPBrushComponent)
|
||||
DESERIALIZE_COMPONENT(BoneComponent)
|
||||
DESERIALIZE_COMPONENT(SkinnedModelComponent)
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -30,11 +30,14 @@ namespace Nuake
|
||||
}
|
||||
|
||||
Ref<SkeletalAnimation> animation = model->GetCurrentAnimation();
|
||||
float newAnimationTime = animation->GetCurrentTime() + (ts * animation->GetTicksPerSecond());
|
||||
animation->SetCurrentTime(newAnimationTime);
|
||||
if (animation && model->IsPlaying)
|
||||
{
|
||||
float newAnimationTime = animation->GetCurrentTime() + (ts * animation->GetTicksPerSecond());
|
||||
animation->SetCurrentTime(newAnimationTime);
|
||||
|
||||
auto& rootBone = model->GetSkeletonRootNode();
|
||||
UpdateBonePositionTraversal(rootBone, animation, animation->GetCurrentTime());
|
||||
auto& rootBone = model->GetSkeletonRootNode();
|
||||
UpdateBonePositionTraversal(rootBone, animation, animation->GetCurrentTime());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user