Channels ▼


Importing 3D Models into Mobile Java Devices

Source Code Accompanies This Article. Download It Now.

Making the Immediate Mode Model

Since I couldn't generate M3G files, the best solution for me was to assemble the model as a Mesh using VertexArrays, then perform an immediate-mode render on it. My new plan still required building the model, then either finding a plug-in or writing a translator program to convert the model's data into triangle strips.

I chose Art of Illusion (www.artofillusion .org) as the 3D authoring application because it has an option for converting models into triangle strips, a feature that might simplify writing a translator program. It also is cross-platform, which meant I could press-gang my Apple Powerbook to do the work while I wrote the Java ME code on Windows.

Because the project already involved rocket science, I designed a retro-style Buck Rogers rocketship as the 3D model. Thus, the model "brocket" was born (Figure 2). I made the texture file, brocket2.png, to apply a simple color pattern on brocket's hull. I had Art of Illusion save the model in OBJ format, a 3D file format used by many authoring programs. The resulting files were brocket.obj, which contained the model's data, and brocket.mtl, which stored some appearance information and a reference to the texture map file.

[Click image to view at full size]

Figure 2: Using Art of Illusion to make the 3D model, brocket.

Before attempting to write a translator, I took one last stroll through Google to see if something similar was available. Luckily, I stumbled onto "Loading OBJ Models into M3G" (http://fivedots.coe, where Andrew Davison describes his ObjView program—a Java utility that reads an OBJ file, renders the 3D objects with Java 3D, and writes the object data out as M3G VertexArrays. The source code was also available. This was exactly what I needed.

To use ObjView, you need Java SE 1.4.x SDK or later installed on your PC or Mac, along with Java 3D, which implements a 3D API for Java desktop applications. Originally developed by Sun, Java 3D is an open-source technology. For Windows, Java 3D is available online ( For Mac OS 10.4.x, Java 3D comes preinstalled. For Mac OS 10.3.x, you can download Java 3D ( java3dandjavaadvancedimagingupdate.html).

First, I compiled the ObjView source files, per directions in objM3G.pdf. Next, I had Art of Illusion save the model in OBJ format, along with the .mtl file to preserve texture information. I copied the resulting brocket.obj, brocket.mtl, and brocket2.png files to the directory with the ObjView classes. Using the console window, I switched to that directory and had Java execute ObjView and read the OBJ file.

ObjView rendered the brocket model in Figure 3, complete with the texture image. Clicking and dragging the mouse rotates the model within the window so that you can inspect your handiwork.

[Click image to view at full size]

Figure 3: ObjView rendering the brocket model, with a texture applied.

One problem ObjView's display revealed was that Art of Illusion could mangle the texture maps. This is probably my fault, as I found the application's interface for applying a texture map around a complex object difficult to use. To apply the texture to the model successfully, I used Milkshape (, a 3D authoring program that has versatile texture-mapping tools and can import/export a variety of 3D file formats (Figure 4).

[Click image to view at full size]

Figure 4: Applying the texture to the brocket model with Milkshape.

When you're satisfied with the result, exit ObjView and it writes the model's geometry out as several M3G VertexArrays. These arrays describe the model's surfaces (as triangle strips), its surface normals (for calculating lighting effects), and its texture coordinates (which map a 2D image onto the surfaces). These VertexArrays appear as Java source code in the output file ObjView generates, examObj.txt. ObjView also writes some Appearance information and other visual attributes to this file, which are accessed through the code's built-in function setMatColours(). This file's contents can be copied and pasted directly into your application's display class, which is typically a Canvas.

Listing One shows the output ObjView generates, with the VertexArrays abbreviated for clarity. Technically, the data is actually stored as arrays, and the code's built-in methods, getVerts(), getNormals(), and getTextures(), load this data into VertextArrays. The built-in function setMatColours() sets the model's overall color to a light gray and its shininess to the maximum value of 128.0, which causes any specular highlights to be concentrated, rather than diffused.

// Methods for model in brocket.obj
  private short[] getVerts()
  // return an array holding Vertexes [2457 values / 3 = 819 points] 
    short[] vals = {
          15,-3,-56,     16,-3,-56,     16,-4,-60,
     16,-4,-60,     26,-8,-70,     15,-3,-56,  
     -11,-2,-41,    -11,-5,-40,    -14,-4,-26      };
    return vals;
  }  // end of getVerts()
  private byte[] getNormals()
  // return an array holding Normals [2457 values / 3 = 819 points] 
    byte[] vals = {
          -110,-66,-6,   -70,105,-23,   -78,70,-73,  
     -78,70,-73,    -89,-77,-51,   -110,-66,-6,  
     92,85,23,      120,39,21,     99,79,19      };
    return vals;
  }  // end of getNormals()
  private short[] getTexCoords()
  // return an array holding TexCoords [1638 values / 2 = 819 points] 
    short[] vals = {
          160,72,   163,72,   164,68,
     164,68,   191,58,   160,72,
     86,87,    86,88,    78,102      };
    return vals;
  }  // end of getTexCoords()
  private int[] getStripLengths()
  // return an array holding the lengths of each triangle strip
    int[] lens = {
      44, 28, 40, 76, 31, 69, 15, 85, 36, 8, 21, 22, 156, 44, 28, 40, 76
    return lens;
  }  // end of getStripLengths()
  private Material setMatColours()
  // set the material's colour and shininess values
    Material mat = new Material();
    mat.setColor(Material.AMBIENT, 0x00000000);
    mat.setColor(Material.EMISSIVE, 0x00000000);
    mat.setColor(Material.DIFFUSE, 0xFFCDCDCD);
    mat.setColor(Material.SPECULAR, 0x00000000);
    return mat;
  } // end of setMatColours()
Listing One

Related Reading

More Insights

Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.