/** Ray trace (rat race?) * @author: Phil Gage */ public class RayTrace { World world; // FrameBuffer framebuffer; TemporalBitmap bitmap; //Temporal coherence private Point point = new Point(); private Intersection intersection = new Intersection(); private Intersection closest = new Intersection(); private Intersection shadowIntersection = new Intersection(); // Ray ID number for grid mailbox acceleration // Must be static to be unique across multiple cameras // (could make this the ray count for statistics?) static long rayId = 1; int maxlevel = 5; // max trace recursion depth /** Initialize ray tracer and framebuffer */ RayTrace (World world, int width, int height) { this.world = world; //save the world! // framebuffer = new FrameBuffer(width, height); } /** Return true if shadowed */ boolean shadow (Point point, AbstractObject self, Vector3 direction) { Ray ray = new Ray (point, direction); //fix AbstractObject obj; if (world.grid == null) { for (int i=0; i Constants.EPSILON) return true; //shadowed } } else { ++rayId; if (world.grid.traverse (ray,rayId,self,bitmap,shadowIntersection) > Constants.EPSILON) return true; //shadowed } return false; //visible } /** Return color for intersection */ // tbd make this a plug-in class for objects... void shade (Intersection intersection, Color color, int level) { Point point = intersection.point; Vector3 d = intersection.incident; AbstractObject s = intersection.obj; Vector3 normal= intersection.normal; //fix Light light; double intensity; color.set(Color.BLACK); //zeros for (int i=0; i 0.0) intensity = intensity/(s.material.specular- s.material.specular*intensity+intensity); if (intensity > 0.0 && !shadow(point,s,light.direction)) color.addScaled(s.material.kd*intensity,light.color); //fix kd } color.multiply(s.getColor(point)); // color.addScaled(s.material.kd,s.getColor(point)); //fix kd // Specular Reflection if (s.material.ks > 0.0) { Ray r2 = new Ray (point,Ray.reflect(d,normal)); Color col2 = new Color(); trace (r2,col2,level); color.addScaled(s.material.ks,col2); } // Refraction if (s.material.kt > 0.0) { //tbd refract ray // Ray r2 = new Ray (point,Ray.refract(d,normal,TBD)); Ray r2 = new Ray (point,d); //fake, no refract, fix!!! Color col2 = new Color(); trace (r2,col2,level); color.addScaled(s.material.kt,col2); } // Ambient color.add(Light.ambient); } /** Trace a ray recursively and return color */ // tbd add max level and min color contribution checks... void trace (Ray ray, Color color, int level) { AbstractObject obj; double dist = -1, t = Constants.INFINITY; // Return black (zeros) if max depth exceeded // to prevent infinite recursion with reflection if (level > maxlevel) { color.set(Color.BLACK); return; } ++Statistics.rayCount; closest.obj = null; if (world.grid == null) { for (int i=0; i Constants.EPSILON && dist < t) { t = dist; closest.set(intersection); closest.obj = obj; } } } else { ++rayId; t = world.grid.traverse (ray,rayId,null,bitmap,closest); } if (closest.obj != null) { shade (closest, color, level+1); } else color.set(world.getBackground(ray.direction)); } }