我正在尝试实现以下代码:
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;
管理编辑:
在我进行了修正之后,如果我将相机向下指向一下,则会绘制对象,但如果我将相机指向一点,则所有对象都会完全消失(这次不会绘制它们)。你知道可能会发生什么吗?提前谢谢。
如果相机指向下方:
如果相机指向一点:
答案 0 :(得分:0)
我终于可以解决问题了。它存在于飞机的计算中(我没有像我应该那样使用矩阵),我改变了它,一切都很完美。