Model Poser
by Bob Rost

What is it?

Model Poser is an implementation of an experimental animation program by Takeo Igarashi, the creator of the Teddy 3d modelling software. My goal was to create a version as similar to Takeo's in function as possible, but written in C++ for BeOS, instead of in Java for Windows. Most importantly, I wanted my implementation to reflect Takeo's work ethic of creating powerful tools with simple, elegant interfaces.

The Application

Click here for demo video (DivX AVI, 3.3 MB)

Model Poser is written in C++ for BeOS R5. It will only run on systems will the beta OpenGL rewrite. It consists of several operation modes.


Pose Mode
Selecting pose mode will create a new key position, which the user may place anywhere on the screen. After clicking to set the position, the model may be posed as desired. Left click will rotate a model piece around its pivot, middle click will move the pivot, and right click will select a different piece. The currently selected piece is always highlighted.


View Mode
Once poses have been created, view mode may be selected to interpolate the model. Moving the mouse around the screen interpolates between the poses, with each pose having a weight proportional to the inverse square of the distance between it's key position and the current mouse location.


Record Mode
Record mode behaves like view mode, except that the mouse position is recorded 25 times every second. This allows the user to create an animation to be played back. If there is a previously recorded animation, it will be deleted when record mode is selected.


Play Mode
Once an animation has been recorded, play mode will play it back. The animation has 25 samples per second of the mouse position, but this can create jerky playback. To create a smoother playback, the current virtual mouse position during playback is calculated by interpolating between the sampled positions. Play mode will loop an animation repeatedly with a half-second interpolation between the last and first frames on the loop.

The Software Components

TGA image loader
This code, found on the internet, was written by Nate Miller and is freely available for non-commercial use. It loads TGA images as OpenGL textures.

model3d
I wrote this as a simple 3d model display class. It has a simple programming interface which allows a 3d model to be built by inputting a list of vertex locations and face vertex indices. The model can then be displayed in OpenGL with a single function call. One of the features is automatic normal calculation for faces and vertices. Unfortunately, this particular feature does not seem to be threadsafe, so it has been disabled in Model Poser to prevent crashes.

ASEModel
This class imports 3dmax ASE models and allows easy manipulation. It supports one level of children. Each piece of the model resides in a geom_info struct. This struct uses a model3d to hold the mesh data, and it also contains default rotation information, as well as the names of the piece and its parent. The pose struct holds the concept of a model's current positioning. It holds the pivot's rotation and position for each piece of the 3d model.

The main ASEModel class has various functions that make Model Poser work as well as it does. It has functions that allow selecting, rotating, and moving a model piece. Additionally, it has functions for saving poses, retreiving saved poses, and striking an arbitrary pose. And of course, to top it all off, it has a single Draw() function.

BeGLUT
This is what makes the hardware 3d acceleration possible under BeOS. Retail versions of BeOS do not have hardware accelerated OpenGL. Because of this, the only previously available version of GLUT was software rendering only, which obviously will not provide acceptable performance. Since beta versions of an OpenGL rewrite allow high performance hardware acceleration, I decided to write GLUT so that managing the 3d window would still be a simple task. The official GLUT source code is really messy, and I didn't want to touch it, so instead I chose to write BeGLUT from scratch, which, being written natively for BeOS, would take advantage of the capabilities of BeOS, such as its superior multithreading and its clean API. BeGLUT doesn't support the full set of GLUT functions, but the important ones are there to allow window, mouse, and keyboard control.

Possible Improvements

There are a few areas in which I could improve this program if I had been able to devote more time to it. The first one is the interpolation scheme. When I asked Takeo about his implementation, he pointed me to a paper describing a method of creating height fields with constraint points. Because I currently use an inverse square dropoff weighting, all of the key poses have some degree of influence on the resulting pose. The height field method would allow a key pose to be the only influencing pose when the mouse is over its key position, and key poses whose positions were relatively far from the mouse cursor would have no influence on the resulting pose.

Next, I would like to implement video file output. Using the BeOS media API, it would not be all that difficult to grab the OpenGL frame buffer and send it to an AVI file as a frame. Implementing the pose control during output would be similar to the playback ability I have already implemented.

One more area in which I would have liked to improve the program is rendering options. Currently, faceted rendering is the only supported style. Other options such as smooth shading, texture mapping, and cel shading could provide an appealing flair to the application.

Thanks

Original idea and implementation by Takeo Igarashi. Sprites created by Andrew Klein.