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