/Users/lyon/j4p/src/graphics/raytracers/raytracer/tracer/Scene.java
|
1 package graphics.raytracers.raytracer.tracer;
2
3 import java.awt.*;
4 import java.util.Vector;
5
6 public class Scene {
7
8 private Vector targetList = new Vector();
9 private Light light = new Light();
10 private Eye eye = new Eye();
11
12 private Dimension screenSize;
13
14 public static Sphere makeSphere(
15 double x, double y, double z, double r) {
16 return
17 Sphere.makeSphere(x, y, z, r);
18 }
19
20 public Target getTargetAt(int i) {
21 return (Target) targetList.elementAt(i);
22 }
23
24 public int getNumberOfTargets() {
25 return targetList.size();
26 }
27
28 public Vec3f getLight() {
29 return light.getPosition();
30 }
31
32 public Vec3f getEye() {
33 return eye.getPosition();
34 }
35
36 /**
37 renderABand - renders lines y0 through
38 y1, returning the result.
39 */
40
41 public int[] render() {
42 int h = screenSize.height;
43 int w = screenSize.width;
44 int hh = 2 * h;
45 int pixels[] = new int[w * h];
46 int line[] = new int[w];
47 for (short pixY = 0; pixY < h; pixY++) {
48 line = renderALine(pixY);
49 for (int x = 0; x < line.length; x++)
50 pixels[x + pixY * w] = line[x];
51 //System.arraycopy(line,0,pixels,pixY*w,w-1);
52 }
53 return pixels;
54 }
55 //This is the part that
56 //the rmi server executes...
57 //VC Note!!
58 public int[] renderALine(
59 short pixY) {
60 int w = screenSize.width;
61 Vec3f pp = new Vec3f(0, 0, 0);
62 int line[] = new int[w];
63 for (int pixX = 0; pixX < w; pixX++) {
64 getProjPlane(pixX, pixY, pp);
65 int c = trace(pp);
66 line[pixX] = (255 << 24) | (c << 16) | (c << 8) | (c << 0);
67 }
68 return line;
69 }
70
71 public static void main(String args[]) {
72 Scene scene = new Scene(new Dimension(64, 64));
73 scene.render();
74 }
75
76 private void getProjPlane(int x, int y, Vec3f pp) {
77 int h = screenSize.height;
78 int w = screenSize.width;
79 float ystep = 2.0f / h;
80 float xstep = 2.0f / w;
81 pp.x = -1 + xstep * x;
82 pp.y = 1 - ystep * y;
83 }
84
85 public int[] render1() {
86 int w = screenSize.width;
87 int h = screenSize.height;
88 int pixY = 0;
89 int pixX = 0;
90 float ystep = 1.0f / h;
91 float xstep = 1.0f / w;
92 int ww = 2 * w;
93 int hh = 2 * h;
94 Vec3f projPlane
95 = new Vec3f(-1, 1, 0);
96
97 int pixels[] = new int[w * h];
98 int c = 0;
99 int xi = 0;
100 int yi = 0;
101 for (pixY = 0; pixY < hh; pixY++) {
102 projPlane.x = -1;
103 projPlane.y -= ystep;
104
105 for (pixX = 0; pixX < ww; pixX++) {
106 projPlane.x += xstep;
107 c = trace(projPlane);
108 xi = pixX / 2;
109 yi = pixY / 2;
110
111 pixels[xi + w * yi] = (255 << 24) | (c << 16) | (c << 8) | (c << 0);
112 }
113 }
114 return pixels;
115 }
116
117 public void preview() {
118 ip.hak.Double4 d4[] = new ip.hak.Double4[targetList.size()];
119 for (int i = 0; i < targetList.size(); i++) {
120 Sphere st = (Sphere) targetList.elementAt(i);
121 Vec3f v = st.getCenter();
122 d4[i] = new ip.hak.Double4(v.x, v.y, v.z, st.getRadius());
123 }
124
125 ip.hak.Preview pv = new ip.hak.Preview(d4);
126 }
127
128 public Scene(Dimension _screenSize) {
129 // set up the lights and pinhole
130
131 screenSize = _screenSize;
132 // Build targetList by hand for now. We should eventually let the
133 // users build their objects interactively.
134 targetList.addElement(makeSphere(0.05, -0.3, 0.0, 0.3));
135 targetList.addElement(makeSphere(0.05, 0.06, 0.0, 0.24));
136 targetList.addElement(makeSphere(0.05, 0.19, -0.205, 0.01));
137 targetList.addElement(makeSphere(0.05, 0.09, -0.237, 0.01));
138 targetList.addElement(makeSphere(0.05, 0.0, -0.230, 0.01));
139 targetList.addElement(makeSphere(0.05, 0.32, -0.205, 0.018));
140 targetList.addElement(makeSphere(0.05, 0.34, 0.0, 0.2));
141 targetList.addElement(makeSphere(0.1, 0.4, -0.195, 0.02));
142 targetList.addElement(makeSphere(-0.02, 0.393, -0.185, 0.02));
143
144 targetList.addElement(makeSphere(0.0, 0.0, 10, 10));
145
146 for (int i = 0; i < targetList.size(); i++)
147 if (!(
148 (Target) targetList.elementAt(i)).initScene())
149 ((Target) targetList.elementAt(i)).initScene(this);
150 }
151
152 int trace(Vec3f projP) {
153 float t[] = new float[1];
154 int color = 0;
155 Vec3f R1 = new Vec3f(projP);
156 R1.sub(eye.getPosition());
157 R1.normalize();
158
159 t[0] = 0;
160 int obj = intersectObjects(
161 eye.getPosition(), R1, t, 0, false);
162
163 /* if it does then find out how to paint the pixel */
164 Target tgt = getTargetAt(obj);
165 if (t[0] > 0)
166 color = tgt.shade(obj, R1, t);
167
168 color += 16; // ambient light
169
170 if (color > 255)
171 color = 255;
172
173 return color;
174 }
175
176 int intersectObjects(
177 Vec3f R0, Vec3f R1,
178 float result[], int object,
179 boolean shadowCheck) {
180 float minDist = 0, dist;
181 int hit = -1;
182
183 for (int i = 0; i < targetList.size(); i++) {
184 if ((shadowCheck == true) && (object == i))
185 continue;
186 dist =
187 getTargetAt(i).intersectTest(R0, R1, i);
188
189 if (dist == 0)
190 continue;
191
192 /* save the first t */
193 if ((minDist == 0) && (dist > 0)) {
194 minDist = dist;
195 hit = i;
196 } else if ((dist > 0.0) && (dist < minDist)) {
197 minDist = dist;
198 hit = i;
199 }
200 }
201 result[0] = minDist;
202 return hit;
203 }
204 }
205