3d 从摄影机旋转查看平截头体平面

3d 从摄影机旋转查看平截头体平面,3d,camera,rotation,culling,3d,Camera,Rotation,Culling,我试图通过旋转点并检查它们是否在相机前面(球形对象的半径)来执行视锥剔除。远近顶部和底部平面工作正常,但当摄影机角度camRot.y不接近0时,右侧和左侧不会像它们应该的那样进行消隐 当我旋转平面以匹配视锥体时,问题出现了。旋转的平面最终围绕错误的轴旋转。(当我向下看时,左平面和右平面的法线向量与近平面的方向相同) (objectOffsetFromCamera.z*-cos(camRot.x)*cos(camRot.y)+ objectOffsetFromCamera.x*sin(camRot

我试图通过旋转点并检查它们是否在相机前面(球形对象的半径)来执行视锥剔除。远近顶部和底部平面工作正常,但当摄影机角度camRot.y不接近0时,右侧和左侧不会像它们应该的那样进行消隐

当我旋转平面以匹配视锥体时,问题出现了。旋转的平面最终围绕错误的轴旋转。(当我向下看时,左平面和右平面的法线向量与近平面的方向相同)

(objectOffsetFromCamera.z*-cos(camRot.x)*cos(camRot.y)+
objectOffsetFromCamera.x*sin(camRot.x)*cos(camRot.y)+
objectOffsetFromCamera.y*-sin(camRot.y)-(绘制距离+半径)<0&//远平面距离
objectOffsetFromCamera.z*-cos(camRot.x)*cos(camRot.y)+
objectOffsetFromCamera.x*sin(camRot.x)*cos(camRot.y)+
objectOffsetFromCamera.y*-sin(camRot.y)+半径>=0&//
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)+半径>=0&//右平面,对无零camRot.y值进行了错误检测。
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)+半径>=0&//左平面,对无零camRot.y值进行了错误检测。
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))+半径>=0&&//顶面
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))+半径>=0)//底面
我不确定这个问题是否有一个简单的解决方案,但由于它接近于工作,我希望我不必像我在一些教程中发现的那样重做

需要做的是确保相机上下看时,额外的(FOV_X/2)旋转是正确的,但我不能绕着怎么旋转的方向转

而且,所有的cos和sin计算都是每帧进行一次,只是将它们移动到代码中以显示完成了什么

如果我的帖子/代码无法理解,我很抱歉

我现在让它工作了,至少看起来它工作了。 我当前的代码(几乎)。FOV_X和FOV_Y是常数,取决于FOV和纵横比

    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);
void摄影机::calcFrustumPlanes()
{
fru.pfar.x=sin(rot.x)*cos(rot.y);
frustumPlanes.pfar.y=-sin(rot.y);
fru.pfar.z=-cos(rot.x)*cos(rot.y);
fru.pnear.x=sin(rot.x)*cos(rot.y);
frustumPlanes.pnear.y=-sin(rot.y);
fru.pnear.z=-cos(rot.x)*cos(rot.y);
x=sin(rot.x+cos(rot.y)*FOV_x*cos(rot.y)+cos(rot.x)*sin(sin(rot.y)*FOV_x)*sin(rot.y);
pleft.y=-sin(rot.y)*cos(sin(rot.y)*FOV_X);
z=-cos(rot.x+cos(rot.y)*FOV_x)*cos(rot.y)+sin(rot.x)*sin(sin(rot.y)*FOV_x)*sin(rot.y);
x=sin(rot.x-cos(rot.y)*FOV_x)*cos(rot.y)+cos(rot.x)*sin(-sin(rot.y)*FOV_x)*sin(rot.y);
y=-sin(rot.y)*cos(-sin(rot.y)*FOV_X);
z=-cos(rot.x-cos(rot.y)*FOV_x)*cos(rot.y)+sin(rot.x)*sin(-sin(rot.y)*FOV_x)*sin(rot.y);
fru.ptop.x=sin(rot.x)*cos(rot.y+FOV_y);
frustumPlanes.ptop.y=-sin(rot.y+FOV_y);
ptop.z=-cos(rot.x)*cos(rot.y+FOV_y);
fru.pbotom.x=sin(rot.x)*cos(rot.y-FOV_y);
frustumPlanes.pbotom.y=-sin(rot.y-FOV_y);
frustumPlanes.pbotom.z=-cos(rot.x)*cos(rot.y-FOV_y);
}
bool摄像头::iWithInfustum(glm::ivec3对象位置,浮动半径)
glm::vec3 camOffset=objectPos-pos;
返回(glm::dot(camOffset,frustumPlanes.pfar)<(绘制距离+半径)&&
glm::点(camOffset,FRU.pnear)>=-半径&&
glm::点(camOffset,FRU.pleft)>=-半径&&
glm::点(camOffset,Fruitt.pright)>=-半径&&
glm::点(camOffset,frustumPlanes.ptop)>=-半径&&
glm::dot(camOffset,FRU.PBOTOM)>=-半径);

所以FOV_X分别是FOV,FOV_Y是纵横比?而且在pleft.X=sin这样的行中似乎缺少右括号(
    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);