#include #include #include #include #include #include #include #include "mesh.hpp" #include "model.hpp" #include "arrays.hpp" #include "texture.hpp" using namespace sim::graphics; struct proc_state { unsigned int offset = 0; std::string base; std::vector vertices; std::vector indices; }; static unsigned int proc_texture(const proc_state& state, aiMaterial* mat, aiTextureType type) { if(mat->GetTextureCount(type) == 0) { return 0; } aiString str; mat->GetTexture(type, 0, &str); std::string filename(str.C_Str()); std::replace(filename.begin(), filename.end(), '\\', '/'); return texture::load(state.base + "/" + filename); } static void proc_mesh(proc_state& state, std::vector& meshes, aiMesh* mesh, const aiScene* scene) { aiMaterial* material = scene->mMaterials[mesh->mMaterialIndex]; unsigned int texid = proc_texture(state, material, aiTextureType_DIFFUSE); unsigned int offset = state.offset; for(unsigned int i = 0; i < mesh->mNumVertices; i++) { arrays::vertex vertex; vertex.texid = texid; vertex.pos = {mesh->mVertices[i].x, mesh->mVertices[i].y, mesh->mVertices[i].z}; if(mesh->HasNormals()) { vertex.normal = {mesh->mNormals[i].x, mesh->mNormals[i].y, mesh->mNormals[i].z}; } if(mesh->mTextureCoords[0]) { vertex.texpos = {mesh->mTextureCoords[0][i].x, mesh->mTextureCoords[0][i].y}; vertex.do_tex = 1; } state.vertices.push_back(vertex); } for(unsigned int i = 0; i < mesh->mNumFaces; i++) { aiFace face = mesh->mFaces[i]; for(unsigned int j = 0; j < face.mNumIndices; j++) { state.indices.push_back(face.mIndices[j] + offset); } } state.offset += mesh->mNumVertices; } static void proc_node(proc_state& state, std::vector& meshes, aiNode* node, const aiScene* scene) { for(size_t i = 0; i < node->mNumMeshes; i++) { aiMesh* mesh = scene->mMeshes[node->mMeshes[i]]; proc_mesh(state, meshes, mesh, scene); } for(size_t i = 0; i < node->mNumChildren; i++) { proc_node(state, meshes, node->mChildren[i], scene); } } void model::load(std::string base, std::string filename) { proc_state state {.base = base}; std::string path = base + "/" + filename; Assimp::Importer importer; const aiScene *scene = importer.ReadFile(path.c_str(), aiProcess_Triangulate | aiProcess_FlipUVs); proc_node(state, meshes, scene->mRootNode, scene); sim::graphics::mesh m; m.set_vertices(&state.vertices[0], state.vertices.size(), GL_STATIC_DRAW); m.set_indices(&state.indices[0], state.indices.size(), GL_STATIC_DRAW); meshes.push_back(std::move(m)); } void model::render() const { for(const mesh& m : meshes) { m.bind(); m.render(); } }