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.