I have also written a C++ class system to hold the model, a loader which will load from disk the KMD file and store it in the classes, and naturally a KMD viewer, which will display the model to screen.
After researching Quake's MD3, MD2 and other similar formats I decided to create my own binary per-vertex keyframe based animated model format (KMD binary file specification).
In plain "non-jargon" terms, this means I have created both a specification and implementation of how to store - in a computer, in binary- an animated 3D model for display (example: the penguin model below). This format has been designed to be small, so lots of models can be stored - even on small computers. I have also written a custom converter, to convert existing models to my (KMD) format, and a custom display program, which can be used in other programs to display KMD models too.
The format is loosely based on the OBJ and MTL formats in a binary form, but is also pretty similar to Quake's MD3 / MD2 formats.
I have written a C++ utility which takes multiple sets of sequenced OBJ files (one set per animation) and consolidates the data into one '.kmd' file. The KMD file does not, however, store any image data used for textures in the animation.
(To the right, we can see a KMD model in the viewer. The green outline is the next keyframe and the red the current, base, keyframe. The model is interpolated between the two.)
Some of the features of the KMD format and it's associated utilities:
• Per-vertex keyframe animation, which means that models can be animated without the constraints of skeletal animation, and also are usually faster to display at run-time, as calculating interpolated vertices is less intensive than calculating bone positions and skinning the bones.
• Multiple animations per file. KMD files can store an effectively arbitrary number of animations in one file, each broken down into keyframes. The only constraint is that each animation must share the same vertex order, and be constructed of the same faces (relative to the vertices).
• 'Replay in reverse', a feature which means a flag is set when the animation is created, which signals that after one play of the animation it should be played again, but in reverse. This is done when the model is loaded at runtime: the keyframes are simply duplicated, reversed and appended to the animation.
• Binary format, which in this case means the files are up to 65% smaller than their ASCII equivalents.
• Small file sizes on disk, achieved by:
- Only storing the vertex and vertex normal data for each keyframe (face and vertex texture coordinate data will stay consistent throughout the animation so these are stored only once).
- Index based face definitions. Like OBJ, KMD only stores unique vertices, and stores faces as indices to these vertices.
• Flags in the animated model file for settings such as 'replay in reverse', looping, and the smoothing type (smooth or flat) of each face (in fact a default smoothing setting is worked out then any faces with non-default storing are indexed).
• "Special Points", models can be given 'special points', which act like vertices however are invisible- and can be accessed by index from an application once the model is loaded.They are used for attaching models together and ensuring models interact correctly with their environments.
• Fully consolidated data by storing all of the data in one file, except the image, the loading of which is not part of KMD's functionality.
• Morphing can be done between animations, and in my KMD viewer is as easy as calling a function with the animation to morph to ID and the time allowed to morph.