import java.lang.*; import java.io.*; public class Scene { public Colour Ambient; private int numberObjects; private int numberLights; private Object[] sceneObjects; private Light[] sceneLights; // Maximum reflection depth we will trace to private static int MaxDepth=2; // Temporary static variables for lighting phase // this saves some overhead in memory mangement private Vector n; private Vector h; private Colour kd; // temporary variable for diffuse private Colour ks; // temporary variable for specular public Scene() { numberObjects = 0; sceneObjects = null; numberLights = 0; sceneLights = null; // Default ambient light Ambient = new Colour (0.5,0.5,0.5); // Initialise static variables n = new Vector(); h = new Vector(); kd = new Colour(); ks = new Colour(); } // Note this deletes original scene public void setNumberObjects(int n) { numberObjects = n; sceneObjects = new Object[n]; } public int getNumberObjects() { return numberObjects; } public void setObject(int i, Object o) { sceneObjects[i]=o; } public void setNumberLights(int n) { numberLights = n; sceneLights = new Light[n]; } public int getNumberLights() { return numberLights; } public void setLight(int i, Light o) { sceneLights[i]=o; } public boolean intersect(Ray ray, Colour colour, int depth) { double tmin = java.lang.Double.MAX_VALUE; double t; int hitObject=-1; t = tmin; for (int i=0;i 0.0) { //intersection found if(t < tmin){ tmin = t; hitObject = i; } } } if (hitObject > -1) { /* We have an intersection so calculate lighting */ Point p = ray.getPointAt(tmin); calculateColour(colour, sceneObjects[hitObject], p, ray, depth); colour.clamp(); return true; } else { return false; } } private void calculateColour(Colour colour, Object object, Point p, Ray ray, int depth) { Light light; // temporary reference to current light Vector direction = new Vector(); // ray indicating direction to light /* Ambient component */ colour.copy(object.SurfaceMaterial.Ambient); colour.mult(Ambient); /* Object normal at the intersection point */ n.copy(object.normal(p)); /* For each light in the scene */ /* Hint: the "nextlight" label can be used to jump back to the start if the point is in shadow from a particular light */ nextlight: for (int i=0;i 0.0) { double pnh; direction.normalise(); /* Your code here (1) - is the light occluded by another object ?*/ Vector.subtract(h,ray.Origin,p); h.normalise(); Vector.add(h,h,direction); h.normalise(); double nh = Vector.dot(n,h); kd.copy(object.SurfaceMaterial.Diffuse); ks.copy(object.SurfaceMaterial.Specular); if (object.SurfaceMaterial.Shininess < 1) { pnh = 0.0; } else { pnh = Math.pow(nh, object.SurfaceMaterial.Shininess); } kd.scale(nl); ks.scale(pnh); kd.add(ks); kd.mult(light.Intensity); colour.add(kd); } } /* Your code here (2) - do a recursive ray trace. Use specular colour to modulate the colour returned by the recursive intersect call */ colour.clamp(); } public void read(SceneReader is) throws Exception { /* * read the objects */ numberObjects = is.readInt(); System.out.println("Scene has "+ numberObjects+ " objects"); setNumberObjects(numberObjects); for(int i=0; i