Monday, April 5, 2010

Implementing Spatial Alignment

First, let me recap why spatial alignment is important: when we transplant the upper body from one motion to the lower body of another, it is likely there will be noticeable problems in the form of twitching unless both motions were similar enough. This is because the upper body is usually correlated with lower body movements, and transplanting destroys this correlation.

Earlier in my project, I found a quick way to get rid of the twitching was to not transplant the joint above the root, the lowerback joint, which is responsible for rotation about the torso. Although excluding the lowerback joint eliminates the twitching, it sacrifices some rotation. A solution to this is proposed in "Splicing Upper-Body Actions with Locomotion" by Heck, Kovar, Gleicher [2006].

Following their method, called spatial alignment, we should compute a rotation for the lowerback joint that best aligns the shoulders and spine of the motion we use for the upper body with the motion for the lower body. The orientation is found by computing point clouds and solving for the closed form solution in "Closed-form solution of absolute orientation using unit quaternions" [Horn 1987].

Although it sounds simple enough, I've encountered a number of issues while trying to implement it. The closed form solution needs to compute eigenvalues of a system, so I had to find the appropriate matrix library to do that. I then implemented the solution and had to run many unit tests to ensure that it was implemented correctly.

The method involves computing point clouds in both motions using the locations of the shoulders and spine of the character. Before computing the orientation from the closed form solution using the point clouds as input, the paper advises that we translate and rotate the point clouds so that the lowerback joint coincides with the origin. However, this seems to have introduced more twitching/noise (assuming I implemented correctly). I found that just making the root coincide with the origin to produce less noise, but I'm not entirely sure if that's the right approach. To troubleshoot whether I was doing things correctly, I wrote some code to visualize the point clouds in different colors for the two motions - this definitely helped to find quick orientation problems. The implementation involves conversions between Euler angles, rotation matrices, and quaternions. What initially caused me problems was the order of the Euler angles, which was YZX for the root and ZYX for the rest of the joints.

Results and observations coming soon...

No comments:

Post a Comment