Frustum剔除 - 错误评估平截头体平面中的一个点

时间:2014-08-04 03:51:42

标签: opengl culling frustum

我正在尝试实现以下代码:

http://www.lighthouse3d.com/tutorials/view-frustum-culling/geometric-approach-implementation/

我需要在我的图形引擎中使用视锥体剔除。

我的职能是:

void frustum::updateCameraData()
{
    float _ratio = float(globalData::windowWidth/globalData::windowHeight);
    // store the information
    this->ratio = _ratio;
    this->angle = globalData::cameraAngle;
    this->nearD = globalData::zNear;
    this->farD = globalData::zFar;

    // compute width and height of the near and far m_frustumane sections
    tang = (float)tan(PI * globalData::cameraAngle * 0.5) ;
    nh = nearD * tang;
    nw = nh * _ratio;
    fh = farD  * tang;
    fw = fh * _ratio;

}

    void frustum::extractFrustum(vector3f camPosition, vector3f camDirection, vector3f camUp)
{
    cout << "camPosition = ";
    camPosition.print();
    cout << " camDirection = ";
    camDirection.print();
    cout << " camUp = ";
    camUp.print();
    cout << "\n";
    vector3f dir,nc,fc,X,Y,Z,Zn;


    // compute the Z axis of camera
    // this axis points in the opposite direction from
    // the looking direction
    Z = camPosition - camDirection;
    Z.Normalize();

    // X axis of camera with given "up" vector and Z axis
    X = camUp * Z;
    X.Normalize();

    // the real "up" vector is the cross product of Z and X
    Y = Z * X;

    // compute the centers of the near and far planes
    nc = camPosition - Z * nearD;
    fc = camPosition - Z * farD;

    // compute the 4 corners of the frustum on the near plane
    ntl = nc + Y * nh - X * nw;
    ntr = nc + Y * nh + X * nw;
    nbl = nc - Y * nh - X * nw;
    nbr = nc - Y * nh + X * nw;

    // compute the 4 corners of the frustum on the far plane
    ftl = fc + Y * fh - X * fw;
    ftr = fc + Y * fh + X * fw;
    fbl = fc - Y * fh - X * fw;
    fbr = fc - Y * fh + X * fw;



    Zn = vector3f(-Z.x,-Z.y,-Z.z);
    m_frustum[NEARP].setNormalAndPoint(Zn,nc);
    m_frustum[FARP].setNormalAndPoint(Z,fc);

    vector3f aux,normal;

    aux = (nc + Y*nh) - camPosition;
    aux.Normalize();
    normal = aux * X;
    Zn = nc+Y*nh;
    m_frustum[TOP].setNormalAndPoint(normal,Zn);

    aux = (nc - Y*nh) - camPosition;
    aux.Normalize();
    normal = X * aux;

    Zn = nc-Y*nh;
    m_frustum[BOTTOM].setNormalAndPoint(normal,Zn);

    aux = (nc - X*nw) - camPosition;
    aux.Normalize();
    normal = aux * Y;

    Zn = nc-X*nw;
    m_frustum[LEFT].setNormalAndPoint(normal,Zn);

    aux = (nc + X*nw) - camPosition;
    aux.Normalize();
    normal = Y * aux;

    Zn = nc+X*nw;
    m_frustum[RIGHT].setNormalAndPoint(normal,Zn);

}

bool frustum::pointInFrustum( float x, float y, float z )
{
    vector3f point = vector3f(x,y,z);

    for(int i=0; i < 6; i++)
    {
        cout << "m_frustum[i].distance(point) = "<< m_frustum[i].distance(point) <<" < 0\n";
        if (m_frustum[i].distance(point) < 0)
        {
            return false;
        }
    }
    return true;
}



/*this is used to calculate the distance of point to plane*/

float distance(vector3f &p) {

    return (d + normal.innerProduct(p));
}

但是,我收到了不需要的结果(这是我的调试信息):

   camPosition = (0, 15, 40) camDirection = (0, 0, 0) camUp = (0, 1, 0)

NO DRAWN: object0
posicion: -20,0,-20
/*object position*/ vector3f point = vector3f(-20,0,-20)
m_frustum[0].distance(point) = 14.7867 < 0
/*object position*/ vector3f point = vector3f(-20,0,-20)
m_frustum[1].distance(point) = 14.485 < 0
/*object position*/ vector3f point = vector3f(-20,0,-20)
m_frustum[2].distance(point) = 14.2216 < 0
/*object position*/ vector3f point = vector3f(-20,0,-20)
m_frustum[3].distance(point) = -15.0501 < 0
NO DRAWN: object1
posicion: 0,0,-20
/*object position*/ vector3f point = vector3f(0,0,-20)
m_frustum[0].distance(point) = 14.7867 < 0
/*object position*/ vector3f point = vector3f(0,0,-20)
m_frustum[1].distance(point) = 14.485 < 0
/*object position*/ vector3f point = vector3f(0,0,-20)
m_frustum[2].distance(point) = 14.2216 < 0
/*object position*/ vector3f point = vector3f(0,0,-20)
m_frustum[3].distance(point) = -15.0501 < 0
NO DRAWN: object2
posicion: 20,0,-7
/*object position*/ vector3f point = vector3f(20,0,-7)
m_frustum[0].distance(point) = 14.7867 < 0
/*object position*/ vector3f point = vector3f(20,0,-7)
m_frustum[1].distance(point) = 14.485 < 0
/*object position*/ vector3f point = vector3f(20,0,-7)
m_frustum[2].distance(point) = 14.2216 < 0
/*object position*/ vector3f point = vector3f(20,0,-7)
m_frustum[3].distance(point) = -15.0501 < 0
NO DRAWN: object3
posicion: -40,0,-20
/*object position*/ vector3f point = vector3f(-40,0,-20)
m_frustum[0].distance(point) = 14.7867 < 0
/*object position*/ vector3f point = vector3f(-40,0,-20)
m_frustum[1].distance(point) = 14.485 < 0
/*object position*/ vector3f point = vector3f(-40,0,-20)
m_frustum[2].distance(point) = 14.2216 < 0
/*object position*/ vector3f point = vector3f(-40,0,-20)
m_frustum[3].distance(point) = -15.0501 < 0

没有一个对象通过测试(我用pointInFrustrum()测试,使用点作为每个对象的位置。

如果我在没有视锥体剔除的情况下渲染场景,一切看起来都很完美,但是要使用它,没有任何东西通过测试。任何想法哪里可以是错误? (代码是我上面提到的链接。)

所有物体都在视野中......

矩阵由glm :: mat4;

管理

编辑:

在我进行了修正之后,如果我将相机向下指向一下,则会绘制对象,但如果我将相机指向一点,则所有对象都会完全消失(这次不会绘制它们)。你知道可能会发生什么吗?提前谢谢。

如果相机指向下方:

enter image description here

如果相机指向一点:

enter image description here

1 个答案:

答案 0 :(得分:0)

我终于可以解决问题了。它存在于飞机的计算中(我没有像我应该那样使用矩阵),我改变了它,一切都很完美。