🥊

8th Wall × Babylon.jsで 物理演算する

2023/07/04に公開

この記事はBabylon.js ゆるほめLT会 vol.2で話す内容の一部です.
スライドもぜひ読んでください!
https://speakerdeck.com/sakutama_11/8th-wall-x-babylon-dot-jsdehavok-physics-babylon-dot-js-yuruhomelthui-vol-dot-2
https://babylonjs.connpass.com/event/285198/

【著者】 さくたまです. ARとドラムとNeRFが好きです.
https://twitter.com/sakutama_11

8th WallでBabylon.jsのHavok pluginは使えます

Babylon.jsへのサポートが薄く,サンプルほとんどない 8th Wallですが,Babylon.jsのHavok pluginによる物理演算がちゃんと動きます.
8th Wallで物理演算を使うために色々cdnで読み込んで組み合わせるの面倒だと思うので,pluginとしてまとめて使えるBabylon.js便利ですね!
https://www.8thwall.com/8thwall/unitcube-babylonjs
https://doc.babylonjs.com/features/featuresDeepDive/physics/havokPlugin

方法

Babylon.jsテンプレートから8th Wallプロジェクトを作る

アカウントもろもろはあることを前提に書きます.
下記のBabylon.jsのサンプルプロジェクトにアクセスし,clone projectを押すだけで簡単に8th Wall上でBabylon.jsが動くプロジェクトが作れます.
https://www.8thwall.com/8thwall/unitcube-babylonjs

Havok pluginが使えるBabylon.js(ver 6.0.0以上)の読み込み

元々のBabylon.jsサンプルにあるhead.html

head.html
<!-- Copyright (c) 2022 8th Wall, Inc. -->
<!-- head.html is optional; elements will be added to your html head before app.js is loaded. -->

<!-- Use "8thwall:" meta tags to hook into 8th Wall's build process and developer tools. -->
<meta name="8thwall:renderer" content="babylonjs:5.23.0" />
<meta name="8thwall:package" content="@8thwall.xrextras" />
<meta name="8thwall:package" content="@8thwall.landing-page" />

<!-- Other external scripts and meta tags can also be added. -->
<meta
  name="viewport"
  content="width=device-width, initial-scale=1.0, user-scalable=no"
/>
...

Havok pluginが使える6.0.0以上のBabylon.jsを読み込み直す. Havok pluginも別途umdで読見込む必要あり.

head.html
<!-- Copyright (c) 2022 8th Wall, Inc. -->
<!-- head.html is optional; elements will be added to your html head before app.js is loaded. -->

<!-- Use "8thwall:" meta tags to hook into 8th Wall's build process and developer tools. -->
<!-- Babylon.js version should be higher than 6.0.0 -->
<meta name="8thwall:renderer" content="babylonjs:6.10.0" />
<meta name="8thwall:package" content="@8thwall.xrextras" />
<meta name="8thwall:package" content="@8thwall.landing-page" />

<!-- Other external scripts and meta tags can also be added. -->
<meta
  name="viewport"
  content="width=device-width, initial-scale=1.0, user-scalable=no"
/>
<!-- Needed for shadows -->
<script
  src="//cdn.babylonjs.com/materialsLibrary/babylonjs.materials.min.js"
  crossorigin="anonymous"
></script>
<!-- Needed for physics -->
<script
  src="//cdn.babylonjs.com/havok/HavokPhysics_umd.js"
  crossorigin="anonymous"
></script>

Havok physicsの使用を宣言

HavokPhysicsの使用を宣言し,有効化します. HavokPhysicsの読み込みにawait使うと怒られるのでinitXrScene関数をasync functionにしてください.

babylonjs-scene-init.js
const initXrScene = async ({scene, camera}) => {
  ...
  const havokInstance = await HavokPhysics()
  const havokPlugin = new BABYLON.HavokPlugin(true, havokInstance)
  scene.enablePhysics(new BABYLON.Vector3(0, -9.8, 0), havokPlugin)
})

オブジェクトの物理演算を有効にする

せっかくなのでサンプルの素材だけで物理を実感できるようにしてみます.動きがわかりやすいようにrestitutionを高めにしています.サンプルの箱が地面で弾むように動くはずです.

babylonjs-scene-init.js
const initXrScene = async ({scene, camera}) => {
  ...
  scene.enablePhysics(new BABYLON.Vector3(0, -9.8, 0), havokPlugin)
  
  // ここから追加
  box.position.y = 4
  const boxAggregate = new BABYLON.PhysicsAggregate(box, BABYLON.PhysicsShapeType.BOX, {mass: 1, restitution: 0.9}, scene)
  const groundAggregate = new BABYLON.PhysicsAggregate(ground, BABYLON.PhysicsShapeType.BOX, {mass: 0}, scene)
})

終わりに

とても簡単に物理演算を有効にできました.パフォーマンス比較などしていませんが, Havok Physicsは軽量な物理演算で,大量のインスタンスを動かしている例なども見かけるので,ARで現実の物体とのインタラクションを表現してより現実味のあるコンテンツを作れると面白いですね!

↓音が出るドラムを作りました
https://iwakenlab.8thwall.app/sakutama-havok

Discussion