mirror of
https://github.com/antopilo/Nuake.git
synced 2026-09-15 20:08:54 +03:00
Added skeleton hierarchy
This commit is contained in:
@@ -11,6 +11,7 @@
|
||||
#include "src/Rendering/Buffers/VertexArray.h"
|
||||
#include "src/Rendering/Buffers/VertexBufferLayout.h"
|
||||
|
||||
|
||||
#include <future>
|
||||
|
||||
namespace Nuake
|
||||
@@ -199,4 +200,9 @@ namespace Nuake
|
||||
SetupMesh();
|
||||
return true;
|
||||
}
|
||||
|
||||
void SkinnedMesh::SetSkeletalAnimation(Ref<SkeletalAnimation> skeletalAnimation)
|
||||
{
|
||||
m_SkeletalAnimation = skeletalAnimation;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "src/Rendering/AABB.h"
|
||||
#include "src/Resource/Resource.h"
|
||||
#include "src/Resource/Serializable.h"
|
||||
#include "src/Resource/SkeletalAnimation.h"
|
||||
|
||||
#include "src/Rendering/Vertex.h"
|
||||
#include "src/Rendering/Mesh/Bone.h"
|
||||
@@ -39,7 +40,12 @@ 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;
|
||||
|
||||
@@ -77,7 +77,6 @@ namespace Nuake
|
||||
}
|
||||
|
||||
ProcessSkinnedNode(scene->mRootNode, scene);
|
||||
|
||||
if (scene->HasAnimations())
|
||||
{
|
||||
SkeletalAnimation animation;
|
||||
@@ -353,6 +352,23 @@ namespace Nuake
|
||||
}
|
||||
}
|
||||
|
||||
void ModelLoader::ProcessSkeleton(SkeletonNode& des, const aiNode* src)
|
||||
{
|
||||
// Create a Bone object for this node
|
||||
SkeletonNode bone;
|
||||
bone.Name = src->mName.C_Str();
|
||||
bone.Transform = ConvertMatrixToGLMFormat(src->mTransformation);
|
||||
|
||||
des.ChildrenCount++;
|
||||
des.Children.push_back(bone);
|
||||
|
||||
// Recursively process child nodes (bones)
|
||||
for (uint32_t i = 0; i < src->mNumChildren; i++)
|
||||
{
|
||||
ProcessSkeleton(bone, src->mChildren[i]);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<uint32_t> ModelLoader::ProcessIndices(aiMesh* mesh)
|
||||
{
|
||||
auto indices = std::vector<uint32_t>();
|
||||
|
||||
@@ -48,6 +48,7 @@ namespace Nuake
|
||||
std::vector<SkinnedVertex> ProcessSkinnedVertices(aiMesh* mesh);
|
||||
void SetVertexBoneData(SkinnedVertex& vertex, int boneId, float weight);
|
||||
void ProcessAnimationNode(SkeletonNode& dest, const aiNode* src);
|
||||
void ProcessSkeleton(SkeletonNode& des, const aiNode* src);
|
||||
|
||||
static inline Matrix4 ConvertMatrixToGLMFormat(const aiMatrix4x4& from)
|
||||
{
|
||||
|
||||
@@ -11,12 +11,24 @@ namespace Nuake
|
||||
Vector3 Scalings;
|
||||
};
|
||||
|
||||
struct BoneTransformTrack
|
||||
{
|
||||
std::vector<float> positionTimestamps = {};
|
||||
std::vector<float> rotationTimestamps = {};
|
||||
std::vector<float> scaleTimestamps = {};
|
||||
|
||||
std::vector<Vector3> positions = {};
|
||||
std::vector<Quat> rotations = {};
|
||||
std::vector<Vector3> scales = {};
|
||||
};
|
||||
|
||||
class SkeletalAnimation
|
||||
{
|
||||
private:
|
||||
float m_Duration;
|
||||
int m_TicksPerSecond;
|
||||
|
||||
std::unordered_map<std::string, BoneTransformTrack> m_Tracks;
|
||||
std::vector<Bone> m_Bones;
|
||||
|
||||
public:
|
||||
|
||||
@@ -20,6 +20,7 @@ namespace Nuake
|
||||
SkinnedModel(const std::string path);
|
||||
~SkinnedModel();
|
||||
|
||||
SkeletonNode& GetSkeletonRootNode() { return m_SkeletonRoot; }
|
||||
void SetSkeletonRootNode(SkeletonNode& root)
|
||||
{
|
||||
m_SkeletonRoot = std::move(root);
|
||||
|
||||
@@ -466,33 +466,25 @@ namespace Nuake
|
||||
return;
|
||||
}
|
||||
|
||||
SkinnedModelComponent& component = entity.GetComponent<SkinnedModelComponent>();
|
||||
for (Ref<SkinnedMesh>& model : component.ModelResource->GetMeshes())
|
||||
auto& component = entity.GetComponent<SkinnedModelComponent>();
|
||||
auto& skeletonRoot = component.ModelResource->GetSkeletonRootNode();
|
||||
|
||||
Entity skeletonRootEntity = CreateEntity(skeletonRoot.Name);
|
||||
skeletonRootEntity.AddComponent<BoneComponent>();
|
||||
entity.AddChild(skeletonRootEntity);
|
||||
|
||||
CreateSkeletonTraverse(skeletonRootEntity, skeletonRoot);
|
||||
}
|
||||
|
||||
void Scene::CreateSkeletonTraverse(Entity& entity, SkeletonNode& skeletonNode)
|
||||
{
|
||||
for (auto& c : skeletonNode.Children)
|
||||
{
|
||||
for (auto& bone : model->GetBones())
|
||||
{
|
||||
auto& parentComponent = entity.GetComponent<ParentComponent>();
|
||||
Entity boneEntity = CreateEntity(c.Name);
|
||||
boneEntity.AddComponent<BoneComponent>();
|
||||
entity.AddChild(boneEntity);
|
||||
|
||||
Logger::Log("bone found:" + bone.Name, "debug", VERBOSE);
|
||||
if (EntityExists(bone.Name) == false)
|
||||
{
|
||||
Entity boneEntity = CreateEntity(bone.Name);
|
||||
boneEntity.AddComponent<BoneComponent>();
|
||||
|
||||
Vector3 position;
|
||||
Quat rotation;
|
||||
Vector3 scale;
|
||||
Decompose(bone.Offset, position, rotation, scale);
|
||||
|
||||
auto& transformComponent = entity.GetComponent<TransformComponent>();
|
||||
transformComponent.SetLocalPosition(position);
|
||||
transformComponent.SetLocalRotation(rotation);
|
||||
transformComponent.SetLocalScale(scale);
|
||||
transformComponent.SetLocalTransform(bone.Offset);
|
||||
|
||||
entity.AddChild(boneEntity);
|
||||
}
|
||||
}
|
||||
CreateSkeletonTraverse(boneEntity, c);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
namespace Nuake
|
||||
{
|
||||
class SkeletonNode;
|
||||
class Entity;
|
||||
class SceneRenderer;
|
||||
|
||||
@@ -93,5 +94,8 @@ namespace Nuake
|
||||
|
||||
// Component specific utilies
|
||||
void CreateSkeleton(Entity& entity);
|
||||
|
||||
private:
|
||||
void CreateSkeletonTraverse(Entity& entity, SkeletonNode& skeletonNode);
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user