天天看點

PhysX3 User Guide 05 - Scene Queries

原文位址:http://www.cnblogs.com/mumuliang/archive/2011/06/04/2072708.html

有兩種方式查詢場景中的碰撞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傳回。

PhysX3 User Guide 05 - Scene Queries

     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對象。

繼續閱讀