zhouqijie

碰撞查询

碰撞检测的另一任务是回答关于游戏世界中碰撞体积的假想问题(hypothetical question),例如物体从A点移动到B点是否会碰到什么障碍物,例如找出给定半径内所有敌人对象。这些操作被称为碰撞查询(collision query)。碰撞查询的尸体并不存在于碰撞实体,它完全不会影响世界中的其他物体。

最常用的查询类型是投射(cast)



1.射线投射

最简单的投射是射线投射(ray cast)。射线投射实际上投射的是有向线段,有起点和终点(多数碰撞系统不支持无限长的光线)。投射线段如果与碰撞世界物体相交,可以传回最早接触点或者所有接触点的集合。

射线投射系统的线段通常以起点p0以及增量向量d描述,起点加上增量向量后就会得出终点p1。

$p(t) = p_0 + td, t ∈[0, 1]$

struct RaycastHit{
    float t;//接触点的t值
    uint colliderId;//击中的碰撞体ID
    vec3 normal; //接触点法线
    //...其他信息
}

射线投射的应用:

  1. 视线判断
  2. 武器系统
  3. AI系统
  4. 载具系统
  5. 其他…

2.形状投射

形状投射(shape cast)另一种对碰撞系统的常见查询,是查询一个凸形状可以沿一有向线段移动多远才会碰到其他物体。

  1. 投射形状已插入或者接触到至少一个其他的碰撞体。
  2. 投射形状在起点没有与任何其他碰撞体相交。
struct ShapeCastContact
{
    float t;
    uint colliderId;
    vec3 contactPoint;
    vec3 normal;
    //...其他信息
}

形状投射的应用:

  1. 判断摄像机是否与游戏世界的物体碰撞。
  2. 角色移动时的离地检测。

3.Overlap

有时需要判断碰撞体是否位于游戏中某些特定体积内。例如获取一个半径范围内所有敌人列表。

Havok提供一种特别的碰撞体”Phantom”,Phantom和零距离形状投射的区别是Phantom是持续存在的,能利用时间一致性优化。
Cre:Unity中可以调用Physics.Overlap()来获取范围内所有碰撞体。

4.其他查询

Havok支持最近点(closest point)查询,给定一个碰撞体,就能找出其他接近的碰撞体上的最近点集合。

(END)