The Assignment

This assignment will build on your OpenGL code from assignments 3, 4, or 5 (or mine, if yours was not working) by recording a motion path and playing it back. While the user is walking around the scene, you should record their position (x/y) and view orientation every second. When the user hits the "p" key, you will play back a smoothed version of the path they walked over the past five seconds using Catmull-Rom spline interpolation. Do not worry about the final partial second (so your final position will not quite reach your location when you pressed "p").

Since Catmull-Rom splines need additional samples before and after the path, you will repeat the first point twice and repeat the last point twice.

Rotations interpolate more reliably using quaternions. You can convert from a matrix, M, to quaternion, Q using

Q.w = sqrt(max(0, 1 + M[0][0] + M[1][1] + M[2][2]))/2;
Q.x = sqrt(max(0, 1 + M[0][0] - M[1][1] - M[2][2]))/2;
Q.y = sqrt(max(0, 1 - M[0][0] + M[1][1] - M[2][2]))/2;
Q.z = sqrt(max(0, 1 - M[0][0] - M[1][1] + M[2][2]))/2;
Q.x = copysign(Q.x, M[2][1] - M[1][2]);
Q.y = copysign(Q.y, M[0][2] - M[2][0]);
Q.z = copysign(Q.z, M[1][0] - M[0][1]);

After interpolation, convert from quaternion form back to matrix form

float xx = Q.x * Q.x;
float xy = Q.x * Q.y;
float xz = Q.x * Q.z;
float xw = Q.x * Q.w;

float yy = Q.y * Q.y;
float yz = Q.y * Q.z;
float yw = Q.y * Q.w;

float zz = Q.z * Q.z;
float zw = Q.z * Q.w;

M[0][0] = 1 - 2 * (yy + zz);
M[0][1] =     2 * (xy - zw);
M[0][2] =     2 * (xz + yw);

M[1][0] =     2 * (xy + zw);
M[1][1] = 1 - 2 * (xx + zz);
M[1][2] =     2 * (yz - xw);

M[2][0] =     2 * (xz - yw);
M[2][1] =     2 * (yz + xw);
M[2][2] = 1 - 2 * (xx + yy);

Both of these conversions based on content at

Extra Credit

Each time the user presses the "x" key, record the position, direction, and time. Construct a new non-uniform spline using the Catmull-Rom rules for endpoint position and velocity, but with using the actual recorded time values recorded t=0 and t=1 for the start and end time of each segment. Your project should also run all the way to the end position when the user pressed "p", since you can deal with non-uniform control point spacing.

What to turn in

Turn in this assignment electronically by pushing your source code to your class git repository by 11:59 PM on the day of the deadline and tagging the commit assn6. Do your development in the GLapp directory, continuing to modify the code there. It is not necessary to make a copy. Version control allows us to check out the assignment 4 or 5 versions for grading while you work on assignment 6, even if you commit and push along the way.

Also include an assn6.txt file telling us about your assignment. Do not forget to tell us what (if any) help you received from books, web sites or people other than the instructor and TA.

Check in along the way with useful checkin messages. We will be looking at your development process, so a complete and perfectly working assignment submitted in a single checkin one minute before the deadline will NOT get full credit. Individual checkins of complete files one at a time just before the deadline will also NOT get full credit. Do be sure to check in all of your source code, CMakeLists.txt, and updated .gitignore file, but no build files, log files, generated images, zip files, libraries, or other non-code content.

Be sure to include the details of the system you used for the assignment in your assn6.txt in case we have problems.