Jump to content
  • Advertisement
Sign in to follow this  
Basic

Help with .OBJ format

This topic is 4461 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

I'm trying to write a parser for .obj objects, but I have stumbled into a major road block. Here's a basic stripped down .obj file to the bare minimum of what it needs to properly display an object. # Vertices: 5 # Texture vertices: 16 # Normals: 5 # Faces: 5 v 1.000000 0.000000 -1.000000 v 1.000000 0.000000 1.000000 v -1.000000 0.000000 -1.000000 v -1.000000 0.000000 1.000000 v -0.000001 0.500000 -0.000001 f 3 5 1 f 2 4 3 1 f 3 4 5 f 4 2 5 f 2 1 5 # The end. The first set of information is just general information about your model. The second set is the position of the vertices. The third is where you place your geometric vertices. You may also add a texture and normal coordinates using slashes(ex: 1/1/2 1/1/1 2/2/1), but I've stripped those out for simplicity. My question is, how do you calculate the geometric vertices. Where does 3 5 1 come from on the first line. I understand that it takes 3 vertices to make up that face. And then the next line consists of four vertices making up the face(2 4 3 1), but how do I calculate those numbers. If I want to save my object, do I calculate a 4x4 matrix and just pop in the values for a 5 polygon object? I'm a little confused, and any help would be much appreciated.

Share this post


Link to post
Share on other sites
Advertisement
Basic,

Generally speaking, what you're looking for is the concept of an "index list." Nearly all meshes/models - cubes, pyramids, semi-spheres, grids, etc...will duplicate positions. For example, a cube has only 8 'vertices', but 12 triangles, each of 3 points totaling 36 points in space. So why does a cube not have 36 vertices? Well, because the triangles 'share' points in space...so although a cube may be made up of 36 points in space, only 8 of those points are unique. To save memory, we represent the points of a cube by simply listing the 8 unique points and then providing "indicies" into that list of 8.

In your example you provide 5 vertices...then you provide 16 indicies into that list of vertices. You've segmented them into polygons, but regardless, you're still using 16 indices into the list, creating a set of 16 points, all made up of 5 unique vertices.

f 3 5 1

The above line just says you've got a facet (polygon/surface) made up of the indices 3, 5, and 1...since its 3 points, it's a facet which happens to look like a triangle. And you can determine the rest for yourself.

How do you know which ones to use? Well, you just work it out for yourself. Think of a cube, which has 8 unique positions, then think about each of the quads or triangles that make up the cube, for each surface you store the 4 indices which make up that surface...then the next surface, the next, etc...until you've created all 6 surfaces, using indicies into your list of 8 vertices.

Hopefully this explanation will help you understand the problem set better. If you have additional questions, don’t hesitate to ask.

Cheers!

Share this post


Link to post
Share on other sites
Thanks Jeremy, I'm pretty sure I have a solid understanding now. :)

The part I'm confused about is the actual application. So when I read this file, and then start plotting the vertices to use for each face, do I just test every combination until I eventually have my object? I could work this example out in my head, but what happens when I have a more complicated object with hundreds of vertices?

I'll do a search for an index list on google and see if that helps.

Thanks again ++
:)

Share this post


Link to post
Share on other sites
Watch out for model loaders which unconditionally re-calculate the vertex normals using its own algorithm.

Annoying.

Specify vn x y z declares a vertex normal. It is also associated with the same indexing order as used by the vertices in the face specification statements.

To add the information to your face, you need to separate the information by forward slashes, such as: f v//vn

The space between the two slashes is where the texture coordinate information usually goes, but we are not including that for now, right?

Example:

# single triangle, single normal
v 1.0 1.0 1.0
v 0.0 0.0 0.0
v 0.0 0.0 1.0

vn 1.0 1.0 1.0

# don't forget that you can use different vertex normals per vertex as well!
# i cheaped out
f 1//1 2//1 3//1

Share this post


Link to post
Share on other sites
Okay, thanks for the explanation.

The trick now is, how do I store which vertices each face is using so I can avoid bad geometry?

Share this post


Link to post
Share on other sites
Load all vertices in an array of:

struct Vert {
float verts[ 3 ];
}



And all faces in an array of:

struct ObjFace {
unsigned int vertIds[3];
unsigned int texCoordIds[3];
unsigned int normalIds[3];
};



Now, in your rendering loop, for each face:
setNormalsFromArray( face.normalIds[ 0 ])
drawVertexFromArray( face.vertIds[ 0 ]);
setNormalsFromArray( face.normalIds[ 1 ])
drawVertexFromArray( face.vertIds[ 1 ]);
setNormalsFromArray( face.normalIds[ 2 ])
drawVertexFromArray( face.vertIds[ 2 ]);

It concerns me that I received around 10 IIS 500.13 errors in trying to submit this.

Share this post


Link to post
Share on other sites
Thanks Woodsmen, I've finally got it. :)

(Gamedev has been running really sluggish lately) :(

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!