Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/134.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 是否应该每帧重建一个八叉树? 当在一个游戏中使用一个用于冲突检测时,是否应该在每个帧中重建树,或者假设一半的对象在一个帧中移动有更好的方式吗?< P>如果场景随每个帧变化,那么你必须重做树。 < P>如果场景中有很多静态几何,考虑建立单独的八叉树。您还可以通过使用更复杂的叶节点来表达相同的想法,这些叶节点可以区分静态几何体和非静态几何体_C++_Algorithm - Fatal编程技术网

C++ 是否应该每帧重建一个八叉树? 当在一个游戏中使用一个用于冲突检测时,是否应该在每个帧中重建树,或者假设一半的对象在一个帧中移动有更好的方式吗?< P>如果场景随每个帧变化,那么你必须重做树。 < P>如果场景中有很多静态几何,考虑建立单独的八叉树。您还可以通过使用更复杂的叶节点来表达相同的想法,这些叶节点可以区分静态几何体和非静态几何体

C++ 是否应该每帧重建一个八叉树? 当在一个游戏中使用一个用于冲突检测时,是否应该在每个帧中重建树,或者假设一半的对象在一个帧中移动有更好的方式吗?< P>如果场景随每个帧变化,那么你必须重做树。 < P>如果场景中有很多静态几何,考虑建立单独的八叉树。您还可以通过使用更复杂的叶节点来表达相同的想法,这些叶节点可以区分静态几何体和非静态几何体,c++,algorithm,C++,Algorithm,一句话:只需要重新生成您必须的内容。如果您有非常动态的数据移动每一帧,并且仍然需要加速碰撞检测,我实际上建议使用固定的3D网格。二维等效: 它还可以作为自由列表翻倍,以允许固定时间的删除,就像这样(使用next索引作为同一网格单元中下一个元素的索引,或者如果已删除,则将下一个自由元素从自由堆栈中弹出): 另一个例子: 现在在三维空间中,这似乎需要爆炸性的记忆。然而,诀窍是让每个单元格将一个32位索引存储到一个数组中,基本上作为一个单独链接的索引列表。这将每个单元的大小减少到32位。现在,如

一句话:只需要重新生成您必须的内容。

如果您有非常动态的数据移动每一帧,并且仍然需要加速碰撞检测,我实际上建议使用固定的3D网格。二维等效:

它还可以作为自由列表翻倍,以允许固定时间的删除,就像这样(使用
next
索引作为同一网格单元中下一个元素的索引,或者如果已删除,则将下一个自由元素从自由堆栈中弹出):

另一个例子:

现在在三维空间中,这似乎需要爆炸性的记忆。然而,诀窍是让每个单元格将一个32位索引存储到一个数组中,基本上作为一个单独链接的索引列表。这将每个单元的大小减少到32位。现在,如果您存储一个100x100x100网格(100万个单元),则所需的时间不到4兆字节

当元素四处移动时,您只需将它们从它们所占用的单元格中移除、移动并插入新的单元格即可。要做到这一点,您所要做的就是操纵一些32位索引(没有内存分配/释放来将元素从一组单元格传输到其他单元格)。这都是恒定的时间,不需要重新平衡树或分割过于拥挤的八分之一或类似的东西

您还可以使用网格层次结构(这听起来可能像八叉树,但不同)。我的意思是,对于场景中的整个网格对象,可能有一个粗略的网格。然后,每个网格对象可能会为其每个部分存储一个粗略的网格,例如10x10x10。然后每个零件为其每个多边形存储一个精细网格或八叉树。这允许非有机网格,比如说,刚性的部分像机器人一样旋转,以避免必须更新多边形的精细网格/八叉树,并在开始旋转腿部和手臂时更新其自身的部分粗网格和世界对象的粗网格,例如,只有有机模型在被骨骼变形时才需要更新其精细网格,例如


我会为完全静态的元素/部分保留八叉树,这些元素/部分永远不需要每帧更新,我会使用一个漂亮的八叉树,稀疏的,可能还有一些后处理,以便缓存友好的内存访问。如果您可以假设八叉树在构建后永远不需要更新,那么您就有更多的时间来加速对它们的搜索并最小化它们的内存使用。

如果场景随着每一帧的变化而变化,那么您必须更新树。并不总是需要“重做”整个树。我自己的实现可以在对象移动时根据需要进行更新。您是否可以这样做取决于您如何实现它;我认为它们是同义词。但你的观点是正确的——这几乎就像你需要一面脏旗来标记改变了的部分一样。我有两个澄清的问题。如果一个图元最终与两个平铺/正方形重叠(由于宽度/高度),并移动,您如何有效地更新其在栅格中的位置?第二,如果可以将所有唯一实体存储在多个位置,如何高效地查询它们?这是一个相当复杂的问题。关于所有的可能性,我这里有一个冗长得可笑的答案:。最简单的方法是,如果你的代理的大小范围很小,比如你最大的代理比最小的代理大不了多少,那么当你在特定点搜索碰撞代理时,你可以使用上界半径或类似的东西。将搜索半径扩大到最大代理的上限大小/半径。。。。。。这是一种愚蠢的解决方案,但在适当的情况下,它可以非常有效,而且自然非常简单。这样做时,即使代理与多个网格单元重叠,也只需将其视为一个点,并将其存储在其中心点占据的一个单元中。另一种选择是松散结构,在上面详细的回答中,我给出了一个示例,说明了如何制作松散的网格和松散的四叉树(很容易扩展到三维的松散八叉树)。最后,只需将代理冗余存储在它重叠的所有单元格中。如果你这样做了,那么你想要使用足够大的单元格,这样你就不会有像巨大的代理占用2000个网格单元格那样的空间,而这些网格单元格会很糟糕。另一个是,您希望将一些flyweight指针存储到代理,使其尽可能轻。最后,如果您想在存在重叠和冗余时高效地找到唯一的实体,一种方法是像布尔(可以是单个位)一样存储到代理。执行查询时,仅当此布尔值设置为false时,才将代理添加到列表中。如果是,则将其设置为true。完成后,循环遍历结果集,并将[…][…]这些布尔值设置回false。这是一种廉价而肮脏的技巧,可以在线性时间内找到唯一集(使用极其廉价的迭代),而无需更昂贵的哈希查找或涉及树数据结构的线性算法来表示唯一集。