Improved object-oriented multiple user avatar library for QUANTA
I've worked with the CAVERNsoft and QUANTA avatar code in Performer, but we do not have any code available for using it with an Open Inventor scene graph. I decided that rather than trying to adapt the existing code's "template," it would be a lot easier to just start from scratch and create an entirely new set of code for handling avatars. This updated code exhibits better object-oriented design, and it separates class responsibilities. The old code required managing duplicate avatar and manager classes. A direct dependence existed between the two. I've tracked down a few minor bugs in QUANTA while integrating the networking. The server code included in the archive makes efficient use of threads and signals to reduce the CPU load.
Download: qavatar.zip (.zip, 126k, April 13, 2004)
The new code is organized in a similar manner, but I have added some Design Patterns. I have dropped the C++ templates to hopefully enhance compatibility. There are four main classes involved in QAvatar:
Viewing the UML for the classes makes it clear that the QAvatar and QAvatarManager classes are heavyweight classes. However, the manager class is not likely to require subclasses. It operates through its avatar instance. QAvatarFactory is pretty lightweight, as all it has to do is create a concrete QAvatar instance. This approach behaves similar to templates without the need for using template code.
Programming with this library requires making new subclasses, but that's not a big deal. The biggest importance for subclasses is to set the QAvatar data buffer sizes. Subclasses should set the values for each of the aux, hello, and tracker buffers. The manager adjusts its own buffers based on the sizes specified within the avatar object. I thought about different ways to tackle this problem, but I really wanted to keep responsibilities separate to avoid the dual subclassing dictated by the older avatar code.
I wrote some simple classes to demonstrate the code's behavior on the command line. I implemented signal handling to properly operate blocking network updates, so the application behaves better while waiting for network data. The required subclasses is really basic. For example, consider a simple factory:
class DemoFactory : public QAvatarFactory
It's very simple and straight-forward. When the QAvatarManager needs to create a new avatar, it generates a unique ID (or uses the one received over the network) and passes that to the factory method. The factory creates a new instance and returns it to the caller. Here's sample code for a very basic listener that receives notification from the manager:
class DemoListener : public QAvatarListener
No callbacks... just simple notification messages. The manager passes
the avatar instance, so that instance can be queried for any class-specific
information. Creating graphic representations of avatars is thus within
the domain of
Documentation is available using doxygen, so I just need to make sure that the example programs are clear enough.
Building the Library
The source code is configured using CMake, the same build tool used for the Visualization Toolkit. I work on multiple platforms, and it's a nightmare to separately manage Makefiles, Visual Studio Projects, and any other platform-specific build settings. CMake uses a single CMakeLists.txt file to configure everything on just about any platform. I have built qavatar on MacOS X, Windows 2000, IRIX, and Linux without any trouble.