Model::Model(std::string filename, bool invert) { std::vector<float> vertice_data; aiMatrix4x4 trafo; aiIdentityMatrix4(&trafo); scene = aiImportFile(filename.c_str(), aiProcessPreset_TargetRealtime_Quality);// | aiProcess_FlipWindingOrder); if (!scene) { std::string log = "Unable to load mesh from "; log.append(filename); THROW_EXCEPTION(log); } //Load the model recursively into data loadRecursive(root, invert, vertice_data, scene, scene->mRootNode); //Get bounding box and scale it std::pair<float, glm::vec3> aabb = FindBoundingBox(vertice_data); //Apply scale root.transform = glm::scale(root.transform, glm::vec3(aabb.first, aabb.first, aabb.first)); //Apply translation root.transform = glm::translate(root.transform, aabb.second); n_vertices = vertice_data.size(); //Create the VBOs from the data. if (fmod(static_cast<float>(n_vertices), 3.0f) < 0.000001f){ vertices.reset(new GLUtils::VBO(vertice_data.data(), n_vertices*sizeof(float))); } else THROW_EXCEPTION("The number of vertices in the mesh is wrong"); }
Model::Model(std::string filename, bool invert) { min_dim = glm::vec3(std::numeric_limits<float>::min()); max_dim = glm::vec3(std::numeric_limits<float>::max()); std::vector<float> vertex_data, normal_data; aiMatrix4x4 trafo; aiIdentityMatrix4(&trafo); scene = aiImportFile(filename.c_str(), aiProcessPreset_TargetRealtime_Quality);// | aiProcess_FlipWindingOrder); if (!scene) { std::string log = "Unable to load mesh from "; log.append(filename); THROW_EXCEPTION(log); } //Load the model recursively into data loadRecursive(root, invert, vertex_data, normal_data, scene, scene->mRootNode); // Scale first, Translate center second! std::pair<glm::vec3, glm::vec3> translateVectors = getTranslateVectors(vertex_data); root.transform = glm::scale(root.transform, translateVectors.first); root.transform = glm::translate(root.transform, translateVectors.second); n_vertices = vertex_data.size(); //Create the VBOs from the data. if (fmod(static_cast<float>(n_vertices), 3.0f) < 0.000001f) { vertices.reset(new GLUtils::VBO(vertex_data.data(), n_vertices*sizeof(float), GL_ARRAY_BUFFER)); normals.reset(new GLUtils::VBO(normal_data.data(), n_vertices*sizeof(float), GL_ARRAY_BUFFER)); } else THROW_EXCEPTION("The number of vertices in the mesh is wrong"); }
Model::Model(std::string filename, bool invert) { //std::vector<float> vertex_data, normal_data; std::vector<Vertex> vertex_data; std::vector<unsigned int> indices_data; int pos = filename.find_last_of("/"); if(pos == std::string::npos) pos = filename.find_last_of("\\"); folderPath = filename.substr(0, pos + 1); scene = aiImportFile(filename.c_str(), aiProcessPreset_TargetRealtime_Quality);// | aiProcess_FlipWindingOrder); if (!scene) { std::string log = aiGetErrorString(); THROW_EXCEPTION(log); } max_dim = -glm::vec3(std::numeric_limits<float>().max()); min_dim = glm::vec3(std::numeric_limits<float>().max()); //Load the model recursively into data loadRecursive(root, invert, indices_data, vertex_data, scene, scene->mRootNode); float tmp; tmp = max_dim.x - min_dim.x; tmp = max_dim.y - min_dim.y > tmp ? max_dim.y - min_dim.y : tmp; tmp = max_dim.z - min_dim.z > tmp ? max_dim.z - min_dim.z : tmp; float scaleFactor = 1.0f / tmp; glm::vec3 center = (max_dim + min_dim); center /= 2; root.transform = glm::scale(glm::mat4(1), glm::vec3(scaleFactor)); root.transform = glm::translate(root.transform, -center); n_vertices = indices_data.size(); std::cout << "Loaded model with " << n_vertices << " vertices" << std::endl; //Create the VBOs from the data. if (fmod(static_cast<float>(n_vertices), 3.0f) < 0.000001f) { indices.reset(new GLUtils::BO<GL_ELEMENT_ARRAY_BUFFER>(indices_data.data(), indices_data.size() * sizeof(unsigned int))); vertices.reset(new GLUtils::BO<GL_ARRAY_BUFFER>(vertex_data.data(), vertex_data.size() * sizeof(Vertex))); std::cout << "Created and uploaded VBOs" << std::endl; } else { THROW_EXCEPTION("The number of vertices in the mesh is wrong"); } }
void Model::loadRecursive(MeshPart& part, bool invert, std::vector<float>& vertex_data, const aiScene* scene, const aiNode* node) { //update transform matrix. notice that we also transpose it aiMatrix4x4 m = node->mTransformation; for (int j=0; j<4; ++j) for (int i=0; i<4; ++i) part.transform[j][i] = m[i][j]; // draw all meshes assigned to this node for (unsigned int n=0; n < node->mNumMeshes; ++n) { const struct aiMesh* mesh = scene->mMeshes[node->mMeshes[n]]; //apply_material(scene->mMaterials[mesh->mMaterialIndex]); part.first = vertex_data.size()/6; part.count = mesh->mNumFaces*6; //Allocate data vertex_data.reserve(vertex_data.size() + part.count*6); //Add the vertices from file for (unsigned int t = 0; t < mesh->mNumFaces; ++t) { const struct aiFace* face = &mesh->mFaces[t]; if(face->mNumIndices != 3) THROW_EXCEPTION("Only triangle meshes are supported"); for(unsigned int i = 0; i < face->mNumIndices; i++) { int index = face->mIndices[i]; //get Vertexes vertex_data.push_back(mesh->mVertices[index].x); vertex_data.push_back(mesh->mVertices[index].y); vertex_data.push_back(mesh->mVertices[index].z); //get Normals if (mesh->HasNormals()){ vertex_data.push_back(mesh->mNormals[index].x); vertex_data.push_back(mesh->mNormals[index].y); vertex_data.push_back(mesh->mNormals[index].z); } } } } // load all children for (unsigned int n = 0; n < node->mNumChildren; ++n) { part.children.push_back(MeshPart()); loadRecursive(part.children.back(), invert, vertex_data, scene, node->mChildren[n]); } }
void Model::loadRecursive(MeshPart& part, bool invert, std::vector<unsigned int>& indices, std::vector<Vertex>& vertex_data, const aiScene* scene, const aiNode* node) { std::cout << "loading one part" << std::endl; //update transform matrix. notice that we also transpose it aiMatrix4x4 m = node->mTransformation; for (int j=0; j<4; ++j) for (int i=0; i<4; ++i) part.transform[j][i] = m[i][j]; // draw all meshes assigned to this node for (unsigned int n=0; n < node->mNumMeshes; ++n) { std::cout << "\tloading mesh part " << n << std::endl; const struct aiMesh* mesh = scene->mMeshes[node->mMeshes[n]]; //apply_material(scene->mMaterials[mesh->mMaterialIndex]); applyMateriale(scene->mMaterials[mesh->mMaterialIndex], part.materiale); part.first = indices.size(); part.count = mesh->mNumFaces * 3; //Allocate data indices.reserve(part.first + part.count); vertex_data.reserve(vertex_data.size() + mesh->mNumVertices); for (unsigned int t = 0; t < mesh->mNumFaces; ++t) { const struct aiFace* face = &mesh->mFaces[t]; if(face->mNumIndices != 3) THROW_EXCEPTION("Only triangle meshes are supported"); for(unsigned int i = 0; i < face->mNumIndices; i++) { int index = face->mIndices[i]; indices.push_back(vertex_data.size() + index); } } for(unsigned int t = 0; t < mesh->mNumVertices; ++t){ Vertex v; unsigned int index = t; // set vertex position v.position = glm::vec3(mesh->mVertices[index].x, mesh->mVertices[index].y, mesh->mVertices[index].z); // compute bounding box max_dim.x = v.position.x < max_dim.x ? max_dim.x : v.position.x; max_dim.y = v.position.y < max_dim.y ? max_dim.y : v.position.y; max_dim.z = v.position.z < max_dim.z ? max_dim.z : v.position.z; min_dim.x = v.position.x > min_dim.x ? min_dim.x : v.position.x; min_dim.y = v.position.y > min_dim.y ? min_dim.y : v.position.y; min_dim.z = v.position.z > min_dim.z ? min_dim.z : v.position.z; // get normal if(mesh->HasNormals()) v.normal = glm::vec3(mesh->mNormals[index].x, mesh->mNormals[index].y, mesh->mNormals[index].z); // get uv coord if(mesh->HasTextureCoords(0)) v.texCoord = glm::vec2(mesh->mTextureCoords[0][index].x, mesh->mTextureCoords[0][index].y); vertex_data.push_back(v); } } // load all children for (unsigned int n = 0; n < node->mNumChildren; ++n) { part.children.push_back(MeshPart()); loadRecursive(part.children.back(), invert, indices, vertex_data, scene, node->mChildren[n]); } }