在WPF中进行碰撞检测
前文我簡要的介紹了在WPF中,如何控制攝像頭移動,已達到動畫的效果。也帶來了一個新的問題:攝像頭移動的時候,毫無阻攔,這就是所謂的“穿墻模式”。有沒有什么辦法解決這個問題呢?有,就是在移動攝像頭前先進行“碰撞檢測”,確定攝像頭的新位置區間中沒有其他的三維模型。本文將介紹如何在WPF中進行三維碰撞檢測。
利用Rect3D.IntersectsWith 方法
在進入下一節前,先看看最簡單的碰撞檢測方式:利用Rect3D.IntersectsWith 方法。
Model3D有一個Bounds屬性,用來表示該Model3D的邊界:
該屬性是Rect3D類型的,我們可以使用IntersectsWith 來確定相機位置所在的矩形是否與此Rect3D相交。如果是,則說明相機移動到Rect3D內部,沖突發生;如果否,則表示相機離Model3D還有一段距離,可以放心地移動。
沒有發生碰撞
發生碰撞的情況
使用Rect3D.IntersectsWith 方法,對于規規矩矩的正方體來說,效果很好。但是如果使用Rect3D.IntersectsWith 方法檢測攝像機是否和不規則物品的外接多邊形發生碰撞,精確性會降低很多。就拿上圖來說,紅色方塊所在的攝像機實際上和房子還有很遠一段距離,但卻在房子所在區域里,這個時候,Rect3D.IntersectsWith 檢測的結果是“碰撞發生了”。
因此,需要用稍微復雜一點的方法,VisualTreeHelper.HitTest方法,對三維物品進行命中測試,以處理不規則物品的碰撞檢測問題。
利用VisualTreeHelper.HitTest 方法
VisualTreeHelper.HitTest是由三個函數重載而成的,在三維世界里,使用:
public static void HitTest(Visual3D reference,HitTestFilterCallback filterCallback,HitTestResultCallback resultCallback,HitTestParameters3D hitTestParameters )方法來進行命中測試。
reference:要進行命中測試的 Visual3D。 也就是場景中的不規則的三維物品。
filterCallback:表示命中測試篩選回調值的方法,有時候,并非所有的三維物品都是不可穿越的,例如泳池中的水,在沒有結冰的前提下是阻止不了Camera移動的,因此,可以filterCallback設置這些物體。
resultCallback:表示命中測試結果回調值的方法。
hitTestParameters:要進行命中測試的三維參數值。
對于最后一個參數,hitTestParameters,使用的是HitTestParameters3D的一個子類:RayHitTestParameters(也是目前HitTestParameters3D的唯一子類)。該類表示一個射線。
看到這里,你大體會意思到如何使用VisualTreeHelper.HitTest來進行碰撞檢測了吧。沒錯!我們將Camera所在的位置看做射線的端點,Camera移動的方向看做射線的方向。通過VisualTreeHelper.HitTest方法,能得到當該射線的端點和Visual3D對象交點的距離:
當這個距離滿足一定的值時,就能得出:碰撞已發生。
protected bool isCollision = false;public bool TestCollision(ProjectionCamera camera) {isCollision=false;foreach(Visual3D 3d in Word.Children){RayHitTestParameters rayparams =new RayHitTestParameters(camera.Position, camera.LookDirection);VisualTreeHelper.HitTest(element, null, HTResult, rayparams);if(isCollision) return true;}return false; }public HitTestResultBehavior HTResult(System.Windows.Media.HitTestResult rawresult) {RayHitTestResult rayResult = rawresult as RayHitTestResult;if (rayResult != null){RayMeshGeometry3DHitTestResult rayMeshResult =rayResult as RayMeshGeometry3DHitTestResult;//如果距離小于1.0,則認為碰撞已發生if (rayMeshResult.DistanceToRayOrigin < 1.0){isCollision = true;return HitTestResultBehavior.Stop;}}return HitTestResultBehavior.Continue; }轉載于:https://www.cnblogs.com/carekee/articles/2039135.html
總結
以上是生活随笔為你收集整理的在WPF中进行碰撞检测的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: iOS7磨砂设计效果换成透明效果
- 下一篇: 学习:java设计模式—工厂模式