[Omniverse] Physicsを使う

  • by

このブログでOmniverseのPhysicsについてはまとめてなかったので、現在どこで使えるのかというのを書いていくことにしました。
後々、Unity Connector経由でUnityからPhysicsを含むシーンをUSD経由で渡します。

ここではOmniverse USD Composer 2023.2.2を使用しました。

OmniverseでのPhysics

PhysX」はNVIDIA社が開発・提供している物理シミュレーションのエンジンです。
Unityでも物理機能としてPhysXが使われています。
OmniverseではPhysics機能の内部エンジンとしてPhysXが使われています。
というよりも、OmniverseはPhysXを完全に内包してしまっているともいえます。
PhysXを直接操作する必要はありません。
また、USDはファイルフォーマットとして標準でPhysics情報を持っています。

Physicsでできること

  • RigidBody : 剛体シミュレーション(PhysicsJointも含む)
  • Deformable : ソフトボディ
  • Particles : パーティクル
  • Particle Cloth : 布表現
  • Articulation : 関節の可動

PhysicsJointは複数の剛体をつなぐ仕組みです。
Articulationは聞きなれないかもしれません。
産業用ロボットなどを構成する場合、物理要素の連結を表現することができる仕組みです。
USDでは、PhysicsJointの構造のルートに対してArticulation Rootを与えて構築します。
これらは後々まとめる予定です。

今回はまず剛体/Deformable(ソフトボディ)/Particle Clothを見ていきます。
今回は大量の球体を配置するのだけPythonスクリプト( https://github.com/ft-lab/omniverse_sample_scripts/blob/main/Physics/RigidBody/rigidbody_benchmark.py )を使用。
それ以外はUSD Composer上のUI上で行いました。

Physicsへのアクセス手段

USD ComposerではUIからある程度Physicsの設定を行うことができます。
それ以外に大きく以下の2つのアクセス手段があります。
USDファイルにPhysicsの情報を書き出せば使えますが、より細かく制御する場合はPythonスクリプトを使うほうが効率がいいと思います。
プログラムでパラメータを与えるほうが効率がいい場合も多々あります。

  • USDファイル
  • Pythonスクリプト(Extension)

Python ScriptはUSD APIと結びついており、C++のOmniverse ConnectorからもPhysicsを制御することができます。

Physicsのサンプル

USD Composerの[Window]-[Simulation]-[Demo Scenes]を選択すると、Physicsのサンプル一覧を開くことができます。
それぞれに対してPythonスクリプトのコードも用意されているため、これで一通りのPhysicsの機能を確認できます。

Physics Demo ScenesウィンドウにさまざまなPhysicsのサンプルがあります。
PhysicsやPythonスクリプトについては、これから学習していくと分かりやすいかと思います。

Physicsの機能を見ていく

それではいくつかPhysicsの機能を見ていきます。

RigidBody (剛体)

次の動画は、変形しない形状(剛体)同士の衝突の例。
球が自由落下し、地面の直方体に衝突しています。


なお、Physicsの動きを確認する場合はPlayを実行するようにしてください。

両方に衝突を判断するColliderが割り当てられており、球はColliderとRigidBodyが割り当てられています。

また、PhysicsSceneとして重力の向き (0, -1, 0)。これは鉛直下向き。
重力加速度980.0(cm/s^2)を確認できます。

PhysicsSceneはグローバルな物理設定を保持しています。
USDの単位はデフォルトでcmですので、ここで重力加速度をmに変換する計算をしてみます。
cmからm変換で0.01倍するので9.8(m/s^2)となり、一般的な地球の重力加速度になっているのが分かります。

これらの要素により、デフォルトではRigidBodyを与えられた剛体は重力を受けて自由落下することになります。

USDを更新せずにPhysicsを実行

デフォルトでは、Physicsの剛体を配置してアニメーション再生すると重いです。
これは、アニメーション時にフレームごとにUSDを更新する書き込みが走るのが原因になります。
Viewportの設定から Show By Type – Physics – Simulation Settings を選択。
Simulation Settingsウィンドウで"Fabric GPU"を選択します。

これで純粋なGPUのPhysics計算が行われるため段違いに速くなります。

RigidBody : Kinematic

RigidBodyのパラメータとして"Kinematic Enabled"があります。
デフォルトはOffです。
これをOnにした場合、対象の剛体は重力や外力の影響を受けません。
その代わり、ユーザが動かすRigidBodyに力を与えることができます。

PhysicsJoint

複数の剛体をPhysicsJointでつなぎます。
以下の場合は、CubeA、CubeB、CubeCの3つの剛体があり、それぞれにColliderとRigidBodyを割り当てています。
また、CubeAはKinematicにしました。

このとき、CubeAとCubeB、CubeBとCubeCをPhysicsJoint(ここではRevoluteJoint)でつないでいます。
Playすると、CubeAは固定された状態でCubeB、CubeCが連結されて動きます。

注意点として、USDでのPhysicsJointはRigidBodyが階層化されていません。

RigidBodyは互いに階層を持てない(ネストできない)点に注意してください。
PhysicsJointでつなぐことで関係を指示することになります。
上記は互いに1:1でつないでいますが、1:nの接続も可能です。
以下は、CubeAに対してCubeA-CubeB、CubeA-CubeDの2つの接続が存在しています。

PhysicsJointの種類は以下のようなものがあります。

  • Revolute Joint
  • Fixed Joint
  • D6 Joint
  • Prismatic Joint
  • Spherecal Joint
  • Distance Joint
  • Gear Joint

    PhysicsJointは2剛体の接続を管理するベースのパラメータと、個々の種類ごとのパラメータを組み合わせて使用します。

Gear Jointはまだ私が学習していないので省き、それ以外のジョイントを試してみました。

PhysicsJointの種類 : Revolute Joint

上記でのPhysicsJointは「Revolute Joint」というのを使いました。
これは、1軸を中心に回転を行います。また、回転角度の最小と最大も指定できます。

なお、軸の向きはワールドまたはローカル座標のXYZ軸固定というわけではなく、回転を与えて自由な向きにすることができます。

また、1軸の回転で回転角度制限を無制限(Not Limited)にすることで、スクリューのような回転を与えることができます。

PhysicsJointの種類 : Fixed Joint

Fixed Jointを使用すると2つの剛体をつなぎますが、この場合は不動になります。

剛体の親子関係を与えたい場合に使用します。

PhysicsJointの種類 : D6 Joint

D6 Jointは移動(Translation)、回転(Rotation)をそれぞれの軸に対して指定できます。
D6 Jointは万能型で、Revolute JointやFixed Joint、Distance Jointなどと同じような動作を行うことができます。
自由度の高い反面、パラメータの指定は少し難しいです。
次の例ではLimitのTranslationを調整し、紐のような動作を行うようにしました。

PhysicsJointの種類 : Prismatic Joint

Prismatic Jointは平行移動の制限をかけるのに便利なPhysicsJointです。

PhysicsJointの種類 : Spherecal Joint

Spherecal Jointは球体関節のように、指定の軸を中心として半球上に自由回転させることができます。

PhysicsJointの種類 : Distance Joint

Distance Jointは紐もしくはバネの効果を与えるのに適しているPhysicsJointです。
次の例ではバネの効果を与えてみました。

ソフトボディ : Deformable

MeshのSphereに対してDeformable Bodyを与えてみました。
Meshを選択し、Add – Physics – Deformable Bodyで物理属性を追加します。
これはソフトボディの効果を与えます。

Simulation Mesh Resolutionの値を上げることで、より弾力がある感じになります。

Particle Cloth

Blender上でSubdivideを使って60分割しています。
これをUSD Composerにインポートしました。

平面のMeshを選択し、Add – Physics – Particle Clothで物理属性を追加します。
USD Composerでは以下のようになりました。

今回は、まず基本的なPhysicsの要素について列挙してみました。
リアルタイムエンジンでPhysicsを触ったことある方は、よく見たことがある機能だと気づくかと思います。
物理エンジンは昨今はだいたい同じ機能が提供されてますね。内部でPhysXを使うことが多いのでおなじみかもしれません。

まず概要をさっと列挙したいため、次回はパーティクルについて書いていく予定です。
その後、実際の設定方法などまとめていきます。