hey guys. I wanted to post my approach to frustrum culling, in perspective mode.
The code takes into account a few assumptions, like the order of placement for the camera.
It can be made alot more robust, but I’v put in the main logic. In doesnt take into account any sorting of objects.
public class Frustrum {
private static float xGradient, yGradient, distance, a1, b1, a2, b2, temp, x, y, z;
public static void init(float fieldOfView, float aspectRatio) {
xGradient = (float)Math.tan(Math.toRadians(fieldOfView)/2f);
yGradient = (float)Math.tan(Math.toRadians(fieldOfView*aspectRatio)/2f);
}
run at the start of program
public static void update() {
a1 = (float)Math.cos(-Math.toRadians(Camera.yRot));
b1 = (float)Math.sin(-Math.toRadians(Camera.yRot));
a2 = (float)Math.cos(-Math.toRadians(Camera.xRot));
b2 = (float)Math.sin(-Math.toRadians(Camera.xRot));
}
update should be called, when the camera rotation changes (or every cycle).
//Returns mapObjects distance from the camera, if mapObject is not in frustrum will return 0
public static float check(MapObject o, float radius) {
//UN TRANSLATE CAMERA POSITION
x = o.xPos - Camera.trueX;
y = o.yPos - Camera.trueY;
z = o.zPos - Camera.trueZ;
//UN ROTATE CAMERA Y ROTATION
temp = (x * a1) - (z * b1);
z = (x * b1) + (z * a1);
x = temp;
//UN ROTATE CAMERA X ROTATION
temp = (z * b2) + (y * a2);
z = (z * a2) - (y * b2);
y = temp;
//CHECK SIDE OF SCREEN BOOLEAN EQUATIONS
if (y + radius < xGradient*z || x + radius < yGradient*z) return 0;
z = -z;
if (y - radius > xGradient*z || x - radius > yGradient*z) return 0;
//* DISTANCE FROM CAMERA BOOLEAN CHECK - RADIAL VERSION - SLOWER!
z = (float)Math.sqrt((x*x) + (y*y) + (z*z));
if (z > Settings.fDistance || z < Settings.cDistance) return 0;
//* DISTANCE FROM CAMERA BOOLEAN CHECK - FAST VERSION
//if (z > Settings.fDistance || z < Settings.cDistance) return 0;
return z;
}
}
this is the actual frustrum code check.
ASSUMES CAMERA IS POSITION IN THE FOLLOWING WAY:
ratate(camera.xRot, 1, 0, 0);
ratate(camera.yRot, 0, 1, 0);
translate(-camera.x, -camera.y, -camera.z); //notice negative translation
Sure the order of rotation and translation can be changed depending on the camera placement.