+#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