您的位置:首页 > 产品设计 > UI/UE

PhysX3 User Guide 05 - Scene Queries

2011-06-04 16:26 337 查看
有两种方式查询场景中的碰撞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)就是一个典型应用。

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

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,包括PxSceneQueryFilterFlags和PxFilterData

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::ePREFILTER 或
PxSceneQueryFilterFlag::ePOSTFILTER .

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



eNONE,表示shape不许参与后面的query处理。

eBLOCK,表示shape是hit最终结束在的物体blocking hit,凡是比该shape更远的shape都不必参与query。(从后文来看该shape并没有被过滤掉,仍然是参与query的。)

eTOUCH,表示shape是一个touching hit,参与query处理,除非后续filter callback给它过滤掉了。



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

Caching

PxSceneQueryCache 可以用来加速某些情况下的query,尤其是raycastAny, raycastSingle 和 sweepSingle .它的工作方式是:在缓存中定义了一些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对象。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: