Sign in to follow this  

Loading .obj files

This topic is 3868 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hallo, First of all I not sure if this is the right place to post this, so admins feel free to delete or move this post. 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)
// 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;
}


Thank you for your time

Share this post


Link to post
Share on other sites
You might be looking at the wrong code for the answer.

This would be a good debugging strategy to follow to isolate the problem:

- Build the box by hand (not parsing the box) and try to render it
If the box shows up incorrectly then the problem has nothing to do with your parser, it has to do with your intersection code, then try to isolate the intersection code that is causing the problem (it could be something else, like your camera, or your shading, etc, etc)


- If the code that is causing problems is the parser then try to debug it, or use existing code. The DirectX SDK comes with a .obj parser if I remember correctly, which works well, you can use that or compare your code with it.

Share this post


Link to post
Share on other sites
Thanks for your reply. I have already done that, or I made a simpler example and used only a single triangle and that rendered as it should.


// Create the triangles as the file is loaded
// Dont work, not sure where the error is
triangleList = createTriangel(vertexList);

// Temp, just to check. This works perfect.
//triangleList.push_back(Triangle(Vector3D(0,0,0),Vector3D(-150,0,0),Vector3D(0,150,0)));



I have made a few changes to the code, and I think I read the file as it should now, but still it does not work. The file I try to read now only has a single triangle, with the coordinates of the triangle I used to check if my intersection code works. If it try to print the coordinates of the loaded triangle they maches what the should be, but when I try to render I get a empty screen.



#include "Input.h"
#include <iostream>
#include <string>
#include <fstream>
#include <windows.h>
#include <vector>
#include <sstream>

// 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> mesh; // 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
//mesh = createTriangel(vertexList);

// Temp, just to check. This workd perfect.
mesh.push_back(Triangle(Vector3D(0,0,0),Vector3D(-150,0,0),Vector3D(0,150,0)));

return mesh;
}


// Convert a string into a vertex
Vector3D processVertex(std::string line)
{
std::string vertexString[3];
int x = 0;

for (int i = 2; i <= line.size(); i++)
{
if ( line[i] == ' ')
{
x++;
}
else
{
// add to same cord
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;
}

Thanks for any help :)

Share this post


Link to post
Share on other sites

This topic is 3868 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this