### 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 island generation working working, you will find my sample solution in the "island" 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 island program to interactively walk over the landscape with a third-person view using typical game keyboard and mouse controls. 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. 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 rates (per second), then scaled by the elapsed time between frames.

Render the player walking over the terrain as a small version of the provided Sphere shape. You'll need to shrink the size and add a position and rotation that can be changed by your navigation code. As you navigate over the terrain, the sphere should remain a constant height above the landscape. To figure out the player's height, consider just their horizontal (x,y) position. Find the player's current triangle by computing the 2D barycentric coordinates of their position for each landscape triangle, looking for one where 0 ≤ α, β, γ ≤ 1. Use barycentric interpolation of the vertex z coordinates of the that triangle to compute the surface height at the player's position, then add a constant offset to place them above the surface (α z0 + β z1 + γ z2 + h). If the computed elevation is below sea level, or if the (x,y) position is not inside any of the triangles (because they are out at sea), position the player a constant height above sea level.

A third-person view is created by combining an orbit transform with a translation to the player position (i.e. `translate*rotate*rotate*translate`).

### 634 only

Rather than loop through all of the triangles to find the one below the sphere, create some auxilliary data structure to track the position from triangle to triangle. If the sphere's position is outside of one of the edges of its last triangle, try the triangle on the other side of that edge. You may sometimes need to walk through a few triangles in the traversal (especially if you exit a triangle near one of its vertices), but should be able to visit considerably fewer triangles to find the new location than you would the exhaustive search. On startup, or when outside the island, you can fall back to the exhaustive search (Ideally, you'd triangulate all walkable areas with triangles, but that's more complicated than I want to make this assignment).

### Extra Credit(435 & 634)

For up to 25 points of extra credit, try to keep the player's viewpoint above the surface of the island or sea. If it would be below the surface, adjust the tilt upward until it is not. You'll need to explicitly compute the position of the camera, and run a second barycentric search for that camera view point. If the camera's z is below the surface, you will need to figure out the tilt angle that would get you above that surface.

If there is no valid tilt angle that would place the viewpoint above the current triangle (which can happen if the viewpoint is buried a couple of triangles deep in a hill), skip the adjustment and leave the view where it was. For full extra credit, march in steps of how far away the camera is from the character, from close to the character to the full actual camera distance, tilting the view up at each step to keep the camera above the surface. In a real game, good third-person camera placement can be more complex than I intend for this extra credit, but even the single-triangle version should give some idea of how camera placement constraints work. Some games even treat the third-person camera as an independent AI character, trying to avoid obstructions and set up a good view of both character and action.

### Tips

Shrink the sphere and change the wasd keys to move it north/west/south/east before you touch the barycentric code or do anything with the view. Then work on the barycentric elevation so the sphere follows the terrain. Only once you can see the sphere moving correctly over the surface should you change the heading to use the pan angle. Finally, once that is working, change the view to the third-person view. If you make the view changes early, it is far to easy to end up with a view that doesn't show anything, and not be able to tell why.

Consider shrinking the max altitude of your island. The tall craggy island looks good from far away, but can be way steeper than you would want for walking.

### 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 `assn4`. 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. Finally, if you did anything toward the extra credit, be sure to tell us about it in this file.

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.