diff --git a/out/production/EPQ 3D renderer/App.class b/out/production/EPQ 3D renderer/App.class index 488c832..a13221e 100644 --- a/out/production/EPQ 3D renderer/App.class +++ b/out/production/EPQ 3D renderer/App.class Binary files differ diff --git a/out/production/EPQ 3D renderer/Face.class b/out/production/EPQ 3D renderer/Face.class index b38f9a6..54b5092 100644 --- a/out/production/EPQ 3D renderer/Face.class +++ b/out/production/EPQ 3D renderer/Face.class Binary files differ diff --git a/out/production/EPQ 3D renderer/Matrix.class b/out/production/EPQ 3D renderer/Matrix.class index c8eecf9..698f676 100644 --- a/out/production/EPQ 3D renderer/Matrix.class +++ b/out/production/EPQ 3D renderer/Matrix.class Binary files differ diff --git a/out/production/EPQ 3D renderer/Object3d.class b/out/production/EPQ 3D renderer/Object3d.class index 7724b1a..694bbc1 100644 --- a/out/production/EPQ 3D renderer/Object3d.class +++ b/out/production/EPQ 3D renderer/Object3d.class Binary files differ diff --git a/out/production/EPQ 3D renderer/Player.class b/out/production/EPQ 3D renderer/Player.class index 8b9f9c0..b8bf0db 100644 --- a/out/production/EPQ 3D renderer/Player.class +++ b/out/production/EPQ 3D renderer/Player.class Binary files differ diff --git a/out/production/EPQ 3D renderer/Screen.class b/out/production/EPQ 3D renderer/Screen.class index bcf7d88..6d7f20a 100644 --- a/out/production/EPQ 3D renderer/Screen.class +++ b/out/production/EPQ 3D renderer/Screen.class Binary files differ diff --git a/out/production/EPQ 3D renderer/Triangle.class b/out/production/EPQ 3D renderer/Triangle.class index 2cd17e2..5a043b9 100644 --- a/out/production/EPQ 3D renderer/Triangle.class +++ b/out/production/EPQ 3D renderer/Triangle.class Binary files differ diff --git a/out/production/EPQ 3D renderer/Vector3D.class b/out/production/EPQ 3D renderer/Vector3D.class index c8090a9..79370e5 100644 --- a/out/production/EPQ 3D renderer/Vector3D.class +++ b/out/production/EPQ 3D renderer/Vector3D.class Binary files differ diff --git a/src/App.java b/src/App.java index bf5ec33..a2131d2 100644 --- a/src/App.java +++ b/src/App.java @@ -37,23 +37,46 @@ public static void initObjects(){ mainCollection = new ObjectCollection(); +// mainCollection.addObject(new Object3d(new PointComp[]{ +// new PointComp(-10,-10,-10), +// new PointComp(-10,-10,10), +// new PointComp(-10,10,-10), +// new PointComp(-10,10,10), +// new PointComp(10,-10,-10), +// new PointComp(10,-10,10), +// new PointComp(10,10,-10), +// new PointComp(10,10,10) +// +// }, new int[][]{ +// {0,2,3,1}, +// {4,5,7,6}, +// {0,1,5,4}, +// {1,3,7,5}, +// {3,2,6,7}, +// {2,0,4,6}, +// }, true)); +// mainCollection.addObject(new Object3d(new PointComp[]{ +// new PointComp(-10,10,10), +// new PointComp(-10,-10,10), +// new PointComp(10,10,10), +// new PointComp(10,-10,10), +// new PointComp(0,0,24) +// }, new int[][]{ +// {0,2,3,1}, +// {1,0,4}, +// {0,2,4}, +// {2,3,4}, +// {3,1,4} +// }, true)); mainCollection.addObject(new Object3d(new PointComp[]{ - new PointComp(-10,-10,-10), - new PointComp(-10,-10,10), - new PointComp(-10,10,-10), - new PointComp(-10,10,10), - new PointComp(10,-10,-10), - new PointComp(10,-10,10), - new PointComp(10,10,-10), - new PointComp(10,10,10) - + new PointComp(0,0,0), + new PointComp(20,0,0), + new PointComp(0,10,0), + new PointComp(0,0,10), }, new int[][]{ - {0,2,3,1}, - {4,5,7,6}, - {0,1,5,4}, - {1,3,7,5}, - {3,2,6,7}, - {2,0,4,6}, + {0,1,2}, + {0,2,3}, + {0,3,1} }, true)); } } diff --git a/src/Face.java b/src/Face.java index d027d53..2ad549d 100644 --- a/src/Face.java +++ b/src/Face.java @@ -28,7 +28,7 @@ point.setRotatedPoint(camMatrix); point.setProjectedPoint(FPDis, scrX, scrY); // skip rendering if any points are behind the camera - if(point.getRotatedPoint().z < 0){ + if(point.getRotatedPoint().z < 0.1){ valid = false; break; } @@ -68,9 +68,6 @@ valid = true; }} if(!valid){throw new RuntimeException("Could not calculate normal of face");} - normal = new Vector3D( - vec1.y*vec2.z - vec1.z*vec2.y, - vec1.z*vec2.x - vec1.x*vec2.z, - vec1.x*vec2.y - vec1.y*vec2.x); + normal = vec1.cross(vec2); } } diff --git a/src/Matrix.java b/src/Matrix.java index 81cc3b2..7202d29 100644 --- a/src/Matrix.java +++ b/src/Matrix.java @@ -7,7 +7,7 @@ x = _x; y= _y; items = new double[y][x]; } - public double item(int _x, int _y){ + public double getItem(int _x, int _y){ return items[_y][_x]; } public void setItem(int _x, int _y, double val){ @@ -27,7 +27,7 @@ for(int ry = 0; ry< result.y; ry+=1){ newItem = 0; for(int i = 0; i<x; i+=1){ - newItem += this.item(i, ry)*mult.item(rx, i); + newItem += this.getItem(i, ry)*mult.getItem(rx, i); } result.setItem(rx, ry, newItem); }} @@ -38,22 +38,22 @@ } public void multiplyPoint3to(Point3D point, Point3D result) { if(x==3){ - result.x = point.x * item(0,0) + point.y*item(1,0) + point.z*item(2,0); - result.y = point.x * item(0,1) + point.y*item(1,1) + point.z*item(2,1); - result.z = point.x * item(0,2) + point.y*item(1,2) + point.z*item(2,2); + result.x = point.x * getItem(0,0) + point.y* getItem(1,0) + point.z* getItem(2,0); + result.y = point.x * getItem(0,1) + point.y* getItem(1,1) + point.z* getItem(2,1); + result.z = point.x * getItem(0,2) + point.y* getItem(1,2) + point.z* getItem(2,2); } else if(x == 4){ - result.x = point.x * item(0,0) + point.y*item(1,0) + point.z*item(2,0) + item(3,0); - result.y = point.x * item(0,1) + point.y*item(1,1) + point.z*item(2,1) + item(3,1); - result.z = point.x * item(0,2) + point.y*item(1,2) + point.z*item(2,2) + item(3,2); + result.x = point.x * getItem(0,0) + point.y* getItem(1,0) + point.z* getItem(2,0) + getItem(3,0); + result.y = point.x * getItem(0,1) + point.y* getItem(1,1) + point.z* getItem(2,1) + getItem(3,1); + result.z = point.x * getItem(0,2) + point.y* getItem(1,2) + point.z* getItem(2,2) + getItem(3,2); } else {throw new RuntimeException("wrong-dimensions");} } public void multiplyPoint2to(Point2D point, Point2D result) throws Exception { if(x==2){ - result.x = (int)(point.x * item(0,0) + point.y*item(0,1)); - result.y = (int)(point.x * item(1,0) + point.y*item(1,1)); + result.x = (int)(point.x * getItem(0,0) + point.y* getItem(0,1)); + result.y = (int)(point.x * getItem(1,0) + point.y* getItem(1,1)); } else if(x == 3){ - result.x = (int)(point.x * item(0,0) + point.y*item(0,1) + item(0,2)); - result.y = (int)(point.x * item(1,0) + point.y*item(1,1) + item(1,2)); + result.x = (int)(point.x * getItem(0,0) + point.y* getItem(0,1) + getItem(0,2)); + result.y = (int)(point.x * getItem(1,0) + point.y* getItem(1,1) + getItem(1,2)); } else {throw new Exception("wrong-dimensions");} } } diff --git a/src/Object3d.java b/src/Object3d.java index 976859a..9382d8b 100644 --- a/src/Object3d.java +++ b/src/Object3d.java @@ -25,19 +25,13 @@ faces) { // check whether faces are pointing towards or away from the camera // TODO figure out angle - Vector3D camVec = new Vector3D( - face.points[0].point.x - playerPos.x, - face.points[0].point.y - playerPos.y, - face.points[0].point.z - playerPos.z - ); - double ang = face.normal.angleTo(camVec); - //debugimg.getGraphics().drawString(Math.round(Math.toDegrees(ang)) + " angle " + iterator, 10, 20 + 10*iterator); + Vector3D camVec = new Vector3D(0,0,0); + camVec.createFrom2Points(playerPos, face.points[0].point); int numberOfPixels = 0; - if(ang <= Math.PI/2-0.01){ + if(face.normal.angleTo(camVec) <= Math.PI/2-0.01){ numberOfPixels = face.draw(img, debugimg, camMatrix, FPDis, scrX, scrY); } debugimg.getGraphics().drawString(iterator + ": " +numberOfPixels , 10, 20 + 10*iterator); - iterator += 1; } } @@ -73,9 +67,20 @@ pointB = point.point; distance = newDis;}} boundingSphereC = new Point3D( - (pointA.x+ pointB.x) / 2, + (pointA.x + pointB.x) / 2, (pointA.y + pointB.y)/2, - (pointA.y + pointB.y)/2); + (pointA.z + pointB.z)/2); boundingSphereR = Math.sqrt(distance)/2; + boolean valid = false; + for (PointComp point: + points) { + distance = Math.sqrt( + Math.pow(boundingSphereC.x - point.point.x, 2)+ + Math.pow(boundingSphereC.y - point.point.y, 2)+ + Math.pow(boundingSphereC.z - point.point.z, 2)); + if(distance > boundingSphereR){ + boundingSphereR = distance; + } + } } } diff --git a/src/ObjectCollection.java b/src/ObjectCollection.java index efe60cc..fb9de3f 100644 --- a/src/ObjectCollection.java +++ b/src/ObjectCollection.java @@ -11,7 +11,7 @@ public ArrayList<Object3d> objects = new ArrayList<Object3d>(); public void invalidate(boolean invalidatePoints){ - // the first level of object collections should contain all the points for the sub-levels. + // the first level of object collections should contain all the points for the sublevels. // this means that we only need to invalidate them at the top level if(invalidatePoints){for (PointComp point: points) { @@ -27,16 +27,26 @@ } } - public void draw(BufferedImage img, BufferedImage debugimg, Matrix camMatrix, double FPDis, int scrX, int scrY, Point3D playerPos){ - // todo check for frustum culling + public void draw(BufferedImage img, BufferedImage debugImg, Matrix camMatrix, Point3D playerPos, Plane[] frustumPlanes, double FPDis, int scrX, int scrY){ for (Object3d object: objects) { - object.draw(img, debugimg, camMatrix, FPDis, scrX, scrY, playerPos); + boolean draw = true; + int i = 0; + for (Plane plane: + frustumPlanes) { + debugImg.getGraphics().drawString( + "Dis: " + String.format("%.1f", plane.getDistance(object.boundingSphereC)), 500, 10 + 20*i); + if(plane.getDistance(object.boundingSphereC) < -object.boundingSphereR){ + draw = false; + break;} + i += 1; + } + if(draw){object.draw(img, debugImg, camMatrix, FPDis, scrX, scrY, playerPos);} } // todo check for frustum culling for(ObjectCollection collection: subCollections){ - collection.draw(img, debugimg, camMatrix, FPDis, scrX, scrY, playerPos); + collection.draw(img, debugImg, camMatrix, playerPos, frustumPlanes, FPDis, scrX, scrY); } } public void addCollection(int[] pointList){ diff --git a/src/Plane.java b/src/Plane.java new file mode 100644 index 0000000..fa525cf --- /dev/null +++ b/src/Plane.java @@ -0,0 +1,27 @@ +public class Plane { + public Point3D mainPoint; + public Vector3D normalVector; + + public double getDistance(Point3D point){ + Vector3D vec = new Vector3D(0,0,0); + vec.createFrom2Points(mainPoint, point); + return normalVector.dot(vec); + } + public void initFrom3Points(Point3D _mainPoint, Point3D point1, Point3D point2){ + // find normal vector to 3 points + Vector3D vec1 = new Vector3D(0,0,0); + Vector3D vec2 = new Vector3D(0,0,0); + vec1.createFrom2Points(_mainPoint, point1); + vec2.createFrom2Points(point1, point2); + initFromPointAndVector(_mainPoint, vec1.cross(vec2)); + } + public void initFromPointAndVector(Point3D _mainPoint, Vector3D _normalVector){ + // convert to unit vector + mainPoint = _mainPoint; + double len = _normalVector.getLength(); + normalVector = new Vector3D( + _normalVector.x / len, + _normalVector.y / len, + _normalVector.z / len); + } +} diff --git a/src/Player.java b/src/Player.java index 25215e5..cb16b47 100644 --- a/src/Player.java +++ b/src/Player.java @@ -5,20 +5,35 @@ public class Player { + public Plane[] frustumPlanes = new Plane[6]; // image that represents the player's position on the board private BufferedImage image; // current position of the player on the board grid + private Matrix rotMatrix; public Matrix camMatrix; + private Matrix invRotMatrix; + private Matrix invCamMatrix; public double FOV = 100; protected double Fpdis; - private Point3D position = new Point3D(-30,0,0); + protected Point3D FPWorldPos; + protected PointComp[] ScreenCornerPosS = new PointComp[4]; + private Point3D position = new Point3D(0,0,0); private Point3D rotation = new Point3D(0,Math.PI / 2, 0); private Point3D direction = new Point3D(0,0,0); public Vector3D viewVector = new Vector3D(0,0,0); public double mouseSensitivity = 0.005; // radians per pixel // called when the player is initialised - public Player() { - Fpdis = Math.tanh(Math.toRadians(FOV)/2d); + public Player(int scrX, int scrY) { + Fpdis = 1/Math.tan(Math.toRadians(FOV)/2d); + for(int i = 0; i < 6; i+=1){ + frustumPlanes[i] = new Plane(); + } + double yVal = (double)scrY / (double)scrX; + // flip x and y because reasons + ScreenCornerPosS[0] = new PointComp(-yVal,-1, 0); + ScreenCornerPosS[1] = new PointComp(yVal,-1, 0); + ScreenCornerPosS[2] = new PointComp(-yVal,1, 0); + ScreenCornerPosS[3] = new PointComp(yVal,1, 0); } // unused because the player should not be drawn @@ -43,9 +58,9 @@ direction.x += 1; } else if (key == KeyEvent.VK_S && -direction.x < 1) { direction.x += -1; - } else if (key == KeyEvent.VK_D && direction.y < 1) { + } else if (key == KeyEvent.VK_A && direction.y < 1) { direction.y += 1; - } else if (key == KeyEvent.VK_A && -direction.y < 1) { + } else if (key == KeyEvent.VK_D && -direction.y < 1) { direction.y += -1; } else if (key == KeyEvent.VK_SPACE && direction.z < 1) { direction.z += 1; @@ -58,9 +73,9 @@ direction.x -= 1; } else if (key == KeyEvent.VK_S && -direction.x > -1) { direction.x -= -1; - } else if (key == KeyEvent.VK_D && direction.y > -1) { + } else if (key == KeyEvent.VK_A && direction.y > -1) { direction.y -= 1; - } else if (key == KeyEvent.VK_A && -direction.y > -1) { + } else if (key == KeyEvent.VK_D && -direction.y > -1) { direction.y -= -1; } else if (key == KeyEvent.VK_SPACE && direction.z > -1) { direction.z -= 1; @@ -71,7 +86,7 @@ public void tick(Point2D mouseRel) { // gets called once every tick, before the repainting process happens. // change rotation depending on mouse movement - rotation.z += mouseRel.x * mouseSensitivity; + rotation.z -= mouseRel.x * mouseSensitivity; // force z rotation to wrap around if(rotation.z<-Math.PI){ rotation.z = Math.PI; @@ -79,13 +94,13 @@ rotation.z = -Math.PI; } rotation.y += mouseRel.y * mouseSensitivity; - // max out y rotation at 0 and 90 degrees + // max out y rotation at 0 and -90 degrees if(rotation.y < 0){ rotation.y = 0; } else if(rotation.y > Math.PI){ rotation.y = Math.PI; } - // calculate direction vector to translate position by + // define rotation and translation matrices Matrix zMat = new Matrix(3, 3); zMat.setItems(new double[][]{ {Math.cos(rotation.z), Math.sin(rotation.z), 0}, @@ -104,13 +119,25 @@ {0, Math.cos(rotation.x), Math.sin(rotation.x)}, {0, -Math.sin(rotation.x), Math.cos(rotation.x)}} ); - // calculate inverse Z mat for player movement + // calculate inverse matrices Matrix izMat = new Matrix(3, 3); izMat.setItems(new double[][]{ {Math.cos(-rotation.z), Math.sin(-rotation.z), 0}, {-Math.sin(-rotation.z), Math.cos(-rotation.z), 0}, {0, 0, 1}} ); + Matrix iyMat = new Matrix(3, 3); + iyMat.setItems(new double[][]{ + {Math.cos(-rotation.y), 0, -Math.sin(-rotation.y)}, + {0, 1, 0 }, + {Math.sin(-rotation.y), 0, Math.cos(-rotation.y) }} + ); + Matrix ixMat = new Matrix(3, 3); + ixMat.setItems(new double[][]{ + {1, 0, 0 }, + {0, Math.cos(-rotation.x), Math.sin(-rotation.x)}, + {0, -Math.sin(-rotation.x), Math.cos(-rotation.x)}} + ); // apply izMat to direction vector try { Point3D dirvec = new Point3D(0,0,0); @@ -125,15 +152,64 @@ {0, 1, 0, -position.y}, {0, 0, 1, -position.z}} ); - // multiply out camera matrix for rotation - camMatrix = xMat.multiply(yMat).multiply(zMat); - // calculate view vector - /*Point3D viewPoint = new Point3D(0,0,0); - camMatrix.multiplyPoint3to(new Point3D(0,0,1), viewPoint); - viewVector.x = viewPoint.x;viewVector.y=viewPoint.y;viewVector.z=viewPoint.z;*/ + // multiply out matrices + rotMatrix = xMat.multiply(yMat).multiply(zMat); + camMatrix = rotMatrix.multiply(traMat); + invRotMatrix = izMat.multiply(iyMat).multiply(ixMat); + // I really don't want to do it like this, but I don't think there's any other way without messing up + // all my other matrices :( + invCamMatrix = new Matrix(4, 3); + for(int x = 0; x<3; x+=1){ + for(int y = 0; y<3; y+=1){ + invCamMatrix.setItem(x, y, invRotMatrix.getItem(x, y)); + }} + for(int y = 0; y<3; y+=1){ + invCamMatrix.setItem(3, y, -traMat.getItem(3, y)); + } - // add translation to camMatrix - camMatrix = camMatrix.multiply(traMat); + // calculate view vector + Point3D viewPoint = new Point3D(0,0,0); + invRotMatrix.multiplyPoint3to(new Point3D(0,0,1), viewPoint); + // todo - work out why i need to reverse this + viewVector.x = viewPoint.x;viewVector.y=viewPoint.y;viewVector.z=viewPoint.z; + + // calculate camera focal point and edges in world coordinates + FPWorldPos = new Point3D( + position.x - viewVector.x*Fpdis, + position.y - viewVector.y*Fpdis, + position.z - viewVector.z*Fpdis); + for (PointComp point: + ScreenCornerPosS) { + point.invalidate(); + point.setRotatedPoint(invCamMatrix); + } + // find frustum planes + // near plane + //frustumPlanes[0].initFromPointAndVector(position, viewVector); + frustumPlanes[0].initFrom3Points(ScreenCornerPosS[0].getRotatedPoint(), + ScreenCornerPosS[1].getRotatedPoint(), ScreenCornerPosS[2].getRotatedPoint()); + // far plane + int farPlaneDis = 1000; + frustumPlanes[1].initFromPointAndVector( + new Point3D( + position.x + viewVector.x*farPlaneDis, + position.y + viewVector.y*farPlaneDis, + position.z + viewVector.z*farPlaneDis), + // invert the view vector because the normal needs to point the other way + new Vector3D(-viewVector.x, -viewVector.y, -viewVector.z)); + // mid planes + // left plane + frustumPlanes[2].initFrom3Points(FPWorldPos, + ScreenCornerPosS[0].getRotatedPoint(), ScreenCornerPosS[1].getRotatedPoint()); + // right plane + frustumPlanes[3].initFrom3Points(FPWorldPos, + ScreenCornerPosS[3].getRotatedPoint(), ScreenCornerPosS[2].getRotatedPoint()); + // top plane + frustumPlanes[4].initFrom3Points(FPWorldPos, + ScreenCornerPosS[1].getRotatedPoint(), ScreenCornerPosS[3].getRotatedPoint()); + // bottom plane + frustumPlanes[5].initFrom3Points(FPWorldPos, + ScreenCornerPosS[2].getRotatedPoint(), ScreenCornerPosS[0].getRotatedPoint()); } // returnValue Functions diff --git a/src/Point3D.java b/src/Point3D.java index 595db2d..81ef356 100644 --- a/src/Point3D.java +++ b/src/Point3D.java @@ -20,15 +20,17 @@ } public Point2D project(double fpdis, int scrX, int scrY){ return new Point2D( - (int)(((fpdis*y)/z + .5)*scrX), - (int)(((fpdis*x)/z + .5)*scrY) + (int)(((fpdis*y)/(z) + .5)*scrX), + (int)(((fpdis*x)/(z) + .5)*scrY) // multiply by scrX both times such that the projected screen always projects points between -1<x<1. // this means that there isn't any weird scaling, and the FOV is in terms of horizontal.. ness. ); } public void projectOn(double fpdis, int scrX, int scrY, Point2D point){ - point.x = (int)(scrX*((fpdis*y)/z + .5)); - point.y = (int)(scrX*((fpdis*x)/z + .5)); + // this is a mess of random fixes because none of my coordinates are correct. :( + // sorry + point.x = scrX - (int)(scrX*0.5*((fpdis*y)/(z) + 1)); + point.y = (int)(scrX*0.5*((fpdis*x)/(z) + ((double)scrY/(double)scrX))); } public double[] get(){ return new double[]{x, y, z}; diff --git a/src/Screen.java b/src/Screen.java index 4192a73..05594fc 100644 --- a/src/Screen.java +++ b/src/Screen.java @@ -1,7 +1,6 @@ import java.awt.*; import java.awt.event.*; import java.awt.image.BufferedImage; -import java.util.ArrayList; import javax.swing.*; public class Screen extends JPanel implements ActionListener, KeyListener, MouseListener, MouseMotionListener { @@ -10,7 +9,7 @@ // mouse private boolean captured = false; private final Point2D mouseRel = new Point2D(0,0); - private Cursor invisibleCursor; + private final Cursor invisibleCursor; public ObjectCollection mainCollection; @@ -52,7 +51,7 @@ invisibleCursor = toolkit.createCustomCursor(cursorImage, hotSpot, "InvisibleCursor"); // initialize the game state - player = new Player(); + player = new Player(TILE_SIZE*COLUMNS, TILE_SIZE*ROWS); // this timer will call the actionPerformed() method every DELAY ms timer = new Timer(DELAY, this); timer.start(); @@ -86,8 +85,8 @@ } private void drawScreen(Graphics g) { BufferedImage img = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_RGB ); - BufferedImage debugimg = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB); - debugimg.createGraphics(); + BufferedImage debugImg = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB); + debugImg.createGraphics(); g.setColor(Color.white); // line.point2.x = 100*Math.sin(ang) + 200; // line.point2.y = 100*Math.cos(ang) + 200; @@ -108,26 +107,60 @@ Triangle t2 = null; try { t1 = new Triangle( - newPoints.get(0).project(player.Fpdis, getWidth(), getHeight()), - newPoints.get(1).project(player.Fpdis, getWidth(), getHeight()), - newPoints.get(2).project(player.Fpdis, getWidth(), getHeight())); + newPoints.get(0).project(player.FPDis, getWidth(), getHeight()), + newPoints.get(1).project(player.FPDis, getWidth(), getHeight()), + newPoints.get(2).project(player.FPDis, getWidth(), getHeight())); } catch(NullPointerException ignored){} try{ t2 = new Triangle( - newPoints.get(0).project(player.Fpdis, getWidth(), getHeight()), - newPoints.get(2).project(player.Fpdis, getWidth(), getHeight()), - newPoints.get(3).project(player.Fpdis, getWidth(), getHeight())); + newPoints.get(0).project(player.FPDis, getWidth(), getHeight()), + newPoints.get(2).project(player.FPDis, getWidth(), getHeight()), + newPoints.get(3).project(player.FPDis, getWidth(), getHeight())); } catch(NullPointerException ignored){} try{t1.draw(img);}catch (NullPointerException ignored){} try{t2.draw(img);}catch (NullPointerException ignored){} ang += 0.02;*/ mainCollection.invalidate(true); - mainCollection.draw(img, debugimg, player.camMatrix, player.Fpdis, getWidth(), getHeight(), player.getPos()); + mainCollection.draw(img, debugImg, player.camMatrix, player.getPos(), player.frustumPlanes, player.Fpdis, getWidth(), getHeight()); g.drawImage(img, 0, 0, this); - g.drawImage(debugimg, 0, 0, this); + // DEBUG DRAWING - g.drawString(Math.round(1000/(float)(System.currentTimeMillis() - lastTime)) + " fps" , 10, 10); + debugImg.getGraphics().drawString(Math.round(1000/(float)(System.currentTimeMillis() - lastTime)) + " fps" , 10, 10); + debugImg.getGraphics().drawString("fpPos: " + + String.format("%.2f", player.FPWorldPos.x) + " " + + String.format("%.2f", player.FPWorldPos.y) + " " + + String.format("%.2f", player.FPWorldPos.z) + " ", 100, 30); + g.drawImage(debugImg, 0, 0, this); + debugImg.getGraphics().drawString("playerPos: " + + String.format("%.2f", player.getPos().x) + " " + + String.format("%.2f", player.getPos().y) + " " + + String.format("%.2f", player.getPos().z) + " ", 100, 50); + debugImg.getGraphics().drawString("rotation: " + + Math.round(Math.toDegrees(player.getRot().x)) + " " + + Math.round(Math.toDegrees(player.getRot().y)) + " " + + Math.round(Math.toDegrees(player.getRot().z)) + " ", 300, 50); + debugImg.getGraphics().drawString("viewVec: " + + String.format("%.2f",player.viewVector.x) + " " + + String.format("%.2f",player.viewVector.y) + " " + + String.format("%.2f",player.viewVector.z) + " ", 100, 70); + for(int i = 0; i<4; i+=1){ + debugImg.getGraphics().drawString("camPoint " + i + ": " + + String.format("%.2f", player.ScreenCornerPosS[i].getRotatedPoint().x) + " " + + String.format("%.2f", player.ScreenCornerPosS[i].getRotatedPoint().y) + " " + + String.format("%.2f", player.ScreenCornerPosS[i].getRotatedPoint().z), 10, 90 + 20 * i); + } + for(int i = 0; i<6; i+=1){ + debugImg.getGraphics().drawString("plane " + i + ": " + + String.format("%.2f", player.frustumPlanes[i].mainPoint.x) + " " + + String.format("%.2f", player.frustumPlanes[i].mainPoint.y) + " " + + String.format("%.2f", player.frustumPlanes[i].mainPoint.z) + ", normal: " + + String.format("%.2f", player.frustumPlanes[i].normalVector.x) + " " + + String.format("%.2f", player.frustumPlanes[i].normalVector.y) + " " + + String.format("%.2f", player.frustumPlanes[i].normalVector.z), 10, 170 + 20 * i); + } + + g.drawImage(debugImg, 0, 0, this); lastTime = System.currentTimeMillis(); } diff --git a/src/Triangle.java b/src/Triangle.java index 77dbada..08c5c43 100644 --- a/src/Triangle.java +++ b/src/Triangle.java @@ -25,7 +25,6 @@ } // returns int for debug public int draw(BufferedImage img){ - int numberOfPixels = 0; // debug long lastMillis; if (!is_initialised){initialise();} diff --git a/src/Vector3D.java b/src/Vector3D.java index 55457f4..6680548 100644 --- a/src/Vector3D.java +++ b/src/Vector3D.java @@ -1,5 +1,7 @@ // technically not required as vectors have the same information as points, but it's useful to have separate vector and point things.. +import java.util.Vector; + public class Vector3D { public double x; public double y; @@ -10,6 +12,14 @@ y = _y; z = _z; } + public void createFrom2Points(Point3D start, Point3D end){ + x = end.x - start.x; + y = end.y - start.y; + z = end.z - start.z; + } + public double getLength(){ + return Math.sqrt(x*x + y*y + z*z); + } public double angleTo(Vector3D vec2){ return Math.acos( (x*vec2.x + y*vec2.y + z*vec2.z) @@ -17,4 +27,13 @@ Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2) + Math.pow(z, 2)) * Math.sqrt(Math.pow(vec2.x, 2) + Math.pow(vec2.y, 2) + Math.pow(vec2.z, 2)))); } + public Vector3D cross(Vector3D vec2){ + return new Vector3D( + y*vec2.z - z*vec2.y, + z*vec2.x - x*vec2.z, + x*vec2.y - y*vec2.x); + } + public double dot(Vector3D vec2){ + return x*vec2.x + y* vec2.y+z* vec2.z; + } }