a3a290c80096279f31d105265316e23d1d316479
[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 inline glm::mat4 aiMatrixToMat4(aiMatrix4x4 from) {
19         glm::mat4 to;
20         for (int i = 0; i < 4; i++)
21                 for (int j = 0; j < 4; j++)
22                         to[i][j] = from[j][i];
23         return to;
24 }
25
26 inline aiMatrix4x4 mat4ToaiMatrix(glm::mat4 from) {
27         aiMatrix4x4 to;
28         for (int i = 0; i < 4; i++)
29                 for (int j = 0; j < 4; j++)
30                         to[i][j] = from[j][i];
31         return to;
32 }
33
34 class Model {
35
36         struct Animation {
37                 double duration;
38                 std::vector<const aiNodeAnim*> nodeAnims;
39         };
40
41         typedef std::map<std::string, std::pair<unsigned int, aiBone*>> BoneMap;
42         typedef std::map<std::string, std::vector<const Animation>> AnimMap;
43         typedef std::map<std::string, glm::mat4> BoneTransforms;
44
45         struct VertBones {
46                 unsigned int ids[4] = {0, 0, 0 ,0};
47                 float weights[4] = {1, 0, 0, 0};
48         };
49
50         struct Mesh {
51                 Mesh(const aiMesh *aiMesh, GLuint progId);
52                 GLuint progId, vao, numIndices;
53                 unsigned int materialIndex;
54                 BoneMap boneMap;
55         };
56         
57         public:
58                 Model(const aiScene *scene, Program p);
59                 void draw(Skybox skybox, const float tick) const;
60
61                 class Node {
62                         public:
63                                 Node(aiNode &aiNode, GLuint progId, AnimMap *animMap, std::set<std::string> allBones, Node *parent);
64
65                                 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;
66                                 const std::vector<Node*> &getChildren() const { return children; }
67                                 Node* findNode(const aiNode &aiNode);
68                                 aiNode &ai;
69
70                                 // an extra transform
71                                 glm::mat4 transform = glm::mat4(1);
72                                 
73                                 glm::mat4 totalTrans(const glm::mat4 parentTrans, const float tick) const;
74
75                                 const Node *parent;
76                                 const Node &getRoot() const;
77
78                                 bool operator==(const Node &rhs) const;
79
80                         private:
81                                 const GLuint progId;
82
83                                 const AnimMap *animMap;
84                                 std::vector<Node*> children;
85                                 std::vector<unsigned int> meshIndices;
86                                 const bool isBone;
87                 };
88                 
89                 Node* getRoot() { return root; }
90                 Node* find(const aiString name) const;
91                 Node* find(const std::string &name) const;
92         
93         private:
94                 const Program program;
95                 
96                 std::vector<Mesh> meshes;
97                 Node *root;
98
99                 std::vector<Material> materials;
100
101                 AnimMap animMap;
102
103                 BoneTransforms calcBoneTransforms(const Node &n, const float tick, const std::set<std::string> bones, const glm::mat4 parentTrans) const;
104                 void loadModel(const std::string &path);
105 };
106
107 #endif