ecc8842b7e3807d901d642dc721f572a8cd91b78
[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         struct Mesh {
36                 Mesh(const aiMesh *aiMesh, GLuint progId);
37                 GLuint progId, vao, numIndices;
38                 unsigned int materialIndex;
39                 BoneMap boneMap;
40                 const aiMesh &ai;
41         };
42         
43         public:
44                 Model(const aiScene *scene, Program p);
45                 void draw(Skybox skybox, const float tick) const;
46
47                 class Node {
48                         public:
49                                 Node(aiNode &aiNode, GLuint progId, AnimMap *animMap, std::set<std::string> allBones, Node *parent);
50
51                                 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;
52                                 const std::vector<Node*> &getChildren() const { return children; }
53                                 Node* findNode(const aiNode &aiNode);
54                                 aiNode &ai;
55
56                                 // an extra transform
57                                 glm::mat4 transform = glm::mat4(1);
58                                 
59                                 glm::mat4 totalTrans(const glm::mat4 parentTrans, const float tick) const;
60
61                                 const Node *parent;
62                                 const Node &getRoot() const;
63
64                                 bool operator==(const Node &rhs) const;
65
66                         private:
67                                 const GLuint progId;
68
69                                 const AnimMap *animMap;
70                                 std::vector<Node*> children;
71                                 std::vector<unsigned int> meshIndices;
72                                 const bool isBone;
73                 };
74                 
75                 Node& getRoot() const { return *root; }
76                 Node* find(const aiString name) const;
77                 Node* find(const std::string &name) const;
78
79                 std::pair<glm::vec3, float> closestVertex(Model::Node &node, glm::vec3 a, glm::vec3 b, glm::mat4 parentTrans = glm::mat4(1)) const;
80         
81         private:
82                 const Program program;
83                 
84                 std::vector<Mesh> meshes;
85                 Node *root;
86
87                 std::vector<Material> materials;
88
89                 AnimMap animMap;
90
91                 BoneTransforms calcBoneTransforms(const Node &n, const float tick, const std::set<std::string> bones, const glm::mat4 parentTrans) const;
92                 void loadModel(const std::string &path);
93 };
94
95 #endif