Do boning and animation properly
[opengl.git] / model.hpp
index e0c8a2d93acd0a4e7fedcd542bcc4a36cb1746a9..bf6f08f346133920d792870d6a0f42249fe5e0cd 100644 (file)
--- a/model.hpp
+++ b/model.hpp
@@ -1,4 +1,6 @@
 #include <vector>
 #include <vector>
+#include <map>
+#include <set>
 #ifdef __APPLE__
 #include <GL/glew.h>
 #else
 #ifdef __APPLE__
 #include <GL/glew.h>
 #else
@@ -6,51 +8,80 @@
 #endif
 #include <glm/glm.hpp>
 #include <assimp/scene.h>
 #endif
 #include <glm/glm.hpp>
 #include <assimp/scene.h>
-#include <assimp/Importer.hpp>
 #include "material.hpp"
 #include "program.hpp"
 #include "skybox.hpp"
 
 #include "material.hpp"
 #include "program.hpp"
 #include "skybox.hpp"
 
+inline glm::mat4 aiMatrixToMat4(aiMatrix4x4 from) {
+       glm::mat4 to;
+       for (int i = 0; i < 4; i++)
+               for (int j = 0; j < 4; j++)
+                       to[i][j] = from[j][i];
+       return to;
+}
+
 class Model {
 
 class Model {
 
+       struct Animation {
+               double duration;
+               std::vector<const aiNodeAnim*> nodeAnims;
+       };
+
+       typedef std::map<std::string, std::pair<unsigned int, aiBone*>> BoneMap;
+       typedef std::map<std::string, std::vector<const Animation>> AnimMap;
+       typedef std::map<std::string, glm::mat4> BoneTransforms;
+
+       struct VertBones {
+               unsigned int ids[4] = {0, 0, 0 ,0};
+               float weights[4] = {1, 0, 0, 0};
+       };
+
        struct Mesh {
                Mesh(const aiMesh *aiMesh, GLuint progId);
                GLuint progId, vao, numIndices;
                unsigned int materialIndex;
        struct Mesh {
                Mesh(const aiMesh *aiMesh, GLuint progId);
                GLuint progId, vao, numIndices;
                unsigned int materialIndex;
+               BoneMap boneMap;
        };
        
        public:
        };
        
        public:
-               Model(const std::string &path, Program p, Skybox s);
-               void draw() const;
+               Model(const aiScene *scene, Program p);
+               void draw(Skybox skybox, const float tick) const;
 
                class Node {
                        public:
 
                class Node {
                        public:
-                               Node(const aiNode &aiNode, GLuint progId);
-                               void draw(const std::vector<Mesh> &meshes, const std::vector<Material> &materials, const Skybox s, glm::mat4 parentModel) const;
+                               Node(const aiNode &aiNode, GLuint progId, AnimMap *animMap);
+                               void draw(const std::vector<Mesh> &meshes, const std::vector<Material> &materials, const Skybox s, const float tick, const BoneTransforms &boneTransforms, glm::mat4 parentModel) const;
                                const std::vector<Node*> &getChildren() const { return children; }
                                Node* findNode(const aiNode &aiNode);
                                const std::vector<Node*> &getChildren() const { return children; }
                                Node* findNode(const aiNode &aiNode);
-                               glm::mat4 model = glm::mat4(1);
                                const aiNode &ai;
                                const aiNode &ai;
+
+                               // an extra transform
+                               glm::mat4 transform = glm::mat4(1);
+                               
+                               glm::mat4 totalTrans(const glm::mat4 parentTrans, const float tick) const;
+
                        private:
                                const GLuint progId;
 
                        private:
                                const GLuint progId;
 
+                               const AnimMap *animMap;
                                std::vector<Node*> children;
                                std::vector<unsigned int> meshIndices;
                };
                
                Node* getRoot() { return root; }
                                std::vector<Node*> children;
                                std::vector<unsigned int> meshIndices;
                };
                
                Node* getRoot() { return root; }
-               Node* find(const std::string &name);
+               Node* find(const aiString name) const;
+               Node* find(const std::string &name) const;
        
        private:
                const Program program;
        
        private:
                const Program program;
-               const Skybox skybox;
                
                std::vector<Mesh> meshes;
                Node *root;
 
                std::vector<Material> materials;
 
                
                std::vector<Mesh> meshes;
                Node *root;
 
                std::vector<Material> materials;
 
-               void loadModel(const std::string &path);
+               AnimMap animMap;
 
 
-               Assimp::Importer importer;
+               BoneTransforms calcBoneTransforms(const Node &n, const float tick, const std::set<std::string> bones, const glm::mat4 parentTrans) const;
+               void loadModel(const std::string &path);
 };
 };