- 1. Assumptions
- 2. Parsing a File
- 3. Groups
- 4. Polygonal Data
- 5. Vertex Data
- 6. Render States
- 7. Materials
- 8. Supported Statements
Assumptions
All end-user interactions with the OBJParser revolve around two primary classes: OBJParser
and OBJState
.
The former is the class to invoke to perform the actual parse, while the latter stores the state of the parsed file. For the rest of this guide, the following assumptions will be made:
parser
is an instance ofOBJParser
state
is an instance ofOBJState
Parsing a File
To parse an OBJ file, all you need to do is create an instance of the OBJParser
and then provide a file path:
1 | OBJParser parser; |
Once parsed, the contents of the file are placed within an OBJState
instance that belongs to the parser. This state can be retrieved via:
1 | OBJState* state = parser.getOBJState(); |
This is a pointer to a member variable, not member pointer, of the parser. So as long as the parser is valid, the pointer to the state will be. But the parser will clear away the internal data of the state before starting each new parse.
The rest of this guide will detail how to access and interpret data in the state.
Groups
A standard OBJ file is typically split into multiple groups. Each group can represent a single side of an individual mesh, or a single mesh among hundreds in a complex scene.
Groups are identified by their unique names and they contain the polygonal structures that make up the model. A container of all parsed groups can be retrieved from the OBJState
via:
1 | std::vector<OBJGroup const*> groups; |
Polygonal Data
There are three different types of polygonal data that are stored inside of a group:
- Points
- Lines
- Faces
These are represented by the OBJPoint
, OBJLine
, and OBJFace
structures.
OBJPoint
Vector of OBJVertexGroup
objects. Each vertex group represents a single, individual point.
OBJLine
Vector of OBJVertexGroup
objects. Each vertex group represents an individual segment of a single line.
OBJFace
A collection of four OBJVertexGroup
objects.
If all four vertex groups are in use, then the face represents a quad. If only three are in use, then the face represents a triangle.
Additionally maintains a reference to the render state that was active when the face was declared. This is an index that can be supplied to OBJState::getRenderState
.
OBJVertexGroup
A vertex group is a structure of three integer indices. Each index references a polygonal vertex element (spatial, texture, or normal) which can be used to access a specific vertex in the data containers.
The OBJ file format specifies that all indices are 1-based and can additionally be negative. But as standard containers are 0-based and do not support negative values, these indices have been pre-transformed to work with them.
All unspecified indices are set to -1. This can be used to not only check if normals, for example, are used, but to also check if an OBJFace
represents a quad or triangle:
1 | if(face.group3.indexSpatial == -1) |
Vertex Data
There are four different types of vertex data that can be stored in an OBJ file:
- Spatial
- Texture
- Normal
- Parameter
The first three are used by both polygonal and free-form structures, while the last is free-form only. They can be retrieved via:
1 | std::vector<OBJVector4> const* spatial = state->getSpatialData(); |
These can then be referenced by the index data stored in points, lines, faces, and curves. For example:
1 | auto spatial = state->getSpatialData(); |
Render States
At any time during the parsing of an OBJ file, the render state of that model or scene may change. The most common of these state changes in modern applications is the material, but there are numerous other render state attributes.
These states are most important when rendering faces, which is why each face maintains an index to the specific state that was active.
As an example, we can retrieve the material that was active when a face was created by:
1 | OBJFace face = ...; |
Materials
Materials are parsed from .mtl
files that are referenced in OBJ files via the mtllib
statement. Each material file (also called libraries) can contain an indefinite number of individual materials.
When parsed, the materials are stored in an internal map within the state in the form of OBJMaterial
objects. They may be retrieved via:
1 | std::vector<OBJMaterial const*> materials; |
Each material can have a multitude of elements, but the most important (and commonly used) are the reflectivity values and the texture maps.
An example of fetching data from a material:
1 | auto material = materials->at(0); |
Supported Statements
List of all statements supported by the OBJParser for both OBJ and MTL formats. Note all statements are case-sensitive.
See the following links for more detailed explanations:
http://paulbourke.net/dataformats/obj/
http://paulbourke.net/dataformats/mtl/
OBJ
Statement | Official | Brief |
---|---|---|
v |
✓ | Vertex spatial data |
vt |
✓ | Vertex texture data |
vn |
✓ | Vertex normal data |
vp |
✓ | Vertex parameter data |
cstype |
✓ | Free-form type |
deg |
✓ | Free-form degree |
bmat |
✓ | Free-form basis matrix |
step |
✓ | Free-form step size |
p |
✓ | Polygonal points |
l |
✓ | Polygonal line |
f |
✓ | Polygonal face (quad/tri) |
curv |
✓ | Free-form curve |
curv2 |
✓ | Free-form 2D curve |
surf |
✓ | Free-form surface |
parm |
✓ | Free-form parameter |
trim |
✓ | Free-form trim curve |
hole |
✓ | Free-form hole curve |
scrv |
✓ | Free-form special curve |
sp |
✓ | Free-form special point |
end |
✓ | Free-form statement end |
con |
✓ | Free-form surface connection |
g |
✓ | Group state set |
s |
✓ | Smoothing group state set |
mg |
✓ | Merging group state set |
o |
✓ | Object name |
bevel |
✓ | Sets bevel interpolation |
c_interp |
✓ | Sets color interpolation |
d_interp |
✓ | Sets dissolve interpolation |
lod |
✓ | Sets level-of-detail |
usemtl |
✓ | Sets active material |
mtllib |
✓ | Sets material library path |
shadow_obj |
✓ | Sets shadow object |
trace_obj |
✓ | Sets tracer object |
ctech |
✓ | Curve subdivision technique |
stech |
✓ | Surface subdivision technique |
MTL
Statement | Official | Brief |
---|---|---|
newmtl |
✓ | Starts new material definition |
Ka |
✓ | Ambient reflectivity |
Kd |
✓ | Diffuse reflectivity |
Ks |
✓ | Specular reflectivity |
Ke |
Emissive reflectivity | |
Tf |
✓ | Transmission filter |
d |
✓ | Dissolve |
Tr |
Transparency (dissolve inverse) | |
illum |
✓ | Illumination |
Ns |
✓ | Specular Exponent |
sharpness |
✓ | Sharpness |
Ni |
✓ | Optical density |
map_Ka |
✓ | Ambient texture |
map_Kd |
✓ | Diffuse texture |
map_ks |
✓ | Specular texture |
map_Ns |
✓ | Specular exponent texture |
map_Ke |
Emissive texture | |
map_d |
✓ | Dissolve texture |
decal |
✓ | Decal texture |
disp |
✓ | Displacement Texture |
bump |
✓ | Bump texture |
map_bump |
Bump texture | |
map_aat |
✓ | Anti-aliasing texture |
refl |
✓ | Reflection map |