import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.Objects;
// 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(BufferedImage img, BufferedImage 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;
}
}
}
}