We can now export the animation data from the 3D modeling package of our choice, but before we actually make use of them, let's take a quick look at the new file types that we've just generated.
A SKEL file contains all the information pertaining to the skeleton of our animation. The file first defines an instance of a CIwAnimSkel
class, which is a wrapper for a number of CIwAnimBone
instances.
The CIwAnimSkel
instance is derived from the CIwResource
class and therefore has a name associated with it so that it can be looked up in the resource manager. The name of the instance is taken from the filename of a SKEL file, which in turn comes from the name of the root bone of the skeleton.
Each of the CIwAnimBone
instances have a name, position, and rotation associated with it, which defines the bind pose of the animation. The position is just a vector in model space, while the rotation is stored as a quaternion. Except for the first bone, which is the root bone, each bone will also list its parent bone, thus building up the skeletal hierarchy.
The SKEL file gets
exported into the models
sub-directory alongside the GEO and MTL files. An example of a SKEL file is as follows:
CIwAnimSkel { numBones 12 CIwAnimBone { name "FlagPoleBase" pos {-0.38309,-1.27709,0} rot {0.70711,0,0,0.70711} } CIwAnimBone { name "PoleA" parent "FlagPoleBase" pos {258.20248,0.00000,0} rot {1,0,0,0} } CIwAnimBone { name "PoleB" parent "PoleA" pos {255.88675,0.00000,0} rot {1.00000,0,0,-0.00200} } CIwAnimBone { name "PoleC" parent "PoleB" pos {257.60138,-0.00000,0} rot {0.00000,0.99998,0.00615,0.00000} } CIwAnimBone { name "PoleD" parent "PoleC" pos {255.08751,-0.00000,-0.00000} rot {0.00000,0.99998,0.00621,0.00000} } CIwAnimBone { name "PoleE" parent "PoleD" pos {257.19775,0.00000,-0.00000} rot {1.00000,0,0,0.00206} } CIwAnimBone { name "FlagStart" parent "PoleE" pos {152.41219,0.00000,-0.00000} rot {0.61894,0,0,-0.78544} } CIwAnimBone { name "FlagA" parent "FlagStart" pos {85.99931,-0.00000,-0.00000} rot {0.99505,0,0,0.09934} } CIwAnimBone { name "FlagB" parent "FlagA" pos {57.19376,0.00000,-0.00000} rot {1.00000,0,0,0.00128} } CIwAnimBone { name "FlagC" parent "FlagB" pos {61.42473,0.00000,-0.00000} rot {0.99996,0,0,0.00846} } CIwAnimBone { name "FlagD" parent "FlagC" pos {60.33911,0,-0.00000} rot {0.99996,0,0,-0.00877} } CIwAnimBone { name "FlagE" parent "FlagD" pos {60.36695,-0.00000,-0.00000} rot {0.99985,0,0,0.01754} } }
The SKIN file is the bridge between the skeleton and the vertices of the 3D model in its bind pose. It contains all the data representing which vertices are influenced by which bones.
The file starts by defining an instance of the CIwAnimSkin
class. This instance contains references to the CIwAnimSkel
instance that defines the bones of the required skeleton, and also the CIwModel
instance that will be used for rendering the model once the new vertex positions have been calculated. As with the SKEL file, the name given to the CIwAnimSkin
instance is derived from the filename of the SKIN file.
The file then contains a number of instances of the CIwAnimSkinSet
class, which indicates which vertices are modified by which bones. This is achieved by first listing the bones, up to a maximum of four, then the number of vertices in the set. The bone weights are then specified for each vertex by providing the index of the vertex in the model vertex stream, followed by a weight value for each bone. The sum of the weight values for each vertex must total to one.
The SKIN file is also exported to the models
subdirectory and the following code provides a partial example of one. These files tend to be quite large due to the sheer amount of data required for even a simple animation, so an extract should provide enough of a flavor of what these files look like.
CIwAnimSkin { skeleton "FlagPoleBase" model "Flag" CIwAnimSkinSet { useBones { FlagPoleBase } numVerts 16 vertWeights {0,1} vertWeights {1,1} vertWeights {2,1} vertWeights {3,1} vertWeights {4,1} vertWeights {35,1} vertWeights {58,1} vertWeights {60,1} vertWeights {62,1} vertWeights {64,1} vertWeights {65,1} vertWeights {90,1} vertWeights {91,1} vertWeights {92,1} vertWeights {93,1} vertWeights {94,1} } CIwAnimSkinSet { useBones { FlagPoleBase PoleA } numVerts 10 vertWeights {5,0.50170,0.49830} vertWeights {6,0.50251,0.49749} vertWeights {7,0.50177,0.49823} vertWeights {8,0.50116,0.49884} vertWeights {9,0.50114,0.49886} vertWeights {57,0.50251,0.49749} vertWeights {59,0.50177,0.49823} vertWeights {61,0.50116,0.49884} vertWeights {63,0.50114,0.49886} vertWeights {66,0.50170,0.49830} } // Several more CIwAnimSkinSet instances would have been // defined here but they have been left out to avoid // filling the book with boring numbers! CIwAnimSkinSet { useBones { FlagA FlagB FlagC FlagD } numVerts 8 vertWeights {39,0.15992,0.33285,0.33292,0.17431} vertWeights {44,0.15632,0.33444,0.33462,0.17462} vertWeights {49,0.17817,0.32895,0.32812,0.16476} vertWeights {54,0.18163,0.32749,0.32638,0.16450} vertWeights {106,0.15632,0.33444,0.33462,0.17462} vertWeights {112,0.17817,0.32895,0.32812,0.16476} vertWeights {120,0.18163,0.32749,0.32638,0.16450} vertWeights {121,0.15992,0.33285,0.33292,0.17431} } CIwAnimSkinSet { useBones { FlagB FlagC FlagD FlagE } numVerts 20 vertWeights {40,0.14751,0.34532,0.34603,0.16114} vertWeights {41,0.02763,0.13480,0.41879,0.41879} vertWeights {45,0.14368,0.34743,0.34842,0.16046} vertWeights {46,0.02625,0.13072,0.42151,0.42151} vertWeights {50,0.16232,0.34459,0.34444,0.14865} vertWeights {51,0.03730,0.16777,0.39776,0.39717} vertWeights {55,0.16581,0.34255,0.34229,0.14936} vertWeights {56,0.03875,0.17110,0.39544,0.39471} vertWeights {102,0.02763,0.13480,0.41879,0.41879} vertWeights {103,0.02625,0.13072,0.42151,0.42151} vertWeights {107,0.14368,0.34743,0.34842,0.16046} vertWeights {108,0.02625,0.13072,0.42151,0.42151} vertWeights {109,0.03730,0.16777,0.39776,0.39717} vertWeights {113,0.16232,0.34459,0.34444,0.14865} vertWeights {114,0.03730,0.16777,0.39776,0.39717} vertWeights {115,0.03875,0.17110,0.39544,0.39471} vertWeights {122,0.16581,0.34255,0.34229,0.14936} vertWeights {123,0.14751,0.34532,0.34603,0.16114} vertWeights {124,0.03875,0.17110,0.39544,0.39471} vertWeights {125,0.02763,0.13480,0.41879,0.41879} } }
The final file type we need to consider is the ANIM file, which as its name suggests is the file that actually defines a particular animation.
The file first declares an instance of the CIwAnim
class, which, as with the other animation class types, will be given a resource name derived from the filename.
The skeleton that this animation will be applied to is the first thing that the CIwAnim
instance will specify. This is then followed by a number of CIwAnimKeyFrame
declarations that detail the positions and orientations of each affected bone at a particular time index.
Key frames do not need to list the orientation and position of each bone in the skeleton. If a bone has not moved relative to its parent, its position will remain as it was at the previous key frame.
The exporters will create an anims
sub-directory to hold all the ANIM files. An example of an ANIM file is provided in the following code; but as with the SKIN file, this is just a partial example so as to
not fill the pages of this book with lots of numbers:
CIwAnim { skeleton "FlagPoleBase" // Keyframe# 1 CIwAnimKeyFrame { time 0 bone "FlagPoleBase" pos {-0.38309,-1.27709,0} rot {0.70711,0,0,0.70711} bone "PoleA" pos {258.20248,0.00000,0} rot {1,0,0,0} bone "PoleB" pos {255.88675,0.00000,0} rot {1.00000,0,0,-0.00200} bone "PoleC" pos {257.60138,-0.00000,0} rot {0.00000,0.99998,0.00615,0.00000} bone "PoleD" pos {255.08751,-0.00000,-0.00000} rot {0.00000,0.99998,0.00621,0.00000} bone "PoleE" pos {257.19775,0.00000,-0.00000} rot {1.00000,0,0,0.00206} bone "FlagStart" pos {152.41219,0.00000,-0.00000} rot {0.61894,0,0,-0.78544} bone "FlagA" pos {85.99931,-0.00000,-0.00000} rot {0.99505,0,0,0.09934} bone "FlagB" pos {57.19376,0.00000,-0.00000} rot {1.00000,0,0,0.00128} bone "FlagC" pos {61.42473,0.00000,-0.00000} rot {0.99996,0,0,0.00846} bone "FlagD" pos {60.33911,0,-0.00000} rot {0.99996,0,0,-0.00877} bone "FlagE" pos {60.36695,-0.00000,-0.00000} rot {0.99985,0,0,0.01754} } // Keyframe# 5 CIwAnimKeyFrame { time 0.16667 bone "FlagPoleBase" pos {-0.38309,-1.27709,0} rot {0.73026,0,0,0.68317} bone "PoleA" pos {258.20248,0.00000,0} rot {0.99889,0,0,-0.04716} bone "PoleB" pos {255.88675,0.00000,0} rot {0.99864,0,0,-0.05222} bone "PoleC" pos {257.60138,-0.00000,0} rot {0.00000,0.99857,-0.05338,0.00000} bone "PoleD" pos {255.08751,-0.00000,-0.00000} rot {0.00000,0.99624,0.08662,-0.00000} bone "PoleE" pos {257.19775,0.00000,-0.00000} rot {0.99483,0,0,-0.10158} } // Keyframe# 15 CIwAnimKeyFrame { time 0.58333 bone "FlagPoleBase" pos {-0.38309,-1.27709,0} rot {0.70668,0,0,0.70754} bone "PoleA" pos {258.20248,0.00000,0} rot {0.99873,0,0,0.05033} bone "PoleB" pos {255.88675,0.00000,0} rot {0.99775,0,0,0.06711} bone "PoleC" pos {257.60138,-0.00000,0} rot {0.00000,0.99951,0.03144,-0.00000} bone "PoleD" pos {255.08751,-0.00000,-0.00000} rot {0.00000,0.99996,0.00868,0.00000} bone "PoleE" pos {257.19775,0.00000,-0.00000} rot {0.99853,0,0,0.05420} } // Further key frames follow to define the remainder of the // animation but these have been removed to avoid including // large amounts of datafile in the pages of this book }
3.145.202.61