New model loading

This commit is contained in:
2020-09-08 21:31:58 +00:00
parent 664523a515
commit 23497ce626
10 changed files with 374 additions and 131 deletions

View File

@@ -1,11 +1,16 @@
#include "Model.h"
#include <iostream>
#include <cassert>
#include <fstream>
Model::Model(const char* pathToModel) {
// Todo: check if model isn't already loaded --> will boost startup time drastically
// actually all models should be loaded at startup and only a handle should be given to the entites...
std::string modelSource = pathToModel;
directory = modelSource.substr(0, modelSource.find_last_of('/'));
loadModel(pathToModel);
}
Model::~Model() {
@@ -25,122 +30,79 @@ void Model::draw(ShaderProgram *shaderProgram) {
}
void Model::loadModel(std::string pathToModel) {
Assimp::Importer importer;
const aiScene *scene = importer.ReadFile(pathToModel, aiProcess_Triangulate | aiProcess_FlipUVs); //aiProcess_OptimizeMeshes ?
std::ifstream input(pathToModel, std::ios::in | std::ios::binary);
if(!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode) {
std::cout << "ERROR::ASSIMP::" << importer.GetErrorString() << std::endl;
return;
if(!input.is_open()) {
std::cout << "Could not find model file " << pathToModel << std::endl;
return;
}
uint32_t numTextures;
input.read((char*) &numTextures, sizeof(uint32_t));
std::vector<uint32_t> textureTypes;
for(unsigned int i = 0; i < numTextures; i++) {
uint32_t currentTextureType;
input.read((char*) &currentTextureType, sizeof(uint32_t));
textureTypes.push_back(currentTextureType);
}
directory = pathToModel.substr(0, pathToModel.find_last_of('/'));
std::vector<std::string> textureSources;
for(unsigned int i = 0; i < numTextures; i++) {
std::string currentTextureSource;
for(unsigned int i = 0; i < 128; i++) {
uint8_t currentChar;
input.read((char*) &currentChar, sizeof(uint8_t));
processNode(scene->mRootNode, scene);
}
void Model::processNode(aiNode *node, const aiScene *scene) {
// Push the node's meshes into the mesh vector
for(uint32_t i = 0; i < node->mNumMeshes; i++) {
aiMesh *mesh = scene->mMeshes[node->mMeshes[i]];
meshes.push_back(processMesh(mesh, scene));
if(currentChar)
currentTextureSource.push_back(currentChar);
}
textureSources.push_back(currentTextureSource);
}
// Process child nodes too
for(uint32_t i = 0; i < node->mNumChildren; i++) {
processNode(node->mChildren[i], scene);
for(unsigned int i = 0; i < numTextures; i++) {
std::string textureSource = directory + '/' + textureSources[i].c_str();
Texture *newTex = new Texture(textureSource.c_str(), textureTypes[i]);
loadedTextures.push_back(newTex);
}
}
// Here starts the first mesh
uint32_t numMeshes;
for(unsigned int j = 0; j < numMeshes; j++) {
Mesh Model::processMesh(aiMesh *mesh, const aiScene *scene) {
std::vector<Vertex> vertices;
std::vector<uint32_t> indices;
std::vector<Texture*> textures;
input.read((char*) &numMeshes, sizeof(uint32_t));
for(uint32_t i = 0; i < mesh->mNumVertices; i++) {
Vertex vertex;
uint32_t numMeshVertices, numMeshIndices, numMeshTextureIds;
// Position
glm::vec3 vector;
vector.x = mesh->mVertices[i].x;
vector.y = mesh->mVertices[i].y;
vector.z = mesh->mVertices[i].z;
vertex.position = vector;
input.read((char*) &numMeshVertices, sizeof(uint32_t));
input.read((char*) &numMeshIndices, sizeof(uint32_t));
input.read((char*) &numMeshTextureIds, sizeof(uint32_t));
// Normals
vector.x = mesh->mNormals[i].x;
vector.y = mesh->mNormals[i].y;
vector.z = mesh->mNormals[i].z;
vertex.normalVec = vector;
// Here starts the first Vertex data
// Texture UV mapping
if(mesh->mTextureCoords[0]) {
glm::vec2 vec;
vec.x = mesh->mTextureCoords[0][i].x;
vec.y = mesh->mTextureCoords[0][i].y;
vertex.textureCoords = vec;
} else {
vertex.textureCoords = glm::vec2(0.0f, 0.0f);
std::vector<Vertex> meshVertices;
for(unsigned int i = 0; i < numMeshVertices; i++) {
Vertex currentVertex;
input.read((char*) &currentVertex, sizeof(Vertex));
meshVertices.push_back(currentVertex);
}
vertices.push_back(vertex);
}
// Indices
for(uint32_t i = 0; i < mesh->mNumFaces; i++) {
aiFace face = mesh->mFaces[i];
for(uint32_t j = 0; j < face.mNumIndices; j++) {
indices.push_back(face.mIndices[j]);
std::vector<uint32_t> meshIndices;
for(unsigned int i = 0; i < numMeshIndices; i++) {
uint32_t currentIndex;
input.read((char*) &currentIndex, sizeof(uint32_t));
meshIndices.push_back(currentIndex);
}
std::vector<Texture*> meshTextures;
for(unsigned int i = 0; i < numMeshTextureIds; i++) {
uint32_t currentTextureId;
input.read((char*) &currentTextureId, sizeof(uint32_t));
meshTextures.push_back(loadedTextures[currentTextureId]);
}
Mesh currentMesh(meshVertices, meshIndices, meshTextures);
meshes.push_back(currentMesh);
}
// Material
if(mesh->mMaterialIndex > 0) {
aiMaterial *material = scene->mMaterials[mesh->mMaterialIndex];
std::vector<Texture*> diffuseMaps = loadMaterialTextures(material, aiTextureType_DIFFUSE, texture_diffuse);
textures.insert(textures.end(), diffuseMaps.begin(), diffuseMaps.end());
std::vector<Texture*> specularMaps = loadMaterialTextures(material, aiTextureType_SPECULAR, texture_specular);
textures.insert(textures.end(), specularMaps.begin(), specularMaps.end());
std::vector<Texture*> normalMaps = loadMaterialTextures(material, aiTextureType_NORMALS, texture_normal);
textures.insert(textures.end(), normalMaps.begin(), normalMaps.end());
std::vector<Texture*> heightMaps = loadMaterialTextures(material, aiTextureType_HEIGHT, texture_height);
textures.insert(textures.end(), heightMaps.begin(), heightMaps.end());
}
return Mesh(vertices, indices, textures);
}
std::vector<Texture*> Model::loadMaterialTextures(aiMaterial *mat, aiTextureType type, uint8_t textureType) {
std::vector<Texture*> textures;
for(uint32_t i = 0; i < mat->GetTextureCount(type); i++) {
aiString filename;
mat->GetTexture(type, i, &filename);
std::string currentPath = directory + '/' + filename.C_Str();
bool skip = 0;
for(uint32_t j = 0; j < loadedTextures.size(); j++) {
if(std::strcmp(loadedTextures[j]->getPath().c_str(), currentPath.c_str()) == 0) {
textures.push_back(loadedTextures[j]);
skip = 1;
break;
}
}
if(!skip) {
Texture *texture = new Texture(currentPath.c_str(), textureType);
loadedTextures.push_back(texture);
// Add newest texture pointer to the mesh's texture-pointer vector
Texture *new_tex = loadedTextures.back();
textures.push_back(new_tex);
}
}
return textures;
}