/* * FlightBox.java * * (C) 2004-2005, Alex S. */ import java.awt.*; import java.util.*; /** * main class of the whole thing */ public class FlightBox extends BufferedApplet { pMatrix matrix = new pMatrix(); pMatrix pmatrix = new pMatrix(); pMap map; // angle, mouse state private double m_anglex,m_angley; private int m_mousex,m_mousey; // used for java's fillpoly thingie... (and some quick & dirty clipping) private int[] x; private int[] y; private int[] z; // clippping ... private int[] cx; private int[] cy; private int[] cz; private int[][] screen_edges; boolean[] keys; // viewers direction/location pMatrix camera; // this is calculated from the camera matrix, and is used for stuff in BSP tree. public double[] eye; double acceleration = 0; double friction = 0; double force = 0; double speed = 0; double frametime = 0; long lastframe = System.currentTimeMillis(); /** * initialize things */ public void init(){ super.init(); // map = pMapGen.generateCubes(7); map = pMapGen.generateRoundedCubes(32,7); map.buildBSP(); keys = new boolean[0x1000]; for (int i=0;i'] || keys['.'] || keys['x']) { force = -70; } else { force = 0; } friction = (double)0.1; acceleration = acceleration + friction * (0 - acceleration); acceleration = Math.min(1000,acceleration + force); // should be force * direction vector speed = speed + friction * (0 - speed); speed = Math.min(2000,speed + acceleration * frametime); speed = Math.max(speed,-1000); double distance = Math.round(speed * frametime); if (distance != 0) { pMatrix nm = new pMatrix(); nm.translate(0,0,distance); nm.mult(camera); double[] neweye = {0,0,0,1}; pMatrix inverse = nm.inverse(); neweye = inverse.mult(neweye); map.traceSphere(eye,neweye,24); if(map.outputFraction > 0){ nm = new pMatrix(); nm.translate(0,0,map.outputFraction * distance); nm.mult(camera); double[] neye = {0,0,0,1}; inverse = nm.inverse(); neye = inverse.mult(neye); camera = nm; eye = neye; } damage = true; } } /* public boolean pointInsideSolidBrush(pBSPNode r,double[] p){ if (r.type == pBSPNode.LEAFNODE) { //System.out.println("Inside Leaf Node: "+r.brushes.size()); for (int i=0;i= 0) { return pointInsideSolidBrush(r.front,p); } else { return pointInsideSolidBrush(r.back,p); } } */ /** * recompute various things when screen size changes */ public void recompute(Rectangle r){ screen_edges = new int[4][3]; int W = r.width-1; int H = r.height-1; int lines[][] = { {0,0,0,H}, {0,H,W,H}, {W,H,W,0}, {W,0,0,0} }; int x1 = 0; int y1 = 1; int x2 = 2; int y2 = 3; for (int i=0;i 0) { allnegative = false; } else { allpositive = false; if (clipz > -10000) { alloutofrange = false; } else { allinrange = false; } } } //System.out.println(""); // trivial rejection if (allpositive) { //System.out.println("\tall positive"); return; } if (alloutofrange) { //System.out.println("\tall out of range."); return; } if (!allnegative) { int[] arr = {0,0,-1,0}; n = SutherlandHodgmanPolygonClip3D(x,y,z,n,cx,cy,cz,arr); if (n == 0) { //System.out.println("all z clipped"); return; } for (k=0;k 0) pRenderFace(face,g); } } /** * render everything in a bsp tree using painter's algorithm (back to front) */ public void pTreeRender(double[] eye,pBSPNode node,Graphics g){ if (node.type != pBSPNode.TREENODE) return; // just render everything here. if (node.plane.eval(eye[0],eye[1],eye[2]) >= 0) { pTreeRender(eye,node.back,g); pRenderFaces(eye,node.faces,g); pTreeRender(eye,node.front,g); } else { pTreeRender(eye,node.front,g); pRenderFaces(eye,node.faces,g); pTreeRender(eye,node.back,g); } } /** * function that gets called whenever something needs to be * rendered. */ public void render(Graphics g) { handleMotion(); if (damage) { g.setColor(Color.lightGray); g.fillRect(0, 0, bounds().width, bounds().height); matrix.push(); matrix.mult(camera); pTreeRender(eye,map.bsp,g); matrix.pop(); // g.drawString("("+eye[0]+","+eye[1]+","+eye[2]+")",10,10); //System.out.println("camera: "+camera); } } /** * mouse event handler: let the user move things */ public boolean mouseDown(Event evt, int x, int y){ m_mousex = x; m_mousey = y; return true; } public boolean mouseUp(Event evt, int x, int y){ return true; } /** * mouse event handler: let the user move things */ public boolean mouseDrag(Event evt, int x, int y){ m_angley += (double)0.015 * (double)(x - m_mousex); m_anglex += (double)0.015 * (double)(y - m_mousey); m_mousex = x; m_mousey = y; return true; } public boolean keyDown(Event evt,int key){ //System.out.println("keyDown: "+key); if (key < 0x1000) keys[key] = true; return true; } public boolean keyUp(Event evt,int key){ //System.out.println("keyUp: "+key); if (key < 0x1000) keys[key] = false; return true; } /** * edge is in Ax + By + D = 0 format. * * dx = x2 - x1; * dy = y2 - y1; * A = dy * B = -dx * D = -(A * x1 + B * y1) */ private int SutherlandHodgmanPolygonClip(int[] ix,int[] iy,int n,int[] ox,int[] oy,int[] edge){ int A,B,D,p,s,k,l,olen,x,y; long d1,d2; // these -need- to be long (some of these values get -very- large. A = edge[0]; B = edge[1]; D = edge[2]; olen = 0; s = n - 1; for (p=0;p= 0 ) { // p is inside if ( (l = ix[s] * A + iy[s] * B + D) >= 0 ) { // s in inside ox[olen] = ix[p]; oy[olen] = iy[p]; olen++; } else { // find intersection d1 = -l; d2 = (d1 + k); ox[olen] = (int)(ix[s] + ( d1 * ( ix[p] - ix[s] ) ) / d2); oy[olen] = (int)(iy[s] + ( d1 * ( iy[p] - iy[s] ) ) / d2); olen++; ox[olen] = ix[p]; oy[olen] = iy[p]; olen++; } } else { if ( (l = ix[s] * A + iy[s] * B + D) >= 0 ) { // s in inside d1 = -k; d2 = (d1 + l); ox[olen] = (int)(ix[p] + ( d1 * ( ix[s] - ix[p] ) ) / d2); oy[olen] = (int)(iy[p] + ( d1 * ( iy[s] - iy[p] ) ) / d2); olen++; } } s = p; } return olen; } /** * edge is Ax + By + Cz + D = 0 */ private int SutherlandHodgmanPolygonClip3D(int[] ix,int[] iy,int[] iz,int n,int[] ox,int[] oy,int[] oz,int[] edge){ int A,B,C,D,p,s,k,l,olen,x,y; long d1,d2; // these -need- to be long (some of these values get -very- large. A = edge[0]; B = edge[1]; C = edge[2]; D = edge[3]; olen = 0; s = n - 1; for (p=0;p= 0 ) { // p is inside if ( (l = ix[s] * A + iy[s] * B + iz[s] * C + D) >= 0 ) { // s in inside ox[olen] = ix[p]; oy[olen] = iy[p]; oz[olen] = iz[p]; olen++; } else { // find intersection d1 = -l; d2 = (d1 + k); ox[olen] = (int)(ix[s] + ( d1 * ( ix[p] - ix[s] ) ) / d2); oy[olen] = (int)(iy[s] + ( d1 * ( iy[p] - iy[s] ) ) / d2); oz[olen] = (int)(iz[s] + ( d1 * ( iz[p] - iz[s] ) ) / d2); olen++; ox[olen] = ix[p]; oy[olen] = iy[p]; oz[olen] = iz[p]; olen++; } } else { if ( (l = ix[s] * A + iy[s] * B + iz[s] * C + D) >= 0 ) { // s in inside d1 = -k; d2 = (d1 + l); ox[olen] = (int)(ix[p] + ( d1 * ( ix[s] - ix[p] ) ) / d2); oy[olen] = (int)(iy[p] + ( d1 * ( iy[s] - iy[p] ) ) / d2); oz[olen] = (int)(iz[p] + ( d1 * ( iz[s] - iz[p] ) ) / d2); olen++; } } s = p; } return olen; } }