Ported over bamboo benchmarks for use as non-Bamboo java benchmarks.
[IRC.git] / Robust / src / Benchmarks / Scheduling / GC / NON_BAMBOO / RayTracer / RayTracer.java
1
2 /**************************************************************************
3  * * Java Grande Forum Benchmark Suite - Version 2.0 * * produced by * * Java
4  * Grande Benchmarking Project * * at * * Edinburgh Parallel Computing Centre *
5  * * email: epcc-javagrande@epcc.ed.ac.uk * * Original version of this code by *
6  * Florian Doyon (Florian.Doyon@sophia.inria.fr) * and Wilfried Klauser
7  * (wklauser@acm.org) * * This version copyright (c) The University of
8  * Edinburgh, 1999. * All rights reserved. * *
9  **************************************************************************/
10
11 public class RayTracer extends Thread {
12
13   public int image[][];
14
15   Scene scene;
16   /**
17    * Lights for the rendering scene
18    */
19   Light lights[];
20
21   /**
22    * Objects (spheres) for the rendering scene
23    */
24   Primitive prim[];
25
26   /**
27    * The view for the rendering scene
28    */
29   View view;
30
31   /**
32    * Temporary ray
33    */
34   // Ray tRay= new Ray();
35   // Ray tRay;
36
37   /**
38    * Alpha channel
39    */
40   // static final int alpha = 255 << 24;
41   static final int alpha;
42
43   /**
44    * Null vector (for speedup, instead of <code>new Vec(0,0,0)</code>
45    */
46   // static final Vec voidVec = new Vec();
47   // static final Vec voidVec;
48
49   /**
50    * Temporary vect
51    */
52   // Vec L = new Vec();
53   // Vec L;
54
55   /**
56    * Current intersection instance (only one is needed!)
57    */
58   // Isect inter = new Isect();
59   // Isect inter;
60
61   /**
62    * Height of the <code>Image</code> to be rendered
63    */
64   int height;
65
66   /**
67    * Width of the <code>Image</code> to be rendered
68    */
69   int width;
70
71   // int datasizes[] = { 150, 500 };
72   int datasizes[];
73
74   public long checksum;
75
76   int size;
77
78   int numobjects;
79
80   public RayTracer() {
81     // tRay = new Ray();
82     alpha = 255 << 24;
83     // voidVec = new Vec();
84     // L = new Vec();
85     // inter = new Isect();
86     checksum = 0;
87     datasizes = new int[2];
88     datasizes[0] = 150;
89     datasizes[1] = 500;
90     numobjects = 0;
91     width = 0;
92     height = 0;
93     size = 0;
94   }
95
96   /**
97    * Create and initialize the scene for the rendering picture.
98    * 
99    * @return The scene just created
100    */
101
102   public Scene createScene() {
103     int x = 0;
104     int y = 0;
105
106     Scene scene = new Scene();
107
108     /* create spheres */
109
110     Primitive p;
111     int nx = 4; // 6
112     int ny = 4; // 6
113     int nz = 4; // 6
114     for (int i = 0; i < nx; i++) {
115       for (int j = 0; j < ny; j++) {
116         for (int k = 0; k < nz; k++) {
117           float xx = (float) (20.0f / (nx - 1) * i - 10.0);
118           float yy = (float) (20.0f / (ny - 1) * j - 10.0);
119           float zz = (float) (20.0f / (nz - 1) * k - 10.0);
120
121           p = new Sphere(new Vec(xx, yy, zz), 3);
122           // p.setColor(i/(float) (nx-1), j/(float)(ny-1),
123           // k/(float) (nz-1));
124           p.setColor(0, 0, (i + j) / (float) (nx + ny - 2));
125           p.surf.shine = (float) 15.0;
126           p.surf.ks = (float) (1.5 - 1.0);
127           p.surf.kt = (float) (1.5 - 1.0);
128           scene.addObject(p);
129         }
130       }
131     }
132
133     /* Creates five lights for the scene */
134     scene.addLight(new Light((float) 100, (float) 100, (float) -50, (float) 1.0));
135     scene.addLight(new Light((float) -100, (float) 100, (float) -50, (float) 1.0));
136     scene.addLight(new Light((float) 100, (float) -100, (float) -50, (float) 1.0));
137     scene.addLight(new Light((float) -100, (float) -100, (float) -50, (float) 1.0));
138     scene.addLight(new Light((float) 200, (float) 200, (float) 0, (float) 1.0));
139
140     /* Creates a View (viewing point) for the rendering scene */
141     View v = new View(new Vec(x, 20, -30), new Vec(x, y, 0), new Vec(0, 1,
142         0),(float) 1.0, (float)(35.0 * 3.14159265 / 180.0), (float)1.0);
143     /*
144      * v.from = new Vec(x, y, -30); v.at = new Vec(x, y, -15); v.up = new
145      * Vec(0, 1, 0); v.angle = 35.0 * 3.14159265 / 180.0; v.aspect = 1.0;
146      * v.dist = 1.0;
147      */
148     scene.setView(v);
149
150     return scene;
151   }
152
153   public void setScene(Scene scene) {
154     // Get the objects count
155     int nLights = scene.getLights();
156     int nObjects = scene.getObjects();
157
158     lights = new Light[nLights];
159     prim = new Primitive[nObjects];
160
161     // Get the lights
162     for (int l = 0; l < nLights; l++) {
163       lights[l] = scene.getLight(l);
164     }
165
166     // Get the primitives
167     for (int o = 0; o < nObjects; o++) {
168       prim[o] = scene.getObject(o);
169     }
170
171     // Set the view
172     view = scene.getView();
173   }
174
175   public void render(Interval interval) {
176
177     // Screen variables
178     int pixCounter = 0; // iterator
179
180     Vec viewVec;
181     viewVec = Vec.sub(view.at, view.from);
182     viewVec.normalize();
183     Vec tmpVec = new Vec(viewVec);
184     tmpVec.scale(Vec.dot(view.up, viewVec));
185     Vec upVec = Vec.sub(view.up, tmpVec);
186     upVec.normalize();
187     Vec leftVec = Vec.cross(view.up, viewVec);
188     leftVec.normalize();
189     float frustrumwidth = (float) (view.dist * Math.tan(view.angle));
190     upVec.scale(-frustrumwidth);
191     leftVec.scale((float) (view.aspect * frustrumwidth));
192
193     // For each line
194     for (int y = interval.yfrom; y < interval.yto; y++) {
195
196       float ylen = (float) (2.0 * y) / (float) interval.width -(float)  1.0;
197
198       // For each pixel of the line
199       int row[]=new int[interval.width];
200       int line_checksum=0;
201       Ray tRay = new Ray();
202       Ray r = new Ray(view.from, new Vec(0,0,0));
203
204       for (int x = 0; x < interval.width; x++) {
205         Vec col = new Vec();
206
207         float xlen = (float) (2.0 * x) / (float) interval.width - (float) 1.0;                                  
208
209         r.D = Vec.comb(xlen, leftVec, ylen, upVec);
210         r.D.add(viewVec);
211         r.D.normalize();
212
213         col = trace( 0, (float) 1.0, r,new Isect(),new Ray(),new Vec());
214
215         // computes the color of the ray
216
217         int red = (int) (col.x * 255.0);
218         if (red > 255)
219           red = 255;
220         int green = (int) (col.y * 255.0);
221         if (green > 255)
222           green = 255;
223         int blue = (int) (col.z * 255.0);
224         if (blue > 255)
225           blue = 255;
226
227         checksum += red;
228         checksum += green;
229         checksum += blue;
230
231         // Sets the pixels
232         row[x]= alpha | (red << 16) | (green << 8) | (blue);
233       } // end for (x)
234
235       image[y-interval.yfrom]=row;
236     } // end for (y)
237
238
239   }
240
241   boolean intersect(Ray r, float maxt, Isect inter) {
242     Isect tp;
243     int i, nhits;
244
245     nhits = 0;
246     inter.t = (float) 1e9;
247     for (i = 0; i < prim.length; i++) {
248       // uses global temporary Prim (tp) as temp.object for speedup
249       tp = prim[i].intersect(r);
250       if (tp != null && tp.t < inter.t) {
251         inter.t = tp.t;
252         inter.prim = tp.prim;
253         inter.surf = tp.surf;
254         inter.enter = tp.enter;
255         nhits++;
256       }
257     }
258     return nhits > 0 ? true : false;
259   }
260
261   /**
262    * Checks if there is a shadow
263    * 
264    * @param r
265    *            The ray
266    * @return Returns 1 if there is a shadow, 0 if there isn't
267    */
268   int Shadow(Ray r, float tmax, Isect inter) {
269     if (intersect(r, tmax, inter))
270       return 0;
271     return 1;
272   }
273
274   /**
275    * Return the Vector's reflection direction
276    * 
277    * @return The specular direction
278    */
279   Vec SpecularDirection(Vec I, Vec N) {
280     Vec r;
281     r = Vec.comb((float) (1.0 / Math.abs(Vec.dot(I, N))), I, (float) 2.0, N);
282     r.normalize();
283     return r;
284   }
285
286   /**
287    * Return the Vector's transmission direction
288    */
289   Vec TransDir(Surface m1, Surface m2, Vec I, Vec N) {
290     float n1, n2, eta, c1, cs2;
291     Vec r;
292     n1 = m1 == null ? (float) 1.0 : m1.ior;
293     n2 = m2 == null ? (float) 1.0 : m2.ior;
294     eta = n1 / n2;
295     c1 = -Vec.dot(I, N);
296     cs2 =(float) ( 1.0 - eta * eta * (1.0 - c1 * c1));
297     if (cs2 < 0.0)
298       return null;
299     r = Vec.comb((float) eta, I,(float) ( eta * c1 - Math.sqrt(cs2)), N);
300     r.normalize();
301     return r;
302   }
303
304   /**
305    * Returns the shaded color
306    * 
307    * @return The color in Vec form (rgb)
308    */
309   Vec shade(int level, float weight, Vec P, Vec N, Vec I, Isect hit,
310       Ray tRay, Vec L) {
311     float n1, n2, eta, c1, cs2;
312     Vec r;
313     Vec tcol;
314     Vec R;
315     float t, diff, spec;
316     Surface surf;
317     Vec col;
318     int l;
319
320     col = new Vec();
321     surf = hit.surf;
322     R = new Vec();
323     if (surf.shine > 1e-6) {
324       R = SpecularDirection(I, N);
325     }
326
327     // Computes the effectof each light
328     for (l = 0; l < lights.length; l++) {
329       // L.sub2(lights[l].pos, P);
330
331       L.x = lights[l].pos.x - P.x;
332       L.y = lights[l].pos.y - P.y;
333       L.z = lights[l].pos.z - P.z;
334
335       if (Vec.dot(N, L) >= 0.0) {
336         t = L.normalize();
337
338         tRay.P = P;
339         tRay.D = L;
340
341         // Checks if there is a shadow
342         if (Shadow(tRay, t, hit) > 0) {
343           diff = Vec.dot(N, L) * surf.kd * lights[l].brightness;
344
345           col.adds(diff, surf.color);
346           if (surf.shine > 1e-6) {
347             spec = Vec.dot(R, L);
348             if (spec > 1e-6) {
349               spec = (float) (Math.pow(spec, surf.shine));
350               col.x += spec;
351               col.y += spec;
352               col.z += spec;
353             }
354           }
355         }
356       } // if
357     } // for
358
359     tRay.P = P;
360     if (surf.ks * weight > 1e-3) {
361       tRay.D = SpecularDirection(I, N);
362       tcol = trace(level + 1, surf.ks * weight, tRay, hit, tRay, L);
363       col.adds(surf.ks, tcol);
364     }
365     if (surf.kt * weight > 1e-3) {
366       if (hit.enter > 0)
367         tRay.D = TransDir(null, surf, I, N);
368       else
369         tRay.D = TransDir(surf, null, I, N);
370       tcol = trace(level + 1, surf.kt * weight, tRay, hit, tRay, L);
371       col.adds(surf.kt, tcol);
372     }
373
374     // garbaging...
375     tcol = null;
376     surf = null;
377
378     return col;
379   }
380
381   /**
382    * Launches a ray
383    */
384   Vec trace(int level, float weight, Ray r, Isect inter, Ray tRay, Vec L) {
385
386     Vec P, N;
387     boolean hit;
388
389     // Checks the recursion level
390     if (level > 6) {
391       return new Vec();
392     }
393     hit = intersect(r, (float) 1e6, inter);
394     if (hit) {
395       P = r.point(inter.t);
396       N = inter.prim.normal(P);
397       if (Vec.dot(r.D, N) >= 0.0) {
398         N.negate();
399       }
400       return shade(level, weight, P, N, r.D, inter, tRay, L);
401     }
402
403     // no intersection --> col = 0,0,0
404     return new Vec(0, 0, 0);
405   }
406
407 }