Java 截锥体剔除仅适用于小对象

Java 截锥体剔除仅适用于小对象,java,opengl,optimization,frustum,culling,Java,Opengl,Optimization,Frustum,Culling,目前,我正在尝试在我的引擎中实现截锥剔除,在较小的对象上,它工作得非常好,但较大的对象被剔除的时间比它们应该的要早得多。 您可以看到,它可以很好地处理较小的对象 但较大的物体被剔除的时间比它们应该的要早得多 这是我的平截头剔除器和平面类: package toolbox; import org.lwjgl.opengl.Display; import org.lwjgl.util.vector.Matrix4f; import org.lwjgl.util.vector.Vector

目前,我正在尝试在我的引擎中实现截锥剔除,在较小的对象上,它工作得非常好,但较大的对象被剔除的时间比它们应该的要早得多。

您可以看到,它可以很好地处理较小的对象 但较大的物体被剔除的时间比它们应该的要早得多

这是我的平截头剔除器和平面类:

 package toolbox;

 import org.lwjgl.opengl.Display;
 import org.lwjgl.util.vector.Matrix4f;
 import org.lwjgl.util.vector.Vector3f;
 import org.lwjgl.util.vector.Vector4f;
 import entities.Entity;
 import main.Camera;
 import utils.Maths;

    public class FrustumCuller {
    private static final float HALF_DIAGONAL = 0.8536F;
    private Camera camera;
    private Plane2[] frustum;
private float farDistance;
private float heightFar;
private float widthFar;

public FrustumCuller(Camera camera) {
    this.frustum = new Plane2[2];
    this.farDistance = camera.getFarPlane();
    this.heightFar = ((float) (2.0D * Math.tan(Maths.degreesToRadians(camera.getFov())) * this.farDistance));
    this.widthFar = ((this.heightFar) * (Display.getWidth() / Display.getHeight()) * 2);
    this.camera = camera;
}

public void updatePlanes() {
    Vector3f point = new Vector3f(this.camera.getPosition().x, this.camera.getPosition().y,
            this.camera.getPosition().z);
    Vector3f direction = new Vector3f();
    Vector3f up = new Vector3f();
    Vector3f down = new Vector3f();
    Vector3f left = new Vector3f();
    Vector3f right = new Vector3f();
    calculateVectorDirections(direction, up, down, right, left);

    Vector3f farPlaneCenter = Vector3f.add(point, new Vector3f(direction.x * this.farDistance,
            direction.y * this.farDistance, direction.z * this.farDistance), null);

    this.frustum[0] = new Plane2(calculatePlaneNormal(point, farPlaneCenter, right, up, this.widthFar / 2.0F),
            point);

    this.frustum[1] = new Plane2(calculatePlaneNormal(point, farPlaneCenter, right, down, -this.widthFar / 2.0F),
            point);
}

public void testEntityInView(Entity entity) {
    boolean render = true;
    Vector3f point = new Vector3f(entity.getPosition().x, entity.getPosition().y, entity.getPosition().z);
    for (Plane2 plane : this.frustum) {
        float distance = plane.getSignedDistance(point);
        if (distance < (-entity.getFurthestPoint())) {
            render = false;
        }
    }
    entity.setCanRender(render);
}

private Vector3f calculatePlaneNormal(Vector3f point, Vector3f farPlaneCenter, Vector3f right, Vector3f onPlane,
        float side) {
    Vector3f sidePoint = Vector3f.add(farPlaneCenter, new Vector3f(right.x * side, right.y * side, right.z * side),
            null);

    Vector3f alongPlane = Vector3f.sub(sidePoint, point, null);
    alongPlane.normalise();
    return Vector3f.cross(onPlane, alongPlane, null);
}

private void calculateVectorDirections(Vector3f direction, Vector3f up, Vector3f down, Vector3f right,
        Vector3f left) {
    Vector4f originalDirection = new Vector4f(0.0F, 0.0F, -1.0F, 1.0F);
    Vector4f originalUp = new Vector4f(0.0F, 1.0F, 0.0F, 1.0F);
    Matrix4f rotation = new Matrix4f();
    rotation.rotate(Maths.degreesToRadians(-this.camera.getYaw()), new Vector3f(0.0F, 1.0F, 0.0F));
    rotation.rotate(Maths.degreesToRadians(-this.camera.getPitch()), new Vector3f(1.0F, 0.0F, 0.0F));
    Matrix4f.transform(rotation, originalUp, originalUp);
    Matrix4f.transform(rotation, originalDirection, originalDirection);
    up.set(originalUp);
    direction.set(originalDirection);
    right.set(Vector3f.cross(direction, up, null));
    right.normalise();
    right.negate(left);
    up.negate(down);
}
包工具箱;
导入org.lwjgl.opengl.Display;
导入org.lwjgl.util.vector.Matrix4f;
导入org.lwjgl.util.vector.Vector3f;
导入org.lwjgl.util.vector.Vector4f;
进口实体。实体;
进口主摄像机;
数学;
公营平截器{
专用静态最终浮子半对角线=0.8536F;
私人摄像机;
私人飞机2[]平台;
私人浮动距离;
私人浮动高度;
私人浮动距离远;
公共平截器(摄像机){
this.trustum=新平面2[2];
this.fardance=camera.getFarPlane();
this.heightFar=((float)(2.0D*Math.tan(Math.degreestorarians(camera.getFov())*this.fardance));
this.widthFar=((this.heightFar)*(Display.getWidth()/Display.getHeight())*2);
这个。照相机=照相机;
}
公共void updatePlanes(){
Vector3f点=新的Vector3f(this.camera.getPosition().x,this.camera.getPosition().y,
此参数为.camera.getPosition().z);
向量3f方向=新向量3f();
向量3f up=新向量3f();
向量3f down=新向量3f();
左向量3f=新向量3f();
向量3f right=新向量3f();
计算方向(方向、上、下、右、左);
向量3f远平面中心=向量3f.add(点,新向量3f(方向x*this.fardance,
方向.y*this.fardance,方向.z*this.fardance),空);
this.trustum[0]=新平面2(计算平面法线(点,远平面中心,右,向上,this.widthFar/2.0F),
点);
this.trustum[1]=新平面2(计算平面法线(点,远平面中心,右,下,-this.widthFar/2.0F),
点);
}
public void testEntityInView(实体){
布尔呈现=真;
Vector3f点=新的Vector3f(entity.getPosition().x,entity.getPosition().y,entity.getPosition().z);
对于(平面2平面:此.平截头体){
浮动距离=平面。getSignedDistance(点);
if(距离<(-entity.getFurthestPoint()){
render=false;
}
}
实体。setCanRender(render);
}
专用向量3F计算平面(向量3F点、向量3F远平面中心、向量3F右、向量3F平面上、,
浮子侧){
向量3f侧点=向量3f.add(平面中心,新向量3f(右x*侧,右y*侧,右z*侧),
无效);
向量3f沿平面=向量3f.sub(边点、点、空);
沿平面。法线化();
返回向量3f.交叉(平面上、平面上、空);
}
专用void计算向量方向(向量3F方向、向量3F向上、向量3F向下、向量3F向右、,
向量3f(左){
矢量4f原始方向=新矢量4f(0.0F,0.0F,-1.0F,1.0F);
矢量4f originalUp=新矢量4f(0.0F,1.0F,0.0F,1.0F);
Matrix4f旋转=新Matrix4f();
rotation.rotate(数学度弧度(-this.camera.getYaw()),新矢量3f(0.0F,1.0F,0.0F));
rotation.rotate(数学度弧度(-this.camera.getPitch()),新矢量3f(1.0F,0.0F,0.0F));
矩阵4f.变换(旋转、原点、原点);
矩阵4f.变换(旋转、原始方向、原始方向);
设置(originalUp);
方向设置(原始方向);
右。设置(向量3f.交叉(方向,向上,空));
对。正常化();
右。否定(左);
向上。否定(向下);
}
}

包工具箱;
导入org.lwjgl.util.vector.Vector3f;
导入渲染。三角形;
导入渲染。三角形;
导入渲染。三角形;
公共类飞机2{
私人三角;
私人矢量3f来源;
私人向量3f正常;
私有浮动常数;
私人浮动t0;
私人浮动t1;
公共平面2(三角形){
这个三角形=三角形;
向量3f point0=三角形。getPointN(0);
向量3f point1=三角形。getPointN(1);
向量3f point2=triangle.getPointN(2);
this.normal=Vector3f.cross(Vector3f.sub(point2,point0,null),Vector3f.sub(point1,point0,null),null);
this.normal.normalise();
this.origin=新矢量3f(点0.x、点0.y、点0.z);
this.constant=(((this.normal.x*this.origin.x+this.normal.y*this.origin.y
+这个.normal.z*这个.origin.z));
}
公共平面2(向量3F正常,向量3F原点){
这.正常=正常;
this.origin=origin;
这个常数=((normal.x*origin.x+normal.y*origin.y+normal.z*origin.z));
}
公共浮点getSignedDistance(矢量3F点){
返回向量3f.dot(this.normal,point)+this.constant;
}
公共布尔值正向(向量3F方向){
浮动点=矢量3f.点(此.法线,方向);

return dot没有说明的未注释的外来代码很难理解,我们中的大多数人甚至都不会感到麻烦。因为在没有之前,您0看不到任何响应…尝试添加一些注释代码的哪些部分做了什么…您如何筛选…您的对象是什么(如何存储等)这可能会吸引一些人的回答。如果你添加这一点,它可能会对未经推荐的没有描述的外国代码中发生的事情有所启发。这很难理解,我们大多数人甚至不会费心。因为你看不到任何回应,直到没有…尝试添加一些注释代码的哪些部分做了什么…你如何筛选…你的对象是什么(如何储存等…)它可能会吸引一些人的回答。如果你加上这个,它可能会对正在发生的事情有所启发
 package toolbox;

 import org.lwjgl.util.vector.Vector3f;

 import rendering.Triangle;

 import rendering.Triangle;

 import rendering.Triangle;

 public class Plane2 {
private Triangle triangle;
private Vector3f origin;
private Vector3f normal;
private float constant;
private float t0;
private float t1;

public Plane2(Triangle triangle) {
    this.triangle = triangle;
    Vector3f point0 = triangle.getPointN(0);
    Vector3f point1 = triangle.getPointN(1);
    Vector3f point2 = triangle.getPointN(2);
    this.normal = Vector3f.cross(Vector3f.sub(point2, point0, null), Vector3f.sub(point1, point0, null), null);

    this.normal.normalise();
    this.origin = new Vector3f(point0.x, point0.y, point0.z);
    this.constant = (-(this.normal.x * this.origin.x + this.normal.y * this.origin.y
            + this.normal.z * this.origin.z));
}

public Plane2(Vector3f normal, Vector3f origin) {
    this.normal = normal;
    this.origin = origin;
    this.constant = (-(normal.x * origin.x + normal.y * origin.y + normal.z * origin.z));
}

public float getSignedDistance(Vector3f point) {
    return Vector3f.dot(this.normal, point) + this.constant;
}

public boolean isFrontFacingTo(Vector3f direction) {
    float dot = Vector3f.dot(this.normal, direction);
    return dot <= 0.0F;
}

public Triangle getTriangle() {
    return this.triangle;
}

public Vector3f getOrigin() {
    return this.origin;
}

public Vector3f getNormal() {
    return this.normal;
}

public float getConstant() {
    return this.constant;
}

public float getT0() {
    return this.t0;
}

public void setT0(float t0) {
    this.t0 = t0;
}

public float getT1() {
    return this.t1;
}

public void setT1(float t1) {
    this.t1 = t1;
}
 }