Wavefront (obj) loader

Overview

This is a basic .obj loader written in C. A C++ wrapper is included. It can parse vertices, texture coordinates, normals, 3 or 4 vertex faces, and .mtl files. There is also support for non-standard object types that are relevant to raytracing. See these pages for details on the standard obj and mtl format definitions.

Please contact me if you have any suggestions for improvements.

The code and tests for the loader is available here. Some sample scenes are also available:

test.obj and test.mtl
cornell_box.obj and cornell_box.mtl

The code is free and public domain.
You may use it as you desire.
No credit is needed. Enjoy!

Bug reports are welcome, of course.

Storage data structures

obj_scene_data
This structure is used for scene access in C. The user is responsible for passing a pointer of this type to int parse_obj_scene(...). The memory allocated to scene storage may be freed by calling void delete_obj_data(...).
obj_vector **vertex_listArray of vertex vector pointers
obj_vector **vertex_normal_listArray of normal vector pointers
obj_vector **vertex_texture_listArray of texture vector pointers
obj_face **face_listArray of face pointers
obj_sphere **sphere_listArray of sphere pointers
obj_plane **plane_listArray of plane pointers
obj_light_point **light_point_listArray of point light pointers
obj_light_quad **light_quad_listArray of quad light pointers
obj_light_disc **light_disc_listArray of disc light pointers
obj_material **material_listArray of material pointers
int vertex_countLength of vertex array
int vertex_normal_countLength of normal vector array
int vertex_texture_countLength of texture vector array
int face_countLength of face array
int sphere_countLength of sphere array
int plane_countLength of plane array
int light_point_countLength of point light array
int light_quad_countLength of quad light array
int light_disc_countLength of disc light array
int material_countLength of material array
obj_camera *cameraPointer to a camera

objLoader
This class can be used in C++. It does very little other than hiding the allocation and freeing of resources.
int load(char *filename)Call this to parse a scene and fill in the data
obj_vector **vertexListArray of vertex vector pointers
obj_vector **normalListArray of normal vector pointers
obj_vector **textureListArray of texture vector pointers
obj_face **faceListArray of face pointers
obj_sphere **sphereListArray of sphere pointers
obj_plane **planeListArray of plane pointers
obj_light_point **lightPointListArray of point light pointers
obj_light_quad **lightQuadListArray of quad light pointers
obj_light_disc **lightDiscListArray of disc light pointers
obj_material **materialListArray of material pointers
int vertexCountLength of vertex array
int normalCountLength of normal vector array
int textureCountLength of texture vector array
int faceCountLength of face array
int sphereCountLength of sphere array
int planeCountLength of plane array
int lightPointCountLength of point light array
int lightQuadCountLength of quad light array
int lightDiscCountLength of disc light array
int materialCountLength of material array
obj_camera *cameraPointer to a camera

Scene data structures

obj_vector
These are used to describe vertex, normal, and texture vectors.
double e[3]Values for x, y, z in 3 space

obj_face
A polygon. Currently limited to triangles and quads.
int vertex_index[MAX_VERTEX_COUNT]Indices of the position vertices
int normal_index[MAX_VERTEX_COUNT]Indices of each vertex normal
int texture_index[MAX_VERTEX_COUNT]Indices of each vertex texture coordinate
int vertex_countNumber of vertices in the face
int material_indexIndex of the assigned material

obj_sphere
A sphere. The length of the up normal can be used as the radius.
int pos_indexIndex of position vertex
int up_normal_indexIndex of up normal
int equator_normal_indexIndex of equator normal
int texture_index[MAX_VERTEX_COUNT]Indices of texture coordinates
int material_indexIndex of the assigned material

obj_plane
Infinite plane.
int pos_indexIndex of position vertex
int normal_indexIndex of the face normal
int rotation_normal_indexIndex of the plane rotation normal
int texture_index[MAX_VERTEX_COUNT]Indices of texture coordinates
int material_indexIndex of the assigned material


obj_light_point
A simple point light source.
int pos_indexIndex of the position vertex
int material_indexIndex of the assigned material

obj_light_disc
An area light shaped like a disc.
int pos_indexIndex of the position vertex
int normal_indexIndex of the direction normal. The length can be used as the disc radius
int material_indexIndex of the assigned material

obj_light_quad
An area light shaped like a quad.
int vertex_index[MAX_VERTEX_COUNT]Indices of the position vertices
int material_indexIndex of the assigned material

obj_camera
A simple camera.
int camera_pos_indexIndex of the position vertex
int camera_look_point_indexIndex of the focus vertex
int camera_up_norm_indexIndex of the up normal

obj_material
Material definition. This is created when parsing a .mtl file.
char name[MATERIAL_NAME_SIZE]String name of the material
char texture_filename[OBJ_FILENAME_LENGTH]Filename of the texture map
double amb[3]Ambient reflectance values
double diff[3]Diffuse reflectance values
double spec[3]Specular reflectance values
double reflectAmount of reflection
double refractAmount of refraction
double transAmount of transparency
double shinySharpness of specular highlight
double glossyGlossiness of reflection
double refract_indexRefractive index of the material

Example code

C example:

obj_scene_data data;
if( !parse_obj_scene(&data, "test.obj") )
	return 0;

// read the scene dta into your data structures

delete_obj_data(&data);

C++ example:

objLoader *objData = new objLoader();
objData->load("test.obj");

// read the scene dta into your data structures

delete(objData);

Example obj data

A quick list of what the parser can handle. For details on the format refer to the obj spec or the test file included with the code.

Vertex:
A vertex is a point in 3d space.

v 0.123 1.23 12.3
v 0.314 3.14 31.4

Normal:
A normal is used as a vertex normal in standard obj. This parser also uses normals in certain object definitions (spheres for instance).

vn 0 1 0
vn 0 0 -1

Texture Coordinate:
Texture coordinates are used to align textures to objects.

vt 5 5 0
vt -5 5 0

Material Library:
A file containing the scene material descriptions.

mtllib location_of_material_file.mtl

Material Reference:
A directive to begin assigning a certain material to all following objects. The mtl file must have already been processed.

usemtl a_material_name

Face:
Polygon faces are defined by a list of position vectices.

v  0.0 0.0 0.0
v  5.0 0.0 0.0
v  5.0 5.0 0.0
v  0.0 5.0 0.0
f 1 2 3
f 1 3 4

Sphere (non-standard):
Spheres are defined with a position vertex and two normals: one for the up normal and one for the equator normal. The length of either normal can be chosen for the sphere radius.

v 10 10 10
vn 1 0 0
vn 1 0 0
sp 1 1 2

Plane (non-standard):
Planes are defined with a position vertex and two normals: one for the rotation normal and one for the plane normal.

v 0 0 -10
vn 0 0 1
vn 1 0 0
pl 1 1 2

Light, point (non-standard):
A simple point light source. Use a material definition to set the output values.

v 10 50 0
lp 1

Light, quad (non-standard):
A 4 cornered area light.

v 0 50 0
v 10 50 0
v 10 50 10
v 0 50 10
lq 1 2 3 4

Light, disc (non-standard):
A disc-shaped arealight source. The normal specifies the direction and size of the disc.

v 0 50 0
vn 0 -1 0
ld 1 1

Camera (non-standard):
Used to define a simple camera. The 2 vertices define the camera position and the point the camera is focusing on. The normal defines the up vector.

v 0 0 -20
v 0 5 5
vn 0 1 0
c 1 2 1

Example mtl data

Object materials can be specified in a separate .mtl file. For details, refer to the mtl spec or the test file that comes with the code. A brief example follows.

newmtl material_name_goes_here
Ka  0.1 0 0      # ambient values
Kd  1 0 0        # diffuse values
Ks  1 1 1        # specular values
Ns  10           # sharpness of specular highlight
map_Ka test.png  # texture map filename
r 0.5            # reflection amount (non-standard)
sharpness 30     # sharpness of reflection
d  0.5           # transparency amount
Ni  1.33         # index of refraction