3D graphics authoring for embedded systems designers: Part 2- Deploying 3D objects

This part of the article is about the basic framework of 3D objects, how they are organized, and fundamentals you will need to understand regardless of the method used to deploy them. 3D objects can be exported from a 3D authoring tool in an array of different formats. Here we will focus on the common Wavefront Technologies OBJ format. The OBJ format is a standard 3D object format supported by virtually every 3D authoring tool. (See note on 3D graphics deployment tools at end of article.)

OBJ files are ASCII text files that contain geometry information for a 3D object. This includes vertex positions, texture coordinates, and polygon faces. A variety of other information can be included in an OBJ file; however, here we will only focus on these three attributes of a 3D object/model. Listing 1 shows the OBJ file that we will be referencing, a simple cube. This could just as easily be an extremely complex several thousand triangle model, but that would take up far too much space to list – so, a cube it is. This model was developed in Autodesk 3ds Max and exported using the OBJ export option. The settings used during export were faces as triangles, texture coordinates and optimize vertex and texture coordinates.

# object Cube01
# vertices begin
v -10.0000 0.0000 10.0000
v -10.0000 0.0000 -10.0000
v 10.0000 0.0000 -10.0000
v 10.0000 0.0000 10.0000
v -10.0000 20.0000 10.0000
v 10.0000 20.0000 10.0000
v 10.0000 20.0000 -10.0000
v -10.0000 20.0000 -10.0000
# vertices end, 8 vertices

# texture coords begin
vt 0.9988 0.3344 0.0000
vt 0.9988 0.6648 0.0000
vt 0.6681 0.6648 0.0000
vt 0.6681 0.3344 0.0000
vt 0.3359 0.6668 0.0000
vt 0.6663 0.6668 0.0000
vt 0.6663 0.9992 0.0000
vt 0.3359 0.9992 0.0000
vt 0.0007 0.6666 0.0000
vt 0.3347 0.6666 0.0000
vt 0.3347 0.9992 0.0000
vt 0.0007 0.9992 0.0000
vt -0.0000 0.3340 0.0000
vt 0.3344 0.3340 0.0000
vt 0.3344 0.6658 0.0000
vt -0.0000 0.6658 0.0000
vt 0.3370 0.3347 0.0000
vt 0.6652 0.3347 0.0000
vt 0.6652 0.6662 0.0000
vt 0.3370 0.6662 0.0000
vt 0.6681 0.6679 0.0000
vt 0.9996 0.6679 0.0000
vt 0.9996 0.9980 0.0000
vt 0.6681 0.9980 0.0000
# texture cords end, 24 texture coords

g Cube01
# faces begin
f 1/1 2/2 3/3
f 3/3 4/4 1/1
f 5/5 6/6 7/7
f 7/7 8/8 5/5
f 1/9 4/10 6/11
f 6/11 5/12 1/9
f 4/13 3/14 7/15
f 7/15 6/16 4/13
f 3/17 2/18 8/19
f 8/19 7/20 3/17
f 2/21 1/22 5/23
f 5/23 8/24 2/21
# faces end, 12 triangles

Listing 1 – Cube01 OBJ file

The entries in the Cube01 OBJ file in Listing 1 labeled with ‘v’ are the vertices that make up the 3D object’s geometric mesh of triangles. Those labeled with ‘vt’ are the texture coordinates, as explained in the previous article. The entries labeled with ‘f’ are the “faces” that make up the 3D object. The entries labeled with ‘#’ are comments and have no bearing on the 3D object.

In this case, our 3D object is made up of 12 faces or triangles that form a “cube” (Figure 1). Each face entry is an index into the vertices (‘v’) and texture coordinate (‘vt’) lists. As you know, a triangle consists of three vertices. So for every triangle, we need three vertex coordinates and three texture coordinates. The first face/triangle entry is 1/1 2/2 3/3. 1/1 indicates the first entry in the vertex list and the first entry in the texture coordinate list. 2/2 indicates the second entry in the vertex list and the second entry in the texture coordinate list. 3/3 indicates the third entry in the vertex list and the third entry in the texture coordinate list.

For the first triangle, the vertex and texture coordinate entries are:

// face 1/1 2/2 3/3
vertex(-10.000000, 0.000000, 10.000000, 0.9988, 0.3344); // 1/1
vertex(-10.000000, 0.000000, -10.000000, 0.9988, 0.6648); // 2/2
vertex( 10.000000, 0.000000, -10.000000, 0.6681, 0.6648); // 3/3

Subsequent faces are assembled accordingly.

Figure 1: Cube01 Mesh

There is a simple way to visualize 3D objects while becoming familiar with the OBJ file format. A free open source programming environment called “Processing” can be downloaded and installed in a PC, Mac, or Linux environment with ease – see http://processing.org. Processing was developed at the MIT Media Lab and is an excellent tool for programming with a focus on visual context. It is ideal for learning embedded 3D programming fundamentals. To save you the time and trouble of typing the source code for our project, all the files you need for the process described in this article can be found at http://ricktewell.wordpress.com.

Launch the Processing environment. You will be taken to a “sketch” notepad. Here you will either cut and paste or type the source code in Listing 2 that will graphically demonstrate how the above Cube01 OBJ file can be expressed in code that actually displays a 3D object on screen.

PImage img;
void setup() {
size(640, 480, P3D);
img = loadImage(“cube.png”);
noStroke();
}

void draw() {
background(0);
noFill();
translate(width / 2, height / 2, 360);
rotateX(map(mouseY, 0, height, -PI, PI));
rotateY(map(mouseX, 0, width, -PI, PI));
textureMode(NORMALIZED);
beginShape(TRIANGLES);
texture(img);
DrawVertices();
endShape();
}

void DrawVertices() {
// Face 1 – f 1/1 2/2 3/3
vertex(-10.000000, 0.000000, 10.000000, 0.9988, 0.3344); // 1/1
vertex(-10.000000, 0.000000, -10.000000, 0.9988, 0.6648); // 2/2
vertex( 10.000000, 0.000000, -10.000000, 0.6681, 0.6648); // 3/3
// Face 2 – f 3/3 4/4 1/1
vertex(10.000000, 0.000000, -10.000000, 0.6681, 0.6648); // 3/3
vertex(10.000000, 0.000000, 10.000000, 0.6681, 0.3344); // 4/4
vertex(-10.000000, 0.000000, 10.000000, 0.9988, 0.3344); // 1/1
// Face 3 – f 5/5 6/6 7/7
vertex(-10.000000, 20.000000, 10.000000, 0.3359, 0.6668); // 5/5
vertex(10.000000, 20.000000, 10.000000, 0.6663, 0.6668); // 6/6
vertex(10.000000, 20.000000, -10.000000, 0.6663, 0.9992); // 7/7
// Face 4 – f 7/7 8/8 5/5
vertex(10.000000, 20.000000, -10.000000, 0.6663, 0.9992); // 7/7
vertex(-10.000000, 20.000000, -10.000000, 0.3359, 0.9992); // 8/8
vertex(-10.000000, 20.000000, 10.000000, 0.3359, 0.6668); // 5/5
// Face 5 – f 1/9 4/10 6/11
vertex(-10.000000, 0.000000, 10.000000, 0.0007, 0.6666); // 1/9
vertex(10.000000, 0.000000, 10.000000, 0.3347, 0.6666); // 4/10
vertex(10.000000, 20.000000, 10.000000, 0.3347, 0.9992); // 6/11
// Face 6 – f 6/11 5/12 1/9
vertex(10.000000, 20.000000, 10.000000, 0.3347, 0.9992); // 6/11
vertex(-10.000000, 20.000000, 10.000000, 0.0007, 0.9992); // 5/12
vertex(-10.000000, 0.000000, 10.000000, 0.0007, 0.6666); // 1/9
// Face 7 – f 4/13 3/14 7/15
vertex(10.000000, 0.000000, 10.000000, -0.0000, 0.3340); // 4/13
vertex(10.000000, 0.000000, -10.000000, 0.3344, 0.3340); // 3/14
vertex(10.000000, 20.000000, -10.000000, 0.3344, 0.6658); // 7/15
// Face 8 – f 7/15 6/16 4/13
vertex(10.000000, 20.000000, -10.000000, 0.3344, 0.6658); // 7/15
vertex(10.000000, 20.000000, 10.000000, -0.0000, 0.6658); // 6/16
vertex(10.000000, 0.000000, 10.000000, -0.0000, 0.3340); // 4/13
// Face 9 – f 3/17 2/18 8/19
vertex(10.000000, 0.000000, -10.000000, 0.3370, 0.3347); // 3/17
vertex(-10.000000, 0.000000, -10.000000, 0.6652, 0.3347); // 2/18
vertex(-10.000000, 20.000000, -10.000000, 0.6652, 0.6662); // 8/19
// Face 10 – f 8/19 7/20 3/17
vertex(-10.000000, 20.000000, -10.000000, 0.6652, 0.6662); // 8/19
vertex(10.000000, 20.000000, -10.000000, 0.3370, 0.6662); // 7/20
vertex(10.000000, 0.000000, -10.000000, 0.3370, 0.3347); // 3/17
// Face 11 – f 2/21 1/22 5/23
vertex(-10.000000, 0.000000, -10.000000, 0.6681, 0.6679); // 2/21
vertex(-10.000000, 0.000000, 10.000000, 0.9996, 0.6679); // 1/22
vertex(-10.000000, 20.000000, 10.000000, 0.9996, 0.9980); // 5/23
// Face 12 – f 5/23 8/24 2/21
vertex(-10.000000, 20.000000, 10.000000, 0.9996, 0.9980); // 5/23
vertex(-10.000000, 20.000000, -10.000000, 0.6681, 0.9980); // 8/24
vertex(-10.000000, 0.000000, -10.000000, 0.6681, 0.6679); // 2/21
}

Listing 2 – Cube01 Processing Source Code

Leave a Reply

Your email address will not be published. Required fields are marked *

*