Rework UI architecture and blendshape animation
[opengl.git] / model.hpp
index 0339538429cc94ae87292ff3f53e56cd460777a6..e7ad29cd2c9f97b0cf3b414c9e1c89aaf7d367b6 100644 (file)
--- a/model.hpp
+++ b/model.hpp
@@ -1,4 +1,9 @@
+#ifndef MODEL_HPP
+#define MODEL_HPP
+
 #include <vector>
+#include <map>
+#include <set>
 #ifdef __APPLE__
 #include <GL/glew.h>
 #else
 #endif
 #include <glm/glm.hpp>
 #include <assimp/scene.h>
+#include "material.hpp"
+#include "program.hpp"
+#include "skybox.hpp"
+
 
 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};
+       };
+       
        public:
-               Model(const std::string &path, GLuint progId): progId(progId) {
-                       loadModel(path);
-               }
-               void draw();
-       private:
-               const GLuint progId;
+               Model(std::vector<std::string> blendshapes, std::string neutral, Program p);
+               Model(const aiScene *scene, Program p);
+               void draw(Skybox skybox, const float tick) const;
 
                struct Mesh {
                        Mesh(const aiMesh *aiMesh, GLuint progId);
+                       GLuint progId, vao, numIndices;
+                       GLuint vbos[6];
+                       unsigned int materialIndex;
+                       BoneMap boneMap;
+                       const aiMesh &ai;
+                       void updatePosBuffer() const;
+               };
+
+               class Node {
+                       public:
+                               Node(aiNode &aiNode, GLuint progId, AnimMap *animMap, std::set<std::string> allBones, Node *parent);
+
+                               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);
+                               aiNode &ai;
+
+                               // an extra transform
+                               glm::mat4 transform = glm::mat4(1);
                                
-                       GLuint vao, vertexVbo, normalVbo, indicesVbo;
+                               glm::mat4 totalTrans(const glm::mat4 parentTrans, const float tick) const;
 
-                       std::vector<glm::vec3> vertices;
-                       std::vector<glm::vec3> normals;
-                       std::vector<glm::vec2> texCoords;
-                       std::vector<GLuint> indices;
+                               const Node *parent;
+                               const Node &getRoot() const;
+
+                               bool operator==(const Node &rhs) const;
+
+                       private:
+                               const GLuint progId;
+
+                               const AnimMap *animMap;
+                               std::vector<Node*> children;
+                               std::vector<unsigned int> meshIndices;
+                               const bool isBone;
+               };
+               
+               Node& getRoot() const { return *root; }
+               Node* find(const aiString name) const;
+               Node* find(const std::string &name) const;
+
+               struct VertexLookup {
+                       glm::vec3 pos;
+                       int meshIdx, vertIdx;
+                       float distance;
                };
+               VertexLookup closestVertex(Model::Node &node, glm::vec3 a, glm::vec3 b, glm::mat4 parentTrans = glm::mat4(1)) const;
                
                std::vector<Mesh> meshes;
+       
+       private:
+               const Program program;
+               Node *root;
+
+               std::vector<Material> materials;
+
+               AnimMap animMap;
+
+               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);
 };
+
+#endif