/** * @author Edouard DUPIN * * @copyright 2011, Edouard DUPIN, all right reserved * * @license BSD v3 (see license file) */ #include #include #include #include #include #include ewol::MeshObj::MeshObj(etk::UString _fileName) : ewol::Mesh(_fileName) { etk::FSNode fileName(_fileName); // Get the fileSize ... int32_t size = fileName.FileSize(); if (size == 0 ) { EWOL_ERROR("No data in the file named=\"" << fileName << "\""); return; } if(false == fileName.FileOpenRead() ) { EWOL_ERROR("Can not find the file name=\"" << fileName << "\""); return; } char inputDataLine[2048]; etk::Vector indicesVertices; etk::Vector indicesUv; etk::Vector indicesNormal; etk::Vector< vec3 > vertices; etk::Vector< vec2 > uvTextures; etk::Vector< vec3 > normals; int32_t lineID = 0; while (NULL != fileName.FileGets(inputDataLine, 2048) ) { lineID++; if (inputDataLine[0]=='v') { if (inputDataLine[1]=='n') { // Vertice normal : vn 0.000000 0.000000 -1.000000 vec3 vertex; sscanf(&inputDataLine[3], "%f %f %f", &vertex.x, &vertex.y, &vertex.z ); normals.PushBack(vertex); } else if (inputDataLine[1]=='t') { // Texture position : vt 0.748573 0.750412 vec2 vertex; sscanf(&inputDataLine[3], "%f %f", &vertex.x, &vertex.y); uvTextures.PushBack(vertex); } else { // Vertice position : v 1.000000 -1.000000 -1.000000 vec3 vertex; sscanf(&inputDataLine[2], "%f %f %f", &vertex.x, &vertex.y, &vertex.z ); vertices.PushBack(vertex); } } else if (inputDataLine[0]=='f') { // face : f 5/1/1 1/2/1 4/3/1* uint32_t vertexIndex[4], uvIndex[4], normalIndex[4]; bool quadMode = true; int32_t matches = sscanf(&inputDataLine[2], "%d/%d/%d %d/%d/%d %d/%d/%d %d/%d/%d\n", &vertexIndex[0], &uvIndex[0], &normalIndex[0], &vertexIndex[1], &uvIndex[1], &normalIndex[1], &vertexIndex[2], &uvIndex[2], &normalIndex[2], &vertexIndex[3], &uvIndex[3], &normalIndex[3] ); if (12 != matches){ // no normal mode : matches = sscanf(&inputDataLine[2], "%d/%d %d/%d %d/%d %d/%d\n", &vertexIndex[0], &uvIndex[0], &vertexIndex[1], &uvIndex[1], &vertexIndex[2], &uvIndex[2], &vertexIndex[3], &uvIndex[3] ); if (8 != matches){ quadMode = false; matches = sscanf(&inputDataLine[2], "%d/%d/%d %d/%d/%d %d/%d/%d\n", &vertexIndex[0], &uvIndex[0], &normalIndex[0], &vertexIndex[1], &uvIndex[1], &normalIndex[1], &vertexIndex[2], &uvIndex[2], &normalIndex[2] ); if (9 != matches){ // no normal mode : matches = sscanf(&inputDataLine[2], "%d/%d %d/%d %d/%d\n", &vertexIndex[0], &uvIndex[0], &vertexIndex[1], &uvIndex[1], &vertexIndex[2], &uvIndex[2] ); if (6 != matches){ EWOL_ERROR("Parsing error in the .obj files : " << fileName << " (l=" << lineID << ") in 'f' section : \"" << &inputDataLine[2] << "\" expected : %d/%d(/%d) %d/%d(/%d) %d/%d(/%d) (%d/%d(/%d)) () for option"); continue; } } } } if (true==quadMode) { indicesVertices.PushBack(vertexIndex[0]); indicesVertices.PushBack(vertexIndex[1]); indicesVertices.PushBack(vertexIndex[2]); // second triangle indicesVertices.PushBack(vertexIndex[0]); indicesVertices.PushBack(vertexIndex[2]); indicesVertices.PushBack(vertexIndex[3]); indicesUv.PushBack(uvIndex[0]); indicesUv.PushBack(uvIndex[1]); indicesUv.PushBack(uvIndex[2]); // second triangle indicesUv.PushBack(uvIndex[0]); indicesUv.PushBack(uvIndex[2]); indicesUv.PushBack(uvIndex[3]); if (12 == matches) { indicesNormal.PushBack(normalIndex[0]); indicesNormal.PushBack(normalIndex[1]); indicesNormal.PushBack(normalIndex[2]); // second triangle indicesNormal.PushBack(normalIndex[0]); indicesNormal.PushBack(normalIndex[2]); indicesNormal.PushBack(normalIndex[3]); } } else { indicesVertices.PushBack(vertexIndex[0]); indicesVertices.PushBack(vertexIndex[1]); indicesVertices.PushBack(vertexIndex[2]); indicesUv.PushBack(uvIndex[0]); indicesUv.PushBack(uvIndex[1]); indicesUv.PushBack(uvIndex[2]); if (9 == matches) { indicesNormal.PushBack(normalIndex[0]); indicesNormal.PushBack(normalIndex[1]); indicesNormal.PushBack(normalIndex[2]); } } // TODO : Calculate normal when none is provided ... } else if (inputDataLine[0]=='s') { // ??? : s off } else if (inputDataLine[0]=='#') { // comment // nothing to do ... just go to the new line ... } else if( inputDataLine[0]=='u' && inputDataLine[1]=='s' && inputDataLine[2]=='e' && inputDataLine[3]=='m' && inputDataLine[4]=='t' && inputDataLine[5]=='l' ) { // Use Material : usemtl imageName.xxx while( inputDataLine[strlen(inputDataLine)-1] == '\n' || inputDataLine[strlen(inputDataLine)-1] == '\r' || inputDataLine[strlen(inputDataLine)-1] == ' ') { if (1 == strlen(inputDataLine) ){ break; } inputDataLine[strlen(inputDataLine)-1] = '\0'; } etk::UString tmpVal(&inputDataLine[7]); ivec2 tmpSize(256, 256); if (NULL != m_texture1) { EWOL_INFO("Release previous loaded texture ... "); ewol::resource::Release(m_texture1); } etk::UString tmpFilename = fileName.GetRelativeFolder() + tmpVal; if (false == ewol::resource::Keep(tmpFilename, m_texture1, tmpSize)) { EWOL_ERROR("Can not load specific texture : " << tmpVal); } } else if( inputDataLine[0]=='m' && inputDataLine[1]=='t' && inputDataLine[2]=='l' && inputDataLine[3]=='l' && inputDataLine[4]=='i' && inputDataLine[5]=='b' ) { // ???? : mtllib cube.mtl } } fileName.FileClose(); // update the number of element in the display ... m_numberOfElments = indicesVertices.Size(); // For each vertex of each triangle for( uint32_t iii=0; iiiGetRefBuffer(0).PushBack(vertices[vertexIndex-1].x); m_verticesVBO->GetRefBuffer(0).PushBack(vertices[vertexIndex-1].y); m_verticesVBO->GetRefBuffer(0).PushBack(vertices[vertexIndex-1].z); m_uvTextures.PushBack(uvTextures[uvIndex-1]); m_verticesVBO->GetRefBuffer(1).PushBack(uvTextures[uvIndex-1].x); m_verticesVBO->GetRefBuffer(1).PushBack(uvTextures[uvIndex-1].y); draw::Color tmpppp(0xFFFFFFFF); draw::Colorf tmppppp(tmpppp); m_coordColor.PushBack(tmppppp); m_verticesVBO->GetRefBuffer(2).PushBack(tmppppp.r); m_verticesVBO->GetRefBuffer(2).PushBack(tmppppp.g); m_verticesVBO->GetRefBuffer(2).PushBack(tmppppp.b); m_verticesVBO->GetRefBuffer(2).PushBack(tmppppp.a); if (indicesNormal.Size()>iii) { uint32_t normalIndex = indicesNormal[iii]; m_normals.PushBack(normals[normalIndex-1]); m_verticesVBO->GetRefBuffer(3).PushBack(normals[normalIndex-1].x); m_verticesVBO->GetRefBuffer(3).PushBack(normals[normalIndex-1].y); m_verticesVBO->GetRefBuffer(3).PushBack(normals[normalIndex-1].z); } } // update all the VBO elements ... m_verticesVBO->Flush(); }