Elements of Graphics: Assignment Six


Due Midnight, Monday April 16.

In this assignment you will add more realistic lighting and material properties to the program you produced for the previous assignment. Your final product should have exactly the same objects and motions as you start with. However, you should replace the circus colors of the existing object with more realistic ones. The cube should end up looking like a silver object, the tetrahedron like a gold one, and the two collision boxes should look three dimensional and appear to light up from within when the collisions happen. You may choose your own material, color and lighting schemes for the last two boxes subject to these constraints.

Your completed assignment should work something like this.

You may start with your own program from the last assignment, or, if you prefer, use mine (its been simplified and clarified relative to the original code we started with):

TetrahedronCollision.java

The other parts of the code are the same as for the last assignment:

CollisionDetector.java
Box.java
Tetrahedron.java

This time around you will have to do some modifications to Box.java and CollisionDetector.java as well as to TetrahedronCollision.java, but you won't need to modify Tetrahedron.java. You will have to modify Box.java to add normals to the faces of the box, or else you won't be able to produce realistic lighting, since as we discussed in class, diffuse and specular lighting depend on the orientation of the surface, which is represented by the normal. You can use the code in Tetrahedron.java as a guide to what to add to Box.java, you have to do the same thing, but you have 6 faces with 4 vertices each instead of 4 faces with 3 vertices each. You'll also have to convert the Point3d stuff to Point3f and xmax, xmin, ymax, ymin, zmax, and zmin to floats since the normal calculations need to be done in floating point, not in double precision. And finally, the Box will be a QuadArray, not a TriangleArray.

Once you've fixed up Box.java, do not succumb to the temptation to put the box or material properties in the Box.java or Tetrahedron.java code. You can set these in TetrahedronCollision.java for each object you create. You'll need to retrieve the Material() for each of your objects and set the parameters to get the lighting effects you want for that object. Here's an example code fragment to do this for the gold tetrahedron:

Tetrahedron tetra = new Tetrahedron();
Appearance app = tetra.getAppearance();
Color3f tetraColor = new Color3f(0.49f, 0.34f, 0.0f);
Color3f hilite = new Color3f(0.89f, 0.79f, 0.0f);
//Material(ambient, emissive, diffuse, specular, shininess)
app.setMaterial(new Material(tetraColor, black, tetraColor,
hilite, 17.0f));
tetraRotate.addChild(tetra);

Notice that the highlight color is different than the diffuse and ambient color, but not white. That's characteristic of metallic objects. If you want shiny plastic, make the highlight white (1.0f, 1.0f, 1.0f). If you want the object to be shinier than this, make the last parameter (17.0f) larger. You'll have to do something similar for each object. A reasonable choice for silver (for the tick tock cube) is:
diffuse and ambient color: (0.37f, 0.37f, 0.37f)
highlight color: (0.89f, 0.89f, 0.89f)
shininess: 17.0f

To make the two boxes on the sides, you'll have also to set Material properties, I'm leaving these up to you as long as you get the effects I asked for above. The two key points are that you'll need to use the emissive property (set to black above) to make the object glow, and you'll need to set that to the "non-glowing" (black, perhaps?) value when you create the boxes, and then have CollisionDetector.java change that to some "glowing" value when the collision is detected instead of changing the color as it does now. To do this, you'll need to set the Material property for each box to be writable. A code fragment for setting up one of these boxes is:

Appearance app = shape.getAppearance();
Color3f bColor = new Color3f(0.45f, 0.3f, 0.2f);
Color3f glow = new Color3f(0.0f, 0.0f, 0.0f);
Color3f bhilite = new Color3f(0.0f, 0.0f, 0.0f);
Material bMat = new Material(bColor, glow, bColor, bhilite, 1.0f);
bMat.setCapability(bMat.ALLOW_COMPONENT_WRITE);
app.setMaterial(bMat);

Finally, you'll need to set up some lights. In particular, you'll need an ambient light, and either a directional light or a point light, or both (or more than one of each). Any light has a color. A directional light also has the direction that the light is going. A point light has the position of the light and an attenuation factor that gives three numbers, a constant attenuation, a linear attenuation, and a quadratic attenuation. A code fragment to set these up is:

DirectionalLight lightd = new DirectionalLight();
lightd.setDirection(new Vector3f(0.0f, -1.0f, -2.0f));
lightd.setColor(new Color3f(0.6f, 0.6f, 1.0f));
lightd.setInfluencingBounds(bounds);
objScale.addChild(lightd);

PointLight lightp = new PointLight();
lightp.setPosition(new Point3f(0.0f, 1.0f, 1.0f));
lightp.setAttenuation(0.0f, 0.6f, 0.4f);
lightp.setColor(new Color3f(0.8f, 0.8f, 0.8f));
lightp.setInfluencingBounds(bounds);
objScale.addChild(lightp);

AmbientLight amb = new AmbientLight();
amb.setColor(new Color3f(0.75f, 0.75f, 0.75f));
amb.setInfluencingBounds(bounds);
objScale.addChild(amb);

Don't just use these, play around with the parameters once your program is working to get a feel for how changing them changes the appearance of the objects. Do the same for the material properties of the two side boxes.

Turn in the assignment through the lab using turnin, with the usual README file, even though you won't run this in the lab. You should turn in copies of CollisionDetector.java and Box.java as well as your modification of TetrahedronCollision.java, since we expect modifications to all three of these.


Don Fussell