package graphics.tracer;
import java.awt.*;
import java.util.Vector;
public class Scene {
private Vector targetList = new Vector();
private Light light = new Light();
private Eye eye = new Eye();
private Dimension screenSize;
public static Sphere makeSphere(
double x, double y, double z, double r) {
return
Sphere.makeSphere(x, y, z, r);
}
public Target getTargetAt(int i) {
return (Target) targetList.elementAt(i);
}
public int getNumberOfTargets() {
return targetList.size();
}
public Vec3f getLight() {
return light.getPosition();
}
public Vec3f getEye() {
return eye.getPosition();
}
public int[] render() {
int h = screenSize.height;
int w = screenSize.width;
int hh = 2 * h;
int pixels[] = new int[w * h];
int line[] = new int[w];
for (short pixY = 0; pixY < h; pixY++) {
line = renderALine(pixY);
for (int x = 0; x < line.length; x++)
pixels[x + pixY * w] = line[x];
}
return pixels;
}
public int[] renderALine(
short pixY) {
int w = screenSize.width;
Vec3f pp = new Vec3f(0, 0, 0);
int line[] = new int[w];
for (int pixX = 0; pixX < w; pixX++) {
getProjPlane(pixX, pixY, pp);
int c = trace(pp);
line[pixX] = (255 << 24) | (c << 16) | (c << 8) | (c << 0);
}
return line;
}
public static void main(String args[]) {
Scene scene = new Scene(new Dimension(64, 64));
scene.render();
}
private void getProjPlane(int x, int y, Vec3f pp) {
int h = screenSize.height;
int w = screenSize.width;
float ystep = 2.0f / h;
float xstep = 2.0f / w;
pp.x = -1 + xstep * x;
pp.y = 1 - ystep * y;
}
public int[] render1() {
int w = screenSize.width;
int h = screenSize.height;
int pixY = 0;
int pixX = 0;
float ystep = 1.0f / h;
float xstep = 1.0f / w;
int ww = 2 * w;
int hh = 2 * h;
Vec3f projPlane
= new Vec3f(-1, 1, 0);
int pixels[] = new int[w * h];
int c = 0;
int xi = 0;
int yi = 0;
for (pixY = 0; pixY < hh; pixY++) {
projPlane.x = -1;
projPlane.y -= ystep;
for (pixX = 0; pixX < ww; pixX++) {
projPlane.x += xstep;
c = trace(projPlane);
xi = pixX / 2;
yi = pixY / 2;
pixels[xi + w * yi] = (255 << 24) | (c << 16) | (c << 8) | (c << 0);
}
}
return pixels;
}
public void preview() {
ip.hak.Double4 d4[] = new ip.hak.Double4[targetList.size()];
for (int i = 0; i < targetList.size(); i++) {
Sphere st = (Sphere) targetList.elementAt(i);
Vec3f v = st.getCenter();
d4[i] = new ip.hak.Double4(v.x, v.y, v.z, st.getRadius());
}
ip.hak.Preview pv = new ip.hak.Preview(d4);
}
public Scene(Dimension _screenSize) {
screenSize = _screenSize;
targetList.addElement(makeSphere(0.05, -0.3, 0.0, 0.3));
targetList.addElement(makeSphere(0.05, 0.06, 0.0, 0.24));
targetList.addElement(makeSphere(0.05, 0.19, -0.205, 0.01));
targetList.addElement(makeSphere(0.05, 0.09, -0.237, 0.01));
targetList.addElement(makeSphere(0.05, 0.0, -0.230, 0.01));
targetList.addElement(makeSphere(0.05, 0.32, -0.205, 0.018));
targetList.addElement(makeSphere(0.05, 0.34, 0.0, 0.2));
targetList.addElement(makeSphere(0.1, 0.4, -0.195, 0.02));
targetList.addElement(makeSphere(-0.02, 0.393, -0.185, 0.02));
targetList.addElement(makeSphere(0.0, 0.0, 10, 10));
for (int i = 0; i < targetList.size(); i++)
if (!(
(Target) targetList.elementAt(i)).initScene())
((Target) targetList.elementAt(i)).initScene(this);
}
int trace(Vec3f projP) {
float t[] = new float[1];
int color = 0;
Vec3f R1 = new Vec3f(projP);
R1.sub(eye.getPosition());
R1.normalize();
t[0] = 0;
int obj = intersectObjects(
eye.getPosition(), R1, t, 0, false);
Target tgt = getTargetAt(obj);
if (t[0] > 0)
color = tgt.shade(obj, R1, t);
color += 16;
if (color > 255)
color = 255;
return color;
}
int intersectObjects(
Vec3f R0, Vec3f R1,
float result[], int object,
boolean shadowCheck) {
float minDist = 0, dist;
int hit = -1;
for (int i = 0; i < targetList.size(); i++) {
if ((shadowCheck == true) && (object == i))
continue;
dist =
getTargetAt(i).intersectTest(R0, R1, i);
if (dist == 0)
continue;
if ((minDist == 0) && (dist > 0)) {
minDist = dist;
hit = i;
} else if ((dist > 0.0) && (dist < minDist)) {
minDist = dist;
hit = i;
}
}
result[0] = minDist;
return hit;
}
}