Before you start

This assignment builds on the previous one. If yours worked, I strongly recommend using your own code as a starting point for this assignment. If you were not able to get your asteroid generation working, you will find my sample solution in the "assn3soln" directory of your GitHub repository. You are free to either use this code to figure out what was wrong with your assignment, or use it as a base for this one. Whichever you choose, be sure to do all of your work for this assignment in the "GLapp" directory of your repository.

The Assignment

For this assignment, you will modify your asteroid program to interactively walk over the surface with a first-person view using typical game keyboard and mouse controls. Add a sky sphere using the sky-color.ppm texture.

Motion should use four keys: holding 'w' should move you in whatever direction you are currently facing, 's' should move you backwards, and 'a' and 'd' should strafe left and right. Your view up vector should be the vector from the center of the asteroid to your current position. Moving the mouse left and right should pan your view horizontally and change your current heading. Moving the mouse up and down should tilt your view, but not affect the heading. All motions should be computed in terms of velocities (units moved per second), then scaled by the elapsed time (dTime) between frames. Note this multiplication of a velocity (in m/s) times a time (in s) results in a distance (in m).

As you navigate over the terrain, the player should remain a constant height above the asteroid. You will need to find the player's current triangle considering just their (u,v) position from the 3D to uv mapping (below). You can find the position within a triangle by computing the 2D barycentric coordinates of the player's uv position between the uv coordinates of each vertex.

```vec2 Map3DtoUV(vec3 P) {
float s = 0.5f/(abs(P.x) + abs(P.y) + abs(P.z));
float t = min(0.f,P.z);
return vec2(P.x - sign(P.x)*t, P.y - sign(P.y)*t)*s + 0.5f;
}```
• The simplest way to do this is to loop through all of the triangles looking for one where the barycentric coordinates satisfy 0 ≤ α, β, γ ≤ 1
• If you implemented the half-edge data structure, you can keep track of the current triangle. When the player leaves that triangle, you can know which edge they crossed based on which of α, β, or γ is negative. Follow the links across that edge to the next triangle. You should continue following edge links until you find the new current triangle in case the player departed the old triangle through a vertex or was moving fast enough to traverse several triangles in one step.
• If your triangles are created in a 2D grid following the octahedral mapping, you can scale the player's uv coordinate to directly find the grid cell, then just need to figure out which of the two triangles for that cell is the correct one.

Once you have found the triangle, use barycentric interpolation of the vert coordinates of that triangle to compute the 3D asteroid position at the player's uv position (α v0 + β v1 + γ v2). Compute the distance from that point to the origin, add a constant height to that radius, then rescale the player location vector to that new (r+h) radius (rescale the player's position rather than directly use the asteroid position to avoid potential jitter from numerical errors).

634 only

You should provide an option to switch back and forth between the first-person view and a third-person view. Smoothly transition over about two seconds when the 'V' key is pressed. In the third person view, render the player walking over the terrain as a small version of the provided Sphere shape. You'll need to shrink the size and the ability to set the position and orientation. You'll also need to either stop drawing the player sphere when in first-person mode so you don't just see the inside of the player object.

Remember that a third-person view is created by combining an first person transformation with a translation of the view back away from the player. You can transition between the two by increasing or decreasing that distance over several frames. At each frame, figure out how far the current time is along that transition, and the view translation distance from that.

Extra Credit(435 & 634)

For up to 5 points, add a debugging mode with view sufficiently far away from the asteroid to see its shape. Includesome indication of player location (e.g. with a sphere as in the grad version). Debugging mode should either have a viewpoint that is still inside the sky sphere, or turn it off. If you choose to do this, I'd do it early to help you debug your primary assignment.

For up to 10 points, include a jump when the player presses the space bar. Retain the current motion vector, but add a vertical component. During the jump, disable any motion or jump input. Compute a gravity vector opposite the up vector each frame, scale by dTime, and add it to the velocity. Continue until the player's position is at or below the asteroid surface. At that point, turn motion keys and snapping to the asteroid surface back on.

For up to 5 points, include a dash when the player is pressing the shift key while moving. The dash should double the velocity while active, but should only last for a limited time, and should have a cool-down before you can use it again.

Tips

Though FPS views normally use a roll/pitch/yaw style transform, to effectively handle the varying up vector, it is easier to construct the transformation matrix directly by columns or use a LookAt (with the 'at' position computed as a point offset in the current forward direction from the player's position).

Though it is possible to extract the position and heading from the transformation matrices, it is far easier go keep track of them as separate vectors or as columns of a WorldFromPlayer matrix in one of your classes structures.

Think before you code about which direction each transformation is going, and where the origin and axes are before and after that transformation.

What to turn in

Do your development in the GLapp directory so we can find it. Also include an assn4.txt file at the top level of your repository telling us about your assignment. Tell us what works, and what does not. Also tell us what (if any) help you received from books, web sites, or people other than the instructor and TA.

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 assn4. See the assn0 project description if you accidentally tag the wrong commit and need to retag.

You must make multiple commits 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 will not count as incremental commits. Do be sure to check in all of your source code, but no build files, log files, generated images, zip files, libraries, or other non-code content.