Lab 4: Interactive terrain

Goal: In this lab, you will render a 3D terrain with objects that interact with it. The terrain is given as a heightmap image.

Since this is the last lab, it is more flexible than usual. There are several interesting non-mandatory tasks at the end.

1) Load and inspect the heightmap.

A "bare bones" program is provided as lab4-1.c. A few heightmap textures are available here: images. You will also need files from earlier labs (textures, helpers). The makefile is similar to old ones.

The initial lab shell is a simple scene with a flat textured quad. It also loads the heightmap "terrain-44.ppm" and prints it contents.

To compile this assignment, perform make lab4-1 on the command line.

Run the assignment by performing ./lab4-1.

Note that the code includes both gluLookAt() (fixed camera) and getCameraMatrix() (interactive camera as lab 2) for placing the camera. You should switch between them as needed.

Questions:

2) Drawing the heightmap

Goal: To draw the heighmap in 3D.

Copy lab4-1.c to lab4-2.c. Make this section's changes to lab4-2.c.

The height map image is available to you as a data array. Figure out a way to draw it in 3D.

Hint: The initial heightmap is extremely small. This is to help you. Use printf as needed.

Hint: Make a double "for" loop over the array, with appropriate scaling for height and width so your terrain matches the given quad.

Hint: Every quad is drawn as two triangles. Do each triangle separately, so you have full control.

Once you have "terrain-44" running, try one of the larger ones. If you have written your code correctly, the larger heightmap should be appropriately drawn with no extra effort.

Questions:

3) Calculate normal vectors and apply lighting

Goal: To make the heightmap look better by using lighting.

Copy lab4-2.c to lab4-3.c. Make this section's changes to lab4-3.c.

Lighting should be familiar to you by now. Generate a normal vector for every polygon in the surface to make a decent lighting of the scene.

Enable lighting for the terrain.

The triangle positions must be used. Calculate two edges of the triangle and find the normal vector using the cross product.

Questions:

4) Calculating map height for a point

Goal: To find the height of the heightmap for any given point and place objects in the scene using that information

Copy lab4-3.c to lab4-4.c. Make this section's changes to lab4-4.c.

Your height map is drawn as a set of triangles. For a given point (x, z), find the y value.

This is done in three steps:

1) Using the scaling of the terrain, calculate what quad the point falls into.

2) The quad is built from two triangles. Figure out which one to use.

3) Calculate the height value. There are several ways to do it. You can interpolate over the surface, or you can use the plane equation.

Using this function, place objects on the surface. The objects can be anything, simple shapes, Utah Teapot, or models loaded from disk. The positions chosen must not be exactly on vertices. Use the low-res terrain for testing.

Questions:

5) Pick one of the "extras" below as final part of the lab.

You only have to do one. If you make more than one, we like it, but don't feel obliged to do it.

Remember that some nice features can be part of your project even if you don't finish them here, in case there are several features below that you feel are desirable (and there surely are).

Copy lab4-4.c to lab4-5.c. Make this section's changes to lab4-5.c.

 

5a) Interaction with a moving object

Goal: To present better tools for managing worlds containing multiple different objects.

In a previous assignment, you placed stationary objects in the terrain. Here you should handle a moving object. The object should move over the surface, but not go straight through it.

Simple version (if you are running out of time): Move in a simple, predetermined path over x and z, and set the height to a suitable distance over the terrain using the measure in (3).

Better version: Introduce a ball, a sphere, into the scene. You can draw it with glutSolidSphere(). It should not be too small. The ball should be given a speed, in the form of a speed vector. Make it move over the scene surface. Can you even make it bounce off the surface in a realistic way?

Advanced version: Find the planes in the terrain that this ball overlaps in the XZ plane. Using the plane equation/dot product, check if the sphere overlaps the terrain, and if it does, move it to a valid position. Also, use the collision plane for calculating a realistic collision.

Questions:

5b) Smooth lighting

Goal: To make better lighting

In section 4, we only demanded normal vectors per triangle. However, if you generate one surface normal for every vertex instead of every polygon, the light will be nice and smooth (to a limit, as long as we use Gouraud shading).

So, the normal vector should not be the normal vector of one plane but the average of all polygons using the vertex.

Questions:

5c) Multitextured terrain

Goal: To make the terrain look even nicer through multitexturing.

Using at least two textures and a shader, blend the textures in some appropriate way (height, slope) to make the terrain more realistic, interesting and/or beautiful.

Questions:

5d) Multiple objects

Goal: To put many objects in the "world"

Intruduce many objects, either many spheres or other objects. In any case, you may use spheres for collision detection. Handle collisions between the objects and between all objects and the surface.

Questions:

5e) Render using arrays

Goal: To prepare the terrain for better performance by using vertex arrays

Above, immediate mode was assumed. Generate vertex arrays for rendering the same surface. Normal vectors are not mandatory.

Questions:

5f) Objects with terrain dependent slope

Goal: To measure the slope of the terrain and apply it on objects

Every polygon has a slope, that is its normal vector. Use that information to draw objects that are appropriately tilted to match the slope. Test using the low-res terrain.

Questions:

5g) The lake

Goal: To handle a part of the terrain separately to make a lake

One of the terrains, "fft-terrain.ppm", has a big flat area in the middle of the map. This area could be considered a "lake". Identify the appropriate "water surface" polygons and paint them blue.

Questions:

5h) Camera movement

Goal: To move the camera over the terrain

When you use the camera movement provided by getCameraMatrix(), you can pass straigth through the terrain, and the stationary use of gluLookAt() allows no movement at all. Make the camera move over the terrain without intersecting it.

Questions:

5i) Frustum culling

Goal: To optimize terrain drawing by only drawing visible parts

When using large terrains, large parts of the terrain will often be outside the viewing frustum. Then drawing can be speeded up significantly by excluded out-of-view polygons. Several way to handle this are outlined in the book.

Questions:

That concludes lab 4. We hope that this gives you a start in programming geometry yourself as needed, and maybe gives you tools and ideas to use in your projects.