我目前正在实施Revelles,Urena和Lastra "An Efficient Parametric Algorithm for Octree Traversal"的论文。在Ray - Octree intersection algorithms中有人实现了它并粘贴了他的代码。我的实现应该是相同的,除了我使用一些向量进行计算。 但是,使用此八叉树仅渲染图像的右上部分,对于图像的其余部分,不会遍历八叉树。要通过以下方法进行遍历或不进行检查:
bool Octnode::intersect( Ray r, SurfaceData *sd )
{
unsigned int a = 0;
v3d o = r.origin();
v3d d = r.direction();
if ( r.direction()[0] < 0. ) {
o[0] = _size[0] - r.origin()[0];
d[0] = -r.direction()[0];
a |= 4;
}
if ( r.direction()[1] < 0. ) {
o[1] = _size[1] - r.origin()[1];
d[1] = -r.direction()[1];
a |= 2;
}
if ( r.direction()[2] < 0. ) {
o[2] = _size[2] - r.origin()[2];
d[2] = -r.direction()[2];
a |= 1;
}
v3d t0 = ( _min - o ) / d;
v3d t1 = ( _max - o ) / d;
scalar t = std::numeric_limits<double>::max();
// traversal -- if any -- starts here
if ( t0.max() < t1.min() ) {
return processSubtree( t0, t1, r, &t, sd, a );
} else {
return false;
}
}
[编辑] 上述方法实现了函数
void ray_parameter( octree *oct, ray r )
来自论文。正如C. Urena指出的那样,论文中有一个错误导致遍历不正确。不幸的是,在此错误发挥作用之前,会跳过遍历。 在可以在C. Urena的链接中找到的Google组中,似乎八角树节点的大小计算方式不同。我做了:
_size = _max - _min;
与
_size = ( _max - _min ) / 2.;
在Google群组中。我将测试并发布另一个更新。的 [/编辑]
[编辑2] 应用Carlos提到的修复程序并将大小缩小一半让我走得很远:
应该完全渲染球体,但至少不是左上角四分之一的所有射线都被拒绝。 [/ Edit 2]
[编辑3] 使用不同的数据集我看似更好的结果,看起来我将不得不调查代码的其他部分。
[/编辑3]
答案 0 :(得分:1)
我没有时间对您的代码进行详细审核,但也许您应该检查原始论文中的错误,该错误也可能出现在您的代码中:您可以在此处看到它:http://lsi.ugr.es/curena/inves/wscg00/ - 这是一个指向谷歌小组讨论的指针。
希望这个帮助, 卡洛斯。