Facebook
From Sploky, 2 Years ago, written in C++.
Embed
Download Paste or View Raw
Hits: 114
  1. #pragma once
  2. #include <vector>
  3. #include "shader.h"
  4. #include "mesh.h"
  5. #include <assimp/Importer.hpp>
  6. #include <assimp/scene.h>
  7. #include <assimp/postprocess.h>
  8. #include <map>
  9.  
  10. namespace glg {
  11.         class Model {
  12.         public:
  13.                 Model(const char* path) {
  14.                         loadModel(path);
  15.                 }
  16.  
  17.                 void draw(Shader& shader) {
  18.                         for (size_t i = 0; i < meshes.size(); i++) {
  19.                                 meshes[i].draw(shader);
  20.                         }
  21.                 }
  22.  
  23.         private:
  24.                 std::map<std::string, Texture2D> loadedTextures;
  25.                 std::vector<Mesh> meshes;
  26.                 std::string directory;
  27.  
  28.                 void loadModel(std::string path) {
  29.                         Assimp::Importer importer;
  30.                         const aiScene* scene = importer.ReadFile(path, aiProcess_Triangulate | aiProcess_FlipUVs);
  31.  
  32.                         if (!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode) {
  33.                                 std::cout << "Could not load model " << importer.GetErrorString() << std::endl;
  34.                                 return;
  35.                         }
  36.  
  37.                         directory = path.substr(0, path.find_last_of('/'));
  38.  
  39.                         processNode(scene->mRootNode, scene);
  40.                 }
  41.  
  42.                 void processNode(aiNode* node, const aiScene* scene) {
  43.                         // processes all the node's meshes
  44.                         for (size_t i = 0; i < node->mNumMeshes; i++) {
  45.                                 aiMesh* mesh = scene->mMeshes[node->mMeshes[i]];
  46.                                 meshes.push_back(processMesh(mesh, scene));
  47.                         }
  48.  
  49.                         // processes all the nodes children
  50.                         for (size_t i = 0; i < node->mNumChildren; i++) {
  51.                                 processNode(node->mChildren[i], scene);
  52.                         }
  53.                 }
  54.  
  55.                 Mesh processMesh(aiMesh* mesh, const aiScene* scene) {
  56.                         std::vector<Vertex> vertices(0);
  57.                         std::vector<unsigned int> indices(0);
  58.                         std::vector<Texture2D> textures(0);
  59.  
  60.                         for (size_t i = 0; i < mesh->mNumVertices; i++) {
  61.                                 Vertex vertex;
  62.  
  63.                                 vertex.position = glm::vec3(mesh->mVertices[i].x, mesh->mVertices[i].y, mesh->mVertices[i].z);
  64.                                
  65.                                 if (mesh->mTextureCoords[0]) {
  66.                                         vertex.texCoords = glm::vec2(mesh->mTextureCoords[0][i].x, mesh->mTextureCoords[0][i].y);
  67.                                 }
  68.                                 vertices.push_back(vertex);
  69.                         }
  70.  
  71.                         for (size_t i = 0; i < mesh->mNumFaces; i++) {
  72.                                 aiFace face = mesh->mFaces[i];
  73.                                 for (size_t j = 0; j < face.mNumIndices; j++) {
  74.                                         indices.push_back(face.mIndices[j]);
  75.                                 }
  76.                         }
  77.  
  78.                         if (mesh->mMaterialIndex >= 0) {
  79.                                 aiMaterial* material = scene->mMaterials[mesh->mMaterialIndex];
  80.                                 std::vector<Texture2D> diffuseMaps = loadMaterialTextures(material, aiTextureType_DIFFUSE, "diffuse");
  81.                                 textures.insert(textures.end(), diffuseMaps.begin(), diffuseMaps.end());
  82.                         }
  83.  
  84.                         return Mesh(vertices, indices, textures);
  85.                 }
  86.  
  87.                 std::vector<Texture2D> loadMaterialTextures(aiMaterial* mat, aiTextureType type, std::string typeName) {
  88.                         std::vector<Texture2D> textures;
  89.                         for (size_t i = 0; i < mat->GetTextureCount(type); i++) {
  90.                                 aiString str;
  91.                                 mat->GetTexture(type, (unsigned int) i, &str);
  92.                                 if (loadedTextures.find(str.C_Str()) != loadedTextures.end()) {
  93.                                         textures.push_back(loadedTextures[str.C_Str()]);
  94.                                 }
  95.                                 else if (loadedTextures.find(str.C_Str()) == loadedTextures.end()){
  96.                                         std::string fullPath = std::string((directory + '/' + std::string(str.C_Str())).c_str());
  97.                                         Texture2D texture(fullPath.c_str(), 0);
  98.                                         textures.push_back(texture);
  99.                                         loadedTextures[str.C_Str()] = texture;
  100.                                 }
  101.                         }
  102.                         return textures;
  103.                 }
  104.         };
  105. }
captcha