/* * PuppetApplet.java * * (C) 2004-2005, Alex S. */ import java.awt.*; import java.util.*; /* class BodyNode { public Vector children; public pMatrix matrix; public BodyNode(){ children = new Vector(); matrix = new pMatrix(); } } */ public class PuppetApplet extends BufferedApplet { pMatrix matrix = new pMatrix(); pMatrix pmatrix = new pMatrix(); // points/colors that are rendered. Vector points = new Vector(); Vector colors = new Vector(); // for z sorting double[] avgz; int[] polyorder; // pre-computed points. Vector cube = new Vector(); // current rendering color Color currentColor = Color.red; // 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; // screen rectangle int minx,maxx,miny,maxy; boolean[] keys; /** * dumps phere to rendering pipeline */ public void dumpCube(){ int i,j; j=cube.size(); for (i=0;i=0 && avgz[j] > e2;j--) { avgz[j+1] = avgz[j]; polyorder[j+1] = polyorder[j]; } polyorder[j+1] = e1; avgz[j+1] = e2; } } pMatrix camera = new pMatrix(); //double[] ploc = {0,0,144,1}; double acceleration = 0; double friction = 0; double force = 0; double speed = 0; double frametime = 0; long lastframe = System.currentTimeMillis(); public void handleMotion(){ long currentframe = System.currentTimeMillis(); frametime = (currentframe - lastframe) / 1000.0; lastframe = currentframe; if(m_anglex != 0.0 || m_angley != 0.0){ pMatrix nm = new pMatrix(); nm.rotatex(m_anglex); nm.rotatey(m_angley); nm.mult(camera); camera = nm; m_anglex = m_angley = 0.0; damage = true; } if(keys[127] || keys['q']){ // del key pMatrix nm = new pMatrix(); nm.rotatez(Math.PI/100); nm.mult(camera); camera = nm; damage = true; } if(keys[1025] || keys['e']){ // ins key pMatrix nm = new pMatrix(); nm.rotatez(-Math.PI/100); nm.mult(camera); camera = nm; damage = true; } if(keys[1006] || keys['a']){ // left key pMatrix nm = new pMatrix(); nm.rotatey(-Math.PI/100); nm.mult(camera); camera = nm; damage = true; } if(keys[1007] || keys['d']){ // right key pMatrix nm = new pMatrix(); nm.rotatey(Math.PI/100); nm.mult(camera); camera = nm; damage = true; } if(keys[1004] || keys['w']){ // up key pMatrix nm = new pMatrix(); nm.rotatex(Math.PI/100); nm.mult(camera); camera = nm; damage = true; } if(keys[1005] || keys['s']){ // down key pMatrix nm = new pMatrix(); nm.rotatex(-Math.PI/100); nm.mult(camera); camera = nm; damage = true; } if(keys['<'] || keys[','] || keys['z']){ //System.out.println("< is pressed"); force = 100; }else if(keys['>'] || keys['.'] || keys['x']){ force = -70; }else{ force = 0; } friction = 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(200,speed + acceleration * frametime); speed = Math.max(speed,-100); double distance = Math.round(speed * frametime); if(distance != 0){ pMatrix nm = new pMatrix(); nm.translate(0,0,distance); nm.mult(camera); /* // todo: collision detection pMatrix inverse = camera.inverse(); double[] vec = {0,0,0,1}; vec = inverse.mult(vec); */ camera = nm; damage = true; } } /** * function that gets called whenever something needs to be * rendered. */ public void render(Graphics g) { handleMotion(); if (damage) { // screen rectangle minx = 0; // 10; maxx = bounds().width; // bounds().width-10; miny = 0; // 10; maxy = bounds().height; // bounds().height-10; g.setColor(Color.lightGray); g.fillRect(0, 0, bounds().width, bounds().height); matrix.push(); matrix.mult(camera); //matrix.translate(-ploc[0],-ploc[1],-ploc[2]); matrix.scale(64); /* g.setColor(Color.black); g.drawString("sin: "+m_angley+"; cos: "+(m_anglex)+"; ang: "+ Math.atan2(m_anglex,m_angley),10,10); */ /* if(m_angley != 0 || m_anglex != 0){ pMatrix nm = new pMatrix(); nm.rotatex(m_anglex); nm.rotatey(m_angley); nm.mult(camera); camera = nm; m_anglex = m_angley = 0; } */ //matrix.mult(camera); dumpModel(); // calculate average z for all points. avgz = new double[points.size() / 4]; polyorder = new int[points.size() / 4]; int k,i=0,j=points.size(); double[] plane = new double[4]; for (i=0;i 0) { int clipz,n = 4; for (k=0; k < n; k++) { double[] point = (double[])points.elementAt(poly+k); //point = pmatrix.mult(point); x[k] = (int)(point[0]); // / point[3]); y[k] = (int)(point[1]); // / point[3]); z[k] = clipz = (int)(point[2]); // / point[3]); // clipping // trivial cases, all points have positive or all negative z if (clipz > 0) allnegative = false; else allpositive = false; } // trivial rejection if (allpositive) continue; if (!allnegative) n = clipToZ(n); if (n == 0) continue; /* allnegative = allpositive = true; // test for (k=0; k < n; k++) { clipz = z[k]; if (clipz > 0){ allnegative = false; }else{ allpositive = false; } } // trivial rejection if (allpositive){ System.out.println("Aha, all positive!!!!"); } if (!allnegative){ System.out.println("Aha... Not all negative!!!"); } */ // project face coordinates for(k=0;k= minx) { // point is on right side cx[c] = x[i]; cy[c++] = y[i]; continue; } next = (i+1) % n; prev = (i+n-1) % n; dist = x[i] - minx; if (dist < 0) dist = -dist; if (x[prev] >= minx) { abs = x[prev]-minx; if (abs < 0) abs = -abs; d = (float)dist / (float)(dist + abs); cx[c] = minx; cy[c++] = y[i]+(int)(d*(y[prev]-y[i])); } if (x[next] >= minx) { abs = x[next]-minx; if (abs < 0) abs = -abs; d = (float)dist / (float)(dist + abs); cx[c] = minx; cy[c++] = y[i]+(int)(d*(y[next]-y[i])); } } if (c == 0) return c; n = c; tmp = x; x = cx; cx = tmp; tmp = y; y = cy; cy = tmp; // miny clip c = 0; for (i=0;i= miny) { // point is on right side cx[c] = x[i]; cy[c++] = y[i]; continue; } next = (i+1) % n; prev = (i+n-1) % n; dist = y[i] - miny; if (dist < 0) dist = -dist; if (y[prev] >= miny) { abs = y[prev]-miny; if (abs < 0) abs = -abs; d = (float)dist / (float)(dist + abs); cx[c] = x[i]+(int)(d*(x[prev]-x[i])); cy[c++] = miny; } if (y[next] >= miny) { abs = y[next]-miny; if (abs < 0) abs = -abs; d = (float)dist / (float)(dist + abs); cx[c] = x[i]+(int)(d*(x[next]-x[i])); cy[c++] = miny; } } if (c == 0) return c; n = c; tmp = x; x = cx; cx = tmp; tmp = y; y = cy; cy = tmp; // maxx clip c = 0; for (i=0;i