import java.awt.image.*;
import java.awt.Graphics;
import java.awt.Color;
import java.awt.Event;
import java.awt.Image;
import java.awt.Font;
public class Raytrace extends java.applet.Applet implements Runnable {
//---- DATA ----------------------------------------------------------------//
//- Thread data
Thread runThread;
//- Output image data
static int image_w = 160, image_h = 160;
byte r[], g[], b[];
byte buf[];
byte back[];
IndexColorModel pal;
MemoryImageSource src;
Image im;
byte poly_alpha[];
//- Mouse move stuff
int mouse_oldx, mouse_oldy;
int pause = 0;
//- 3D Object data
// Rotation matrix
double m[][];
// Object 1
int o1_rx, o1_ry, o1_rz;
double o1_cx, o1_cy, o1_cz;
int o1_numpoints;
double o1_x[], o1_y[], o1_z[];
double o1_tx[], o1_ty[], o1_tz[];
double o1_sx[], o1_sy[], o1_sz[];
int o1_numfaces;
int o1_fn[], o1_f[][];
double o1_nx[], o1_ny[], o1_nz[];
double o1_tnx[], o1_tny[], o1_tnz[];
// Object 2
int o2_rx, o2_ry, o2_rz;
double o2_cx, o2_cy, o2_cz;
int o2_numpoints;
double o2_x[], o2_y[], o2_z[];
double o2_tx[], o2_ty[], o2_tz[];
double o2_sx[], o2_sy[], o2_sz[];
int o2_numfaces;
int o2_fn[], o2_f[][];
double o2_nx[], o2_ny[], o2_nz[];
double o2_tnx[], o2_tny[], o2_tnz[];
// BSP Tree
static int bsp_size = 256;
static int bsp_polysize = 8;
int bsp_num;
int bsp_left[];
int bsp_right[];
int bsp_poly_num[];
double bsp_poly_sx[][], bsp_poly_sy[][];
double bsp_poly_x[][], bsp_poly_y[][], bsp_poly_z[][];
double bsp_nx[], bsp_ny[], bsp_nz[];
double bsp_x[], bsp_y[], bsp_z[];
int bsp_object[];
// Polygon stack
static int polystack_size = 256;
static int polystack_polysize = 8;
int polystack_sp, polystack_bp;
int polystack_num[];
double polystack_x[][], polystack_y[][], polystack_z[][];
double polystack_sx[][], polystack_sy[][];
double polystack_nx[], polystack_ny[], polystack_nz[];
double polystack_cx[], polystack_cy[], polystack_cz[];
double polystack_clip[][];
int polystack_object[];
// Polygon data
int poly_ymin, poly_ymax;
int poly_xmin[], poly_xmax[];
int poly2_ymin, poly2_ymax;
int poly2_xmin[], poly2_xmax[];
// Lookup tables
double sintable[], costable[];
//---- INIT & THREAD FUNCTIONS ---------------------------------------------//
//---- init
public void init() {
int size = image_w*image_h;
int i, j, k;
char rr, gg, bb;
double d;
String s;
System.out.println("LKS Renderer v0.1");
//- Set up image buffer and palette
buf = new byte[size];
back = new byte[size];
r = new byte[256];
g = new byte[256];
b = new byte[256];
s = "*(!'1*89%])%%.";
for(i=0; i<size; i++) {
buf[i] = 0;
}
rr = (57*5)&255;
gg = (57*3)&255;
bb = (57*7)&255;
for(i=0; i<64; i++) {
r[i] = (byte)(i*4);
g[i] = (byte)(i*4);
b[i] = (byte)(i*4);
}
for(i=0; i<64; i++) {
r[i+64] = (byte)(i*4);
g[i+64] = (byte)(0);
b[i+64] = (byte)(0);
}
s += "%^(1@% %) *^).";
for(i=0; i<64; i++) {
r[i+128] = (byte)(255);
g[i+128] = (byte)(i*3);
b[i+128] = (byte)(i*3);
}
for(i=0; i<64; i++) {
r[i+192] = (byte)(0);
g[i+192] = (byte)(0);
b[i+192] = (byte)(i*4);
}
s += "%4$(@**.? ^*%-";
// Alpha blending
poly_alpha = new byte[256*64];
for(j=0; j<64; j++) {
for(i=0; i<64; i++) {
poly_alpha[(j<<8)+i] = (byte)((i+j)>>1);
}
for(i=0; i<64; i++) {
poly_alpha[(j<<8)+i+64] = (byte)(64+i+j);
}
for(i=0; i<64; i++) {
poly_alpha[(j<<8)+i+128] = 0;
}
for(i=0; i<64; i++) {
poly_alpha[(j<<8)+i+192] = (byte)((i+j)>>1);
}
}
// Make background
s += "* !1(%?*/?^89*";
for(j=0; j<image_h; j++) {
for(i=0; i<image_w; i++) {
d = ((i-image_w/2)*(i-image_w/2)+(j-image_h/2)*(j-image_h/2))*0.0035;
k = (int)(d);
if(k<0) { k=0; }
back[i+j*image_w] = (byte)(192+(k&63));
}
}
s += "*%*%-*//*?*%*+";
k=image_w*(image_h-7)-16;
for(j=0; j<5; j++) {
for(i=0; i<14; i++) {
if(s.charAt(i+14*j) == '*' || s.charAt(i+14*j) == '%') {
back[k] = (byte)255;
back[k+image_w+1] = (byte)192;
}
k++;
}
k += image_w-14;
}
pal = new IndexColorModel(8, 256, r, g, b);
src = new MemoryImageSource(image_w, image_h, pal, buf, 0, image_w);
src.setAnimated(true);
im = createImage(src);
//- Create lookup tables
sintable = new double[4096];
costable = new double[4096];
for(i=0; i<4096; i++) {
sintable[i] = Math.sin(3.1415926*i/2048);
costable[i] = Math.cos(3.1415926*i/2048);
}
//- Create matrix
m = new double[3][3];
//- Create BSP tree
bsp_object = new int[bsp_size];
bsp_left = new int[bsp_size];
bsp_right = new int[bsp_size];
bsp_poly_num = new int[bsp_size];
bsp_poly_sx = new double[bsp_size][bsp_polysize];
bsp_poly_sy = new double[bsp_size][bsp_polysize];
bsp_poly_x = new double[bsp_size][bsp_polysize];
bsp_poly_y = new double[bsp_size][bsp_polysize];
bsp_poly_z = new double[bsp_size][bsp_polysize];
bsp_nx = new double[bsp_size];
bsp_ny = new double[bsp_size];
bsp_nz = new double[bsp_size];
bsp_x = new double[bsp_size];
bsp_y = new double[bsp_size];
bsp_z = new double[bsp_size];
// Create stacks
polystack_num = new int[polystack_size];
polystack_sx = new double[polystack_size][polystack_polysize];
polystack_sy = new double[polystack_size][polystack_polysize];
polystack_nx = new double[polystack_size];
polystack_ny = new double[polystack_size];
polystack_nz = new double[polystack_size];
polystack_x = new double[polystack_size][polystack_polysize];
polystack_y = new double[polystack_size][polystack_polysize];
polystack_z = new double[polystack_size][polystack_polysize];
polystack_cx = new double[polystack_size];
polystack_cy = new double[polystack_size];
polystack_cz = new double[polystack_size];
polystack_object = new int[polystack_size];
polystack_clip = new double[polystack_size][polystack_polysize];
polystack_sp = 0;
polystack_bp = 0;
//- Create polygon
poly_xmin = new int[image_h];
poly_xmax = new int[image_h];
poly2_xmin = new int[image_h];
poly2_xmax = new int[image_h];
//- Create objects
// Initial position of object 1
o1_cx = 0; o1_cy = 0; o1_cz = 5.0;
o1_rx = 0; o1_ry = 0; o1_rz = 0;
// Define points of object 1
o1_numpoints = 4;
o1_x = new double[4]; o1_y = new double[4]; o1_z = new double[4];
o1_tx = new double[4]; o1_ty = new double[4]; o1_tz = new double[4];
o1_sx = new double[4]; o1_sy = new double[4]; o1_sz = new double[4];
o1_x[0] = 1.8; o1_y[0] = 1.8; o1_z[0] = 1.8;
o1_x[1] = -1.8; o1_y[1] = 1.8; o1_z[1] = -1.8;
o1_x[2] = 1.8; o1_y[2] = -1.8; o1_z[2] = -1.8;
o1_x[3] = -1.8; o1_y[3] = -1.8; o1_z[3] = 1.8;
/*
o1_x[0] = 1.8; o1_y[0] = 1.8; o1_z[0] = 0;
o1_x[2] = 1.8; o1_y[2] = -1.8; o1_z[2] = 0;
o1_x[1] = -1.8; o1_y[1] = 1.8; o1_z[1] = 0;
o1_x[3] = -1.8; o1_y[3] = -1.8; o1_z[3] = 0;
*/
// Define faces of object 1
o1_numfaces = 4;
o1_nx = new double[4]; o1_ny = new double[4]; o1_nz = new double[4];
o1_tnx = new double[4]; o1_tny = new double[4]; o1_tnz = new double[4];
makenormal_o1( 0, 0, 2, 1);
makenormal_o1( 1, 1, 2, 3);
makenormal_o1( 2, 0, 1, 3);
makenormal_o1( 3, 3, 2, 0);
// Initial position of object 2
o2_cx = 0; o2_cy = 0; o2_cz = 5.0;
o2_rx = 0; o2_ry = 0; o2_rz = 0;
o2_numpoints = 16;
// Define points of object 2
o2_x = new double[16]; o2_y = new double[16]; o2_z = new double[16];
o2_tx = new double[16]; o2_ty = new double[16]; o2_tz = new double[16];
o2_sx = new double[16]; o2_sy = new double[16]; o2_sz = new double[16];
o2_x[ 0] = 1.5; o2_y[ 0] = 0.5; o2_z[ 0] = 2.5;
o2_x[ 1] = 1.0; o2_y[ 1] = 0.5; o2_z[ 1] = 2.0;
o2_x[ 2] = 1.0; o2_y[ 2] = -0.5; o2_z[ 2] = 2.0;
o2_x[ 3] = 1.5; o2_y[ 3] = -0.5; o2_z[ 3] = 2.5;
o2_x[ 4] = 1.5; o2_y[ 4] = 0.5; o2_z[ 4] = -2.5;
o2_x[ 5] = 1.0; o2_y[ 5] = 0.5; o2_z[ 5] = -2.0;
o2_x[ 6] = 1.0; o2_y[ 6] = -0.5; o2_z[ 6] = -2.0;
o2_x[ 7] = 1.5; o2_y[ 7] = -0.5; o2_z[ 7] = -2.5;
o2_x[ 8] = -1.5; o2_y[ 8] = 0.5; o2_z[ 8] = -2.5;
o2_x[ 9] = -1.0; o2_y[ 9] = 0.5; o2_z[ 9] = -2.0;
o2_x[10] = -1.0; o2_y[10] = -0.5; o2_z[10] = -2.0;
o2_x[11] = -1.5; o2_y[11] = -0.5; o2_z[11] = -2.5;
o2_x[12] = -1.5; o2_y[12] = 0.5; o2_z[12] = 2.5;
o2_x[13] = -1.0; o2_y[13] = 0.5; o2_z[13] = 2.0;
o2_x[14] = -1.0; o2_y[14] = -0.5; o2_z[14] = 2.0;
o2_x[15] = -1.5; o2_y[15] = -0.5; o2_z[15] = 2.5;
// Define faces of object 2
o2_numfaces = 16;
o2_nx = new double[16]; o2_ny = new double[16]; o2_nz = new double[16];
o2_tnx = new double[16]; o2_tny = new double[16]; o2_tnz = new double[16];
makenormal_o2( 0, 0, 4, 5, 1);
makenormal_o2( 1, 1, 5, 6, 2);
makenormal_o2( 2, 2, 6, 7, 3);
makenormal_o2( 3, 3, 7, 4, 0);
makenormal_o2( 4, 4, 8, 9, 5);
makenormal_o2( 5, 5, 9, 10, 6);
makenormal_o2( 6, 6, 10, 11, 7);
makenormal_o2( 7, 7, 11, 8, 4);
makenormal_o2( 8, 8, 12, 13, 9);
makenormal_o2( 9, 9, 13, 14, 10);
makenormal_o2(10, 10, 14, 15, 11);
makenormal_o2(11, 11, 15, 12, 8);
makenormal_o2(12, 12, 0, 1, 13);
makenormal_o2(13, 13, 1, 2, 14);
makenormal_o2(14, 14, 2, 3, 15);
makenormal_o2(15, 15, 3, 0, 12);
}
public void start() {
if(runThread == null) {
runThread = new Thread(this);
runThread.start();
}
}
public void stop() {
if(runThread != null) {
runThread.stop();
runThread = null;
}
}
public void run() {
while(true) {
try {
runThread.sleep(20);
} catch (InterruptedException e) {
return;
}
redraw();
}
}
//---- EVENT HANDLERS ------------------------------------------------------//
public boolean mouseDown(Event evt, int x, int y) {
pause = 0;
mouse_oldx = x;
mouse_oldy = y;
return true;
}
public boolean mouseUp(Event evt, int x, int y) {
pause = 0;
return true;
}
public boolean mouseDrag(Event e, int x, int y) {
pause = 1;
o1_rx += 12*(y-mouse_oldy);
o1_ry += 8*(y-mouse_oldy)+4*(x-mouse_oldx);
o1_rz += 12*(x-mouse_oldx);
o2_rx += 12*(y-mouse_oldy);
o2_ry += 8*(y-mouse_oldy)+4*(x-mouse_oldx);
o2_rz += 12*(x-mouse_oldx);
mouse_oldx = x;
mouse_oldy = y;
return true;
}
public void update(Graphics g) {
paint(g);
}
public void paint(Graphics g) {
g.drawImage(im, 0, 0, this);
}
//---- VECTOR ROUTINES -----------------------------------------------------//
//---- MakeTrans
public void maketrans(int rx, int ry, int rz) {
double cx, sx, cy, sy, cz, sz;
cx = costable[rx&4095]; cy = costable[ry&4095]; cz = costable[rz&4095];
sx = sintable[rx&4095]; sy = sintable[ry&4095]; sz = sintable[rz&4095];
m[0][0] = cy*cz; m[0][1] = cy*sz; m[0][2] = -sy;
m[1][0] = sx*sy*cz-cx*sz; m[1][1] = sx*sy*sz+cx*cz; m[1][2] = sx*cy;
m[2][0] = cx*sy*cz+sx*sz; m[2][1] = cx*sy*sz-sx*cz; m[2][2] = cx*cy;
}
//---- MakeNormal_o1
public void makenormal_o1(int poly, int p1, int p2, int p3) {
double ax, ay, az, bx, by, bz, nx, ny, nz, n;
ax = o1_x[p3]-o1_x[p2]; ay = o1_y[p3]-o1_y[p2]; az = o1_z[p3]-o1_z[p2];
bx = o1_x[p1]-o1_x[p2]; by = o1_y[p1]-o1_y[p2]; bz = o1_z[p1]-o1_z[p2];
nx = ay*bz-az*by; ny = az*bx-ax*bz; nz = ax*by-ay*bx;
n = 1/Math.sqrt(nx*nx+ny*ny+nz*nz);
o1_nx[poly] = nx*n;
o1_ny[poly] = ny*n;
o1_nz[poly] = nz*n;
}
//---- MakeNormal_o2
public void makenormal_o2(int poly, int p1, int p2, int p3, int p4) {
double ax, ay, az, bx, by, bz, nx, ny, nz, n;
ax = o2_x[p3]-o2_x[p2]; ay = o2_y[p3]-o2_y[p2]; az = o2_z[p3]-o2_z[p2];
bx = o2_x[p1]-o2_x[p2]; by = o2_y[p1]-o2_y[p2]; bz = o2_z[p1]-o2_z[p2];
nx = ay*bz-az*by; ny = az*bx-ax*bz; nz = ax*by-ay*bx;
n = 1/Math.sqrt(nx*nx+ny*ny+nz*nz);
o2_nx[poly] = nx*n;
o2_ny[poly] = ny*n;
o2_nz[poly] = nz*n;
}
//---- PlaneDist
public double planedist(int ptr, double x, double y, double z) {
return bsp_nx[ptr]*(x-bsp_x[ptr]) +
bsp_ny[ptr]*(y-bsp_y[ptr]) +
bsp_nz[ptr]*(z-bsp_z[ptr]);
}
//---- NeedSplit
// Returns non-zero if polygon at poly is split by bsp plane at ptr.
public int needsplit(int poly, int ptr) {
int i, l, r;
double d;
l=0; r=0;
for(i=0; i<polystack_num[poly]; i++) {
if(bsp_nx[ptr]*(polystack_x[poly][i]-bsp_x[ptr]) +
bsp_ny[ptr]*(polystack_y[poly][i]-bsp_y[ptr]) +
bsp_nz[ptr]*(polystack_z[poly][i]-bsp_z[ptr]) < 0) {
l++;
} else {
r++;
}
if(l>0 && r>0) { return 1; }
}
return 0;
}
//---- SplitLine
double split_x, split_y, split_z;
double split_xx, split_yy, split_zz;
double split_cx, split_cy, split_cz;
public void splitline(int ptr) {
double d1 = planedist(ptr, split_x, split_y, split_z);
double d2 = planedist(ptr, split_xx, split_yy, split_zz);
if(d1<0) d1 =- d1;
if(d2<0) d2 =- d2;
split_cx = split_x + d1*(split_xx-split_x)/(d1+d2);
split_cy = split_y + d1*(split_yy-split_y)/(d1+d2);
split_cz = split_z + d1*(split_zz-split_z)/(d1+d2);
}
//---- SplitPoly
// Splits the polygon at stack position poly using the bsp plane at ptr.
// Returns the stack position of the half of the poly in front of the plane
// and the half behind the plane is is stored at poly.
public int splitpoly(int poly, int ptr) {
int i, j, n1, n2;
//- First check which points need to be clipped
for(i=0; i<polystack_num[poly]; i++) {
if(bsp_nx[ptr]*(polystack_x[poly][i]-bsp_x[ptr]) +
bsp_ny[ptr]*(polystack_y[poly][i]-bsp_y[ptr]) +
bsp_nz[ptr]*(polystack_z[poly][i]-bsp_z[ptr]) < 0) {
polystack_clip[poly][i] = -1;
} else {
polystack_clip[poly][i] = 1;
}
}
//- Go around edge of polygon clipping lines which straddle plane
n1 = 0;
n2 = 0;
for(i=0; i<polystack_num[poly]; i++) {
j = i+1; if(j == polystack_num[poly]) { j = 0; }
split_x = polystack_x[poly][i];
split_y = polystack_y[poly][i];
split_z = polystack_z[poly][i];
split_xx = polystack_x[poly][j];
split_yy = polystack_y[poly][j];
split_zz = polystack_z[poly][j];
if(polystack_clip[poly][i] < 0 && polystack_clip[poly][j] < 0) {
// Both points outside
polystack_x[polystack_sp+1][n2] = split_x;
polystack_y[polystack_sp+1][n2] = split_y;
polystack_z[polystack_sp+1][n2] = split_z;
n2++;
} else if(polystack_clip[poly][i] < 0 && polystack_clip[poly][j] > 0) {
// First point outside, second inside
splitline(ptr);
polystack_x[polystack_sp][n1] = split_cx;
polystack_y[polystack_sp][n1] = split_cy;
polystack_z[polystack_sp][n1] = split_cz;
n1++;
polystack_x[polystack_sp+1][n2] = split_x;
polystack_y[polystack_sp+1][n2] = split_y;
polystack_z[polystack_sp+1][n2] = split_z;
n2++;
polystack_x[polystack_sp+1][n2] = split_cx;
polystack_y[polystack_sp+1][n2] = split_cy;
polystack_z[polystack_sp+1][n2] = split_cz;
n2++;
} else if(polystack_clip[poly][i] > 0 && polystack_clip[poly][j] < 0) {
// First point inside, second outside
splitline(ptr);
polystack_x[polystack_sp][n1] = split_x;
polystack_y[polystack_sp][n1] = split_y;
polystack_z[polystack_sp][n1] = split_z;
n1++;
polystack_x[polystack_sp][n1] = split_cx;
polystack_y[polystack_sp][n1] = split_cy;
polystack_z[polystack_sp][n1] = split_cz;
n1++;
polystack_x[polystack_sp+1][n2] = split_cx;
polystack_y[polystack_sp+1][n2] = split_cy;
polystack_z[polystack_sp+1][n2] = split_cz;
n2++;
} else {
// Both points inside
polystack_x[polystack_sp][n1] = split_x;
polystack_y[polystack_sp][n1] = split_y;
polystack_z[polystack_sp][n1] = split_z;
n1++;
}
}
// Poly becomes one of the clipped polygons
for(i=0; i<n2; i++) {
polystack_x[poly][i] = polystack_x[polystack_sp+1][i];
polystack_y[poly][i] = polystack_y[polystack_sp+1][i];
polystack_z[poly][i] = polystack_z[polystack_sp+1][i];
}
polystack_num[poly] = n2;
polystack_cx[poly] = (polystack_x[poly][0] + polystack_x[poly][1] + polystack_x[poly][2]) * (1.0/3.0);
polystack_cy[poly] = (polystack_y[poly][0] + polystack_y[poly][1] + polystack_y[poly][2]) * (1.0/3.0);
polystack_cz[poly] = (polystack_z[poly][0] + polystack_z[poly][1] + polystack_z[poly][2]) * (1.0/3.0);
// The other is in the new polystack element
polystack_num[polystack_sp] = n1;
polystack_nx[polystack_sp] = polystack_nx[poly];
polystack_ny[polystack_sp] = polystack_ny[poly];
polystack_nz[polystack_sp] = polystack_nz[poly];
polystack_cx[polystack_sp] = (polystack_x[polystack_sp][0] + polystack_x[polystack_sp][1] + polystack_x[polystack_sp][2]) * (1.0/3.0);
polystack_cy[polystack_sp] = (polystack_y[polystack_sp][0] + polystack_y[polystack_sp][1] + polystack_y[polystack_sp][2]) * (1.0/3.0);
polystack_cz[polystack_sp] = (polystack_z[polystack_sp][0] + polystack_z[polystack_sp][1] + polystack_z[polystack_sp][2]) * (1.0/3.0);
polystack_sp++;
return polystack_sp-1;
}
//---- Line
public void line(double x1, double y1, double x2, double y2) {
int i, x, y;
for(i=0; i<100; i++) {
x = (int)(x1 + (x2-x1)*i/100);
y = (int)(y1 + (y2-y1)*i/100);
if(x>=0 && x<image_w && y>=0 && y<image_h) {
buf[x+image_w*y] = (byte)255;
}
}
}
//---- POLYGON ROUTINES ----------------------------------------------------//
//---- Poly_Clear
public void poly_clear() {
int i;
poly_ymin = image_h;
poly_ymax = 0;
for(i=0; i<image_h; i++) {
poly_xmin[i] = image_w;
poly_xmax[i] = 0;
}
}
//---- Poly_Line
public void poly_line(double x1, double y1, double x2, double y2) {
double t;
int x, y, i;
int iy1, iy2;
if(y2>y1) {
// line going down - right hand side
iy1 = (int)(y1)+1;
iy2 = (int)(y2)+1;
if(iy1 >= image_h) { return; }
if(iy2 <= 0) { return; }
if(iy1 < 0) { iy1 = 0; }
if(iy2 > image_h) { iy2 = image_h; }
if(iy1 < poly_ymin) { poly_ymin = iy1; }
if(iy2 > poly_ymax) { poly_ymax = iy2; }
for(y=iy1; y<iy2; y++) {
x = (int)(x1 + (x2-x1)*(y-y1)/(y2-y1));
if(x > image_w) { x = image_w; }
if(x < 0) { x = 0; }
poly_xmax[y] = x;
}
} else {
// line going up - left hand side
t = x1; x1 = x2; x2 = t;
t = y1; y1 = y2; y2 = t;
iy1 = (int)(y1)+1;
iy2 = (int)(y2)+1;
if(iy1 >= image_h) { return; }
if(iy2 <= 0) { return; }
if(iy1 < 0) { iy1 = 0; }
if(iy2 > image_h) { iy2 = image_h; }
if(iy1 < poly_ymin) { poly_ymin = iy1; }
if(iy2 > poly_ymax) { poly_ymax = iy2; }
for(y=iy1; y<iy2; y++) {
x = (int)(x1 + (x2-x1)*(y-y1)/(y2-y1));
if(x > image_w) { x = image_w; }
if(x < 0) { x = 0; }
poly_xmin[y] = x;
}
}
}
//---- Poly_Fill_Col
public void poly_fill_col(byte c) {
int x, y, o, oo;
oo = image_w*poly_ymin;
for(y=poly_ymin; y<poly_ymax; y++) {
o = oo + poly_xmin[y];
for(x=poly_xmin[y]; x<poly_xmax[y]; x++) buf[o++] = c;
// TEMP - draw backfacing as well
o = oo + poly_xmax[y];
for(x=poly_xmax[y]; x<poly_xmin[y]; x++) buf[o++] = c;
oo += image_w;
}
}
//---- Poly_Fill_Alpha
public void poly_fill_alpha(byte c) {
int x, y, o, oo;
oo = image_w*poly_ymin;
for(y=poly_ymin; y<poly_ymax; y++) {
o = oo + poly_xmin[y];
for(x=poly_xmin[y]; x<poly_xmax[y]; x++) { buf[o] = poly_alpha[(c<<8)+buf[o]]; o++; }
// TEMP - draw backfacing as well
o = oo + poly_xmax[y];
for(x=poly_xmax[y]; x<poly_xmin[y]; x++) { buf[o] = poly_alpha[(c<<8)+buf[o]]; o++; }
oo += image_w;
}
}
//---- Poly_Fill_Add
public void poly_fill_add(byte c) {
int x, y, o, oo;
oo = image_w*poly_ymin;
for(y=poly_ymin; y<poly_ymax; y++) {
o = oo + poly_xmin[y];
for(x=poly_xmin[y]; x<poly_xmax[y]; x++) buf[o++] += c;
// TEMP - draw backfacing as well
o = oo + poly_xmax[y];
for(x=poly_xmax[y]; x<poly_xmin[y]; x++) buf[o++] += c;
oo += image_w;
}
}
//---- Poly2_Clear
public void poly2_clear() {
int i;
poly2_ymin = image_h;
poly2_ymax = 0;
for(i=0; i<image_h; i++) {
poly2_xmin[i] = image_w;
poly2_xmax[i] = 0;
}
}
//---- Poly2_Line
public void poly2_line(double x1, double y1, double x2, double y2) {
double t;
int x, y, i;
int iy1, iy2;
// x1 = image_w-x1;
// x2 = image_w-x2;
if(y2>y1) {
// line going down - right hand side
iy1 = (int)(y1)+1;
iy2 = (int)(y2)+1;
if(iy1 >= image_h) { return; }
if(iy2 <= 0) { return; }
if(iy1 < 0) { iy1 = 0; }
if(iy2 > image_h) { iy2 = image_h; }
if(iy1 < poly2_ymin) { poly2_ymin = iy1; }
if(iy2 > poly2_ymax) { poly2_ymax = iy2; }
for(y=iy1; y<iy2; y++) {
x = (int)(x1 + (x2-x1)*(y-y1)/(y2-y1));
if(x > image_w) { x = image_w; }
if(x < 0) { x = 0; }
poly2_xmin[y] = x;
}
} else {
// line going up - left hand side
t = x1; x1 = x2; x2 = t;
t = y1; y1 = y2; y2 = t;
iy1 = (int)(y1)+1;
iy2 = (int)(y2)+1;
if(iy1 >= image_h) { return; }
if(iy2 <= 0) { return; }
if(iy1 < 0) { iy1 = 0; }
if(iy2 > image_h) { iy2 = image_h; }
if(iy1 < poly2_ymin) { poly2_ymin = iy1; }
if(iy2 > poly2_ymax) { poly2_ymax = iy2; }
for(y=iy1; y<iy2; y++) {
x = (int)(x1 + (x2-x1)*(y-y1)/(y2-y1));
if(x > image_w) { x = image_w; }
if(x < 0) { x = 0; }
poly2_xmax[y] = x;
}
}
}
//---- Poly2_Fill_Col
public void poly2_fill_col(byte c) {
int x, y, o, oo;
int t;
if(poly2_ymin < poly_ymin) { poly2_ymin = poly_ymin; }
if(poly2_ymax > poly_ymax) { poly2_ymax = poly_ymax; }
if(poly2_ymin < 0) { poly2_ymin = 0; }
if(poly2_ymax > image_h) { poly2_ymax = image_h; }
oo = image_w*poly2_ymin;
for(y=poly2_ymin; y<poly2_ymax; y++) {
if(poly2_xmin[y] < poly_xmin[y]) { poly2_xmin[y] = poly_xmin[y]; }
if(poly2_xmax[y] > poly_xmax[y]) { poly2_xmax[y] = poly_xmax[y]; }
if(poly2_xmin[y] < 0) { poly2_xmin[y] = 0; }
if(poly2_xmax[y] > image_w) { poly2_xmax[y] = image_w; }
o = oo + poly2_xmin[y];
for(x=poly2_xmin[y]; x<poly2_xmax[y]; x++) buf[o++] = c;
oo += image_w;
}
}
//---- Poly2_Fill_Add
public void poly2_fill_add(byte c) {
int x, y, o, oo;
int t;
if(poly2_ymin < poly_ymin) { poly2_ymin = poly_ymin; }
if(poly2_ymax > poly_ymax) { poly2_ymax = poly_ymax; }
if(poly2_ymin < 0) { poly2_ymin = 0; }
if(poly2_ymax > image_h) { poly2_ymax = image_h; }
oo = image_w*poly2_ymin;
for(y=poly2_ymin; y<poly2_ymax; y++) {
if(poly2_xmin[y] < poly_xmin[y]) { poly2_xmin[y] = poly_xmin[y]; }
if(poly2_xmax[y] > poly_xmax[y]) { poly2_xmax[y] = poly_xmax[y]; }
if(poly2_xmin[y] < 0) { poly2_xmin[y] = 0; }
if(poly2_xmax[y] > image_w) { poly2_xmax[y] = image_w; }
o = oo + poly2_xmin[y];
for(x=poly2_xmin[y]; x<poly2_xmax[y]; x++) buf[o++] += c;
oo += image_w;
}
}
//---- BSP ROUTINES --------------------------------------------------------//
//---- BSP_Clear
public void bsp_clear() {
bsp_num = 0;
polystack_sp = 0;
polystack_bp = 0;
}
//---- BSP_Add_o1
// This is a simple adding routine because o1 is put in the BSP tree first.
public void bsp_add_o1(int poly, int p1, int p2, int p3) {
double x, y, z;
int ptr;
// Ignore backfacing polygons
if(o1_tnx[poly]*o1_tx[p1] +
o1_tny[poly]*o1_ty[p1] +
o1_tnz[poly]*o1_tz[p1] > 0) return;
// If tree empty just put polygon as root
if(bsp_num == 0) {
bsp_object[bsp_num] = 1;
bsp_poly_num[bsp_num] = 3;
bsp_poly_sx[bsp_num][0] = o1_sx[p1]; bsp_poly_sy[bsp_num][0] = o1_sy[p1];
bsp_poly_sx[bsp_num][1] = o1_sx[p2]; bsp_poly_sy[bsp_num][1] = o1_sy[p2];
bsp_poly_sx[bsp_num][2] = o1_sx[p3]; bsp_poly_sy[bsp_num][2] = o1_sy[p3];
bsp_x[bsp_num] = o1_tx[p1];
bsp_y[bsp_num] = o1_ty[p1];
bsp_z[bsp_num] = o1_tz[p1];
bsp_nx[bsp_num] = o1_tnx[poly];
bsp_ny[bsp_num] = o1_tny[poly];
bsp_nz[bsp_num] = o1_tnz[poly];
/*
bsp_x[bsp_num] = 0;
bsp_y[bsp_num] = 0;
bsp_z[bsp_num] = 5;
bsp_nx[bsp_num] = 0;
bsp_ny[bsp_num] = 0;
bsp_nz[bsp_num] = 1;
*/
bsp_left[bsp_num] = -1;
bsp_right[bsp_num] = -1;
bsp_num++;
} else if(bsp_num < bsp_size) {
// Add to end of BSP array
bsp_object[bsp_num] = 1;
bsp_poly_num[bsp_num] = 3;
bsp_poly_sx[bsp_num][0] = o1_sx[p1]; bsp_poly_sy[bsp_num][0] = o1_sy[p1];
bsp_poly_sx[bsp_num][1] = o1_sx[p2]; bsp_poly_sy[bsp_num][1] = o1_sy[p2];
bsp_poly_sx[bsp_num][2] = o1_sx[p3]; bsp_poly_sy[bsp_num][2] = o1_sy[p3];
bsp_x[bsp_num] = o1_tx[p1];
bsp_y[bsp_num] = o1_ty[p1];
bsp_z[bsp_num] = o1_tz[p1];
bsp_nx[bsp_num] = o1_tnx[poly];
bsp_ny[bsp_num] = o1_tny[poly];
bsp_nz[bsp_num] = o1_tnz[poly];
bsp_left[bsp_num] = -1;
bsp_right[bsp_num] = -1;
// Add to tree
ptr = 0;
x = (o1_tx[p1] + o1_tx[p2] + o1_tx[p3]) * (1.0/3.0);
y = (o1_ty[p1] + o1_ty[p2] + o1_ty[p3]) * (1.0/3.0);
z = (o1_tz[p1] + o1_tz[p2] + o1_tz[p3]) * (1.0/3.0);
while(ptr != -1) {
if(bsp_object[ptr] == 1) {
// If it's this object just use a point within this poly
if(bsp_nx[ptr]*(x-bsp_x[ptr]) +
bsp_ny[ptr]*(y-bsp_y[ptr]) +
bsp_nz[ptr]*(z-bsp_z[ptr]) < 0) {
if(bsp_left[ptr] == -1) {
bsp_left[ptr] = bsp_num;
bsp_num ++;
ptr = -1;
} else {
ptr = bsp_left[ptr];
}
} else {
if(bsp_right[ptr] == -1) {
bsp_right[ptr] = bsp_num;
bsp_num ++;
ptr = -1;
} else {
ptr = bsp_right[ptr];
}
}
} else {
System.out.println("ERROR: Object 1 not alone in BSP tree");
}
}
}
}
//---- BSP_Add_o2
public void bsp_add_o2(int poly, int p1, int p2, int p3, int p4) {
double x, y, z;
int ptr;
/*
// Ignore backfacing polygons
if(o2_tnx[poly]*o2_tx[p1] +
o2_tny[poly]*o2_ty[p1] +
o2_tnz[poly]*o2_tz[p1] > 0) return;
*/
// Put this polygon on stack
polystack_num[polystack_sp] = 4;
polystack_x[polystack_sp][0] = o2_tx[p1];
polystack_y[polystack_sp][0] = o2_ty[p1];
polystack_z[polystack_sp][0] = o2_tz[p1];
polystack_x[polystack_sp][1] = o2_tx[p2];
polystack_y[polystack_sp][1] = o2_ty[p2];
polystack_z[polystack_sp][1] = o2_tz[p2];
polystack_x[polystack_sp][2] = o2_tx[p3];
polystack_y[polystack_sp][2] = o2_ty[p3];
polystack_z[polystack_sp][2] = o2_tz[p3];
polystack_x[polystack_sp][3] = o2_tx[p4];
polystack_y[polystack_sp][3] = o2_ty[p4];
polystack_z[polystack_sp][3] = o2_tz[p4];
polystack_nx[polystack_sp] = o2_tnx[poly];
polystack_ny[polystack_sp] = o2_tny[poly];
polystack_nz[polystack_sp] = o2_tnz[poly];
polystack_cx[polystack_sp] = (o2_tx[p1] + o2_tx[p2] + o2_tx[p3]) * (1.0/3.0);
polystack_cy[polystack_sp] = (o2_ty[p1] + o2_ty[p2] + o2_ty[p3]) * (1.0/3.0);
polystack_cz[polystack_sp] = (o2_tz[p1] + o2_tz[p2] + o2_tz[p3]) * (1.0/3.0);
polystack_sp++;
bsp_add_o2_recurse(0, polystack_sp-1);
polystack_sp--;
}
//---- BSP_Add_o2_Recurse
public void bsp_add_o2_recurse(int ptr, int poly) {
int split;
double sx, sy;
int i, j;
// Check if the poly needs splitting at this node.
split = 0;
if(bsp_object[ptr] != 2) {
split = needsplit(poly, ptr);
}
if(split == 0) {
// No split - just add in front or behind depending on center point
if(bsp_nx[ptr]*(polystack_cx[poly]-bsp_x[ptr]) +
bsp_ny[ptr]*(polystack_cy[poly]-bsp_y[ptr]) +
bsp_nz[ptr]*(polystack_cz[poly]-bsp_z[ptr]) < 0) {
if(bsp_left[ptr] != -1) {
bsp_add_o2_recurse(bsp_left[ptr], poly);
} else {
bsp_left[ptr] = bsp_add_o2_poly(poly);
}
} else {
if(bsp_right[ptr] != -1) {
bsp_add_o2_recurse(bsp_right[ptr], poly);
} else {
bsp_right[ptr] = bsp_add_o2_poly(poly);
}
}
} else {
// Split polygon
int sp = polystack_sp;
split = splitpoly(poly, ptr);
if(bsp_left[ptr] != -1) {
bsp_add_o2_recurse(bsp_left[ptr], poly);
} else {
bsp_left[ptr] = bsp_add_o2_poly(poly);
}
if(bsp_right[ptr] != -1) {
bsp_add_o2_recurse(bsp_right[ptr], split);
} else {
bsp_right[ptr] = bsp_add_o2_poly(split);
}
polystack_sp = sp;
}
}
//---- BSP_Add_o2_Poly
public int bsp_add_o2_poly(int poly) {
int i;
double sx, sy;
bsp_object[bsp_num] = 2;
bsp_poly_num[bsp_num] = polystack_num[poly];
for(i=0; i<polystack_num[poly]; i++) {
bsp_poly_x[bsp_num][i] = polystack_x[poly][i];
bsp_poly_y[bsp_num][i] = polystack_y[poly][i];
bsp_poly_z[bsp_num][i] = polystack_z[poly][i];
sx = (image_w*0.5) + 100.0*polystack_x[poly][i]/polystack_z[poly][i];
sy = (image_h*0.5) - 100.0*polystack_y[poly][i]/polystack_z[poly][i];
bsp_poly_sx[bsp_num][i] = sx; bsp_poly_sy[bsp_num][i] = sy;
}
bsp_x[bsp_num] = polystack_x[poly][0];
bsp_y[bsp_num] = polystack_y[poly][0];
bsp_z[bsp_num] = polystack_z[poly][0];
bsp_nx[bsp_num] = polystack_nx[poly];
bsp_ny[bsp_num] = polystack_ny[poly];
bsp_nz[bsp_num] = polystack_nz[poly];
bsp_left[bsp_num] = -1;
bsp_right[bsp_num] = -1;
bsp_num++;
return bsp_num-1;
}
//---- BSP_Reflect_Recurse
public void bsp_reflect_recurse(int ptr, int refl) {
int i, j;
int left;
byte col;
double npa;
double x, y, z, xx, yy, zz, sx, sy, sxx, syy;
if(ptr == -1) { return; }
left = 1;
if(bsp_nx[ptr]*bsp_x[ptr] +
bsp_ny[ptr]*bsp_y[ptr] +
bsp_nz[ptr]*bsp_z[ptr] < 0) { left = -1; }
// Do far branch
if(left < 0) {
bsp_reflect_recurse(bsp_left[ptr], refl);
} else {
bsp_reflect_recurse(bsp_right[ptr], refl);
}
// Draw polygon
poly2_clear();
i = ptr;
x = bsp_poly_x[i][bsp_poly_num[i]-1];
y = bsp_poly_y[i][bsp_poly_num[i]-1];
z = bsp_poly_z[i][bsp_poly_num[i]-1];
npa = bsp_nx[refl]*(x-bsp_x[refl]) +
bsp_ny[refl]*(y-bsp_y[refl]) +
bsp_nz[refl]*(z-bsp_z[refl]);
x -= 2*bsp_nx[refl]*npa;
y -= 2*bsp_ny[refl]*npa;
z -= 2*bsp_nz[refl]*npa;
sx = (image_w*0.5) + 100.0*x/z;
sy = (image_h*0.5) - 100.0*y/z;
for(j=0; j<bsp_poly_num[i]; j++) {
xx = x; yy = y; zz = z;
sxx = sx; syy = sy;
x = bsp_poly_x[i][j];
y = bsp_poly_y[i][j];
z = bsp_poly_z[i][j];
npa = bsp_nx[refl]*(x-bsp_x[refl]) +
bsp_ny[refl]*(y-bsp_y[refl]) +
bsp_nz[refl]*(z-bsp_z[refl]);
x -= 2*bsp_nx[refl]*npa;
y -= 2*bsp_ny[refl]*npa;
z -= 2*bsp_nz[refl]*npa;
sx = (image_w*0.5) + 100.0*x/z;
sy = (image_h*0.5) - 100.0*y/z;
poly2_line(sxx, syy, sx, sy);
}
if(bsp_object[ptr] == 2) {
x = bsp_nx[ptr];
y = bsp_ny[ptr];
z = bsp_nz[ptr];
npa = bsp_nx[refl]*x +
bsp_ny[refl]*y +
bsp_nz[refl]*z;
x -= 2*bsp_nx[refl]*npa;
y -= 2*bsp_ny[refl]*npa;
z -= 2*bsp_nz[refl]*npa;
col = (byte)(32+31*x);
poly2_fill_col(col);
}
// Do near branch
if(left < 0) {
bsp_reflect_recurse(bsp_right[ptr], refl);
} else {
bsp_reflect_recurse(bsp_left[ptr], refl);
}
}
//---- BSP_Recurse
public void bsp_recurse(int ptr) {
int i, j;
int left;
byte col;
if(ptr == -1) { return; }
left = 1;
if(bsp_nx[ptr]*bsp_x[ptr] +
bsp_ny[ptr]*bsp_y[ptr] +
bsp_nz[ptr]*bsp_z[ptr] < 0) { left = -1; }
// System.out.print(ptr);
// System.out.print(",");
// System.out.println(left);
// Do far branch
if(left < 0) {
bsp_recurse(bsp_left[ptr]);
} else {
bsp_recurse(bsp_right[ptr]);
}
// Draw polygon
poly_clear();
i = ptr;
for(j=0; j<bsp_poly_num[i]-1; j++)
poly_line(bsp_poly_sx[i][j], bsp_poly_sy[i][j], bsp_poly_sx[i][j+1], bsp_poly_sy[i][j+1]);
poly_line(bsp_poly_sx[i][j], bsp_poly_sy[i][j], bsp_poly_sx[i][0], bsp_poly_sy[i][0]);
if(bsp_object[ptr] == 1) {
poly_fill_col((byte)0);
} else {
col = (byte)(32+31*bsp_nx[ptr]);
poly_fill_col(col);
}
// If it's reflective do more stuff
if(bsp_object[ptr] == 1) {
if(left < 0) {
bsp_reflect_recurse(bsp_right[ptr], ptr);
} else {
bsp_reflect_recurse(bsp_left[ptr], ptr);
}
col = (byte)(64+32+31*bsp_nx[ptr]);
poly_fill_add(col);
}
// Do near branch
if(left < 0) {
bsp_recurse(bsp_right[ptr]);
} else {
bsp_recurse(bsp_left[ptr]);
}
}
//---- BSP_Render
public void bsp_render() {
if(bsp_num > 0) bsp_recurse(0);
}
//---- RENDER ROUTINES -----------------------------------------------------//
//---- Redraw
int k=0;
public void redraw() {
int i, j, o;
char r;
int x, y;
double sx1, sy1, sx2, sy2;
// Clear buffer
for(i=0; i<image_w*image_h; i++) buf[i] = back[i];
// Change object positions
if(pause == 0) {
o1_rx += 1; o1_ry += 17; o1_rz -= 3;
o2_rx -= 7; o2_ry -= 9; o2_rz += 4;
}
// Transform all points in object 1
maketrans(o1_rx, o1_ry, o1_rz);
for(i=0; i<o1_numpoints; i++) {
o1_tx[i] = m[0][0]*o1_x[i] + m[0][1]*o1_y[i] + m[0][2]*o1_z[i] + o1_cx;
o1_ty[i] = m[1][0]*o1_x[i] + m[1][1]*o1_y[i] + m[1][2]*o1_z[i] + o1_cy;
o1_tz[i] = m[2][0]*o1_x[i] + m[2][1]*o1_y[i] + m[2][2]*o1_z[i] + o1_cz;
o1_sx[i] = (image_w*0.5) + 100.0*o1_tx[i]/o1_tz[i];
o1_sy[i] = (image_h*0.5) - 100.0*o1_ty[i]/o1_tz[i];
/*
x = (int)o1_sx[i];
y = (int)o1_sy[i];
if(x>=0 && x<image_w && y>=0 && y<image_h) {
buf[x+image_w*y] = (byte)255;
}
*/
}
for(i=0; i<o1_numfaces; i++) {
o1_tnx[i] = m[0][0]*o1_nx[i] + m[0][1]*o1_ny[i] + m[0][2]*o1_nz[i];
o1_tny[i] = m[1][0]*o1_nx[i] + m[1][1]*o1_ny[i] + m[1][2]*o1_nz[i];
o1_tnz[i] = m[2][0]*o1_nx[i] + m[2][1]*o1_ny[i] + m[2][2]*o1_nz[i];
}
// Transform all points in object 2
maketrans(o2_rx, o2_ry, o2_rz);
for(i=0; i<o2_numpoints; i++) {
o2_tx[i] = m[0][0]*o2_x[i] + m[0][1]*o2_y[i] + m[0][2]*o2_z[i] + o2_cx;
o2_ty[i] = m[1][0]*o2_x[i] + m[1][1]*o2_y[i] + m[1][2]*o2_z[i] + o2_cy;
o2_tz[i] = m[2][0]*o2_x[i] + m[2][1]*o2_y[i] + m[2][2]*o2_z[i] + o2_cz;
o2_sx[i] = (image_w*0.5) + 100.0*o2_tx[i]/o2_tz[i];
o2_sy[i] = (image_h*0.5) - 100.0*o2_ty[i]/o2_tz[i];
/*
x = (int)o2_sx[i];
y = (int)o2_sy[i];
if(x>=0 && x<image_w && y>=0 && y<image_h) {
buf[x+image_w*y] = (byte)255;
}
*/
}
for(i=0; i<o2_numfaces; i++) {
o2_tnx[i] = m[0][0]*o2_nx[i] + m[0][1]*o2_ny[i] + m[0][2]*o2_nz[i];
o2_tny[i] = m[1][0]*o2_nx[i] + m[1][1]*o2_ny[i] + m[1][2]*o2_nz[i];
o2_tnz[i] = m[2][0]*o2_nx[i] + m[2][1]*o2_ny[i] + m[2][2]*o2_nz[i];
}
// Empty BSP tree
bsp_clear();
// Add object 1 to BSP
bsp_add_o1( 0, 0, 2, 1);
bsp_add_o1( 1, 1, 2, 3);
bsp_add_o1( 2, 0, 1, 3);
bsp_add_o1( 3, 3, 2, 0);
/*
*/
// Add object 2 to BSP
bsp_add_o2( 0, 0, 4, 5, 1);
bsp_add_o2( 4, 4, 8, 9, 5);
bsp_add_o2( 8, 8, 12, 13, 9);
bsp_add_o2(12, 12, 0, 1, 13);
bsp_add_o2( 2, 2, 6, 7, 3);
bsp_add_o2( 6, 6, 10, 11, 7);
bsp_add_o2(10, 10, 14, 15, 11);
bsp_add_o2(14, 14, 2, 3, 15);
/*
for(i=0; i<8; i++) {
System.out.print("bsp: (");
System.out.print(bsp_nx[i]);
System.out.print(", ");
System.out.print(bsp_ny[i]);
System.out.print(", ");
System.out.print(bsp_nz[i]);
System.out.print(") : ");
System.out.println(bsp_nx[i]*bsp_x[i]+bsp_ny[i]*bsp_y[i]+bsp_nz[i]*bsp_z[i]);
}
System.out.print("left: (");
for(i=0; i<8; i++) {
System.out.print(bsp_left[i]);
System.out.print(" ");
}
System.out.println("");
System.out.print("right: (");
for(i=0; i<8; i++) {
System.out.print(bsp_right[i]);
System.out.print(" ");
}
System.out.println("");
*/
bsp_add_o2( 3, 3, 7, 4, 0);
bsp_add_o2( 7, 7, 11, 8, 4);
bsp_add_o2(11, 11, 15, 12, 8);
bsp_add_o2(15, 15, 3, 0, 12);
bsp_add_o2( 1, 1, 5, 6, 2);
bsp_add_o2( 5, 5, 9, 10, 6);
bsp_add_o2( 9, 9, 13, 14, 10);
bsp_add_o2(13, 13, 1, 2, 14);
// Render BSP
bsp_render();
// Put little cornery moving bit
k = (k+1)&255;
for(o=0, j=0; j<8; j++, o+=image_w-8) {
for(i=0; i<8; i++) {
buf[o++] = (byte)( (((k+i+j)&4)>>2)*64+63 );
}
}
/* * /
for(i=0; i<16; i++) {
sx1 = (image_w*0.5) + 100.0*bsp_x[i]/bsp_z[i];
sy1 = (image_w*0.5) - 100.0*bsp_y[i]/bsp_z[i];
sx2 = (image_w*0.5) + 100.0*(bsp_x[i]+bsp_nx[i])/(bsp_z[i]+bsp_nz[i]);
sy2 = (image_w*0.5) - 100.0*(bsp_y[i]+bsp_ny[i])/(bsp_z[i]+bsp_nz[i]);
line(sx1, sy1, sx2, sy2);
}
/* */
// Update screen
src.newPixels(0, 0, image_w, image_h);
}
//---- END OF CLASS --------------------------------------------------------//
}