盒子测试还可以优化,在一定程度上,仅仅只有测试它的顶点,叫做“正顶点”和“负顶点”(叫做最大顶点和最小顶点)。
盒子在(视景体)之外在足够的情况下测试一个单独的顶点,其中的第二个顶点,仅仅在需要区分盒子完全在视景体之内还是部分在视景体之内的情况下做测试。
因此什么是这些点呢?找到这些点有多高的难度?
假设一个平面和它的法线,一个正顶点是从盒子沿着法线方向延伸,负顶点刚好是相反。
如果顶点p是在平面错误的边,盒子可以直接被丢弃,它完全是在视景体之外。另一方面,如果顶点p是在平面正确的边,那么还要测试顶点n的情况,来确定盒子是完全在平面的正确边还是盒子跟平面相交。
那么我们如何找到这些点的难度,让我们考虑两种情况:轴对齐盒(AAB),面向盒(OB)。在第一种情况中,AAB,是非常简单和低廉的计算代价来找到它们。
假设AAB包含x, y, z元素并且在xmin和xmax;ymin和ymax;和zmin和zmax。正点p的成分如下所示:
p = (xmin,ymin,zmin)
if (normal.x >= 0)
p.x = xmax;
if (normal.y >=0))
p.y = ymax;
if (normal.z >= 0)
p.z = zmax:
负点n应用相反的规则:
n = (xmax,ymax,zmax)
if (normal.x >= 0)
n.x = xmin;
if (normal.y >=0))
n.y = ymin;
if (normal.z >= 0)
n.z = zmin:
如果盒子没有轴对齐,比如,一个OB,但是这相对较高代价来计算这两个点,由Moller and Haines 所提出的方法是变换到盒子空间中的法线。因此假设盒子的三个轴,bx,by,bz。为了将法线转换到法线,仅仅只需要在这些轴投影法线。
nb = (bx . n, by . n, bz . n)
在盒子空间中的法线,nb,经常用来计算顶点p和顶点n。对于OB,测试实现是用三个点乘,然后加上用来计算1个或者2个距离计算的测试。如果盒子在视景体之外它应该比测试盒子的八个顶点的速度。
给以顶点p和顶点n,下面的代码用来寻找在视景体中找到位置的如下:
int FrustumG::boxInFrustum(AABox &b) {
int result = INSIDE;
//for each plane do ...
for(int i=0; i < 6; i++) {
// is the positive vertex outside?
if (pl[i].distance(b.getVertexP(pl[i].normal)) < 0)
return OUTSIDE;
// is the negative vertex outside?
else if (pl[i].distance(b.getVertexN(pl[i].normal)) < 0)
result = INTERSECT;
}
return(result);
}
英文地址
原文地址:http://www.arcosu.com/post/index/103