Hi All,
does anyone know any good tutorials on parsing an object file into your program, specifically with regards to when a vertex has multiple normal values defined in the faces section?
Much appreciated,
Graham
Hi All,
does anyone know any good tutorials on parsing an object file into your program, specifically with regards to when a vertex has multiple normal values defined in the faces section?
Much appreciated,
Graham
I do not think that a tutorial is needed for this because the file format is well known and described e.g. on Wikipedia https://en.wikipedia.org/wiki/Wavefront_.obj_file and there are also very good implementations out there you could take a look at https://github.com/syoyo/tinyobjloader
I already implemented multiple parsers and it wasnt absolutely difficult nor time consuming to understand the file format
It's likely one of the easiest file formats, with dozens or more loaders already existing. Plenty of documentation as Shaarigan pointed out.
When you have vertex normals, you don't average them. Something like weighted averaging needed only when you calculating normals on your own, because there's no normals data in obj file.
Now you must construct all vertices with all corresponding data (just like that, combined value of position/texture_coord/normal), then build index, removing duplicate vertices, i.e verts that has all the same pos/tex_co/norm. In the end there might be more verts in your vertex buffer than there's 'v' directives in obj file, and that's normal.
The first thing you must accept - is that 'v' directive does not create your final vertex. It only describes position in space. Resulting vertex is a combination of all data from all v/vt/vn streams.
Face vertex index in 'v' stream will tell about source vertex identity (same index means physically same point, while different indices means unrelated verts even if those are in same position), but that's needed only when you reconstruct normals, so shouldn't bother you at the moment.
You might misunderstand something while indices are for storing less data, .obj files define faces the original model was build from so this isnt something inside the file format itself but more a thing your game (engine) would process.
For your example
v 1.0 0.0 0.0
v 0.0 -0.5 -1.0
v -1.0 0.0 0.0
v 0.0 -0.5 1.0
vn 0.0 0.707106 0.707106
vn 0.0 0.707106 -0.707106
f 1//2 2//2 3//2
f 1//1 3//1 4//1
The resulting mesh would consist of
//First Triangle
vec3 1.0 0.0 0.0 | vec3 0.0 0.707106 -0.707106
vec3 0.0 -0.5 -1.0 | vec3 0.0 0.707106 -0.707106
vec3 -1.0 0.0 0.0 | vec3 0.0 0.707106 -0.707106
//Second Triangle
vec3 1.0 0.0 0.0 | vec3 0.0 0.707106 0.707106
vec3 -1.0 0.0 0.0 | vec3 0.0 0.707106 0.707106
vec3 0.0 -0.5 1.0 | vec3 0.0 0.707106 0.707106
//in a 6 component Vertex Buffer 3 components Vertices and 3 components Normals
To get an Index Buffer you need to store each combination of values once and set an index at its position. In your case you have to store all 6 faces because they do not share any vertex.
How you do it is up to you, someone store them in a constant array so vertex positions first then normals, I prefer normaly storing vertices as is in the buffer so vertex | normals | vertex | normals. Both work as expected and there is no right way of indexing
If you want actual working code for parsing, please try this link -> https://github.com/chrisjansson/ObjLoader
I used this code early on when I was understanding the format, its a good start. It has some flaws, but its useable. Assumes all models are only using 3 verts per face so you need to triangulate models first.
As far as I can see there are 3 ways of converting an obj file to arrays of vertices and normals and I was wondering which Is the best / industry standard way of doing it.
If what you're asking is "what way does GameX parse .obj files?" then you should understand that GameX most likely doesn't even use .obj files at all. Thing is, .obj is a fine enough format for tutorial material, but it's a horrible format for real-world usage; slow and error-prone to parse. GameX most likely uses it's own proprietary binary model format, with it's own exporter(s) from common modelling program(s), and just loads the format directly into vertex buffers without any parsing at all. So the best/industry standard way of parsing .obj files is actually: don't; use a better format instead.
Thanks for the replies.
I see now that option 2 and 3 that I mentioned are just two different ways of doing the same thing and I knew option 1 was not the way to go.
I have a script which extracts the data from the .obj file and creates 3 text files one for the vertices in the correct order, one for the normals in the correct order and one for the indices, which I then read in in my game.