このブログで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を使うことが多いのでおなじみかもしれません。
まず概要をさっと列挙したいため、次回はパーティクルについて書いていく予定です。
その後、実際の設定方法などまとめていきます。