Assignment 3: A Hilly Dungeon Crawl
Due: Monday, May 23
This is an extension of the previous assignment. Your dungeon will now provide for terrain that has fluctuations in altitude; different rooms will be at different heights. Ramps will connect the rooms. Also, the rooms may contain objects of different types which you will model with SketchUp. As before, you should be able to move the camera through the virtual space using the keyboard, though for extra credit the movement should be smooth, not discrete. The other big change is that you must make use of light sources and the Phong shading model for the surfaces of the terrain.
Specifications:
- The lay-out of the labyrinth will be specified in the file dungeon.dat, which your program must read at start-up. The file consists of two parts, both analogous to what was in the input file in the previous assignment.
- First part of input file:
This specifies the topology of the labyrinth.
- Each line of the file consists of asterix ('*'), space, and digit characters. The asterices indicate the positions of solid walls. The first and last character in each line will be an asterix, the first and last lines of this section of the input file will consist completely of asterices, and each line of the file will have the same number of characters.
- If a cell consists of an integer, x, that number represents a relative height of the floor.
- If a cell contains a space character, that space represents a ramp between two rooms, which may be at different elevations. You are guaranteed that either both the cells above and below, or both the cells to the left and the right will be '*' (i.e., walls). The other two cells will either be integers or another space character. Thus, ramps may be longer than one cell, but are always one cell in width. This can be a bit tricky, so be careful here. The slopes of your ramps should be continuous between the non-ramp spaces.
- Second part of input file:
this parallels the first part: there will be the same number of lines, and each will consist of the same number of characters. Effectively we are defining a parallel 2-d array. This data specifies the contents of the a labyrinth.
- The asterices represent walls as in the first part, and, indeed, are a direct copy of the asterices in the first part.
- A cell may be one of several values:
- 1-6 = a light of one of 6 different colors. The colors are your choice, but the sum of all 6 lights should be an RGB value that is observably different from (255, 255, 255). The light must have some kind of physical representation (a "glowing" cube, sphere, etc. You might use the emissive component of materials to effect this.)
- c = a "crate". A solid, visible object that blocks entry to that space. These are not walls. Make them short enough that the camera can "see over" to what is behind them. The object model should be loaded from a collada file created by SketchUp. It must be more than a simple rectangular prism.
- $ = a treasure. This can be anything, a golden sphere, for example. The object model should be loaded from a collada file created by SketchUp. It must be distinguishable from the crates and more than a simple rectangular prism.
- The simulated viewer should start in the lower right-hand corner of the labyrinth, facing 'north' (along the positive y axis).
- The walls appear to be tall enough that the camera can not see their tops. Easiest is to put a roof on the labyrinth. The camera should not be able to see through the walls.
- There should be a simulated "floor" that the camera can not see through.
- The user should be able to move the viewer via a keypad: 8 will move the viewer forward one space, 4 and 6 will turn the viewer 90 degrees to the left and right, 2 will move the viewer backward one space. If forward of backward movement would take the viewer into a wall, then the action should have no effect. Moving into a space that contains a treasure should remove that treasure from the labyrinth. It should not be possible to move into a wall, or into a space containing a crate.
- When the user types a movement key that should result in movement, the movement must be smooth. This is easily accomplished by animating the movement. Use a loop that uses sleep() calls or the system clock to move the camera a portion of the way toward the destination every fraction of a second (1/30th second gives a good animation). Alternatively you can juse the idle callback function: you might use a flag to indicate whether the user is in the middle of completing a move, and variables to indicate the user's current position (i.e., not yet in the center of the destination square).
- The 'q' or 'Q' key should terminate the program.
- The 'r' or 'R' key should reset the dungeon and the viewer to their original states/orientations.
- When the user is in a space containing a light, clicking with the mouse should toggle the light on or off.
- The camera should be colocated with a spotlight shining in the direction of movement. The light should be white, but not brighter than 50% of maximum. The 'l' or 'L' key should toggle the flashlight/headlight.
- The floor of the dungeon should be shiny, as if it were waxed (i.e., make the floors specular).
- Texture-map the surfaces of the walls, using a different texture for east/west walls and the north/south walls.
Here is a sample input file.
Accessing Sketchup Datafiles
To access the vertex, triangle and edge data in a Google Sketchup exported file, use my SketchUpCollada class. (You can download the entire contents of that project here.)
Graduate Student Requirements (and extra credit for undergrads)
For those of you taking this course for graduate credit you should complete the assignment as indicated above, with the following changes:
Motion of the camera should no longer be integral. The 4 and 6 keys should rotate the camera left and right, respectively, but only at a fixed rate for as long as the keys are held down. Upon release, the camera should remain at its current orientation. Likewise and 8 and 2 keys should move the camera forward and backward, but only for so long as the keys are held down. Not that movement along the ramps may be complicated by this. For each frame of animation, you can calculate the x,z coordinate easily enough, and the y-coordinate will be a fixed amount above the floor at that (x,z) position. But the height of the floor varies across ramps....
The program must still disallow the camera from passing through any walls. This is a simple form of collision detection, for each frame of animation, calculate whether the movement of the camera would take it into a space that is a wall. If so, do not move the camera.
Add a sky-dome or sky-cube to your program.
Hints:
Play with the diffuse, ambient, and specular coefficients to get a nice looking effect. Add the texture maps only after you've got most stuff working.
Submission:
Submit your source code to the appropriate dropbox in emuonline.edu.