概要
Jolt Physics は、C++ で記述された高性能でマルチコアに最適化された剛体物理および衝突検出ライブラリです。ゲームや VR アプリケーションに適しており、『Horizon Forbidden West』や『DEATH STRANDING 2』などの大作タイトルに採用されています。このライブラリは、コンストレイント、ソフトボディ、ビークル、幅広い衝突クエリなどの機能をサポートしています。
README プレビュー
[](https://cla-assistant.io/jrouwe/JoltPhysics)\n[](https://github.com/jrouwe/JoltPhysics/actions/)\n[](https://sonarcloud.io/dashboard?id=jrouwe_JoltPhysics)\n[](https://sonarcloud.io/dashboard?id=jrouwe_JoltPhysics)\n[](https://sonarcloud.io/dashboard?id=jrouwe_JoltPhysics)\n[](https://sonarcloud.io/dashboard?id=jrouwe_JoltPhysics)\n\n# Jolt Physics\n\nA multi core friendly rigid body physics and collision detection library. Suitable for games and VR applications. Used by Horizon Forbidden West and Death Stranding 2: On the Beach.\n\n[](https://www.playstation.com/en-us/games/horizon-forbidden-west/)\n[](https://www.playstation.com/en-us/games/death-stranding-2-on-the-beach/)\n\n|[](https://www.youtube.com/watch?v=pwyCW0yNKMA)|\n|:-|\n|*A YouTube video showing a ragdoll pile simulated with Jolt Physics.*|\n\nFor more demos and [videos](https://www.youtube.com/watch?v=pwyCW0yNKMA&list=PLYXVwtOr1CBxbA50jVg2dKUQvHW_5OOom) go to the [Samples](Docs/Samples.md) section.\n\n## Design considerations\n\nWhy create yet another physics engine? Firstly, it has been a personal learning project. Secondly, I wanted to address some issues that I had with existing physics engines:\n\n* Games do more than simulating physics. These things happen across multiple threads. We emphasize on concurrently accessing physics data outside of the main simulation update:\n * Sections of the simulation can be loaded / unloaded in the background. We prepare a batch of physics bodies on a background thread without locking or affecting the simulation. We insert the batch into the simulation with a minimal impact on performance.\n * Collision queries can run parallel to adding / removing or updating a body. If a change to a body happened on the same thread, the change will be immediately visible. If the change happened on another thread, the query will see a consistent before or after state. An alternative would be to have a read and write version of the world. This prevents changes from being visib
FAQ (5)
トラブル対応ARM/AArch64におけるJolt PhysicsのCountLeadingZerosでの__builtin_clz(0)未定義動作エラーを修正する方法は?
Jolt/Math/Math.h の ARM ブランチにパッチを適用し、__builtin_clz を呼び出す前にゼロが処理されるようにします:
return inValue ? __builtin_clz(inValue) : 32;
v5.6.0 のコードで、以下を:
#else
return __builtin_clz(inValue);
#endif
以下のように置き換えます:
#else
return inValue ? __builtin_clz(inValue) : 32;
#endif
これにより、他のアーキテクチャブランチおよび、ゼロに対して 32 を返す ARM の clz 命令と動作が一致します。Clang では、Clang がこの操作をゼロの結果が定義された形式に変換するため、UBSan のレポートは実質的に誤検出です。一方、GCC はゼロを未定義として扱い、結果の範囲が 0〜31 であるという前提に基づいて最適化を行う可能性があります。メンテナーは、ゼロチェックが単一の命令にコンパイルされることから、これを受け入れました。パッチを適用した後、-fsanitize=undefined を付けた場合も含めて、Jolt とプロジェクトをリビルドしてください。
トラブル対応JoltPhysics静的ライブラリからXCFrameworkを作成する際に発生する「Unknown header: 0xb17c0de」エラーを修正するにはどうすればよいですか?
このエラーは、Release/Distribution ビルドで CMake の INTERPROCEDURAL_OPTIMIZATION が有効になり、-flto=thin が渡されて LLVM ビットコードが .a ファイルに埋め込まれるために発生します。xcodebuild -create-xcframework はこれらのオブジェクトをパッケージ化できません。XCFramework ビルド用に IPO を無効にして Jolt を再ビルドしてください:
cmake -S Build -B build-apple -DCMAKE_BUILD_TYPE=Release -DINTERPROCEDURAL_OPTIMIZATION=OFF
cmake --build build-apple --config Release
その後、新しくビルドされた .a ファイルから XCFramework を作成します。CMake 経由で統合する場合は、Jolt を追加する前に CMAKE_INTERPROCEDURAL_OPTIMIZATION を OFF に設定するか、set_target_properties(Jolt PROPERTIES INTERPROCEDURAL_OPTIMIZATION OFF) を適用することもできます。LTO は通常の直接的な静的リンクでは有効のままにして構いません。XCFramework にバンドルする場合に限って無効にしてください。
トラブル対応Jolt Physicsを使用したGodotで、湾曲した球状の惑星上で平らなRigidBodyがジッター(振動)する問題を修正するにはどうすればよいですか?
惑星の SphereShape3D コリジョンを、球体メッシュから生成した ConcavePolygonShape3D のトライメッシュに置き換えてください。より単純なジオメトリであれば、ConvexPolygonShape3D でも対応できます。現在、Jolt は大きな球体に対して接触点を 1 つしか報告しないため、平坦な剛体との安定した接触には不十分です。トライメッシュであれば複数の接触点が得られます。RigidBody で Continuous Collision Detection(連続衝突検出)を有効にすると初期のめり込みを軽減できますが、根本的な単一接触による不安定性は解決されません。
トラブル対応Jolt Physics 5.6で、積み重ねられたオブジェクトがスリープ状態になったときに剛体が消えたり、トランスフォームがNaNになったりする問題を修正するにはどうすればよいですか?
これは AngularFrictionConstraintPart における Jolt 5.6 のリグレッションです。スリープに近い状態では、inv_effective_mass が 1.40129846e-45 のような非正規化数になることがあり、1.0f / inv_effective_mass の計算が INF へオーバーフローし、角速度とボディのトランスフォームを汚染します。この修正は、issue #2092 を修正する「Avoiding overflow to INF if inverse effective mass is denormal」というタイトルのアップストリームの変更に含まれています。JoltPhysics を最新の master、またはその修正を含む 5.6.0 以降の最初のリリースに更新し、その後 UPBGE のクリーンリビルドを実行してください。一時的な回避策としては、AngularFrictionConstraintPart が存在しない 5.5.0 のコミット 23dadd0e603f1b321142d4c74df07fce85064989 へ JoltPhysics をダウングレードしてください。平面の細分化や非アクティブ化の設定を変更しても、ソルバーの順序に影響を与えるだけで、根本的なオーバーフローは修正されません。
トラブル対応Jolt CharacterVirtual がトライアングルメッシュ上でカプセルの側面やエッジの接触を誤って地面として分類してしまう問題を修正する方法
CharacterVirtualSettings::mSupportingVolume を正しく設定してください。これを設定しないと、カプセルの下半球の上部付近にあるコンタクトが支持コンタクトとして扱われ、キャラクターが落下せずにエッジへ張り付いてしまう可能性があります。
支持ボリュームの平面は、カプセルの底部球の中心、つまりカプセルの底からカプセル半径 1 個分上の位置に設定します。カプセル半径が 0.3 m の場合は 0.3 m を使用し、0.1 m や 0.2 m は使用しないでください。球の中心より低い値では、階段のステップ処理(stair stepping)が失敗する可能性があるためです。
上方向軸が Z の場合は、ローカル点 (0, 0, 0.3) を通り、法線 (0, 0, 1) を持つ平面として定義します。デフォルトの Y-up 設定の場合は、点 (0, 0.3, 0) を通り、法線 (0, 1, 0) を使用します。概念的には次のようになります。
settings.mSupportingVolume = Plane::sFromPointNormal(
Vec3(0, 0, 1), // 上方向軸
Vec3(0, 0, settings.mShape->GetInnerRadius()) // 底部球の中心
);
シェイプが半径を公開していない場合は、カプセルの半径をそのまま使用してください。これにより、底部球の中心より上方にある側面のコンタクトが地面のコンタクトとして選択されるのを防ぎます。