【问题标题】:Generate every combination of objects (without duplicate) in a BSP Tree在 BSP 树中生成每个对象组合(不重复)
【发布时间】:2017-01-27 11:35:36
【问题描述】:

我正在使用一个碰撞检测系统 Binary Space Partitioning Tree。我有两种对象:

  • 需要检查与其他对象碰撞的动态对象(角色、射弹),
  • 静态对象(如墙壁)不会相互碰撞测试,但只能针对动态对象进行测试。

为此,我使用了两种数据结构:用于存储所有动态对象的列表,以及包含所有对象(动态或静态)的 BSP 树。因此,每个动态对象都存储在两个结构中。

最后,我通过遍历列表并使用树来测试每个对象来执行碰撞检测,如下所示:

foreach(DynamicObject dynobj in myListOfDynamicObjects)
{
    //check the collision against every close dynamic or static objects
    myBSPtree.CheckCollision(dynobj);
}

然而,在这一点上,我没有想到:两个动态对象之间的每次碰撞检查都会进行两次。例如:

\ 动态对象列表:{dynA, dynB} 树:dynA / \ 静态1动态B

组合测试:

  • dynA - dynA (处理无用的情况)
  • dynA - 静态1
  • dynA - dynB
  • dynB - dynA(同上)
  • dynB - 静态1
  • dynB - dynB

为了跳过无用的检查,我想在每个对象上添加一个属性 Order :它将是对象构造时给出的唯一标识符,并像这样使用:

if(dynA.Order < dynB.Order){ CheckCollision(dynA,dynB); }

这样,每个对象组合只进行一次碰撞检查。

我的问题是:如果这种技术是正确的(我的意思是它是一个好的设计吗?),并且由于每个对象在 C# 中都有一个唯一的引用,我可以像这样直接比较它们的引用吗:(?)

if(dynA.Reference < dynB.Reference){ CheckCollision(dynA,dynB); }

我们可以使用 object.ReferenceEquals 来查看两个引用是否相等,但是我们可以对这些引用进行实际比较吗?

【问题讨论】:

  • 你的方法对我来说似乎很合理。你甚至可以使用GetHashCode() method(但是为了处理哈希冲突,检查还应该包括相等性)。您始终可以生成一个唯一标识符,但我不确定您的情况是否有必要。

标签: c# tree collision-detection bsp-tree


【解决方案1】:

我会好好看看 Quake/2/3 如何处理这个问题。您可以在此处考虑一些优化:

1) 使用三次子体积作为 3 维网格来缓存每个实体所在的 BSP 区域。这样,您只需针对整个树的子集测试每个动态对象。随着 BSP 树大小的增长,这是一个巨大的性能提升。

这是我的实现,从 Quake2 中借用并且为了可读性而进行了大量清理:

https://github.com/jdolan/quetoo/blob/master/src/server/sv_world.c

2) 为避免重复的碰撞检查,只需在主碰撞入口点引入一个计数器,并在每次调用该函数时递增它。测试给定对象时,将其自己的碰撞计数器设置为当前计数器值。在进行任何工作之前检查该值。这就是 Quake 避免两次检查相同 BSP 节点的方式。

if (obj->collisionCounter == _collisionCounter) {
    return;
}

obj->collisionCounter = _collisionCounter;

如果您希望您的碰撞代码是线程安全的,请确保您拥有所有碰撞参数和状态的碰撞上下文结构,并将该结构的实例传递给您的所有碰撞函数。当然,在该结构中实现collisionCounter。 Quake 将此结构称为trace_t,顺便说一句。再说一次,如果它有帮助的话,这是我的:

https://github.com/jdolan/quetoo/blob/master/src/collision/cm_trace.c

【讨论】:

    猜你喜欢
    • 2010-12-15
    • 1970-01-01
    • 2012-01-02
    • 1970-01-01
    • 2012-04-14
    • 1970-01-01
    • 2016-06-30
    • 1970-01-01
    • 2019-02-06
    相关资源
    最近更新 更多