diff --git a/src/main/java/uk/org/floop/epq3d/App.java b/src/main/java/uk/org/floop/epq3d/App.java index 0ba19ab..f26bc1c 100644 --- a/src/main/java/uk/org/floop/epq3d/App.java +++ b/src/main/java/uk/org/floop/epq3d/App.java @@ -37,7 +37,7 @@ } public static void initObjects(){ - JsonReader Jason = new JsonReader("cube.json"); + JsonReader Jason = new JsonReader("testingJSON.json"); Jason.getObjects(); mainCollection = Jason.mainCollection; mainCollection.initialiseAll(); diff --git a/src/main/java/uk/org/floop/epq3d/Face.java b/src/main/java/uk/org/floop/epq3d/Face.java index 60e122e..b376bd3 100644 --- a/src/main/java/uk/org/floop/epq3d/Face.java +++ b/src/main/java/uk/org/floop/epq3d/Face.java @@ -12,6 +12,7 @@ public Texture texture; public Matrix[][] perspectiveMappingMatrices; public boolean isInitialised; + public boolean isValid; // fixed face public Face fixedFace; public void initialise(){ @@ -38,177 +39,183 @@ tri.invalidate(); } } - public int draw(int[][] img, int[][] zBuf, BufferedImage debugImg, Matrix camMatrix, double FPDis, int scrX, int scrY){ - if(!isInitialised){ + public int draw(int[][] img, int[][] zBuf, BufferedImage debugImg, Matrix camMatrix, double FPDis, int scrX, int scrY) { + double ang = normal.angleTo(new Vector3D(0.2, 0.5, 1)); + if (!isInitialised) { throw new RuntimeException("Face not initialised"); } - // check for backface culling has been done previously. - // initialise points - int numberOfPixels = 0; - // apply point transforms for all points within the face - boolean valid = applyPointTransforms(camMatrix, FPDis, scrX, scrY); - // this function is completed every frame, without checking whether pixels will be drawn first - bakePerspectiveMatrices(img, zBuf, debugImg, camMatrix, FPDis, scrX, scrY); + if (isValid) { + // the check for backface culling has been done previously. + // initialise points + int numberOfPixels = 0; + // apply point transforms for all points within the face + boolean valid = applyPointTransforms(camMatrix, FPDis, scrX, scrY); + // this function is completed every frame, without checking whether pixels will be drawn first + bakePerspectiveMatrices(img, zBuf, debugImg, camMatrix, FPDis, scrX, scrY); - // if all the points are valid (in front of the camera) draw all tris normally. - if (valid){ - for (Triangle tri: - tris) { - tri.draw(img, zBuf, FPDis, scrX, scrY); - } - } else { + // if all the points are valid (in front of the camera) draw all tris normally. + if (valid) { + for (Triangle tri : + tris) { + tri.draw(img, zBuf, FPDis, scrX, scrY, ang); + } + } else { /*todo check wether there is any slowdown here it might be that the compiler just sorts it but i'm not 100% sure. fix would be to change it so that I only need to loop through points once, and also reduce the number of temporary point objects i use */ - for (int tri_i = 0; tri_i < trisFaceList.length; tri_i += 1) { - // first, count up the number of invalid points in the triangle (points which are behind the camera) - int numOfInvalidPoints = 0; - for (int i = 0; i < 3; i +=1){ - if (points[trisFaceList[tri_i][i]].getRotatedPoint().z < 0.1) { - numOfInvalidPoints += 1; - } - } - if (numOfInvalidPoints == 0) { // if there are no invalid points, treat the triangle normally - // project all points in triangle - tris[tri_i].draw(img, zBuf, FPDis, scrX, scrY); - } else if (numOfInvalidPoints == 1) {// if one point is invalid, interpolate 2 new points and draw 2 new triangles: - // find which point is the invalid one TODO could optimise and find this beforehand - int invalidIndex = -1; + for (int tri_i = 0; tri_i < trisFaceList.length; tri_i += 1) { + // first, count up the number of invalid points in the triangle (points which are behind the camera) + int numOfInvalidPoints = 0; for (int i = 0; i < 3; i += 1) { if (points[trisFaceList[tri_i][i]].getRotatedPoint().z < 0.1) { - invalidIndex = i; - break; + numOfInvalidPoints += 1; } } - if (invalidIndex == -1) { - throw new RuntimeException("How did this happen?!"); - } - Point3D oldPoint1 = points[trisFaceList[tri_i][Math.floorMod(invalidIndex + 1, 3)]].getRotatedPoint(); - Point3D oldPoint2 = points[trisFaceList[tri_i][Math.floorMod(invalidIndex + 2, 3)]].getRotatedPoint(); - Point3D invalidPoint = points[trisFaceList[tri_i][invalidIndex]].getRotatedPoint(); - Point3D newPoint1; - Point3D newPoint2; - // assign old points 1 and 2 based on the index of the invalid point - { - // interpolate between oldPoint1 and invalidPoint - // solving for z = 0.1 for the line between oldPoint1 and invalidPoint, - // separately in the xz and yz planes. - double gradX = (oldPoint1.z - invalidPoint.z) / - (oldPoint1.x - invalidPoint.x); - double gradY = (oldPoint1.z - invalidPoint.z) / - (oldPoint1.y - invalidPoint.y); + if (numOfInvalidPoints == 0) { // if there are no invalid points, treat the triangle normally + // project all points in triangle + tris[tri_i].draw(img, zBuf, FPDis, scrX, scrY, ang); + } else if (numOfInvalidPoints == 1) {// if one point is invalid, interpolate 2 new points and draw 2 new triangles: + // find which point is the invalid one TODO could optimise and find this beforehand + int invalidIndex = -1; + for (int i = 0; i < 3; i += 1) { + if (points[trisFaceList[tri_i][i]].getRotatedPoint().z < 0.1) { + invalidIndex = i; + break; + } + } + if (invalidIndex == -1) { + throw new RuntimeException("How did this happen?!"); + } + Point3D oldPoint1 = points[trisFaceList[tri_i][Math.floorMod(invalidIndex + 1, 3)]].getRotatedPoint(); + Point3D oldPoint2 = points[trisFaceList[tri_i][Math.floorMod(invalidIndex + 2, 3)]].getRotatedPoint(); + Point3D invalidPoint = points[trisFaceList[tri_i][invalidIndex]].getRotatedPoint(); + Point3D newPoint1; + Point3D newPoint2; + // assign old points 1 and 2 based on the index of the invalid point + { + // interpolate between oldPoint1 and invalidPoint + // solving for z = 0.1 for the line between oldPoint1 and invalidPoint, + // separately in the xz and yz planes. + double gradX = (oldPoint1.z - invalidPoint.z) / + (oldPoint1.x - invalidPoint.x); + double gradY = (oldPoint1.z - invalidPoint.z) / + (oldPoint1.y - invalidPoint.y); - newPoint1 = new Point3D( - (0.1 + gradX * oldPoint1.x - oldPoint1.z) / gradX, - (0.1 + gradY * oldPoint1.y - oldPoint1.z) / gradY, - 0.1); - if (!Double.isFinite(gradX)) { - newPoint1.x = oldPoint1.x; + newPoint1 = new Point3D( + (0.1 + gradX * oldPoint1.x - oldPoint1.z) / gradX, + (0.1 + gradY * oldPoint1.y - oldPoint1.z) / gradY, + 0.1); + if (!Double.isFinite(gradX)) { + newPoint1.x = oldPoint1.x; + } + if (!Double.isFinite(gradY)) { + newPoint1.y = oldPoint1.y; + } } - if (!Double.isFinite(gradY)) { - newPoint1.y = oldPoint1.y; - } - } - // interpolate between oldPoint2 and invalid point - { - // interpolate between oldPoint2 and invalidPoint - // solving for z = 0.1 for the line between oldPoint2 and invalidPoint, - // separately in the xz and yz planes. - double gradX = (oldPoint2.z - invalidPoint.z) / - (oldPoint2.x - invalidPoint.x); - double gradY = (oldPoint2.z - invalidPoint.z) / - (oldPoint2.y - invalidPoint.y); + // interpolate between oldPoint2 and invalid point + { + // interpolate between oldPoint2 and invalidPoint + // solving for z = 0.1 for the line between oldPoint2 and invalidPoint, + // separately in the xz and yz planes. + double gradX = (oldPoint2.z - invalidPoint.z) / + (oldPoint2.x - invalidPoint.x); + double gradY = (oldPoint2.z - invalidPoint.z) / + (oldPoint2.y - invalidPoint.y); - newPoint2 = new Point3D( - (0.1 + gradX * oldPoint2.x - oldPoint2.z) / gradX, - (0.1 + gradY * oldPoint2.y - oldPoint2.z) / gradY, - 0.1); - if (!Double.isFinite(gradX)) { - newPoint2.x = oldPoint2.x; + newPoint2 = new Point3D( + (0.1 + gradX * oldPoint2.x - oldPoint2.z) / gradX, + (0.1 + gradY * oldPoint2.y - oldPoint2.z) / gradY, + 0.1); + if (!Double.isFinite(gradX)) { + newPoint2.x = oldPoint2.x; + } + if (!Double.isFinite(gradY)) { + newPoint2.y = oldPoint2.y; + } } - if (!Double.isFinite(gradY)) { - newPoint2.y = oldPoint2.y; - } - } - Triangle newTri; - newTri = new Triangle(oldPoint1.project(FPDis, scrX, scrY), newPoint2.project(FPDis, scrX, scrY), newPoint1.project(FPDis, scrX, scrY), - new boolean[]{false, false, false}, - tris[tri_i].texture, - tris[tri_i].perspectiveMappingMatrix); - newTri.draw(img, zBuf, FPDis, scrX, scrY); - newTri = new Triangle(oldPoint1.project(FPDis, scrX, scrY), oldPoint2.project(FPDis, scrX, scrY), newPoint2.project(FPDis, scrX, scrY), - new boolean[]{false, false, false}, - tris[tri_i].texture, - tris[tri_i].perspectiveMappingMatrix); - newTri.draw(img, zBuf, FPDis, scrX, scrY); - } else if (numOfInvalidPoints == 2) { // if two points are invalid, interpolate and draw triangle w/ new points: - int validIndex = -1; - for (int i = 0; i < 3; i += 1) { - if (points[trisFaceList[tri_i][i]].getRotatedPoint().z > 0.1) { - validIndex = i; - break; + Triangle newTri; + newTri = new Triangle(oldPoint1.project(FPDis, scrX, scrY), newPoint2.project(FPDis, scrX, scrY), newPoint1.project(FPDis, scrX, scrY), + new boolean[]{false, false, false}, + tris[tri_i].texture, + tris[tri_i].perspectiveMappingMatrix); + newTri.draw(img, zBuf, FPDis, scrX, scrY, ang); + newTri = new Triangle(oldPoint1.project(FPDis, scrX, scrY), oldPoint2.project(FPDis, scrX, scrY), newPoint2.project(FPDis, scrX, scrY), + new boolean[]{false, false, false}, + tris[tri_i].texture, + tris[tri_i].perspectiveMappingMatrix); + newTri.draw(img, zBuf, FPDis, scrX, scrY, ang); + } else if (numOfInvalidPoints == 2) { // if two points are invalid, interpolate and draw triangle w/ new points: + int validIndex = -1; + for (int i = 0; i < 3; i += 1) { + if (points[trisFaceList[tri_i][i]].getRotatedPoint().z > 0.1) { + validIndex = i; + break; + } } - } - if (validIndex == -1) { - throw new RuntimeException("How did this happen?!"); - } - Point3D invalidPoint1 = points[trisFaceList[tri_i][Math.floorMod(validIndex + 1, 3)]].getRotatedPoint(); - Point3D invalidPoint2 = points[trisFaceList[tri_i][Math.floorMod(validIndex + 2, 3)]].getRotatedPoint(); - Point3D oldPoint = points[trisFaceList[tri_i][validIndex]].getRotatedPoint(); - Point3D newPoint1; - Point3D newPoint2; - // interpolate for z = 0.1 between invalid1 and oldPoint - { - double gradX = (oldPoint.z - invalidPoint1.z) / - (oldPoint.x - invalidPoint1.x); - double gradY = (oldPoint.z - invalidPoint1.z) / - (oldPoint.y - invalidPoint1.y); + if (validIndex == -1) { + throw new RuntimeException("How did this happen?!"); + } + Point3D invalidPoint1 = points[trisFaceList[tri_i][Math.floorMod(validIndex + 1, 3)]].getRotatedPoint(); + Point3D invalidPoint2 = points[trisFaceList[tri_i][Math.floorMod(validIndex + 2, 3)]].getRotatedPoint(); + Point3D oldPoint = points[trisFaceList[tri_i][validIndex]].getRotatedPoint(); + Point3D newPoint1; + Point3D newPoint2; + // interpolate for z = 0.1 between invalid1 and oldPoint + { + double gradX = (oldPoint.z - invalidPoint1.z) / + (oldPoint.x - invalidPoint1.x); + double gradY = (oldPoint.z - invalidPoint1.z) / + (oldPoint.y - invalidPoint1.y); - newPoint1 = new Point3D( - (0.1 + gradX * oldPoint.x - oldPoint.z) / gradX, - (0.1 + gradY * oldPoint.y - oldPoint.z) / gradY, - 0.1); - if (!Double.isFinite(gradX)) { - newPoint1.x = oldPoint.x; + newPoint1 = new Point3D( + (0.1 + gradX * oldPoint.x - oldPoint.z) / gradX, + (0.1 + gradY * oldPoint.y - oldPoint.z) / gradY, + 0.1); + if (!Double.isFinite(gradX)) { + newPoint1.x = oldPoint.x; + } + if (!Double.isFinite(gradY)) { + newPoint1.y = oldPoint.y; + } } - if (!Double.isFinite(gradY)) { - newPoint1.y = oldPoint.y; - } - } - // interpolate for z = 0.1 between invalid2 and oldPoint - { - double gradX = (oldPoint.z - invalidPoint2.z) / - (oldPoint.x - invalidPoint2.x); - double gradY = (oldPoint.z - invalidPoint2.z) / - (oldPoint.y - invalidPoint2.y); + // interpolate for z = 0.1 between invalid2 and oldPoint + { + double gradX = (oldPoint.z - invalidPoint2.z) / + (oldPoint.x - invalidPoint2.x); + double gradY = (oldPoint.z - invalidPoint2.z) / + (oldPoint.y - invalidPoint2.y); - newPoint2 = new Point3D( - (0.1 + gradX * oldPoint.x - oldPoint.z) / gradX, - (0.1 + gradY * oldPoint.y - oldPoint.z) / gradY, - 0.1); - if (!Double.isFinite(gradX)) { - newPoint2.x = oldPoint.x; + newPoint2 = new Point3D( + (0.1 + gradX * oldPoint.x - oldPoint.z) / gradX, + (0.1 + gradY * oldPoint.y - oldPoint.z) / gradY, + 0.1); + if (!Double.isFinite(gradX)) { + newPoint2.x = oldPoint.x; + } + if (!Double.isFinite(gradY)) { + newPoint2.y = oldPoint.y; + } } - if (!Double.isFinite(gradY)) { - newPoint2.y = oldPoint.y; - } - } - // create and draw new triangle - Triangle newTri; - newTri = new Triangle(newPoint1.project(FPDis, scrX, scrY), newPoint2.project(FPDis, scrX, scrY), oldPoint.project(FPDis, scrX, scrY), - new boolean[]{false, false, false}, - tris[tri_i].texture, - tris[tri_i].perspectiveMappingMatrix); - newTri.draw(img, zBuf, FPDis, scrX, scrY); - } // if all points are invalid, do nothing + // create and draw new triangle + Triangle newTri; + newTri = new Triangle(newPoint1.project(FPDis, scrX, scrY), newPoint2.project(FPDis, scrX, scrY), oldPoint.project(FPDis, scrX, scrY), + new boolean[]{false, false, false}, + tris[tri_i].texture, + tris[tri_i].perspectiveMappingMatrix); + newTri.draw(img, zBuf, FPDis, scrX, scrY, ang); + } // if all points are invalid, do nothing + } } + return numberOfPixels; + + } else { + return 0; } - return numberOfPixels; - } + } /* if (valid) { @@ -318,21 +325,28 @@ // too many new variables Point3D point0 = points[0].point; Point3D point1 = points[1].point; - Point3D point2; Vector3D vec1 = new Vector3D(point1.x - point0.x, point1.y - point0.y, point1.z - point0.z); - Vector3D vec2 = new Vector3D(0,0,0); // initialisation otherwise intellij gets mad + Vector3D vec2 = new Vector3D(); // initialisation otherwise intellij gets mad + // find a vector which is not inline with other vectors boolean valid = false; int i = 2; - while(!valid && i < points.length) { - point2 = points[i].point; - vec2 = new Vector3D(point2.x - point0.x, point2.y - point0.y, point2.z - point0.z); + while(!valid && i <= points.length) { + point0 = point1; + point1 = points[Math.floorMod(i, points.length)].point; + + vec2.x = point1.x - point0.x; vec2.y = point1.y - point0.y; vec2.z = point1.z - point0.z; double angle = Math.abs(vec1.angleTo(vec2)); if(angle > 0.1 && angle < 2*Math.PI - 0.1){ // if the angle between the vectors is between a threshold, the two vectors are valid. // else, calculate the second vector using a different set of points. valid = true; - }} - if(!valid){throw new RuntimeException("Could not calculate normal of face");} + } + i += 1; + } + isValid = valid; + if (!isValid){ + int a = 12; + } normal = vec1.cross(vec2); } diff --git a/src/main/java/uk/org/floop/epq3d/JsonReader.java b/src/main/java/uk/org/floop/epq3d/JsonReader.java index c257612..3a34e8e 100644 --- a/src/main/java/uk/org/floop/epq3d/JsonReader.java +++ b/src/main/java/uk/org/floop/epq3d/JsonReader.java @@ -27,7 +27,7 @@ } public void getObjects(){ textures = getTextures((JSONArray) file.get("textures")); - mainCollection = separateCollection((JSONObject) file.get("collections"), textures); + mainCollection = separateCollection((JSONObject) ((JSONArray)file.get("collections")).get(0), textures); file.get("collection"); } private ObjectCollection separateCollection(JSONObject json, Texture[] textures){ @@ -79,9 +79,11 @@ for (int j = 0; j < jsonFace.size(); j += 1){ faceList[i][j] = Integer.parseInt(String.valueOf(jsonFace.get(j))); uvPointsList[i][j] = new Point2D( - Integer.parseInt(String.valueOf(((JSONArray)jsonUV.get(j)).get(0))), - Integer.parseInt(String.valueOf(((JSONArray)jsonUV.get(j)).get(1))) - ); +0,0 + ); +// Integer.parseInt(String.valueOf(((JSONArray)jsonUV.get(j)).get(0))), +// Integer.parseInt(String.valueOf(((JSONArray)jsonUV.get(j)).get(1))) +// ); } // terrible linear search but idc because this code only runs once diff --git a/src/main/java/uk/org/floop/epq3d/Object3d.java b/src/main/java/uk/org/floop/epq3d/Object3d.java index 037a5ef..ee32035 100644 --- a/src/main/java/uk/org/floop/epq3d/Object3d.java +++ b/src/main/java/uk/org/floop/epq3d/Object3d.java @@ -36,11 +36,10 @@ faces) { // check whether faces are pointing towards or away from the camera - Vector3D camVec = new Vector3D(0,0,0); camVec.createFrom2Points(playerPos, face.points[0].point); int numberOfPixels = 0; - if(face.normal.angleTo(camVec) <= Math.PI/2-0.01){ + if(face.normal.angleTo(camVec) >= Math.PI/2-0.01 || true){ numberOfPixels = face.draw(img, zBuf, debugImg, camMatrix, FPDis, scrX, scrY); } debugImg.getGraphics().drawString(iterator + ": " +numberOfPixels , 10, 20 + 10*iterator); diff --git a/src/main/java/uk/org/floop/epq3d/Player.java b/src/main/java/uk/org/floop/epq3d/Player.java index a02f22a..97e4818 100644 --- a/src/main/java/uk/org/floop/epq3d/Player.java +++ b/src/main/java/uk/org/floop/epq3d/Player.java @@ -9,7 +9,6 @@ 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; @@ -19,9 +18,9 @@ protected double Fpdis; 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); + private final Point3D position = new Point3D(0,0,0); + private final Point3D rotation = new Point3D(0,Math.PI / 2, 0); + private final Vector3D direction = new Vector3D(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 @@ -142,9 +141,16 @@ ); // apply izMat to direction vector try { - Point3D dirvec = new Point3D(0,0,0); - izMat.multiplyPoint3to(direction, dirvec); + Vector3D dirvec = new Vector3D(); + izMat.multiplyVec3to(direction, dirvec); + double dirLen = dirvec.getLength(); + if (dirLen != 0) { + dirvec.x = dirvec.x / (dirLen * 40); + dirvec.y = dirvec.y / (dirLen * 40); + dirvec.z = dirvec.z / (dirLen * 40); + } position.translate(dirvec); + } catch (Exception e) { throw new RuntimeException(e); } @@ -172,7 +178,6 @@ // 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 @@ -187,7 +192,6 @@ } // find frustum planes // near plane - //frustumPlanes[0].initFromPointAndVector(position, viewVector); frustumPlanes[0].initFrom3Points(ScreenCornerPosS[0].getRotatedPoint(), ScreenCornerPosS[1].getRotatedPoint(), ScreenCornerPosS[2].getRotatedPoint()); // far plane diff --git a/src/main/java/uk/org/floop/epq3d/Point3D.java b/src/main/java/uk/org/floop/epq3d/Point3D.java index a9e02cc..fef2a1d 100644 --- a/src/main/java/uk/org/floop/epq3d/Point3D.java +++ b/src/main/java/uk/org/floop/epq3d/Point3D.java @@ -34,6 +34,11 @@ y += trVec.y; z += trVec.z; } + public void translate(Vector3D trVec){ + x += trVec.x; + y += trVec.y; + z += trVec.z; + } public Point2D project(double fpdis, int scrX, int scrY){ return new Point2D( scrX - (int)(scrX*0.5*((fpdis*y)/(z) + 1)), diff --git a/src/main/java/uk/org/floop/epq3d/Screen.java b/src/main/java/uk/org/floop/epq3d/Screen.java index 75e4829..67ff83e 100644 --- a/src/main/java/uk/org/floop/epq3d/Screen.java +++ b/src/main/java/uk/org/floop/epq3d/Screen.java @@ -41,7 +41,7 @@ // double ang = 0; // __config variables__ // controls the delay between each tick in ms - private final int DELAY = 25; + private final int DELAY = 1; // controls the size of the board public static final int scrX = 900; public static final int scrY = 600; @@ -149,7 +149,7 @@ ang += 0.02;*/ mainCollection.invalidate(true); - mainCollection.draw(img, zBuf, debugImg, player.camMatrix, player.getPos(), player.frustumPlanes, player.Fpdis, getWidth(), getHeight()); + mainCollection.draw(img, zBuf, debugImg, player.camMatrix, player.getPos(), player.frustumPlanes, player.Fpdis, scrX, scrY); long time = System.currentTimeMillis(); BufferedImage bufImg = new BufferedImage(scrX, scrY, BufferedImage.TYPE_INT_ARGB); for(int x = 0; x < scrX; x +=1){ diff --git a/src/main/java/uk/org/floop/epq3d/Texture.java b/src/main/java/uk/org/floop/epq3d/Texture.java index 617fb4a..1a35076 100644 --- a/src/main/java/uk/org/floop/epq3d/Texture.java +++ b/src/main/java/uk/org/floop/epq3d/Texture.java @@ -13,12 +13,13 @@ public int[][] img; public Color color; - public Texture(String _name, Color _color){ + public Texture(String _name, Color _color) { name = _name; type = "solid"; color = _color; } - public Texture(String _name, String _imgPath){ + + public Texture(String _name, String _imgPath) { name = _name; type = "image"; @@ -26,7 +27,7 @@ File imgFile = new File(_imgPath); try { BufferedImage _img = ImageIO.read(imgFile); - for(int x = 0; x < _img.getWidth(); x +=1) { + for (int x = 0; x < _img.getWidth(); x += 1) { for (int y = 0; y < _img.getHeight(); y += 1) { img[x][y] = _img.getRGB(x, y); } @@ -35,12 +36,21 @@ throw new RuntimeException(e); } } - public boolean isSolid(){ - if (Objects.equals(type, "solid")){ + + public boolean isSolid() { + if (Objects.equals(type, "solid")) { return true; - } - else{ + } else { return false; } } + + public Color getColor(double ang) { + double multiplier = 1 - ang/(2*Math.PI); + int rgb = color.getRGB(); + int r = rgb & 0xff; + int g = (rgb >> 8) & 0xff; + int b = (rgb >> 16) & 0xff; + return new Color((int) (r*multiplier), (int) (g*multiplier), (int) (b*multiplier)); + } } diff --git a/src/main/java/uk/org/floop/epq3d/Triangle.java b/src/main/java/uk/org/floop/epq3d/Triangle.java index 902f69a..a719072 100644 --- a/src/main/java/uk/org/floop/epq3d/Triangle.java +++ b/src/main/java/uk/org/floop/epq3d/Triangle.java @@ -36,7 +36,7 @@ perspectiveMappingMatrix = mapMatrix; } // returns int for debug - public int draw(int[][] img, int[][] zBuf, double FPDis, int scrX, int scrY){ + public int draw(int[][] img, int[][] zBuf, double FPDis, int scrX, int scrY, double ang){ // long lastMillis; @@ -55,7 +55,7 @@ point1[0] > 0 && point1[1] > 0 && point1[0] < scrX && point1[1] < scrY){ img[point1[0]][point1[1]] = Color.HSBtoRGB(0, 1, 1); } - try { // this error seems to be thrown randomly, for various reasons // todo fix + try { point1 = LineLong.nextPix(); } catch (Exception e){ @@ -92,11 +92,11 @@ if (point1[1] < point2[1]) { for (int y = Math.max(point1[1], 0); y <= Math.min(point2[1], scrY - 1); y += 1) { // function only exists so I don't have to copy paste code everywhere. - drawPix(img, zBuf, FPDis, scrX, scrY, currentLine, x, y, point1[1], point2[1]); + drawPix(img, zBuf, FPDis, scrX, scrY, currentLine, x, y, point1[1], point2[1], ang); } } else { for (int y = Math.max(point2[1], 0); y <= Math.min(point1[1], scrY - 1); y += 1) { - drawPix(img, zBuf, FPDis, scrX, scrY, currentLine, x,y, point1[1], point2[1]); + drawPix(img, zBuf, FPDis, scrX, scrY, currentLine, x,y, point1[1], point2[1], ang); } } } @@ -149,7 +149,7 @@ // assign points to lines is_initialised = true; } - private void drawPix(int[][] img, int[][] zBuf, double FPDis, int scrX, int scrY, char currentLine, int x, int y, int y1, int y2){ + private void drawPix(int[][] img, int[][] zBuf, double FPDis, int scrX, int scrY, char currentLine, int x, int y, int y1, int y2, double ang){ // find Z coordinate of pixel double z1 = LineLong.getZVal(x); double z2; if(currentLine=='A'){z2=LineA.getZVal(x);} else{z2=LineB.getZVal(x);} @@ -167,7 +167,7 @@ // project result Color pixColor; if(texture.isSolid()){ - pixColor = texture.color; + pixColor = texture.getColor(ang); } else { throw new RuntimeException("Textures are not supported"); } diff --git a/src/main/java/uk/org/floop/epq3d/Vector3D.java b/src/main/java/uk/org/floop/epq3d/Vector3D.java index 735a1ec..ecfa94a 100644 --- a/src/main/java/uk/org/floop/epq3d/Vector3D.java +++ b/src/main/java/uk/org/floop/epq3d/Vector3D.java @@ -24,11 +24,18 @@ 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) - /( //----------------------------------------------------------- - 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)))); + double num = dot(vec2) / + (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))); + if (-1