bool load_mesh_from_file(const char *ctm_filepath, mesh_t & mesh) { CTMimporter ctm; try { ctm.Load(ctm_filepath); unsigned int vertex_count = ctm.GetInteger(CTM_VERTEX_COUNT); unsigned int vertex_element_count = 3 * vertex_count; const CTMfloat *vertices = ctm.GetFloatArray(CTM_VERTICES); mesh.vertices.resize(vertex_element_count); std::memcpy(&mesh.vertices[0], vertices, vertex_element_count * sizeof(float)); unsigned int face_count = ctm.GetInteger(CTM_TRIANGLE_COUNT); unsigned int indice_count = face_count * 3; const CTMuint *indices = ctm.GetIntegerArray(CTM_INDICES); mesh.indices.resize(indice_count); std::memcpy(&mesh.indices[0], indices, indice_count * sizeof(unsigned int)); if (ctm.GetInteger(CTM_HAS_NORMALS) == CTM_TRUE) { const CTMfloat *normals = ctm.GetFloatArray(CTM_NORMALS); mesh.normals.resize(vertex_element_count); std::memcpy(&mesh.normals[0], normals, vertex_element_count * sizeof(float)); } else { std::cerr << "*** CTM_HAS_NORMALS == false" << std::endl; } unsigned int uv_map_count = ctm.GetInteger(CTM_UV_MAP_COUNT); if (uv_map_count > 0) { const CTMfloat *tex_coords = ctm.GetFloatArray(CTM_UV_MAP_1); unsigned int tex_coord_element_count = 2 * vertex_count; mesh.tex_coords.resize(tex_coord_element_count); std::memcpy(&mesh.tex_coords[0], tex_coords, tex_coord_element_count * sizeof(float)); } else { std::cerr << "*** UV map not found" << std::endl; } return true; } catch(ctm_error & e) { std::cerr << "*** Loading CTM file failed: " << e.what() << std::endl; return false; } }
bool mesh_t::read_from_file(const char *ctm_filepath, mesh_t &mesh) { CTMimporter ctm; try { ctm.Load(ctm_filepath); } catch(ctm_error & e) { cerr << "*** Loading CTM file failed: " << e.what() << endl; return false; } const CTMfloat *vertices; const CTMuint *indices; const CTMfloat *normals; const CTMfloat *tex_coords; const CTMfloat *tangents; unsigned int vertex_count = ctm.GetInteger(CTM_VERTEX_COUNT); vertices = ctm.GetFloatArray(CTM_VERTICES); unsigned int face_count = ctm.GetInteger(CTM_TRIANGLE_COUNT); unsigned int index_count = face_count * 3; indices = ctm.GetIntegerArray(CTM_INDICES); if (ctm.GetInteger(CTM_HAS_NORMALS) != CTM_TRUE) { cerr << "*** normals not found" << endl; } normals = ctm.GetFloatArray(CTM_NORMALS); unsigned int uv_map_count = ctm.GetInteger(CTM_UV_MAP_COUNT); if (uv_map_count > 0) { tex_coords = ctm.GetFloatArray(CTM_UV_MAP_1); } else { std::cerr << "*** uv map not found" << std::endl; } unsigned int attr_map_count = ctm.GetInteger(CTM_ATTRIB_MAP_COUNT); if (attr_map_count > 0) { tangents = ctm.GetFloatArray(CTM_ATTRIB_MAP_1); } mesh.vertices.resize(vertex_count); for (unsigned int i = 0; i < vertex_count; i++) { vertex_t &v = mesh.vertices[i]; unsigned int j = 3*i; v.position.x = vertices[j]; v.position.y = vertices[j + 1]; v.position.z = vertices[j + 2]; v.position.w = 1.0f; v.normal.x = normals[j]; v.normal.y = normals[j + 1]; v.normal.z = normals[j + 2]; if (uv_map_count > 0) { unsigned int k = 2*i; v.tex_coord.x = tex_coords[k]; v.tex_coord.y = tex_coords[k + 1]; } if (attr_map_count > 0) { v.tangent.x = tangents[j]; v.tangent.y = tangents[j + 1]; v.tangent.z = tangents[j + 2]; } } mesh.indices.resize(index_count); std::memcpy(&mesh.indices[0], indices, index_count * sizeof(unsigned int)); return true; }
bool OpenCTMLoader::readOpenCTM(const char *filename) { // Load the file using the OpenCTM API CTMimporter ctm; // Load the OpenCTM file ctm.Load(filename); // Access the mesh vertices CTMuint vertCount = ctm.GetInteger(CTM_VERTEX_COUNT); const CTMfloat * ctmVertices = ctm.GetFloatArray(CTM_VERTICES); // Access the mesh triangles CTMuint triCount = ctm.GetInteger(CTM_TRIANGLE_COUNT); const CTMuint * indices = ctm.GetIntegerArray(CTM_INDICES); // Filling vertices buffer helper::vector<sofa::defaulttype::Vector3>& my_positions = *(positions.beginEdit()); my_positions.fastResize(vertCount); for (unsigned int i=0; i<vertCount; ++i) { my_positions[i][0] = ctmVertices[i*3]; my_positions[i][1] = ctmVertices[i*3 + 1]; my_positions[i][2] = ctmVertices[i*3 + 2]; } positions.endEdit(); // Filling triangles buffer helper::vector<Triangle>& my_triangles = *(triangles.beginEdit()); my_triangles.fastResize(triCount); for (unsigned int i=0; i<triCount; ++i) { my_triangles[i][0] = indices[i*3]; my_triangles[i][1] = indices[i*3 + 1]; my_triangles[i][2] = indices[i*3 + 2]; } triangles.endEdit(); // Checking if mesh containes normals, otherwise fill empty buffer (NB seems mendatory for mecaObj) if (ctm.GetInteger(CTM_HAS_NORMALS) == CTM_TRUE) { helper::vector<sofa::defaulttype::Vec<3,SReal> >& my_normals = *(normals.beginEdit()); my_normals.fastResize(vertCount); // Access the mesh normals const CTMfloat * ctmNormals = ctm.GetFloatArray(CTM_NORMALS); for (unsigned int i=0; i<vertCount; ++i) { my_normals[i][0] = ctmNormals[i*3]; my_normals[i][1] = ctmNormals[i*3 + 1]; my_normals[i][2] = ctmNormals[i*3 + 2]; } normals.endEdit(); } // Checking if mesh containes texture coordinates. Only one set of UV is handled in SOFA if(ctm.GetInteger(CTM_UV_MAP_COUNT) > 0) { const CTMfloat * ctmTexCoords = ctm.GetFloatArray(CTM_UV_MAP_1); helper::vector<sofa::defaulttype::Vector2>& my_texCoords = *texCoords.beginEdit(); my_texCoords.fastResize(vertCount); for (unsigned int i=0; i<vertCount; ++i) { my_texCoords[i][0] = ctmTexCoords[i*3]; my_texCoords[i][1] = ctmTexCoords[i*3 + 1]; } texCoords.endEdit(); } return true; }
void mesh_manager::load_single_ctm_mesh(const std::string& path, shader_ptr shader, const glm::mat4& matrix, const GLuint tex_id, const std::string& key) { try { // Create a new OpenCTM importer object CTMimporter ctm; // Load the OpenCTM file ctm.Load(path.c_str()); // Access the mesh data CTMuint vertCount = ctm.GetInteger(CTM_VERTEX_COUNT); const CTMfloat * vertices = ctm.GetFloatArray(CTM_VERTICES); const CTMfloat * normals = ctm.GetFloatArray(CTM_NORMALS); CTMuint triCount = ctm.GetInteger(CTM_TRIANGLE_COUNT); const CTMuint * indices = ctm.GetIntegerArray(CTM_INDICES); // Deal with the mesh (e.g. transcode it to our // internal representation) //------------------------- //build vaos and vbos here //mesh_ptr new_mesh = build_mesh_node(shader, matrix, tex_id, scene->mMeshes[0]); //-------------------------------- //generate the vao GLuint assimp_vao_id; glGenVertexArrays(1, &assimp_vao_id); //bind the vao glBindVertexArray(assimp_vao_id); //gererate the vbos std::vector<GLuint> mesh_vbos; GLuint position_vbo; glGenBuffers(1, &position_vbo); //vertices glBindBuffer(GL_ARRAY_BUFFER, position_vbo); glBufferData(GL_ARRAY_BUFFER, 3 * vertCount * sizeof(GLfloat), vertices, GL_STATIC_DRAW); shader->set_attrib_location("in_position", 3); mesh_vbos.push_back(position_vbo); //if (ctm.GetInteger(CTM_HAS_NORMALS) == CTM_TRUE) { GLuint normal_vbo; glGenBuffers(1, &normal_vbo); //normals glBindBuffer(GL_ARRAY_BUFFER, normal_vbo); glBufferData(GL_ARRAY_BUFFER, 3 * vertCount * sizeof(GLfloat), normals, GL_STATIC_DRAW); shader->set_attrib_location("in_normal", 3); mesh_vbos.push_back(normal_vbo); //} //uv coords if (ctm.GetInteger(CTM_UV_MAP_COUNT) > 0) { //just get first uv coords for now const CTMfloat * uvcoords = ctm.GetFloatArray(CTM_UV_MAP_1); GLuint texcoord_vbo; glGenBuffers(1, &texcoord_vbo); //texture glBindBuffer(GL_ARRAY_BUFFER, texcoord_vbo); glBufferData(GL_ARRAY_BUFFER, 2 * vertCount * sizeof(GLfloat), uvcoords, GL_STATIC_DRAW); shader->set_attrib_location("in_texcoord", 2); mesh_vbos.push_back(texcoord_vbo); } //dont think ctm supports tangents? //if (aimesh->HasTangentsAndBitangents() && config_manager::get_bool("load_tangents")) { // GLuint tangent_vbo; // glGenBuffers(1, &tangent_vbo); // //tangents // glBindBuffer(GL_ARRAY_BUFFER, tangent_vbo); // glBufferData(GL_ARRAY_BUFFER, 3 * aimesh->mNumVertices * sizeof(GLfloat), // aimesh->mTangents, GL_STATIC_DRAW); // shader->set_attrib_location("in_tangent", 3); // mesh_vbos.push_back(tangent_vbo); //} get_errors(); GLuint index_vbo; glGenBuffers(1, &index_vbo); //std::vector<GLuint> index_vector; //int num_indices = 0; ////get all the indices //for (unsigned int idx=0; idx < triCount * 3; idx++) { // //for (unsigned int idx=0; idx < aimesh->mFaces[face].mNumIndices; idx++) { // index_vector.push_back( indices[idx] ); // num_indices++; // //} //} //indices glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_vbo); glBufferData(GL_ELEMENT_ARRAY_BUFFER, 3 * triCount * sizeof(GLuint), indices, GL_STATIC_DRAW); mesh_vbos.push_back(index_vbo); // ------------------------ //finally, do the map entry // ------------------------ mesh_ptr new_mesh(new mesh_node(matrix, assimp_vao_id, triCount * 3) ); new_mesh->vao_id = assimp_vao_id; new_mesh->vbos = mesh_vbos; new_mesh->set_texture_id(tex_id); // build mesh end //--------------- // get the key for the mesh string mesh_key = key; if (key.empty()) { //take stem as key boost::filesystem::path p(path); mesh_key = p.stem().generic_string(); } // do we have only one mesh // add the mesh node with the filename as the key _map[mesh_key] = new_mesh; //unbind vao and vbos glBindVertexArray(0); glBindBuffer(GL_ARRAY_BUFFER, 0); if(!(glGetError() == GL_NO_ERROR)) { cout << "mesh_manager: OGL error building node for CTM mesh " << 0 << " of " << path << endl; } } catch(exception &e) { cout << "Error: mesh manager CTM: " << e.what() << endl; } }