Objects in Master/slave Programs

The Syzygy object-importing code was originally written to work only using the no-longer supported scene graph. This means that while you can use most of these objects in master/slave applications via the scene graph owned by each master/slave framework, it can be a pain in the behind.

We are gradually factoring the code to allow it to be used more simply without using the scene graph. So far only the OBJ-format objects have been liberated.

arOBJRenderer

The arOBJRenderer allows you to easily read and render an OBJ file in a master/slave program. See the Wavefront OBJ section for information about the format. Simply:

  1. Instantiate it:
    arOBJRenderer myObj;
    
  2. Read in the file:
    if (!myObj.readOBJ( const string& fileName,
                        const string& subdirectory,
                        const string& dataPath ))
      oops;
    
    The dataPath argument can be a semicolon-delimited list of directory paths. You should read the file in both master and slaves.

  3. Draw it:
    myObj.draw();
    
    New 07/08: arOBJRenderers render much more quickly now, because texture maps are mip-mapped by default. Also, if you want to load one into an OpenGL display list, you should call the new activateTextures() method first:
    myObj.activateTextures();
    int dl = glGenLists(1);
    if (dl == 0) {
      oops;
    }
    glNewList( dl, GL_COMPILE );
    myObj.draw();
    glEndList();
    
    This causes any texture maps to be downloaded to the graphics card, which you want to do before compiling a display list; otherwise, the action of loading the texture to the card will be compiled into the display list, resulting in slower performance than if you hadn't used a display list at all.

Other optional methods:

string arOBJRenderer::getName();
int    arOBJRenderer::getNumberGroups();
void   arOBJRenderer::clear();
void   arOBJRenderer::normalizeModelSize();
float  arOBJRenderer::getIntersection( const arRay& theRay );
arBoundingSphere         arOBJRenderer::getBoundingSphere();
arAxisAlignedBoundingBox arOBJRenderer::getAxisAlignedBoundingBox();
arOBJGroupRenderer*      arOBJRenderer::getGroup( unsigned int i );
arOBJGroupRenderer*      arOBJRenderer::getGroup( const string& name );

Of particular interest are the getGroup() and getBoundingSphere() methods. The former returns an arOBJGroupRenderer that can be rendered separately from the parent object (i.e. if an obj file contains named groups of faces, you can render the groups indvidually). The arOBJGroupRenderer object also has a getBoundingSphere() method. These allow you to do frustum culling:

// draw callback
float modView[16];
float proj[16];
glGetFloatv( GL_MODELVIEW_MATRIX, modView );
glGetFloatv( GL_PROJECTION_MATRIX, proj );
arMatrix4 frustumMatrix = arMatrix4( projectionMatrix ) * arMatrix4( modelViewMatrix );
if (myObj.getBoundingSphere().intersectViewFrustum( frustumMatrix )) {
  myObj.draw();
}

Note that getBoundingSphere() is an expensive operation, so normally you would compute the arBoundingSphere once, cache it, and use its transform() method to apply any constant transformations.

Supported Object Formats

Wavefront OBJ

Syzygy supports most of the official OBJ spec, and tries to fix some of the inconsistencies that programs tend to stick into exported files. A simple OBJ file looks like this:

  # myfile.obj
  o object_name
  v -1 -1 -1
  v -1 -1  1
  v -1  1 -1
  f 1 2 3
  f 2 3 4
  ...

Syzygy supports shading groups, normals, texture coordinates, material files, object names, and convex polygons. It does not support splines or raytracing options.

You can also specify an OBJ Material file, which usually ends in ".mtl". This file must be referenced from an .obj file via the "usemap" command. A material file will let you specify basic colors or textures for the .obj file. The format of an .mtl file is:

  newmtl shaderName
    Kd 0.5 0.5 0.5
    Ka 0.1 0.1 0.1
    Ks 1.0 1.0 1.0
    map_Kd texturefilename.ppm
  newmtl ...

Where shaderName is the name of the corresponding shading group in the .obj file, Kd is the diffuse coeefficient (base color), Ka is the ambient coefficient (background or fill light), and Ks is the specular coefficient (color of highlight). Currently the Ns, or specular power term, is unused since we are using basic OpenGL for rendering. If you specify a map with map_Kd, the texture specified will be used instead of Kd. All .mtl file parameters are optional, and have consistent default values.

Motion Analysis HTR

Used with our Motion Analysis motion capture setup and software, an HTR specifies a series of transformations frame by frame to define animations. By calling arHTR's attachMesh with an additional boolean true value, the HTR will use randomly colored line segments as its "bones":

  ((arHTR*)myObject)->attachMesh(my_name, my_parent, 1);

3D Studio format

We use lib3ds to read in 3ds files, so we can only use versions 3 and 4. If your .3ds file doesn't display or you see an error message when trying to read in the file, this is probably the reason. Simply convert it to version 3 or 4 (there are several free utilities out there), and the new .3ds should load into Syzygy. Basic materials and normals are supported.