Newer
Older
EPQ-3D-renderer / src / Face.java
import java.awt.image.BufferedImage;
import java.security.cert.TrustAnchor;
import java.util.ArrayList;

public class Face {
    PointComp[] points;
    Vector3D normal;
    Triangle[] tris;

    public void initialise(){
        calculateNormal();
        separateTris();
    }

    public void invalidate(){
        for (Triangle tri:
             tris) {
            tri.invalidate();
        }
    }
    public int draw(BufferedImage img, BufferedImage debugImg, Matrix camMatrix, double FPDis, int scrX, int scrY){
        // check for backface culling has been done previously.
        // initialise points
        int numberofPixels = 0;
        boolean valid = true;
        for (PointComp point:
             points) {
            point.setRotatedPoint(camMatrix);
            point.setProjectedPoint(FPDis, scrX, scrY);
            // skip rendering if any points are behind the camera
            if(point.getRotatedPoint().z < 0){
                valid = false;
                break;
            }
        }
        if(valid){for (Triangle tri:
                tris) {
            numberofPixels += tri.draw(img);
        }}
        return numberofPixels;
    }
    public void separateTris(){
        Triangle[] newTris = new Triangle[points.length - 2];
        for(int i = 0; i< newTris.length; i+=1){
            newTris[i] = new Triangle(
                    points[0].getProjectedPoint(),
                    points[i+1].getProjectedPoint(),
                    points[i+2].getProjectedPoint());
        }
        tris = newTris;
    }
    public void calculateNormal(){
        // 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
        // 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);
            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");}
        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);
    }
}