与 BSP 几何体的碰撞

问题描述 投票:0回答:1

我正在制作一个基于 BSP 级别的引擎。我有一个实心叶 BSP 树,我已经可以测试点是否位于实心叶或空叶中,但是我不明白如何对边界框执行相同操作。

我尝试将边界框的最小和最大尺寸添加到速度中:

public bool CanMove(Vector3 _velocity) {
    Vector3 velocity = new Vector3(_velocity.X > 0 ? _velocity.X + max.X : _velocity.X + min.X, _velocity.Y > 0 ? _velocity.Y + max.Y : _velocity.Y + min.Y, _velocity.Z > 0 ? _velocity.Z + max.Z : _velocity.Z + min.Z);
    return IsPointInNode(center + velocity, map.coreNode);
}

bool IsPointInNode(Vector3 position, MapNode node) {
    if (node.isLeaf) {
        return node.isSolid;
    }
    return Vector3.Dot(node.plane.normal, position) + node.plane.distance < 0 ? IsPointInNode(position, node.frontChild) : IsPointInNode(position, node.backChild);
    }
}

它有效,但是一次只能应用最小或最大边界框大小,因此会发生剪切。 我知道 quake 的碰撞外壳 BSP,但这对我来说似乎不太好,因为我预计会有很多不同的对撞机大小,并且为每个对撞机存储单独的树似乎没有吸引力。

是否有更好的方法来使用 BSP 检查边界框碰撞,或者我应该将原始画笔存储在地图内并使用它们进行碰撞检测?

geometry bsp-tree
1个回答
0
投票

我已经弄清楚了。您可以在遍历 BSP 树本身时将碰撞箱大小添加到平面距离,而不是使用具有扩展墙(平面)的单独树:

return Vector3.Dot(node.plane.normal, position) + (node.plane.distance + hullSize) < 0 ? IsPointInNode(position, node.frontChild) : IsPointInNode(position, node.backChild);

如果你的碰撞盒在不同的维度上有不同的尺寸,你只需将平面法线乘以碰撞盒大小即可:

float hullSize = Math.Abs(node.plane.normal.X * size.X) +
                   Math.Abs(node.plane.normal.Y * size.Y) +
                   Math.Abs(node.plane.normal.Z * size.Z);
© www.soinside.com 2019 - 2024. All rights reserved.