Capturing Motion From a Heretic II or Quake 2 Model --------------------------------------------------- I. GwynFlex Motion Capture Background The Motion capture data used by GwynFlex consists of the location in 3D space of each joint, and the rotational angles in 3D space of each bone. This excerpt from the mocap.h header file explains the format of the motion capture data for the original version of GwynFlex (which uses a fixed skeletal structure): // The data will be stored in the following format: // // File header (# frames) // For every frame (as ordered in tris.fm file) // Name of frame (from tris.fm file) // For every bone (BONE_NUM_BONES, including reference bones, // as enumerated in bones.h) // X translation of joint closest to hip (double) // Y translation of joint closest to hip (double) // Z translation of joint closest to hip (double) // For every bone (BONE_NUM_BONES, including reference bones, // as enumerated in bones.h) // Rotation about X axis of joint closest to hip (double) // Rotation about Y axis of joint closest to hip (double) // Rotation about Z axis of joint closest to hip (double) // // The number of frames is determined by the length of the file. // // Translation is given in "units". Translations are added to the // location of the joint, assuming the joint begins at (0,0,0). // // Rotation is given in radians. Rotations use a coordinate system in // which the X axis points right, the Y axis points up, and the Z axis // points away from the viewer, assuming the bone begins aligned along // the positive X axis and got there by applying the reverse rotations // in reverse order. The first set of motion capture data used by GwynFlex was captured from the Corvus model by manually identifying groups of vertices that, when averaged, would give the position of a joint or the position of a bone's "up vector" (aka "bone spin"). This was done using a single exported pose of the Corvus model in .OBJ format, the 3D modeler TrueSpace 2, and a text editor. Since .OBJ is a text format, the .OBJ file was viewed in TrueSpace 2 and the text editor simultaneously. Individual verteces were selected in TrueSpace, and the vertex positions reported by TrueSpace were looked up in the .OBJ file using the text editor, to determine which vertex (e.g. the 5th, the 112th, etc.) was selected. These were collected in groups that appeared to describe the location of a joint or up vector. A C program then scanned the tris.fm file for Corvus, calculated rotational angles and positions from the averaged vertex groups, and wrote the 2.5 MB motion capture file mocap.spz. GwynFlex users can create additional animations by hand, by posing the skeleton within the user interface and saving successive poses to a new .spz file. Poses are saved in the same format as motion capture data, making new and motion captured aniumations interchangeable. The process of creating additional animations by hand, while tedious, allows great flexibility in the resulting animated Heretic II and Quake 2 models. II. Automated Capture of Motion from Exisitng Models The same basic techniques are used to capture motion from an existing Quake 2 or Heretic II model, as were used to capture the motion data from Corvus. Manual vertex identification and grouping has been replaced by an automated technique, described below. Prior to motion capture, the GwynFlex user must set up the model's skeleton, bone twists, and bone bindings exactly as (s)he would prior to animating the model using existing motion capture data. Briefly, the steps are: import a single frame of the model; pose the skeleton inside of the model's mesh; set up the spin for each bone; bind each part of the mesh to the appropriate bone. This user setup defines the locations of joints and orientation of bones within the initial pose. This gives GwynFlex enough information to track the corresponding locations and orientations in all animation frames of the existing model. These are saved using the same file format as the Corvus motion capture data and user-generated animations. Bone spin is tracked by projecting the bone spin vector (at mid-bone) outward through the mesh. The vector will pass through a triangle bound to the bone. The verteces of this triangle are taken as the group to track. The average P of the three verteces in the group is calculated, and a vector originating at P is projected back toward and perpendicular to the bone to determine where along the bone (as a percentage of length) the vector intersects. Call the point of intersection Q. This defines a vector originating at Q (on the bone), perpendicular to the bone, and passing through P. Then vector QP is translated to the midpoint of the bone (as QP'), and the rotational angle R around the axis of the bone between the actual bone spin vector and QP' is calculated. To capture spin for the bone in a given animation frame, GwynFlex first determines the locations of the joints terminating the bone (this is described below). Then the location of P is calculated by averaging the locations of the specified triangle verteces. Then the location of Q is calculated by projecting a perpendicular back to the bone, QP' is calculated, and the position of the bone spin indicator is calculated by rotating QP' around the axis of the bone by angle -R. Joint locations are tracked by identifying, for each joint, four non-coplanar verteces that are bound to exactly one of the bones connected at the joint, and that maintain constant distance from each other across all animation frames. These are taken as the group of verteces that will track the joint position. The bones are assumed to be rigid (constant length) as is the mesh associated with a given bone. Under these conditions, the distance from each vertex to the joint location will be the same in each animation frame, despite the movement of the joint, and the verteces will never be coplanar. The distances are saved as A, B, C, and D for points Pa, Pb, Pc, and Pd respectively. To capture the joint location in a given animation frame, GwynFlex determines the positions of the four tracking points. It then solves the system of equations: i) (x-Xa)^2 + (y-Ya)^2 + (z-Za)^2 = A^2 ii) (x-Xb)^2 + (y-Yb)^2 + (z-Zb)^2 = B^2 iii) (x-Xc)^2 + (y-Yc)^2 + (z-Zc)^2 = C^2 iv) (x-Xd)^2 + (y-Yd)^2 + (z-Zd)^2 = D^2 where Xa is the x-coordinate of Pa, and so on. The point (x, y, z) is the joint location. Four distances are needed, since any three points are coplanar and would produce solutions on either side of the resulting plane, one of which would be false. NOTE: Pathological cases exist in which GwynFlex will not be able to determine a set of verteces to use to track either bone spin or joint position. In these cases the motion capture fails. III. The Math The math for bone spin capture is already used throughout GwynFlex. GwynFlex / h2mocap (the original motion capture program) routinely rotate bones from an arbitrary position in space to lie along the X axis with origin (0,0,0). This same technique is used to rotate QP' and the bone spin vector of the original frame to determine the rotational angle between them about the bone. The quadratic math used to solve for joint location is new to GwynFlex but not too challenging. Conceptually we are calculating the intersection of four spheres. Intersecting two speres defines a circle; adding a third defines two points on the circle; adding a fourth narrows the selection to a single point. Rather than solving the quadratics in closed form, Gwynflex uses a successive approximation technique. A point K0 is chosen that satisfies equation (i), and the vector from Pb to K0 is calculated. Then a point K1 is calculated as the point that satisfies equation (ii) and lies along the vector PbK0. The vector from that point to Pc is calculated. Then a point K2 is calculated as the point that satisfies equation (iii) and lies along the vector PcK1. The vector from Pd to K2 is calculated. Then a point K3 is calculated as the point that satisfies equation (iv) and lies along the vector PdK2. This repeats with equation (i) through (iv) until the location of Kn converges. Generally K0 is chosen as (A+Xa, Ya, Za). NOTE: Do not have mathematical proof that Kn converges - need a hard limit on iterations and motion capture fails if no convergence. However it seems like it should converge since the points are non-coplanar and define a unique solution.