package de.venjinx.util;
import com.jme3.math.FastMath;
import com.jme3.math.Vector3f;
import com.jme3.math.Vector4f;
import com.jme3.renderer.Camera;
public class CameraFrustum {
private Camera camera;
private int w, h;
private float fov, near, far;
private Vector4f nearSides, farSides;
private Vector3f leftDir, rightDir, bottomDir, topDir;
private Vector3f nearCenterPos;
private Vector3f nearLeftPos;
private Vector3f nearRightPos;
private Vector3f nearTopPos;
private Vector3f nearBottomPos;
private Vector3f farCenterPos;
private Vector3f farTopPos;
private Vector3f farBottomPos;
private Vector3f farLeftPos;
private Vector3f farRightPos;
public CameraFrustum(Camera cam) {
camera = cam;
update();
}
public void update() {
w = camera.getWidth();
h = camera.getHeight();
near = camera.getFrustumNear();
far = camera.getFrustumFar();
nearSides = new Vector4f(camera.getFrustumBottom(), camera.getFrustumTop(),
camera.getFrustumLeft(), camera.getFrustumRight());
nearCenterPos = camera.getLocation().add(camera.getDirection());
nearBottomPos = nearCenterPos.add(camera.getUp().mult(nearSides.x));
nearTopPos = nearCenterPos.add(camera.getUp().mult(nearSides.y));
nearLeftPos = nearCenterPos.add(camera.getLeft().mult(-nearSides.z));
nearRightPos = nearCenterPos.add(camera.getLeft().mult(-nearSides.w));
bottomDir = nearBottomPos.subtract(camera.getLocation()).normalizeLocal();
topDir = nearTopPos.subtract(camera.getLocation()).normalizeLocal();
leftDir = nearLeftPos.subtract(camera.getLocation()).normalizeLocal();
rightDir = nearRightPos.subtract(camera.getLocation()).normalizeLocal();
fov = topDir.angleBetween(bottomDir);
farSides = calcFarSides();
farCenterPos = camera.getLocation().add(camera.getDirection().mult(far));
farBottomPos = farCenterPos.add(camera.getUp().mult(farSides.x));
farTopPos = farCenterPos.add(camera.getUp().mult(farSides.y));
farLeftPos = farCenterPos.add(camera.getLeft().mult(-farSides.z));
farRightPos = farCenterPos.add(camera.getLeft().mult(-farSides.w));
}
private Vector4f calcFarSides() {
float farH = 2f * FastMath.tan(fov / 2f) * camera.getFrustumFar();
float farW = farH * (w / h);
return new Vector4f(-farH / 2f, farH / 2f, -farW / 2f, farW / 2f);
}
public Camera getCamera() {
return camera;
}
public float getFov() {
return fov;
}
public float getNear() {
return near;
}
public float getFar() {
return far;
}
public Vector4f getNearSides() {
return nearSides;
}
public Vector4f getFarSides() {
return farSides;
}
public Vector3f getLeftDir() {
return leftDir;
}
public Vector3f getRightDir() {
return rightDir;
}
public Vector3f getBottomDir() {
return bottomDir;
}
public Vector3f getTopDir() {
return topDir;
}
public Vector3f getNearCenterPos() {
return nearCenterPos;
}
public Vector3f getNearLeftPos() {
return nearLeftPos;
}
public Vector3f getNearRightPos() {
return nearRightPos;
}
public Vector3f getNearTopPos() {
return nearTopPos;
}
public Vector3f getNearBottomPos() {
return nearBottomPos;
}
public Vector3f getFarCenterPos() {
return farCenterPos;
}
public Vector3f getFarTopPos() {
return farTopPos;
}
public Vector3f getFarBottomPos() {
return farBottomPos;
}
public Vector3f getFarLeftPos() {
return farLeftPos;
}
public Vector3f getFarRightPos() {
return farRightPos;
}
@Override
public String toString() {
String str = "";
str += "Camera" + camera.getLocation() + " - Width = " + w;
str += ", Height = " + h + ", Fov = " + (fov * FastMath.RAD_TO_DEG) + "\n";
str += "Direction" + camera.getDirection() + ", Up-Axis" + camera.getUp();
str += ", Left-Axis" + camera.getLeft() + "\n";
str += "Frustum:\n";
str += "Near = " + near + " - " + nearCenterPos + "\n";
str += " Bottom = " + nearSides.x + " - " + nearBottomPos + "\n";
str += " Top = " + nearSides.y + " - " + nearTopPos + "\n";
str += " Left = " + nearSides.z + " - " + nearLeftPos + "\n";
str += " Right = " + nearSides.w + " - " + nearRightPos + "\n";
str += "Far = " + far + " - " + farCenterPos + "\n";
str += " Bottom = " + farSides.x + " - " + farBottomPos + "\n";
str += " Top = " + farSides.y + " - " + farTopPos + "\n";
str += " Left = " + farSides.z + " - " + farLeftPos + "\n";
str += " Right = " + farSides.w + " - " + farRightPos + "\n";
return str;
}
}