Update gitattributes
[opengl.git] / model.hpp
1 #ifndef MODEL_HPP
2 #define MODEL_HPP
3
4 #include <vector>
5 #include <map>
6 #include <set>
7 #ifdef __APPLE__
8 #include <GL/glew.h>
9 #else
10 #include <OpenGL/glew.h>
11 #endif
12 #include <glm/glm.hpp>
13 #include <assimp/scene.h>
14 #include "material.hpp"
15 #include "program.hpp"
16 #include "skybox.hpp"
17
18
19 class Model {
20
21         struct Animation {
22                 double duration;
23                 std::vector<const aiNodeAnim*> nodeAnims;
24         };
25
26         typedef std::map<std::string, std::pair<unsigned int, aiBone*>> BoneMap;
27         typedef std::map<std::string, std::vector<const Animation>> AnimMap;
28         typedef std::map<std::string, glm::mat4> BoneTransforms;
29
30         struct VertBones {
31                 unsigned int ids[4] = {0, 0, 0 ,0};
32                 float weights[4] = {1, 0, 0, 0};
33         };
34         
35         public:
36                 Model(std::vector<std::string> blendshapes, std::string neutral, Program p);
37                 Model(const aiScene *scene, Program p);
38                 void draw(Skybox skybox, const float tick) const;
39
40                 struct Mesh {
41                         Mesh(const aiMesh *aiMesh, GLuint progId);
42                         GLuint progId, vao, numIndices;
43                         GLuint vbos[6];
44                         unsigned int materialIndex;
45                         BoneMap boneMap;
46                         const aiMesh &ai;
47                         void updatePosBuffer() const;
48                 };
49
50                 class Node {
51                         public:
52                                 Node(aiNode &aiNode, GLuint progId, AnimMap *animMap, std::set<std::string> allBones, Node *parent);
53
54                                 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;
55                                 const std::vector<Node*> &getChildren() const { return children; }
56                                 Node* findNode(const aiNode &aiNode);
57                                 aiNode &ai;
58
59                                 // an extra transform
60                                 glm::mat4 transform = glm::mat4(1);
61                                 
62                                 glm::mat4 totalTrans(const glm::mat4 parentTrans, const float tick) const;
63
64                                 const Node *parent;
65                                 const Node &getRoot() const;
66
67                                 bool operator==(const Node &rhs) const;
68
69                         private:
70                                 const GLuint progId;
71
72                                 const AnimMap *animMap;
73                                 std::vector<Node*> children;
74                                 std::vector<unsigned int> meshIndices;
75                                 const bool isBone;
76                 };
77                 
78                 Node& getRoot() const { return *root; }
79                 Node* find(const aiString name) const;
80                 Node* find(const std::string &name) const;
81
82                 struct VertexLookup {
83                         glm::vec3 pos;
84                         int meshIdx, vertIdx;
85                         float distance;
86                 };
87                 VertexLookup closestVertex(Model::Node &node, glm::vec3 a, glm::vec3 b, glm::mat4 parentTrans = glm::mat4(1)) const;
88                 
89                 std::vector<Mesh> meshes;
90         
91         private:
92                 const Program program;
93                 Node *root;
94
95                 std::vector<Material> materials;
96
97                 AnimMap animMap;
98
99                 BoneTransforms calcBoneTransforms(const Node &n, const float tick, const std::set<std::string> bones, const glm::mat4 parentTrans) const;
100                 void loadModel(const std::string &path);
101 };
102
103 #endif