Guest User

skeletalAnimation.h

a guest
Jan 14th, 2024
123
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.95 KB | Source Code | 0 0
  1. #include <glm/glm.hpp>
  2. #include <map>
  3. #include <array>
  4. #include <vector>
  5. #include <stack>
  6. #include <iostream>
  7. #include <assimp/Importer.hpp>      // C++ importer interface
  8. #include <assimp/scene.h>           // Output data structure
  9. #include <assimp/postprocess.h>     // Post processing flags
  10.  
  11. struct Vertex {
  12.     static const uint max_bones_in_num_of_vec4 = 4;
  13.     alignas(16) glm::vec3 pos;
  14.     uint boneids[max_bones_in_num_of_vec4*4];
  15.     float weights[max_bones_in_num_of_vec4*4];
  16.  
  17.     void addBoneData(uint boneid, float weight) {
  18.         for(uint i = 0; i < max_bones_in_num_of_vec4*4; i++) {
  19.             if(weights[i] == 0) {
  20.                 boneids[i] = boneid;
  21.                 weights[i] = weight;
  22.                 return;
  23.             }
  24.         }
  25.  
  26.         throw std::runtime_error("More bones than we have space for");
  27.     }
  28.  
  29.     static VkVertexInputBindingDescription getBindingDescription() {
  30.         VkVertexInputBindingDescription bindingDescription{};
  31.         bindingDescription.binding = 0;
  32.         bindingDescription.stride = sizeof(Vertex);
  33.         bindingDescription.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
  34.  
  35.         return bindingDescription;
  36.     }
  37.  
  38.     static std::vector<VkVertexInputAttributeDescription> getAttributeDescriptions() {
  39.         std::vector<VkVertexInputAttributeDescription> attributeDescriptions{};
  40.         attributeDescriptions.resize(max_bones_in_num_of_vec4*2+1);
  41.  
  42.         attributeDescriptions[0].binding = 0;
  43.         attributeDescriptions[0].location = 0;
  44.         attributeDescriptions[0].format = VK_FORMAT_R32G32B32_SFLOAT;
  45.         attributeDescriptions[0].offset = offsetof(Vertex, pos);
  46.  
  47.         uint i = 1;
  48.         for(; i < max_bones_in_num_of_vec4+1; i++) {
  49.             attributeDescriptions[i].binding = 0;
  50.             attributeDescriptions[i].location = i;
  51.             attributeDescriptions[i].format = VK_FORMAT_R32G32B32A32_SFLOAT;
  52.             attributeDescriptions[i].offset = offsetof(Vertex, weights) + (i-1)*16;
  53.         }
  54.  
  55.         for(uint i2 = 0; i2 < max_bones_in_num_of_vec4; i2++) {
  56.             attributeDescriptions[i2+i].binding = 0;
  57.             attributeDescriptions[i2+i].location = i2+i;
  58.             attributeDescriptions[i2+i].format = VK_FORMAT_R32G32B32A32_UINT;
  59.             attributeDescriptions[i2+i].offset = offsetof(Vertex, boneids) + i2*16;
  60.         }
  61.  
  62.         return attributeDescriptions;
  63.     }
  64. };
  65.  
  66. class skeletalAnimation
  67. {
  68. public:
  69.     const aiScene* asmpScene;
  70.     skeletalAnimation(std::string name);
  71.     ~skeletalAnimation();
  72.  
  73.     void loadAnimation(std::string path);
  74.     void printTree();
  75.     void printOgTree();
  76.     void traverse(float animationTime);
  77.  
  78.     struct Node {
  79.         std::string name;
  80.         aiMatrix4x4 localTransformation;
  81.         aiMatrix4x4 transformation;
  82.         int parent;
  83.         int firstChild;
  84.         int nextSibling;
  85.     };
  86.  
  87.     struct Scene {
  88.         Node root;
  89.         int animationIndex = -1;
  90.         int animationDuration;
  91.         aiMatrix4x4 globalInverseTransform;
  92.         std::vector<Node> hierarchy;
  93.         std::vector<Vertex> vertices;
  94.         std::vector<uint> indices;
  95.         std::map<std::string, uint> bone_name_to_index_map;
  96.         struct BoneInfo
  97.         {
  98.             aiMatrix4x4 OffsetMatrix;
  99.             //int FinalTransformation;
  100.  
  101.             BoneInfo(const aiMatrix4x4& Offset)
  102.             {
  103.                 OffsetMatrix = Offset;
  104.                 //FinalTransformation = -1;
  105.             }
  106.         };
  107.  
  108.         std::vector<aiMatrix4x4> finalTransforms;
  109.         std::vector<BoneInfo> bones;
  110.  
  111.         std::vector<uint> mesh_base_vertex;
  112.  
  113.         uint getBoneId(const aiBone* bone) {
  114.             uint boneId = 0;
  115.             std::string boneName(bone->mName.C_Str());
  116.  
  117.             if(bone_name_to_index_map.find(boneName) == bone_name_to_index_map.end()) {
  118.                 boneId = bone_name_to_index_map.size();
  119.                 bone_name_to_index_map[boneName] = boneId;
  120.                 bones.push_back(BoneInfo(bone->mOffsetMatrix));
  121.                 finalTransforms.push_back(aiMatrix4x4());
  122.             } else {
  123.                 boneId = bone_name_to_index_map[boneName];
  124.             }
  125.             return boneId;
  126.         }
  127.     } scene;
  128.  
  129. private:
  130.     /* data */
  131.     Assimp::Importer importer;
  132.     aiNodeAnim* findNodeAnim(const char* nodeName);
  133.     void convertScene();
  134.     void loadMeshes();
  135.     void loadBone(const aiBone* bone, uint meshIndex);
  136.     uint FindPosition(float AnimationTimeTicks, const aiNodeAnim* pNodeAnim);
  137.     void CalcInterpolatedPosition(aiVector3D& Out, float AnimationTimeTicks, const aiNodeAnim* pNodeAnim);
  138.  
  139.     uint FindRotation(float AnimationTime, const aiNodeAnim* pNodeAnim);
  140.     void CalcInterpolatedRotation(aiQuaternion& Out, float AnimationTime, const aiNodeAnim* pNodeAnim);
  141.  
  142.     uint FindScaling(float AnimationTimeTicks, const aiNodeAnim* pNodeAnim);
  143.     void CalcInterpolatedScaling(aiVector3D& Out, float AnimationTimeTicks, const aiNodeAnim* pNodeAnim);
  144. };
Advertisement
Add Comment
Please, Sign In to add comment