PhysX3 User Guide 05 Scene Queries

有两种方式查询场景中的碰撞collision:批处理batched和非批处理non-batched。非批处理查询又称single shot queries,使用PxScene类的接口,是PxScene的一项常规功能。批处理查询是使用PxBatchQuery对象,PS3上只有批处理查询一种方式。

    Raycast queries      

 


查询中用户定义的射线ray会与整个场景相交intersected with the whole scene。PhysX有三种射线:

  • raycastAny
  • raycastSingle
  • raycastMultiple

查询碰撞collision时,返回的最主要的信息是一个布尔是非值,表示碰没碰上,若需获取更多信息,比如射线是不是穿过了什么之类的,就可以用raycastAny。至于交点的确切信息、相交的是个啥形状,这些都不是raycastAny关心的内容,它只关心一件事,是不是有击中发生(there was a hit)。人工智能中的视线查询(line-of-sight queries)就是一个典型应用。

raycastSingleraycastAny先进一些,通过它可以知道第一个被击中的是个嘛。譬如说子弹击中的情形。

raycastMultiple是最高级的。ray会hit到的所有物体都可以得到。好比说穿甲子弹。

注意:* solid物体(sphere, capsule, box, convex)是封闭的closed(即它们包括它们的边界boundaries)

        * plane是封闭的半空间 closed halfspace

        * heightfield也是封闭的,并且是solid物体。 

射线投射在solid物体上,射线是有终点的。射线ray和solid物体的相交intersection会引发一个击中报告hit report。

下表显示了不同物体对射线是否会产生hit report报告的反应是不同的。比如只要起点位于plane内部,即平面以下,无论射线终点在哪儿,也不会有plane被hit的report返回。

  

     Sweep Queries     

 

Queries中Shape会以一指定的方向扫sweep过去,并报告是否与场景Scene有碰撞collision。也有三种sweep方式:

  • sweepAny
  • sweepSingle
  • sweepMultiple

它们的区别也和3种ray之间的区别一样。 

目前支持sweep的形状Shape有box, sphere和capsule。

    Overlap Queries     

 

overlap query返回的是和场景发生碰撞的物体所接触到的其他物体。有两种overlap

  • overapAny 
  • overlapMultiple

overlapAny 也叫placement API,特别适用于只知道场景的体积是不是空的情况。

overlapMultiple并不会在第一次hit后停下来,而是会返回其后所有被碰到的物体。

没有overlapSingle,因为没必要。overlap并没固定一个具体的方向,因此也就不能得到某个方向上的最近或最远,因此single木有存在的意义。(难道时间上也木有排序的意义么?)

overlap接受box,sphere和capsule三种形状。

    Filtering     

 

有几种方法可以把场景中不需要的Shape过滤掉。query与filter有关的参数有:

  • 结构体PxSceneQueryFilterData,包括PxSceneQueryFilterFlagsPxFilterData
  • PxSceneQueryFilterCallback选项

这些灵活多变的filter机制允许用户锁心所欲的自定义过滤行为。俺们来看几个例子:

首先PxSceneQueryFilterFlag::eSTATIC PxSceneQueryFilterFlag::eDYNAMIC 标志提供了第一层过滤。它们表示query是针对场景中的static还是dynamic对象。如果想query全部static或dynamic对象时,这显然比一个一个往filtering callback中加对象要方便。例如,爆炸效果可以球体的overlapMultiple来扫全场景中的dynamic对象(打开PxSceneQueryFilterFlag::eDYNAMIC标志),对static对象只需要给他们加个外力什么的就可以了。

第二个层次上的过滤由PxFilterData提供,它是一个128位的掩码。query会拿shape的掩码跟自己比较,通过才将shape纳入本次query。shape通过的情况有两种:1,query的掩码为零;2,shape的掩码和query的掩码按位与的结果非零(其实非零即等于掩码,掩码通常是只有1位为1)。

filter callback可以建立更灵活的过滤规则。filter callback需实现PxSceneQueryFilterCallback后传给query。然后场景查询可以在需要时调用其。调用时机可能是计算碰撞前也可能是其后,视实际情况。当然在计算之前就决定是不是要丢弃shape的开销是要小一些,但有时候计算以后的结果是你的判断条件之一。设置callback调用时机使用这俩filter标志:PxSceneQueryFilterFlag::ePREFILTERPxSceneQueryFilterFlag::ePOSTFILTER .

filter callback会返回一个PxSceneQueryHitType 。该值可能为:

  • eNONE,表示shape不许参与后面的query处理。
  • eBLOCK,表示shape是hit最终结束在的物体blocking hit,凡是比该shape更远的shape都不必参与query。(从后文来看该shape并没有被过滤掉,仍然是参与query的。)
  • eTOUCH,表示shape是一个touching hit,参与query处理,除非后续filter callback给它过滤掉了。 

eNONEeBLOCK比较简单。NONE就丢弃shape不参与query,BLOCK就将shape加入query。eTOUCH是新增加的值,为了处理像子弹穿过窗户(打碎窗户但继续向前)这样的情形。显而易见eTOUCH只对造成Multiple hits的query有效。

    Caching      

 

PxSceneQueryCache 可以用来加速某些情况下的query,尤其是raycastAny, raycastSinglesweepSingle .它的工作方式是:在缓存中定义了一些shape,甚至三角面(三角面和shape都会被首先测试)。高度时序性的query会因此得到显著的效率提升。解决这类时序问题的一个好方法是将上一帧的query结果放在query缓存对象中。

例如,人工智能的可见度query很可能连续几帧都返回同一个遮挡物blocking shape。那俺们就可以给到这个raycastAny(视线的query常用racycatAny,前面有讲)一个恰当的PxSceneQueryCache,然后呢,query会在检查其他shape之前就马上发现它hit了缓存中的这个shape,然后query就返回了。

再譬如,在缓存中存放上一次的closest hit,这会大大提高query查找closest hit的效率。

    Batched Queries     

 

批查询使用的是PxPatchQuery对象的接口。 顾名思义,就是可以把多个Query组合在一起,然后一次执行(调用PxBatchQuery::execute())。批查询基本上和非批查询是一样的。他俩的区别主要是:

  • PS3的SPUs只能跑批查询
  • 硬编码的过滤方程(hardcoded filtering equation) 不能用于批查询。取而代之的是两个filter shader:PxBatchQueryPreFilterShader 和 PxBatchQueryPostFilterShader

查询结果先写入PxPatchQueryDesc中用户指定的缓冲区,后以同样的顺序输出到PxPatchQuery对象。

原文地址:https://www.cnblogs.com/mumuliang/p/2072708.html