0

I'm trying to perform view frustum culling by rotating points and checking if they are in front of the camera (with a radius for spherical objects). The far near top and bottom planes are working fine, but the right and left does not cull as they should when the camera angle camRot.y is not close to 0.

The problem arise when I rotate the planes to match the view frustum the rotated planes end up rotated around the wrong axis. (When i look down the left and right planes end up with normals vectors in the same direction as the near plane).

    (objectOffsetFromCamera.z*-cos(camRot.x)*cos(camRot.y) +
    objectOffsetFromCamera.x * sin(camRot.x)*cos(camRot.y) +
    objectOffsetFromCamera.y *-sin(camRot.y) - (DRAW_DISTANCE + radius) < 0 && //FARPLANE DISTANCE

    objectOffsetFromCamera.z*-cos(camRot.x)*cos(camRot.y) +
    objectOffsetFromCamera.x* sin(camRot.x)*cos(camRot.y) +
    objectOffsetFromCamera.y*-sin(camRot.y) + radius >= 0 && //NEAR PLANE

    objectOffsetFromCamera.z*-cos(camRot.x + (FOV_X / 2)) *cos(camRot.y) + 
    objectOffsetFromCamera.x* sin(camRot.x + (FOV_X / 2)) *cos(camRot.y) +
    objectOffsetFromCamera.y*-sin(camRot.y) + radius >= 0 && //RIGHT PLANE, bugged for none zero camRot.y values.

    objectOffsetFromCamera.z*-cos(camRot.x - (FOV_X / 2)) * cos(camRot.y) +
    objectOffsetFromCamera.x* sin(camRot.x - (FOV_X / 2)) * cos(camRot.y) +
    objectOffsetFromCamera.y*-sin(camRot.y) + radius >= 0 && //LEFT PLANE, bugged for none zero camRot.y values.

    objectOffsetFromCamera.z*-cos(camRot.x)*cos(camRot.y + (FOV_Y / 2)) +
    objectOffsetFromCamera.x* sin(camRot.x)*cos(camRot.y + (FOV_Y / 2)) +
    objectOffsetFromCamera.y*-sin(camRot.y + (FOV_Y / 2)) + radius >= 0 && //TOP PLANE

    objectOffsetFromCamera.z*-cos(camRot.x)*cos(camRot.y - (FOV_Y / 2)) +
    objectOffsetFromCamera.x* sin(camRot.x)*cos(camRot.y - (FOV_Y  / 2)) +
    objectOffsetFromCamera.y*-sin(camRot.y - (FOV_Y  / 2)) + radius >= 0) //BOTTOM PLANE

I'm not sure if this problem has an easy solution but since it's close to working I hope I don't have to redo like in some tutorials I found.

What needs to be done is to make sure the extra (FOV_X / 2) rotation is rotated correctly with the camera when looking up or down, but I can't wrap my head around how.

Also, all cos and sin calculations are just done ones per frame, just moved them into the code to show what is done.

I'm sorry if my post/code is unintelligible.

I got it working now, at least it looks like it works. My current code (almost). FOV_X and FOV_Y are constants depending on the fov and the aspect ratio.

    void Camera::calcFrustumPlanes()
    {
frustumPlanes.pfar.x = sin(rot.x)*cos(rot.y);
frustumPlanes.pfar.y = -sin(rot.y);
frustumPlanes.pfar.z = -cos(rot.x)*cos(rot.y);

frustumPlanes.pnear.x = sin(rot.x)*cos(rot.y);
frustumPlanes.pnear.y = -sin(rot.y);
frustumPlanes.pnear.z = -cos(rot.x)*cos(rot.y);

frustumPlanes.pleft.x = sin(rot.x + cos(rot.y)*FOV_X*cos(rot.y) + cos(rot.x)*sin(sin(rot.y)*FOV_X)*sin(rot.y);
frustumPlanes.pleft.y = -sin(rot.y)*cos(sin(rot.y)*FOV_X);
frustumPlanes.pleft.z = -cos(rot.x + cos(rot.y)*FOV_X)*cos(rot.y) + sin(rot.x)*sin(sin(rot.y)*FOV_X)*sin(rot.y);

frustumPlanes.pright.x = sin(rot.x - cos(rot.y)*FOV_X)*cos(rot.y) + cos(rot.x)*sin(-sin(rot.y)*FOV_X)*sin(rot.y);
frustumPlanes.pright.y = -sin(rot.y)*cos(-sin(rot.y)*FOV_X);
frustumPlanes.pright.z = -cos(rot.x - cos(rot.y)*FOV_X)*cos(rot.y) +  sin(rot.x)*sin(-sin(rot.y)*FOV_X)*sin(rot.y);

frustumPlanes.ptop.x = sin(rot.x)*cos(rot.y + FOV_Y);
frustumPlanes.ptop.y = -sin(rot.y + FOV_Y);
frustumPlanes.ptop.z = -cos(rot.x)*cos(rot.y + FOV_Y);

frustumPlanes.pbottom.x = sin(rot.x)*cos(rot.y - FOV_Y);
frustumPlanes.pbottom.y = -sin(rot.y - FOV_Y);
frustumPlanes.pbottom.z = -cos(rot.x)*cos(rot.y - FOV_Y);
    }

    bool Camera::isWithinFrustum(glm::ivec3 objectPos, float radius)
glm::vec3 camOffset = objectPos - pos;
return (glm::dot(camOffset, frustumPlanes.pfar) < (DRAW_DISTANCE + radius ) &&
        glm::dot(camOffset, frustumPlanes.pnear)   >= -radius &&
        glm::dot(camOffset, frustumPlanes.pleft)   >= -radius &&
        glm::dot(camOffset, frustumPlanes.pright)  >= -radius  &&
        glm::dot(camOffset, frustumPlanes.ptop)    >= -radius  &&
        glm::dot(camOffset, frustumPlanes.pbottom) >= -radius);

0 Answers0