CrossRoad

XRを中心とした技術ブログ。 Check also "English" category.

Babylon.jsのHavokで力を与えてオブジェクトを動かす方法

クリックしたらボールが動くという仕組みです。非常に単純ですが、公式ドキュメントにサンプルコードがなかったので、解説付きでまとめました。

1. Havokでは、3Dオブジェクトに当てたbodyとshapeで物理演算を実行する

こちらに記載の通りですが、bodyは速度や移動などに関係し、shapeは弾性とか摩擦力などに関係します。

Unityの場合、rigidbody componentとphysicsMaterialで分かれていますが、これと同じように考えるとわかりやすいです。

Bodies and shapes have properties which approximate how they behave in the real world. Bodies have a mass distributions and velocities. The velocity is the speed the body is moving at, while the mass distribution describes how the velocity changes when two bodies interact.Shapes themselves are geometric objects which is used for detecting when bodies are colliding with each other; these shapes additionally have material properties (PhysicsMaterial) such as friction and restitution (which describe how a collision affects the bodies when sliding and bouncing) and a density (which can be used to calculate the mass properties).

Babylon.js docs

参考

docs.unity3d.com

docs.unity3d.com

2. Havokのaggregateを使うと、bodyとshapeを一気に宣言できる

ここに気づかずはまってしまったのですが、よく読むと書いてありました。

The Physics Aggregate is a object that contains a Body and a Shape. It's a helper that allows creating all the objects necessary to physicalize your scene in just one call.

Babylon.js docs

もちろん、bodyとshapeを個別に宣言することもできます。

aggregateの宣言と、aggregateからbodyを読み出す時の書き方例です。

const aggregate = new BABYLON.PhysicsAggregate(sphere, BABYLON.PhysicsShapeType.SPHERE, { mass: 1 }, scene);
aggregate.body.setMassProperties({mass: 10});

2023/8/22追記

https://twitter.com/cx20 さんに教えていただきました。 HavokではPhysics Aggregateもあるのですが、bodyとshapeを分けて宣言する方法を使う方が、より細かいカスタマイズができるようです。

One of the most important new features in the new architecture is the ability to fine-tune the collision shapes and reuse them, improving memory usage and customizability.

Babylon.js docs


3. Havokで力を与えるときはapplyForceかapplyImpulseを使う

従来の物理エンジンと同じです。applyForceは継続的な力、applyImpulseは瞬間的な力です。

A force is a continuous effect that is applied to an object over time, which can change the object's velocity or direction of motion. For example, a force could be used to simulate gravity, wind resistance, or a player pushing an object. An impulse, on the other hand, is a sudden, instantaneous effect that changes the velocity of an object. It is a specific amount of force applied over a very short duration of time,

Babylon.js docs

これらは、先ほど書いたbodyに対して使います。

◾️applyForceの例

シンプルにするため、画面の任意の位置をクリックしたらapplyForceが発動する処理にしました。

Vector3(0,0,100)としたので、クリックしたことでボールが奥 (+z方向) に向かって移動しています。Vector3の値を大きくすると、与える力が大きくなります。

An example of Havok applyForce on Babylon.js

こちらにサンプルコードを作りました。
https://playground.babylonjs.com/#R66K4K

◾️applyImpulseの例

同じく画面の任意の位置をクリックしたら、applyImpulseが発動する処理にしました。

Vector3(0,10,0)としたので、クリックしたことでボールが上 (+y方向) に向かって跳ねます。Vector3の値を大きくすると瞬間的な力が大きくなるので、瞬時に見えなくなります。

An example of Havok applyImpulse on Babylon.js

こちらにサンプルコードを作りました。

https://playground.babylonjs.com/#Z8HTUN#671

4. おわりに

日本語の情報が少ないので手探りですが、これでHavokの基本的な使い方が見えてきたように思います。