Отбор фрустума работает только с небольшими объектами - PullRequest
1 голос
/ 06 мая 2020

В настоящее время я пытаюсь реализовать отбраковку Frustum в моем движке, и на небольших объектах он работает отлично, но более крупные объекты отбраковываются гораздо раньше, чем должны. enter image description here

Вы можете видеть, что он отлично работает с меньшими объектами, но более крупные объекты отбираются намного раньше, чем должны. enter image description here

Вот мой класс Frustum Culler и Plane:

 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);
}

}

 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;
}
 }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...