11#pragma once
22
3+ #include < unordered_map>
4+ #include < vector>
5+
36#include " animation.hpp"
47
58namespace our {
@@ -9,22 +12,27 @@ namespace our {
912 class Animator {
1013 const Animation* currentAnimation;
1114 float currentTime; // in ticks
12- std::vector<glm::mat4> finalBoneMatrices;
15+ // there are 2 types of animations that assimp supports
16+ // 1. skeletal animations that affect the bones and are used for skinning meshes
17+ // 2. node animations that affect any node in the hierarchy but are not used for skinning
18+ // (eg. a whole mesh rotating as a child of a bone, or a light source attached to a bone)
19+ std::vector<glm::mat4> finalBoneMatrices; // for bone animations
20+ std::unordered_map<std::string, glm::mat4> nodeTransforms; // for node animations
1321 bool loop;
1422
1523 void computeBoneTransform (const std::vector<SkeletonNode>& nodes) {
1624 const Skeleton& skeleton = currentAnimation->skeleton ;
1725 std::vector<glm::mat4> globalTransforms (nodes.size ());
26+ nodeTransforms.clear ();
1827
1928 for (int i = 0 ; i < (int )nodes.size (); i++) {
2029 const auto & node = nodes[i];
2130
2231 // animated local transform, fallback to bind pose
2332 glm::mat4 localTransform = node.localTransform ;
24- BoneID id = skeleton.getBoneID (node.name );
25- if (id >= 0 ) {
26- auto it = currentAnimation->bones .find (id);
27- if (it != currentAnimation->bones .end ()) localTransform = it->second .interpolate (currentTime);
33+ auto it = currentAnimation->channels .find (node.name );
34+ if (it != currentAnimation->channels .end ()) {
35+ localTransform = it->second .interpolate (currentTime);
2836 }
2937
3038 // accumulate from parent
@@ -33,6 +41,11 @@ namespace our {
3341 else
3442 globalTransforms[i] = globalTransforms[node.parentIndex ] * localTransform;
3543
44+ // Cache for meshes
45+ nodeTransforms[node.name ] = globalTransforms[i];
46+
47+ // Cache for skeletal bones
48+ BoneID id = skeleton.getBoneID (node.name );
3649 if (id >= 0 && id < (BoneID)finalBoneMatrices.size ())
3750 finalBoneMatrices[id] = skeleton.getGlobalInverseTransform () * globalTransforms[i] *
3851 skeleton.getOffsetMatrix (node.name );
@@ -63,6 +76,12 @@ namespace our {
6376 return finalBoneMatrices;
6477 }
6578
79+ const glm::mat4* getNodeTransform (const std::string& name) const {
80+ auto it = nodeTransforms.find (name);
81+ if (it != nodeTransforms.end ()) return &it->second ;
82+ return nullptr ;
83+ }
84+
6685 bool isFinished () const {
6786 return currentAnimation && currentTime >= currentAnimation->duration ;
6887 }
0 commit comments