213 lines
7.7 KiB
C++

/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license BSD v3 (see license file)
*/
#include <etk/types.h>
#include <etk/Vector.h>
#include <etk/os/FSNode.h>
#include <ewol/debug.h>
#include <ewol/renderer/ResourceManager.h>
#include <ewol/renderer/resources/MeshObj.h>
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<int32_t> indicesVertices;
etk::Vector<int32_t> indicesUv;
etk::Vector<int32_t> 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; iii<indicesVertices.Size(); iii++ ){
// Get the indices of its attributes
uint32_t vertexIndex = indicesVertices[iii];
uint32_t uvIndex = indicesUv[iii];
// Put the attributes in buffers
m_vertices.PushBack(vertices[vertexIndex-1]);
m_verticesVBO->GetRefBuffer(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();
}