iT邦幫忙

2025 iThome 鐵人賽

DAY 13
0
Modern Web

WebXR未來新視界:Babylon.js打造Web的VR/AR/XR體驗系列 第 13

[Day13] 避免碰撞v.s配上Babylon.js物理引擎的碰撞與重力效果(Feature - 單元四)

  • 分享至 

  • xImage
  •  

Feature單元四 Avoiding Collisions:避免碰撞

剛剛加上的模型就像是個投象,並沒有實體。他們是有可能互相穿透的,而為了防止這樣的破綻,這個範例就是要用來防止碰撞。

一個模型都會有一個把它包起來個邊界框,可以使用intersectsMesh方法檢查網格相交的狀況:

mesh1.intersectsMesh(mesh2);

為了防止人車碰撞,因此建了一個長方形盒子來感應車子交疊的時候,並且路人沒有跟這個盒子交疊的時候,就讓路人停下腳步來避免碰撞穿越。所以主要是以下這段利用控制實體的位置來防止互相的碰撞穿越,那如果我想要加上物理引擎來讓他碰撞呢?

scene.onBeforeRenderObservable.add(() => {
    if (carReady) {
        // 重點在這段判斷
        if (!dude.getChildren()[1].intersectsMesh(hitBox) && scene.getMeshByName("car").intersectsMesh(hitBox)) {
            return;
        }

    }
    dude.movePOV(0, 0, step);
    distance += step;

    if (distance > track[p].dist) {

        dude.rotate(BABYLON.Axis.Y, BABYLON.Tools.ToRadians(track[p].turn), BABYLON.Space.LOCAL);
        p +=1;
        p %= track.length; 
        if (p === 0) {
            distance = 0;
            dude.position = new BABYLON.Vector3(1.5, 0, -6.9);
            dude.rotationQuaternion = startRotation.clone();
        }
    }

})

最後可以在playground跑跑看結果

補充:如果我就想互撞呢?

物理引擎 (Physics Engine)是一個把你的物體,依據材質(質量﹑彈性﹑摩擦力),根據物理計算出他的重力與碰撞、跟使用者互動力與運動等的幫手。與動畫設計每一幀不同,你設定規則,他模擬結果。Babylon.js內建了對多種物理引擎的插件支援,整合度非常高。

以下有主要常見的三個引擎的比較:

物理引擎 主要特點 優點 缺點/注意事項
Havok 官方合作、最高效能。由 Microsoft 維護,是專業遊戲(如《上古卷軸》、《最後一戰》)使用的物理引擎的 Web 版本。 效能極佳,穩定且功能強大,是 Babylon.js 官方推薦的未來方向。 授權注意:在客戶端(瀏覽器)使用是免費的。但若要在伺服器端進行物理運算,則需要商業授權。
Ammo.js 功能強大、社群成熟。它是廣受歡迎的 C++ Bullet 物理引擎透過 Emscripten 編譯到 WebAssembly (WASM) 的版本。 效能優於 Cannon.js,功能非常完整,社群支援良好。在 Havok 出現前是最高效能的選擇。 檔案體積相對較大。
Cannon.js 純 JavaScript、最易上手。完全用 JavaScript 寫成,不需要編譯過程。 輕量,易於除錯和理解,非常適合簡單的專案或學習物理概念。 效能是三者中最差的,且已多年未更新,可能存在一些 bug。
  • 新專案或追求高效能:首選 Havok
  • 需要廣泛相容性或已有專案Ammo.js 是一個非常可靠且強大的選擇。
  • 非常簡單的教學或原型Cannon.js 依然可用,但已不推薦用於正式專案。

關於引用物理引擎的方法, 在playground可以試試看加上Havok:

比較關鍵的是這一段 :

    // 使用plugin
    var hk = new BABYLON.HavokPlugin();
    /**
     * enablePhysics是要讓場景啟用物理引擎, 並加上重力, 重力的方向是y軸,
     *  -9.8是模擬地球標準的重力加速度
     * 並告訴要用hk也就是上面一行宣告的Havok引擎來計算效果
     */
    scene.enablePhysics(new BABYLON.Vector3(0, -9.8, 0), hk);

    // Create a sphere shape and the associated body. Size will be determined automatically.
    /**
     * PhysicsAggregate 是一個輔助物件讓模型和對應的物理實體綁在一起, 
     * 所以用這個方式建立的球體就有物力的實體不能隨意變穿透過去
     * mass是物體的質量,質量越大受重力影響越大
     * restitution是彈性的恢復係數,通常是0-1間, 0.75代表碰撞後保留 75% 的能量反彈
     */
    var sphereAggregate = new BABYLON.PhysicsAggregate(sphere, BABYLON.PhysicsShapeType.SPHERE, { mass: 1, restitution:0.75}, scene);

    // 在這行我們建立的地板, mass要為0才不會受到這個場景的重力影響,單純作為一個障礙物待在原地
    var groundAggregate = new BABYLON.PhysicsAggregate(ground, BABYLON.PhysicsShapeType.BOX, { mass: 0 }, scene);

因此,在使用PhysicsAggregate 建立兩個有物理實體的物體-地面跟球體,他們就會互相碰撞而不會穿越過去了。

他真的整合得很好只需要幾行程式碼就可以達到很優秀的效果!

物理引擎的更多文件


上一篇
[Day12] 讓世界動起來:Babylon.js 的基本動畫,讓車子動起來(Feature - 單元三)
系列文
WebXR未來新視界:Babylon.js打造Web的VR/AR/XR體驗13
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言