first person view of castle

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 object loader working, you will find my sample solution in the "a3sample" 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 GLapp program to interactively walk through the castle/castle.obj model with a first-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.

Where the orbit transform of the sample code uses translate(distance)*rotate(tilt)*rotate(pan), a first-person view will use rotate(tilt)*rotate(pan)*translate(viewpoint)

Start the player at a position of (-10000, -1150, 500), looking down the -X axis. As you navigate through the castle, the view should remain a constant height of 500 units above the model. So the player can go up and down stairs, but not teleport to the top of tall walls, allow changes in elevation of up to 250 units. If moving forward would change the elevation by more than that amount, do not allow the player to move in that direction. You should also prevent the player from walking through walls by not allowing a move that would put the player within 250 units of a wall in the motion direction.

To figure out the player's height, trace a ray from the player's position in the -Z direction using barycentric triangle intersection, looking for intersections within 750 units of the current viewpoint (500 to the previous ground, plus an extra 250 in case they are walking down stairs). If there's an intersection between 250 and 750 units below the current viewpoint, adjust the viewpoint elevation to 500 units above that height. To keep the player from walking through a wall, trace a ray in the direction of motion from their current position, looking for a wall intersection within 250 units. If you find one, do not allow that movement.

For the tracing, construct an auxilliary data structure containing just the data for computing ray/triangle intersections for the castle. Precompute everything you can, and do early-out testing to make the ray tracing as efficient as possible. You are only tracing two rays, not millions, so the performance should still be reasonable.

Extra Credit

Your auxilliary data structure should put the triangle ray tracing info into a uniform 3D grid with cells 750x750x750. If a triangle spans multiple cells, put a copy of its barycentric intersection data in each cell that it covers. Use the bounding box of the triangle to figure out which cells the triangle might cover. You will only need to do intersection testing on the triangles within one cell of the player's position, therefore saving a ton of potential intersection computations.

634 only

Load a second model as the player and navigate using a third-person view. A third person view is an orbit around the first-person view: translate(distance)*rotate(tilt)*rotate(pan)*translate(viewpoint). You will also need to use an object transformation for the player model including viewpoint translation and pan rotation, so it will be drawn at the player location looking in the player's view direction (but not tilting with the tilt component of the orbit). You may also want to include some additional scale in the object transform to make your player model fit with the assumptions of player size. If you do not use one of the provided obj models, check your player model into your GLapp/data directory.

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

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.