How to load .obj files?

This is a discussion on How to load .obj files? within the Game Programming forums, part of the General Programming Boards category; Hallo,
I am working on a raytracer and are trying to make a mesh class so that I can load ...

How to load .obj files?

Hallo,

I am working on a raytracer and are trying to make a mesh class so that I can load my own objects from files instead of just having boring primitives. I have written my own simple .obj file loader but something is really really wrong. When I try to load a model of a simple box I only get like 6 pixels that get the color of it. First I thought that maybe it was just because it was to small, but that is not the case (I think).

So I was hoping that someone could take a look and maybe spot whats wrong.

My method is to load the vertex coordinates from a file and construct triangles from it. I have already made a triangle class with intersection and all, so that part should work fine (a single triangle primitive renders perfectly)

Code:

// A small structure for holding the two cordinates of the UV
struct UV
{
float u;
float v;
};
// Convert a string into a Vector3D
Vector3D processVertex(std::string line);
// Create triangle
std::vector<Triangle> createTriangel(std::vector<Vector3D> list);
// Read the file, and convert it so that it can be used to something usefull
std::vector<Triangle> loadFromFile(char* FileName)
{
std::string currentLine; // Variable that holds the current line
// we are using.
std::vector<Vector3D> vertexList; // A dynamic vector array for holding
// the info about the vertexs
std::vector<UV> uvList; // Dynamic list of uvs
std::vector<Vector3D> normal; // Dynamic list with the normals of
// the object
std::vector<Triangle> triangleList; // The list we return to create the object
// as this is bacis we dont need to
// return uv and normals
// Open file
std::ifstream myFile (FileName);
if (myFile.is_open())
{
// While the file is open, we read the info and construct triangles
while ( getline(myFile, currentLine) )
{
// Check if this line holds vertex information. If the line starts
// with "v ", we will use it.
if (currentLine[0] == 'v' && currentLine[1] == ' ' )
{
vertexList.push_back(processVertex(currentLine));
}
// Check if the line holds uv information. If its starts with
// "vt" if a uv.
if (currentLine[0] == 'v' && currentLine[1] == 't')
{
// Read uv info
// My render dont have textures at this point
}
// Check if the line holds normal information. If its starts with
// "vn" if a normal.
if (currentLine[0] == 'v' && currentLine[1] == 'n')
{
// Read normal info
// going to add this later
}
}
// Finished with reading the file, close it
myFile.close();
}
// Create the triangles as the file is loaded
// Dont work, not sure where the error is
triangleList = createTriangel(vertexList);
// Temp, just to check. This workd perfect.
//triangleList.push_back(Triangle(Vector3D(0,0,0),Vector3D(-150,0,0),Vector3D(0,150,0)));
return triangleList;
}
// Convert a string into a vertex
Vector3D processVertex(std::string line)
{
std::string vertexString[3];
for (int x = 0; x < 3; x++)
{
for (int i = 2; i <= line.size(); i++)
{
//Break up the string into the three cordinates
if ( line[i] != ' ')
{
vertexString[x].push_back(line[i]);
}
}
}
// Convert the string into a number
Vector3D vertex( (float)atof(vertexString[0].c_str()),
(float)atof(vertexString[1].c_str()),
(float)atof(vertexString[2].c_str())
);
return vertex;
}
// Convert the vertex cords into triangles
std::vector<Triangle> createTriangel(std::vector<Vector3D> list)
{
std::vector<Triangle> triangleList;
for (int i = 0; i <= list.size(); i= i + 3 )
{
triangleList.push_back(Triangle( list[i + 0],
list[i + 1],
list[i + 2]
));
}
return triangleList;
}

I don't have time at the moment to examine that code, but... Naming your object data files with .obj is probably a bad idea. .obj is the name used on Windows systems for C and C++ intermediate object files. You might want to pick a different extension to avoid confusion. When in doubt, .dat or .bin are usually safe.

I changed some of my code, as there was a problem with ones of the loops reading the information from a line.

Right now it should work, but it does not.

I have tried to print the output from every function and they are right. My three Vector3D variables that represent the three vertexes have the right numbers in them. And so has all the sizes for the arrays.

The weird thing is that this works:

Code:

// The vector is empty at this point
// Add a triangle to the mesh, to check if intersection code works
mesh.push_back(Triangle(Vector3D(0,0,0),Vector3D(-150,0,0),Vector3D(0,150,0)));

But not this:

Code:

// Create triangles out of the list of vertexes
mesh = createTriangel(vertexList);

As the first works, where I create a triangle manually I guess my intersection code works fine, so the problem is with loading from file. Anyone have any ideas to what it could be?
I have tried to print the coordinates of the triangles I load from a file and they are right. I even tried to load the same triangle as I manually create in example one, but that does not even work.

Something here is really messed up, but I have no clue. Maybe I return something wrong or should have a pointer somewhere or something?