package uk.org.floop.epq3d; import java.awt.image.BufferedImage; import java.util.ArrayList; // stores both objects and other object collections public class ObjectCollection { public ArrayList<PointComp> points = new ArrayList<PointComp>(); private Object3d collectionObject; public double boundingSphereR; public Point3D boundingSphereC; public ArrayList<ObjectCollection> subCollections = new ArrayList<ObjectCollection>(); 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 sublevels. // this means that we only need to invalidate them at the top level if(invalidatePoints){for (PointComp point: points) { point.invalidate(); }} for(ObjectCollection subCollection: subCollections){ subCollection.invalidate(false); } for(Object3d object: objects){ object.invalidate(); } } public void draw(int[][] img, int[][] zBuf, BufferedImage debugImg, Matrix camMatrix, Point3D playerPos, Plane[] frustumPlanes, double FPDis, int scrX, int scrY){ for (Object3d object: objects) { 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, zBuf, debugImg, camMatrix, FPDis, scrX, scrY, playerPos);} } // todo check for frustum culling for(ObjectCollection collection: subCollections){ boolean draw = true; int i = 0; for (Plane plane: frustumPlanes) { debugImg.getGraphics().drawString( "Dis: " + String.format("%.1f", plane.getDistance(collection.boundingSphereC)), 500, 10 + 20*i); if(plane.getDistance(collection.boundingSphereC) < -collection.boundingSphereR){ draw = false; break;} i += 1; } collection.draw(img, zBuf, debugImg, camMatrix, playerPos, frustumPlanes, FPDis, scrX, scrY); } } public void addCollection(int[] pointList){ subCollections.add(new ObjectCollection()); } // making sure that all the point indices make sense might be a nightmare but ehh public void addObject(Object3d object){ PointComp[] newpoints = object.points; objects.add(object); // add the new object // merge lists for (PointComp newpoint : newpoints) { boolean found = false; // find out if any of the new points already exist in the list for (PointComp point : points) { if (newpoint == point) { found = true; break; } } if (!found) { points.add(newpoint); } } } public void initialise(){ // init bounding sphere double distance = 0; double newDis; Point3D pointA = points.get(0).point; Point3D pointB = points.get(0).point; // todo - maybe use some vector classes? for (int i = 1; i < points.size(); i+=1) { newDis = Math.pow(points.get(0).point.x - points.get(i).point.x, 2) + Math.pow(points.get(0).point.y - points.get(i).point.y, 2) + Math.pow(points.get(0).point.z - points.get(i).point.z, 2); if (newDis >= distance){ pointA = points.get(i).point; distance = newDis;}} for (PointComp point : points) { newDis = Math.pow(pointA.x - point.point.x, 2) + Math.pow(pointA.y - point.point.y, 2) + Math.pow(pointA.z - point.point.z, 2); if (newDis >= distance){ pointB = point.point; distance = newDis;}} boundingSphereC = new Point3D( (pointA.x + pointB.x) / 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; } } } }