/Users/lyon/j4p/src/graphics/raytracers/rmiRaytracer/raytracer/SphereTarget.java
|
1 package graphics.raytracers.rmiRaytracer.raytracer;
2
3 class SphereTarget implements Target {
4 Vec center;
5 double radius, radiusSq; // precompute radiusSq since we use it a lot
6 static Targets scene;
7 static SceneConsts sConsts;
8
9 public SphereTarget(double x, double y, double z, double r) {
10 center = new Vec(x, y, z);
11 radius = r;
12 radiusSq = r * r;
13
14 if (sConsts == null)
15 sConsts = new SceneConsts();
16 }
17
18 public SphereTarget(Vec v, double r) {
19 center = new Vec(v);
20 radius = r;
21 radiusSq = r * r;
22
23 if (sConsts == null)
24 sConsts = new SceneConsts();
25 }
26
27 public SphereTarget() {
28 center = new Vec(0, 0, 0);
29 radius = radiusSq = 1;
30
31 if (sConsts == null)
32 sConsts = new SceneConsts();
33 }
34
35 public void setScene(Targets s) {
36 scene = s;
37 }
38
39 public boolean isBelongingToScene() {
40 return ((scene == null) ? false : true);
41 }
42
43 public double intersectTest(Vec R0, Vec R1, int object) {
44
45 double t, /* where the ray intersects */
46 loc, /* square distance from center of sphere to projP */
47 tca, /* how far is the 'closest approach' from VRP */
48 thc; /* length sqare of the half chord */
49 Vec vecoc; /* vector to the center of the sphere from VRP */
50 boolean inside = false;
51
52 /* use the closest approach algorithm */
53 vecoc = new Vec(center);
54 vecoc.sub(R0);
55 loc = vecoc.dotProduct(vecoc);
56
57 if (loc <= radiusSq)
58 inside = true;
59
60 tca = vecoc.dotProduct(R1); /* find the closest approach */
61
62 if ((inside != true) && (tca <= 0.0))
63 return (0.0); /* object is behind the VRP */
64
65 /* compute the half chord square from the ray intersection to the
66 intersection normal. */
67 thc = (tca * tca) + radiusSq - loc;
68 if (thc < 0.0)
69 return (0.0); /* ray misses the sphere */
70
71 /* find the ray intersection */
72 if (inside == true)
73 t = tca + Math.sqrt(thc);
74 else
75 t = tca - Math.sqrt(thc);
76
77 return (t);
78 }
79
80 public int shade(int object, Vec R1, double t[]) {
81
82 Vec intersection, normal, lightSource;
83 double intensity;
84 double tShadow[] = new double[1];
85 tShadow[0] = 0;
86
87 /* calculate the intersection POINT on the object */
88 intersection = new Vec(R1);
89 intersection.mult(t[0]);
90 intersection.add(scene.VRP);
91
92 /* find the normal vector from sphere's center to the intersection */
93 normal = new Vec(intersection);
94 normal.sub(center);
95 normal.normalize();
96
97 /* locate the light source from intersection */
98 lightSource = new Vec(scene.light);
99 lightSource.sub(intersection);
100 lightSource.normalize();
101
102 /* check if the light can be "seen" by the intersection point */
103 intersectObjects(intersection, lightSource, tShadow, object, true);
104
105 intensity = lightSource.dotProduct(normal);
106 if (intensity < 0.0)
107 intensity = 0.0;
108
109 if (tShadow[0] > 0.0) /* something is in the way */
110 intensity = sConsts.globalShadowReflectance *
111 intensity; /* pixel gets ambient
112 light only */
113 else { /* pixel gets all kinds of light */
114 intensity = intensity * sConsts.Ip
115 * sConsts.globalObjectReflectance;
116 }
117
118 intensity = intensity + sConsts.ambientLightIntensity
119 * sConsts.ambientLightReflectance;
120 if (intensity > 1.0)
121 intensity = 1.0;
122
123 /* find the corresponding color in the color lookup table */
124 intensity = intensity * 255;
125
126 return ((int) intensity);
127 }
128
129 int intersectObjects(Vec R0, Vec R1, double result[], int object,
130 boolean shadowCheck) {
131 double minDist = 0.0, dist;
132 int hit = -1;
133
134 for (int i = 0; i < scene.getSize(); i++) {
135 if ((shadowCheck == true) && (object == i))
136 continue;
137 dist = ((Target) scene.getElementAt(i)).intersectTest(R0,
138 R1, i);
139
140 if (dist == 0.0)
141 continue;
142
143 /* save the first t */
144 if ((minDist == 0.0) && (dist > 0.0)) {
145 minDist = dist;
146 hit = i;
147 } else if ((dist > 0.0) && (dist < minDist)) {
148 minDist = dist;
149 hit = i;
150 }
151 }
152 result[0] = minDist;
153 return hit;
154 }
155
156 public void debug_test() {
157 System.out.println("SphereTarget.debug_test(): center = " +
158 center.toString() + ", r = " + radius + ", r^2 = "
159 + radiusSq);
160 }
161 }
162