diff --git a/EPQ 3D renderer.iml b/EPQ 3D renderer.iml
index e9c3f97..50eaffd 100644
--- a/EPQ 3D renderer.iml
+++ b/EPQ 3D renderer.iml
@@ -13,5 +13,6 @@
+
\ No newline at end of file
diff --git a/Grass block.png b/Grass block.png
new file mode 100644
index 0000000..2e08778
--- /dev/null
+++ b/Grass block.png
Binary files differ
diff --git a/config.json b/config.json
index 3a39d53..813c394 100644
--- a/config.json
+++ b/config.json
@@ -10,8 +10,8 @@
"__comment":"values are: enabled/disabled",
"masterDebugToggle":"enabled",
"drawDebugHud":"disabled",
- "drawLines":"disabled",
- "overrideBackFaceCulling":"disabled",
+ "drawLines":"false",
+ "overrideBackFaceCulling":"enabled",
"frustumCullingOverridePercent":0,
"drawZBuffer":"disabled"
}
diff --git a/jsonCollections.json b/jsonCollections.json
new file mode 100644
index 0000000..9fa75bc
--- /dev/null
+++ b/jsonCollections.json
@@ -0,0 +1 @@
+{"collections": [{"name": "MainCollection", "subCollections": [], "objects": [{"name": "Cube", "position": [0.0, 0.0, 0.0], "rotation": [0.0, 0.0, 0.0], "scale": [1.0, 1.0, 1.0], "points": [[-1.0, -1.0, -1.0], [-1.0, -1.0, 1.0], [-1.0, 1.0, -1.0], [-1.0, 1.0, 1.0], [1.0, -1.0, -1.0], [1.0, -1.0, 1.0], [1.0, 1.0, -1.0], [1.0, 1.0, 1.0], [-1.0, -1.0, 3.2648987770080566], [-1.0, 1.0, 3.2648987770080566], [1.0, -1.0, 3.2648987770080566], [1.0, 1.0, 3.2648987770080566], [0.0, 0.0, 5.255918979644775]], "faceList": [[0, 1, 3, 2], [2, 3, 7, 6], [6, 7, 5, 4], [4, 5, 1, 0], [2, 6, 4, 0], [7, 3, 1, 5], [11, 10, 8, 9], [11, 9, 12], [10, 11, 12], [9, 8, 12], [8, 10, 12]], "uvPointsList": [[1.0000001192092896, 0.3333333134651184], [1.0000001192092896, 0.6666666865348816], [0.75, 0.6666666865348816], [0.75, 0.3333333134651184], [0.75, 0.3333333134651184], [0.75, 0.6666666865348816], [0.5, 0.6666666865348816], [0.5, 0.3333333134651184], [0.5, 0.3333333134651184], [0.5, 0.6666666865348816], [0.2499999850988388, 0.6666666865348816], [0.2499999850988388, 0.3333333134651184], [0.2499999850988388, 0.3333333134651184], [0.2499999850988388, 0.6666666865348816], [0.0, 0.6666666865348816], [0.0, 0.3333333134651184], [0.5, 0.0], [0.5, 0.3333333134651184], [0.2499999850988388, 0.3333333134651184], [0.2499999850988388, 0.0], [0.5, 0.6666666865348816], [0.5, 1.0], [0.24999994039535522, 1.0], [0.2499999850988388, 0.6666666865348816], [0.5, 0.6666666865348816], [0.2499999850988388, 0.6666666865348816], [0.24999994039535522, 1.0], [0.5, 1.0], [0.5, 0.6666666865348816], [0.5, 1.0], [0.5, 0.6666666865348816], [0.2499999850988388, 0.6666666865348816], [0.5, 0.6666666865348816], [0.2499999850988388, 0.6666666865348816], [0.5, 1.0], [0.24999994039535522, 1.0], [0.5, 1.0], [0.24999994039535522, 1.0], [0.2499999850988388, 0.6666666865348816], [0.24999994039535522, 1.0]], "textureList": ["Material.002", "Material.002", "Material.002", "Material.002", "Material.002", "Material.002", "Material.002", "Material.002", "Material.002", "Material.002", "Material.002"]}]}]}
\ No newline at end of file
diff --git a/jsonTextures.json b/jsonTextures.json
new file mode 100644
index 0000000..ca60de7
--- /dev/null
+++ b/jsonTextures.json
@@ -0,0 +1,3 @@
+{"textures": [{"name": "Dots Stroke", "type": "solid", "color": "cccccc", "imgPath": "/"}, {"name": "Material", "type": "solid", "color": "cccccc", "imgPath": "/"},
+{"name": "Material.002", "type": "image", "color": "cccccc", "imgPath": "Grass block.png"},
+{"name": "Material.001", "type": "image", "color": "cccccc", "imgPath": "Grass block.png"}]}
diff --git a/src/main/java/uk/org/floop/epq3d/Face.java b/src/main/java/uk/org/floop/epq3d/Face.java
index ea4214c..d04e317 100644
--- a/src/main/java/uk/org/floop/epq3d/Face.java
+++ b/src/main/java/uk/org/floop/epq3d/Face.java
@@ -4,7 +4,7 @@
public class Face {
public PointComp[] points;
- public Point2D[] UVPoints;
+ public double[][] UVPoints;
public Vector3D normal;
public double boundingSphereR;
@@ -92,11 +92,13 @@
bakePerspectiveMatrices(drawData);
// if all the points are valid (in front of the camera) draw all tris normally.
+ double lastTime = System.currentTimeMillis();
if (valid) {
for (Triangle tri :
tris) {
tri.draw(drawData, ang);
}
+ drawData.timeSpentDrawingNormalFaces += System.currentTimeMillis() - lastTime;
} else {
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)
@@ -124,8 +126,8 @@
PointComp oldPoint1 = points[trisFaceList[tri_i][Math.floorMod(invalidIndex + 1, 3)]];
PointComp oldPoint2 = points[trisFaceList[tri_i][Math.floorMod(invalidIndex + 2, 3)]];
PointComp invalidPoint = points[trisFaceList[tri_i][invalidIndex]];
- PointComp newPoint1 = new PointComp();
- PointComp newPoint2 = new PointComp();
+ PointComp newPoint1;
+ PointComp newPoint2;
// assign old points 1 and 2 based on the index of the invalid point
// interpolate between oldPoint1 and invalidPoint
newPoint1 = interpolate(drawData, frustumInfo, oldPoint1, invalidPoint);
@@ -137,13 +139,11 @@
Triangle newTri;
newTri = new Triangle(oldPoint1, newPoint2, newPoint1,
new boolean[]{false, false, false},
- tris[tri_i].texture,
- tris[tri_i].perspectiveMappingMatrix);
+ tris[tri_i].texture);
newTri.draw(drawData, ang);
newTri = new Triangle(oldPoint1, oldPoint2, newPoint2,
new boolean[]{false, false, false},
- tris[tri_i].texture,
- tris[tri_i].perspectiveMappingMatrix);
+ tris[tri_i].texture);
newTri.draw(drawData, ang);
} else if (numOfInvalidPoints == 2) { // if two points are invalid, interpolate and draw triangle w/ new points:
int validIndex = -1;
@@ -174,51 +174,46 @@
Triangle newTri;
newTri = new Triangle(newPoint1, newPoint2, oldPoint,
new boolean[]{false, false, false},
- tris[tri_i].texture,
- tris[tri_i].perspectiveMappingMatrix);
+ tris[tri_i].texture);
newTri.draw(drawData, ang);
}
} // if all points are invalid, do nothing
}
+ drawData.timeSpentChoppingFaces += System.currentTimeMillis() - lastTime;
}
}
private PointComp interpolate(drawData drawData, ArrayList frustumInfo, PointComp oldPoint, PointComp invalidPoint){
- // calculate distance to each of the frustum planes. Then store the minimum distance from each of
- double minDis = 0;
- int planeMin = 0;
- for (int planeId:
- frustumInfo) {
- // don't check the near plane
- if(planeId != 0) {
- double dist = drawData.frustumPlanes[planeId].getDistance(invalidPoint.getRotatedPoint());
- if (minDis > dist) {
- minDis = dist;
- planeMin = planeId;
- }
- }
- }
- /* if the minimum distance is less than zero:
- Find the z difference between oldPoint and invalidPoint
- Find the distance from the oldPoint to the plane with that value
- Add this distance to the minDis we found earlier
- divide minDis by this number
- multiply by the Z difference between oldPoint and invalidPoint
- */
- double interpolateZval = 0.01;
- if(minDis < 0 && false){
- interpolateZval = Math.max(interpolateZval,
- (oldPoint.getRotatedPoint().z - invalidPoint.getRotatedPoint().z)*minDis/
- (drawData.frustumPlanes[planeMin].getDistance(oldPoint.getRotatedPoint()) + minDis));
- }
+// // calculate distance to each of the frustum planes. Then store the minimum distance from each of
+// double minDis = 0;
+// int planeMin = 0;
+// for (int planeId:
+// frustumInfo) {
+// // don't check the near plane
+// if(planeId != 0) {
+// double dist = drawData.frustumPlanes[planeId].getDistance(invalidPoint.getRotatedPoint());
+// if (minDis > dist) {
+// minDis = dist;
+// planeMin = planeId;
+// }
+// }
+// }
+ double interpolateZVal = 0.1;
+// if(minDis < 0){
+// Vector3D oldNew = new Vector3D(oldPoint.getRotatedPoint(), invalidPoint.getRotatedPoint());
+// double pointDis = oldNew.getLength();
+// double fraction = -minDis / pointDis;
+// double newZ = (oldPoint.getRotatedPoint().z - invalidPoint.getRotatedPoint().z)*fraction - invalidPoint.getRotatedPoint().z;
+// interpolateZVal = Math.max(interpolateZVal, newZ);
+// }
double gradX = (oldPoint.getRotatedPoint().z - invalidPoint.getRotatedPoint().z) /
(oldPoint.getRotatedPoint().x - invalidPoint.getRotatedPoint().x);
double gradY = (oldPoint.getRotatedPoint().z - invalidPoint.getRotatedPoint().z) /
(oldPoint.getRotatedPoint().y - invalidPoint.getRotatedPoint().y);
Point3D newPointRotated = new Point3D(
- (interpolateZval + gradX * oldPoint.getRotatedPoint().x - oldPoint.getRotatedPoint().z) / gradX,
- (interpolateZval + gradY * oldPoint.getRotatedPoint().y - oldPoint.getRotatedPoint().z) / gradY,
- interpolateZval);
+ (interpolateZVal + gradX * oldPoint.getRotatedPoint().x - oldPoint.getRotatedPoint().z) / gradX,
+ (interpolateZVal + gradY * oldPoint.getRotatedPoint().y - oldPoint.getRotatedPoint().z) / gradY,
+ interpolateZVal);
if (!Double.isFinite(gradX)) {
newPointRotated.x = oldPoint.getRotatedPoint().x;
}
@@ -327,8 +322,11 @@
points[0],
points[i + 1],
points[i + 2],
+ UVPoints[0],
+ UVPoints[i+1],
+ UVPoints[i+2],
new boolean[]{hasEdges, hasEdges, hasEdges},
- texture, perspectiveMappingMatrices[i]);
+ texture);
}
tris = newTris;
trisFaceList = newTrisFaceList;
@@ -379,7 +377,8 @@
Matrix uvTo00 = new Matrix(4, 4);
uvTo00.setItems(new double[][]{{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}});
{
- vOrig.createFrom2Points(UVPoints[tri[0]], UVPoints[tri[1]]);
+ vOrig.x = UVPoints[tri[1]][0] - UVPoints[tri[0]][0];
+ vOrig.y = UVPoints[tri[1]][1] - UVPoints[tri[0]][1];
double rotAng = -vOrig.angleTo(vFin);
// set to rotation
MultMat.setItems(new double[][]{
@@ -401,8 +400,8 @@
uvTo00.multiply(MultMat);
// set to translation
MultMat.setItems(new double[][]{
- {1, 0, 0, -UVPoints[tri[0]].x},
- {0, 1, 0, -UVPoints[tri[0]].y},
+ {1, 0, 0, -UVPoints[tri[0]][0]},
+ {0, 1, 0, -UVPoints[tri[0]][1]},
{0, 0, 1, 0},
{0, 0, 0, 1},
});
@@ -485,7 +484,7 @@
pointFace.set(faceTo00.multiplyPoint3raw(points[tri[2]].point.x, points[tri[2]].point.y, points[tri[2]].point.z));
Point3D pointUV = new Point3D();
- pointUV.set(uvTo00.multiplyPoint3raw(UVPoints[tri[2]].x, UVPoints[tri[2]].y, 0));
+ pointUV.set(uvTo00.multiplyPoint3raw(UVPoints[tri[2]][0], UVPoints[tri[2]][1], 0));
double xScale = pointUV.x / pointFace.x;
//System.out.println("Scale: " + xScale);
diff --git a/src/main/java/uk/org/floop/epq3d/JsonReader.java b/src/main/java/uk/org/floop/epq3d/JsonReader.java
index 18082ec..8ef4d7c 100644
--- a/src/main/java/uk/org/floop/epq3d/JsonReader.java
+++ b/src/main/java/uk/org/floop/epq3d/JsonReader.java
@@ -72,15 +72,15 @@
JSONArray texturesNamesJson = (JSONArray) object.get("textureList");
int[][] faceList = new int[faceListJson.size()][];
- Point2D[][] uvPointsList = new Point2D[faceListJson.size()][];
+ double[][][] uvPointsList = new double[faceListJson.size()][][];
Texture[] texturesList = new Texture[faceListJson.size()];
-
+ int uvIndex = 0;
for (int i = 0; i < faceListJson.size(); i+=1) {
JSONArray jsonFace = (JSONArray) faceListJson.get(i);
String jsonTextureName = (String) texturesNamesJson.get(i);
faceList[i] = new int[jsonFace.size()];
- uvPointsList[i] = new Point2D[jsonFace.size()];
+ uvPointsList[i] = new double[jsonFace.size()][];
// probably inefficient linear search but idc because this code only runs once
for (Texture texture : textures) {
if (Objects.equals(texture.name, jsonTextureName)) {
@@ -91,10 +91,11 @@
for (int j = 0; j < jsonFace.size(); j += 1){
faceList[i][j] = (int)(long)jsonFace.get(j);
if(!texturesList[i].isSolid()){
- uvPointsList[i][j] = new Point2D(
- (int)(double)((JSONArray)uvPointsListJson.get(faceList[i][j])).get(0),
- (int)(double)((JSONArray)uvPointsListJson.get(faceList[i][j])).get(1));
+ uvPointsList[i][j] = new double[2];
+ uvPointsList[i][j][0] = (double)((JSONArray)uvPointsListJson.get(uvIndex)).get(0);
+ uvPointsList[i][j][1] = (double)((JSONArray)uvPointsListJson.get(uvIndex)).get(1);
}
+ uvIndex += 1;
}
}
@@ -108,7 +109,8 @@
JSONObject JsonTexture = (JSONObject) textures.get(i);
if(Objects.equals(JsonTexture.get("type"), "solid")){
result[i] = new Texture(JsonTexture.get("name").toString(), Color.decode('#' + (String) JsonTexture.get("color")));
- //result[i] = new Texture(JsonTexture.get("name").toString(), Color.decode('#' + "0000ff"));
+ } else if(Objects.equals(JsonTexture.get("type"), "image")){
+ result[i] = new Texture(JsonTexture.get("name").toString(), Color.decode('#' + (String) JsonTexture.get("color")), (String) JsonTexture.get("imgPath"));
}
}
return result;
diff --git a/src/main/java/uk/org/floop/epq3d/Line2d.java b/src/main/java/uk/org/floop/epq3d/Line2d.java
index 1e027ae..6e7cb47 100644
--- a/src/main/java/uk/org/floop/epq3d/Line2d.java
+++ b/src/main/java/uk/org/floop/epq3d/Line2d.java
@@ -7,6 +7,8 @@
public class Line2d {
public PointComp point1;
public PointComp point2;
+ public double[] UVPoint1;
+ public double[] UVPoint2;
public boolean isDrawn;
@@ -23,9 +25,11 @@
// drawing progress variables
private int iteratorVal;
private int D;
- public Line2d(PointComp _point1, PointComp _point2, boolean _isDrawn){
+ public Line2d(PointComp _point1, PointComp _point2, double[] _UVPoint1, double[] _UVPoint2, boolean _isDrawn){
point1 = _point1;
point2 = _point2;
+ UVPoint1 = _UVPoint1;
+ UVPoint2 = _UVPoint2;
isDrawn = _isDrawn;
}
/**
diff --git a/src/main/java/uk/org/floop/epq3d/Matrix.java b/src/main/java/uk/org/floop/epq3d/Matrix.java
index 5a3c9ff..621f006 100644
--- a/src/main/java/uk/org/floop/epq3d/Matrix.java
+++ b/src/main/java/uk/org/floop/epq3d/Matrix.java
@@ -123,11 +123,11 @@
public double[] multiplyPoint2raw(double px, double py) {
double[] result = new double[2];
if(x==2){
- result[0] = (int)(px * getItem(0,0) + py* getItem(1,0));
- result[1] = (int)(px * getItem(0,1) + py* getItem(1,1));
+ result[0] = (px * getItem(0,0) + py* getItem(1,0));
+ result[1] = (px * getItem(0,1) + py* getItem(1,1));
} else if(x==3){
- result[0] = (int)(px * getItem(0,0) + py* getItem(1,0) + getItem(2,0));
- result[1] = (int)(px * getItem(0,1) + py* getItem(1,1) + getItem(2,1));
+ result[0] = (px * getItem(0,0) + py* getItem(1,0) + getItem(2,0));
+ result[1] = (px * getItem(0,1) + py* getItem(1,1) + getItem(2,1));
} else {throw new RuntimeException("wrong-dimensions");}
return result;
}
diff --git a/src/main/java/uk/org/floop/epq3d/Object3d.java b/src/main/java/uk/org/floop/epq3d/Object3d.java
index bc3fc5d..0d8b1c2 100644
--- a/src/main/java/uk/org/floop/epq3d/Object3d.java
+++ b/src/main/java/uk/org/floop/epq3d/Object3d.java
@@ -5,7 +5,7 @@
public class Object3d {
public PointComp[] points;
public int[][] faceList;
- public Point2D[][] uvPoints;
+ public double[][][] uvPoints;
public Face[] faces;
public Point3D boundingSphereC;
@@ -13,7 +13,7 @@
public boolean hasEdges;
public Texture[] textures;
- public Object3d(PointComp[] _points, int[][] _faceList, Point2D[][] _uvPoints, boolean _hasEdges, Texture[] _textures, boolean initialise) {
+ public Object3d(PointComp[] _points, int[][] _faceList, double[][][] _uvPoints, boolean _hasEdges, Texture[] _textures, boolean initialise) {
points = _points;
faceList = _faceList;
uvPoints = _uvPoints;
diff --git a/src/main/java/uk/org/floop/epq3d/Screen.java b/src/main/java/uk/org/floop/epq3d/Screen.java
index 6d3d851..7f88312 100644
--- a/src/main/java/uk/org/floop/epq3d/Screen.java
+++ b/src/main/java/uk/org/floop/epq3d/Screen.java
@@ -147,7 +147,7 @@
// DEBUG DRAWING
{
//debugImg.getGraphics().drawString(Math.round(1000 / (float) (System.currentTimeMillis() - lastTime)) + " fps", 10, 10);
- drawData.debugImg.getGraphics().drawString("FrameTime: " + (System.currentTimeMillis() - lastTime) + " millis", 10, 10);
+ drawData.debugImg.getGraphics().drawString(f"FrameTime: " + (System.currentTimeMillis() - lastTime) + " millis", 10, 10);
if(drawData.debugHud) {
drawData.debugImg.getGraphics().drawString("fpPos: " +
String.format("%.2f", player.FPWorldPos.x) + " " +
@@ -200,6 +200,10 @@
}
}
}
+ //System.out.println(drawData.timeSpentChoppingFaces + ", " + drawData.timeSpentDrawingNormalFaces);
+ drawData.timeSpentChoppingFaces = 0;
+ drawData.timeSpentDrawingNormalFaces = 0;
+
// HTTPPost post = new HTTPPost();
// // json WRITING
// json = new JsonWriter();
diff --git a/src/main/java/uk/org/floop/epq3d/Texture.java b/src/main/java/uk/org/floop/epq3d/Texture.java
index 40b3ded..5d256f9 100644
--- a/src/main/java/uk/org/floop/epq3d/Texture.java
+++ b/src/main/java/uk/org/floop/epq3d/Texture.java
@@ -19,14 +19,16 @@
color = _color;
}
- public Texture(String _name, String _imgPath) {
+ public Texture(String _name, Color _color, String _imgPath) {
name = _name;
type = "image";
-
+ color = _color;
// grab file and pack it into a list[][] int (gives better performance than a BufferedImage by a _lot_
- File imgFile = new File(_imgPath);
+ String path = System.getProperty("user.dir") + "/" + _imgPath;
+ File imgFile = new File(path);
try {
BufferedImage _img = ImageIO.read(imgFile);
+ img = new int[_img.getWidth()][_img.getHeight()];
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);
@@ -56,4 +58,15 @@
(int) (Math.min(255, (g + 255*(multiplier-1)) * multiplier - 255*(multiplier-1))),
(int) (Math.min(255, (b + 255*(multiplier-1)) * multiplier - 255*(multiplier-1))));
}
+ public Color getColor(double ang, int x, int y) {
+ double multiplier = 1.5 - ang/(Math.PI);
+ int rgb = img[x][y];
+ int r = (rgb >> 16) & 0xff;
+ int g = (rgb >> 8) & 0xff;
+ int b = rgb & 0xff;
+ return new Color(
+ (int) (Math.min(255, (r + 255*(multiplier-1)) * multiplier - 255*(multiplier-1))),
+ (int) (Math.min(255, (g + 255*(multiplier-1)) * multiplier - 255*(multiplier-1))),
+ (int) (Math.min(255, (b + 255*(multiplier-1)) * multiplier - 255*(multiplier-1))));
+ }
}
diff --git a/src/main/java/uk/org/floop/epq3d/Triangle.java b/src/main/java/uk/org/floop/epq3d/Triangle.java
index 1cd3ef2..f05ae28 100644
--- a/src/main/java/uk/org/floop/epq3d/Triangle.java
+++ b/src/main/java/uk/org/floop/epq3d/Triangle.java
@@ -6,8 +6,14 @@
public PointComp point1;
public PointComp point2;
public PointComp point3;
+ public double[] UVPoint1;
+ public double[] UVPoint2;
+ public double[] UVPoint3;
- public Matrix[] perspectiveMappingMatrix;
+ public Matrix textureMappingMatrix;
+ public Matrix uvTo00;
+ public Matrix uvTo00_inv;
+
public boolean[] edgeList; //edge 1-2 , 2-3, 3-1
@@ -16,26 +22,78 @@
private Line2d LineB;
public Texture texture;
+ public boolean isTextured;
// initialisation variables
private boolean is_initialised = false;
private Point2D min;
private Point2D max;
private Point2D startPoint;
- private double xGradient;
- private double yGradient;
+ private double xzGradient;
+ private double yzGradient;
+
private final Point2D result2 = new Point2D(0,0);
public void invalidate() {
is_initialised = false;
}
- public Triangle(PointComp _pA, PointComp _pB, PointComp _pC, boolean[] _edgeList, Texture _texture, Matrix[] mapMatrix){
+ public Triangle(PointComp _pA, PointComp _pB, PointComp _pC, boolean[] _edgeList, Texture _texture){
+ isTextured = false;
point1 = _pA;
point2 = _pB;
point3 = _pC;
edgeList = _edgeList;
texture = _texture;
- perspectiveMappingMatrix = mapMatrix;
+ }
+ public Triangle(PointComp _pA, PointComp _pB, PointComp _pC, double[] _uvA, double[] _uvB, double[] _uvC, boolean[] _edgeList, Texture _texture){
+ isTextured = !_texture.isSolid();
+ point1 = _pA;
+ point2 = _pB;
+ point3 = _pC;
+ UVPoint1 = _uvA;
+ UVPoint2 = _uvB;
+ UVPoint3 = _uvC;
+ edgeList = _edgeList;
+ texture = _texture;
+ // temporary object for multiplying
+ Matrix MultMat = new Matrix(3, 3);
+ // temporary unit up vector for reference
+ Vector2D vFin = new Vector2D(0, 1);
+ // temporary vector representing a vector between two points on the uv / triangle
+ Vector2D vOrig = new Vector2D(0, 0);
+ // calculate uvTo00 matrix
+ // uvTo00 takes the uv's point 1 to 0,0 with its point 2 at 0,1 (rotated, translated and scaled)
+ uvTo00 = new Matrix(3, 3);
+ uvTo00.setItems(new double[][]{{1, 0, 0}, {0, 1, 0}, {0, 0, 1}});
+ {
+ vOrig.x = (UVPoint2[0] - UVPoint1[0]) ;
+ vOrig.y = (UVPoint2[1] - UVPoint1[1]);
+ double rotAng = -vOrig.angleTo(vFin);
+ // set to rotation
+ MultMat.setItems(new double[][]{
+ {Math.cos(rotAng), Math.sin(rotAng), 0},
+ {-Math.sin(rotAng), Math.cos(rotAng), 0},
+ {0, 0, 1},
+ });
+ uvTo00.multiply(MultMat);
+
+ double scaleFac = 1 / vOrig.getLength();
+ // set to scaling
+ MultMat.setItems(new double[][]{
+ {scaleFac, 0, 0},
+ {0, scaleFac, 0},
+ {0, 0, 1},
+ });
+ uvTo00.multiply(MultMat);
+ // set to translation
+ MultMat.setItems(new double[][]{
+ {1, 0, -UVPoint1[0]},
+ {0, 1, -UVPoint1[1]},
+ {0, 0, 1},
+ });
+ uvTo00.multiply(MultMat);
+ uvTo00_inv = uvTo00.getInverse();
+ }
}
// returns int for debug
public int draw(drawData drawData, double ang){
@@ -121,7 +179,6 @@
return 0;
}
public boolean initialise(drawData drawData){
-
if (point1 == null || point2 == null || point3 == null){
throw new NullPointerException();
}
@@ -143,35 +200,35 @@
// and then assign line A and line B in order
if (point1.getProjectedPoint().x == min.x) {
if (point2.getProjectedPoint().x == max.x){
- LineLong = new Line2d(point1, point2, edgeList[0]);
- LineA = new Line2d(point1, point3, edgeList[2]);
- LineB = new Line2d(point3, point2, edgeList[1]);
+ LineLong = new Line2d(point1, point2, UVPoint1, UVPoint2, edgeList[0]);
+ LineA = new Line2d(point1, point3, UVPoint1, UVPoint3, edgeList[2]);
+ LineB = new Line2d(point3, point2, UVPoint3, UVPoint2, edgeList[1]);
} else {
- LineLong = new Line2d(point1, point3, edgeList[2]);
- LineA = new Line2d(point1, point2, edgeList[0]);
- LineB = new Line2d(point2, point3, edgeList[1]);
+ LineLong = new Line2d(point1, point3, UVPoint1, UVPoint3, edgeList[2]);
+ LineA = new Line2d(point1, point2, UVPoint1, UVPoint2, edgeList[0]);
+ LineB = new Line2d(point2, point3, UVPoint2, UVPoint3, edgeList[1]);
}
}
else if (point2.getProjectedPoint().x == min.x) {
if (point1.getProjectedPoint().x == max.x) {
- LineLong = new Line2d(point2, point1, edgeList[0]);
- LineA = new Line2d(point2, point3, edgeList[1]);
- LineB = new Line2d(point3, point1, edgeList[2]);
+ LineLong = new Line2d(point2, point1, UVPoint2, UVPoint1, edgeList[0]);
+ LineA = new Line2d(point2, point3, UVPoint2, UVPoint3, edgeList[1]);
+ LineB = new Line2d(point3, point1, UVPoint3, UVPoint1, edgeList[2]);
} else {
- LineLong = new Line2d(point2, point3, edgeList[1]);
- LineA = new Line2d(point2, point1, edgeList[0]);
- LineB = new Line2d(point1, point3, edgeList[2]);
+ LineLong = new Line2d(point2, point3, UVPoint2, UVPoint3, edgeList[1]);
+ LineA = new Line2d(point2, point1, UVPoint2, UVPoint1, edgeList[0]);
+ LineB = new Line2d(point1, point3, UVPoint1, UVPoint3, edgeList[2]);
}
}
else if (point3.getProjectedPoint().x == min.x){
if (point1.getProjectedPoint().x == max.x) {
- LineLong = new Line2d(point3, point1, edgeList[2]);
- LineA = new Line2d(point3, point2, edgeList[1]);
- LineB = new Line2d(point2, point1, edgeList[0]);
+ LineLong = new Line2d(point3, point1, UVPoint3, UVPoint1, edgeList[2]);
+ LineA = new Line2d(point3, point2, UVPoint3, UVPoint2, edgeList[1]);
+ LineB = new Line2d(point2, point1, UVPoint2, UVPoint1, edgeList[0]);
} else {
- LineLong = new Line2d(point3, point2, edgeList[2]);
- LineA = new Line2d(point3, point1, edgeList[1]);
- LineB = new Line2d(point1, point2, edgeList[0]);
+ LineLong = new Line2d(point3, point2, UVPoint3, UVPoint2, edgeList[2]);
+ LineA = new Line2d(point3, point1, UVPoint3, UVPoint1,edgeList[1]);
+ LineB = new Line2d(point1, point2, UVPoint1, UVPoint2, edgeList[0]);
}
}
// find z calculation constants
@@ -192,28 +249,85 @@
);
// calculate the cross product of these two vectors in order to obtain a normal vector
Vector3D cross = vec1.cross(vec2);
- // find xGradient and yGradient for the triangle, in terms of z. We take the negative reciprocal of these gradients, because of the normal vector.
- xGradient = -cross.x / cross.z;
- yGradient = -cross.y / cross.z;
- if(!Double.isFinite(xGradient)){
- xGradient = 0;
+ // find xzGradient and yzGradient for the triangle, in terms of z. We take the negative reciprocal of these gradients, because of the normal vector.
+ xzGradient = -cross.x / cross.z;
+ yzGradient = -cross.y / cross.z;
+ if(!Double.isFinite(xzGradient)){
+ xzGradient = 0;
}
- if(!Double.isFinite(yGradient)){
- yGradient = 0;
+ if(!Double.isFinite(yzGradient)) {
+ yzGradient = 0;
}
+ // if the triangle is textured, calculate a matrix to apply the texture
+ if(isTextured) {
+ // temporary object for multiplying
+ Matrix MultMat = new Matrix(3, 3);
+ // temporary unit up vector for reference
+ Vector2D vFin = new Vector2D(0, 1);
+ // temporary vector representing a vector between two points on the uv / triangle
+ Vector2D vOrig = new Vector2D(0, 0);
+ // calculate triTo00 matrix
+ // triTo00 takes the triangle's point 1 to 0,0 with its point 2 at 0,1 (rotated, translated and scaled)
+ Matrix faceTo00 = new Matrix(3, 3);
+ faceTo00.setItems(new double[][]{{1, 0, 0}, {0, 1, 0}, {0, 0, 1}});
+ {
+ vOrig.createFrom2Points(point1.getProjectedPoint(), point2.getProjectedPoint());
+ double rotAng = -vOrig.angleTo(vFin);
+ // set to rotation
+ MultMat.setItems(new double[][]{
+ {Math.cos(rotAng), Math.sin(rotAng), 0},
+ {-Math.sin(rotAng), Math.cos(rotAng), 0},
+ {0, 0, 1},
+ });
+ faceTo00.multiply(MultMat);
-// double testZ2 = LineLong.point2.getProjectedPoint().z;
-// double testZ = refPoint.getProjectedPoint().z +
-// xGradient * (LineLong.point2.getProjectedPoint().x-refPoint.getProjectedPoint().x) +
-// yGradient * (LineLong.point2.getProjectedPoint().y-refPoint.getProjectedPoint().y);
+ double scaleFac = 1 / vOrig.getLength();
+ // set to scaling
+ MultMat.setItems(new double[][]{
+ {scaleFac, 0, 0},
+ {0, scaleFac, 0},
+ {0, 0, 1},
+ });
+ faceTo00.multiply(MultMat);
+ // set to translation
+ MultMat.setItems(new double[][]{
+ {1, 0, -point1.getProjectedPoint().x},
+ {0, 1, -point1.getProjectedPoint().y},
+ {0, 0, 1},
+ });
+ faceTo00.multiply(MultMat);
+ // next, modify the faceTo00 matrix to scale and shear such that point 3 matches up with UV point 3.
+ {
+ // first, apply the calculated matrices to their respective point 3s
+ double[] pointFace = faceTo00.multiplyPoint2raw(
+ point3.getProjectedPoint().x,
+ point3.getProjectedPoint().y
+ );
+ double[] pointUV = (uvTo00.multiplyPoint2raw(UVPoint3[0], UVPoint3[1]));
- double testZ2 = LineA.point2.getProjectedPoint().z;
+ double xScale = pointUV[0] / pointFace[0];
+ MultMat.setItems(new double[][]{
+ {xScale, 0, 0},
+ {0, 1, 0},
+ {0, 0, 1},
+ });
+ faceTo00 = MultMat.multiplyGetResult(faceTo00);
- double testZ = 1/(1/startPoint.z +
- xGradient * (LineA.point2.getProjectedPoint().x-startPoint.x) +
- yGradient * (LineA.point2.getProjectedPoint().y-startPoint.y));
- //System.out.println(testZ - testZ2);
- // assign points to lines
+ double yShearFac = (pointUV[1] - pointFace[1]) / pointUV[0];
+ if (!Double.isFinite(yShearFac)) {
+ yShearFac = 0;
+ }
+ MultMat.setItems(new double[][]{
+ {1, 0, 0},
+ {yShearFac, 1, 0},
+ {0, 0, 1},
+ });
+ faceTo00 = MultMat.multiplyGetResult(faceTo00);
+ // multiply final matrices and set their values in the class
+ textureMappingMatrix = uvTo00_inv.multiplyGetResult(faceTo00);
+ }
+ }
+ }
is_initialised = true;
return true;
}
@@ -221,13 +335,13 @@
// a value of 0 represents a value which is on the camera, at z=0.
// not the best mapping but it's probably good enough
double zVal = 1/((1/startPoint.z +
- (x - startPoint.x)*xGradient +
- (y - startPoint.y)*yGradient));
+ (x - startPoint.x)* xzGradient +
+ (y - startPoint.y)* yzGradient));
int newZ = (int)(2147483647d/(zVal + 1));
// if (newZ == 2147483647){
// System.out.println((1/startPoint.z +
-// (x - startPoint.x)*xGradient +
-// (y - startPoint.y)*yGradient));
+// (x - startPoint.x)*xzGradient +
+// (y - startPoint.y)*yzGradient));
// }
// if the new Z value is greater than the existing Z value on the buffer, the new pixel is calculated and drawn
if(drawData.zBuf[x][y] == 0 ||
@@ -235,10 +349,14 @@
drawData.zBuf[x][y] = newZ;
// project result
Color pixColor;
- if(texture.isSolid()){
- pixColor = texture.getColor(ang);
+ if(isTextured){
+ double[] pos = textureMappingMatrix.multiplyPoint2raw(x, y);
+ pixColor = texture.getColor(ang,
+ Math.floorMod((int)(pos[0]*texture.img.length), texture.img.length),
+ Math.floorMod(-1-(int)(pos[1]*texture.img[0].length), texture.img[0].length)
+ );
} else {
- throw new RuntimeException("Textures are not supported");
+ pixColor = texture.getColor(ang);
}
if(drawData.drawZBuffer){
drawData.drawImg[x][y] = Color.getHSBColor((float)newZ/2147483648f + 0.5f, 1, 1).getRGB();
diff --git a/src/main/java/uk/org/floop/epq3d/drawData.java b/src/main/java/uk/org/floop/epq3d/drawData.java
index ceedde1..f3b618c 100644
--- a/src/main/java/uk/org/floop/epq3d/drawData.java
+++ b/src/main/java/uk/org/floop/epq3d/drawData.java
@@ -45,6 +45,9 @@
public Plane[] frustumPlanes = new Plane[6];
public Point2D mouseRel;
+ //temps
+ public double timeSpentChoppingFaces;
+ public double timeSpentDrawingNormalFaces;
public drawData(String filePath){
Object obj;
try {
diff --git a/src/main/java/uk/org/floop/epq3d/testing.java b/src/main/java/uk/org/floop/epq3d/testing.java
index a439d60..b467d1f 100644
--- a/src/main/java/uk/org/floop/epq3d/testing.java
+++ b/src/main/java/uk/org/floop/epq3d/testing.java
@@ -1,10 +1,18 @@
package uk.org.floop.epq3d;
+import org.opencv.core.Core;
+import org.opencv.core.Mat;
+import org.opencv.imgcodecs.Imgcodecs;
+import org.opencv.videoio.VideoCapture;
+
+import javax.swing.*;
+import java.awt.image.BufferedImage;
+import java.awt.image.DataBufferByte;
+import java.awt.image.WritableRaster;
+import java.nio.file.Paths;
class testing {
public static void main(String[] args) {
- JsonReader Jason = new JsonReader();
- Jason.getObjects();
- ObjectCollection main = Jason.mainCollection;
- Texture[] textures = Jason.textures;
+ System.out.println(System.getProperty("user.dir"));
+ VideoCapture camera = new VideoCapture(filePath);
}
}