text: #pragma once
  
  #include <glm/glm.hpp>
  #include <glm/gtc/matrix_transform.hpp>
  
  #include <assimp/Importer.hpp>
  #include <assimp/scene.h>
  #include <assimp/postprocess.h>
  
  #include "mesh.h"
  
  
  
  Mesh processMesh(aiMesh *mesh, const aiScene *scene) {
          // data to fill
          std::vector<Vertex> vertices;
          std::vector<unsigned int> indices;
          
  
          // walk through each of the mesh's vertices
          for(unsigned int i = 0; i < mesh->mNumVertices; i++)
          {
              Vertex vertex;
              glm::vec3 vector; // we declare a placeholder vector since assimp uses its own vector class that doesn't directly convert to glm's vec3 class so we transfer the data to this placeholder glm::vec3 first.
              // positions
              vector.x = mesh->mVertices[i].x;
              vector.y = mesh->mVertices[i].y;
              vector.z = mesh->mVertices[i].z;
              vertex.Position = vector;
              // normals
              if (mesh->HasNormals())
              {
                  vector.x = mesh->mNormals[i].x;
                  vector.y = mesh->mNormals[i].y;
                  vector.z = mesh->mNormals[i].z;
                  vertex.Normal = vector;
              }
              // texture coordinates
              if(mesh->mTextureCoords[0]) // does the mesh contain texture coordinates?
              {
                  glm::vec2 vec;
                  // a vertex can contain up to 8 different texture coordinates. We thus make the assumption that we won't 
                  // use models where a vertex can have multiple texture coordinates so we always take the first set (0).
                  vec.x = mesh->mTextureCoords[0][i].x; 
                  vec.y = mesh->mTextureCoords[0][i].y;
                  vertex.TexCoords = vec;
  
                  // tangent
                  // vector.x = mesh->mTangents[i].x;
                  // vector.y = mesh->mTangents[i].y;
                  // vector.z = mesh->mTangents[i].z;
                  //vertex.Tangent = vector;
                  // bitangent
                  // vector.x = mesh->mBitangents[i].x;
                  // vector.y = mesh->mBitangents[i].y;
                  // vector.z = mesh->mBitangents[i].z;
                  //vertex.Bitangent = vector;
              }
              else
                  vertex.TexCoords = glm::vec2(0.0f, 0.0f);
  
              vertices.push_back(vertex);
          }
          // now wak through each of the mesh's faces (a face is a mesh its triangle) and retrieve the corresponding vertex indices.
          for(unsigned int i = 0; i < mesh->mNumFaces; i++)
          {
              aiFace face = mesh->mFaces[i];
              // retrieve all indices of the face and store them in the indices vector
              for(unsigned int j = 0; j < face.mNumIndices; j++)
                  indices.push_back(face.mIndices[j]);        
          }
          return Mesh(vertices, indices);
  }
  
  std::vector<Mesh> processNode(aiNode *node, const aiScene *scene) {
  	std::vector<Mesh> meshes;
  	// process each mesh located at the current node
  	for(unsigned int i = 0; i < node->mNumMeshes; i++)
  	{
  	    // the node object only contains indices to index the actual objects in the scene. 
  	    // the scene contains all the data, node is just to keep stuff organized (like relations between nodes).
  	    aiMesh* mesh = scene->mMeshes[node->mMeshes[i]];
  	    meshes.push_back(processMesh(mesh, scene));
  	}
  	// after we've processed all of the meshes (if any) we then recursively process each of the children nodes
  	for(unsigned int i = 0; i < node->mNumChildren; i++)
  	{
  	    processNode(node->mChildren[i], scene);
  	}
  
  	return meshes;
  }
  
  std::vector<Mesh> processModel(const aiScene *scene) {
  	std::vector<Mesh> meshes;
  	// process each mesh located at the current node
  	for(unsigned int i = 0; i < scene->mNumMeshes; i++)
  	{
  	    // the node object only contains indices to index the actual objects in the scene. 
  	    // the scene contains all the data, node is just to keep stuff organized (like relations between nodes).
  	    aiMesh* mesh = scene->mMeshes[i];
  	    meshes.push_back(processMesh(mesh, scene));
  	}
  	return meshes;
  }