Tutorial 8: Meshes

Wavefront .obj file (simplified)

For the sake of simplicity, let's not handle all the quirks of the .obj file format. The rest of this page assumes that the file contains:

Note that each face has the corresponding (1-based) indices for the vertex/texture/normal data for each of the 3 vertices.

For example, here's a simple .obj file representing a square:

v -1.0 0.0 0.0
v 0.0 1.0 0.0
v 0.0 0.0 0.0
v -1.0 1.0 0.0
vt 1.0 0.0
vt 0.0 1.0
vt 0.0 0.0
vt 1.0 1.0
vn 1.0 0.0 0.0
f 1/2/1 2/1/1 3/4/1
f 4/3/1 2/1/1 1/2/1

Attached below is an .obj file for the low-poly teapot we looked at in tutorial.

teapot.obj

Loading the .obj file into your code.

Attached below is some C code that loads in an obj file with the above described format. You will probably need to clean the obj file to remove unnecessary stuff if you're getting them from the internet - or modify the code to ignore other stuff properly. Look at the comments for additional details on how to merge it with your code.

meshes_starter.c

Barycentric Interpolation

Given a point pp on a triangle with vertices AA, BB, CC, we want to be able to figure out the normal / texture coordinates to shade it based on the values from the vertices of the triangle.

Note: Naively we can compute the face normal as (B-A)x(C-A), but that will not give us smooth surfaces as we usually want.

We will do this by forming a weighted sum of the corresponding components of AA, BB, CC such that

p=uA+vB+wCp = u\cdot A + v \cdot B + w \cdot C

Here, uu, vv, and ww need to be computed using Barycentric interpolation. We form these by looking at the ratios of the areas of 33 triangles formed by pp. Look at the diagram below:

Image

So:

How do we compute the area of the triangles? Remember that the magnitude of the cross-product of 2 vectors gives you the area of the parallelogram formed by them. The area of the triangle is then simply half this value. So, for instance, the value of the triangle ABCABC would be:

area(ABC)=(BA)×(CA)/2area(ABC) = ||(B-A)\times (C-A)|| / 2

Additionally note that in the equations for uu, vv, and ww above, we are dividing both numerator and denonimator by 22, and they cancel out. So, we can simplify them as:

Now, we can use these uu, vv, and ww values to take the weighted sum of the normals / texture coordinates for the 3 vertices to get the corresponding values for pp!