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