概要
Box3D は、連続衝突検出、ソフトステップ剛体ソルバー、データ指向設計を備えた、ポータブルな C17 物理エンジンです。マルチスレッド、SIMD、クロスプラットフォームの決定性をサポートしており、大量の剛体スタッキングシナリオに適しています。
README プレビュー
# Box3D\n\n[](https://github.com/erincatto/box3d/actions)\n[](https://cla-assistant.io/erincatto/box3d)\n\n\n\nBox3D is a 3D physics engine for games.\n\n[](https://www.youtube.com/watch?v=jr_Fzl2XwKU)\n\n## Features\n\n### Collision\n\n- Continuous collision detection\n- Contact events\n- Convex hulls, capsules, spheres, triangle meshes, and height fields\n- Multiple shapes per body\n- Collision filtering\n- Ray casts, shape casts, and overlap queries\n- Sensor system\n- Character mover\n\n### Physics\n\n- Robust _Soft Step_ rigid body solver\n- Continuous physics for fast translations and rotations\n- Island based sleep\n- Revolute, prismatic, distance, motor, weld, and wheel joints\n- Joint limits, motors, springs, and friction\n- Joint and contact forces\n- Body movement events and sleep notification\n\n### System\n\n- Data-oriented design\n- Written in portable C17\n- Extensive multithreading and SIMD\n- Optimized for large piles of bodies\n- Cross platform determinism\n- Recording and replay\n\n### Samples\n\n- Uses sokol to run with D3D11 on Windows, Metal on macOS, and OpenGL 4.5 on Linux.\n- Graphical user interface with imgui.\n- Many samples to demonstrate features and performance.\n\n## Building all platforms\n\n- Install [CMake](https://cmake.org/)\n- Install [git](https://git-scm.com/)\n- Ensure these run from the command line\n\n## Building with CMake presets (recommended)\n\nThis uses the presets in `CMakePresets.json`.\n\n- Windows: `cmake --preset windows` then `cmake --build --preset windows-release`\n- Linux: `cmake --preset linux-release` then `cmake --build --preset linux-release`\n- macOS: `cmake --preset macos` then `cmake --build --preset macos-release`\n- Windows MinGW: `cmake --preset mingw-release` then `cmake --build --preset mingw-release`\n\nRun the samples app (must be in the Box3D directory).\n\n- Windows: `.\build\bin\Release\samples.exe`\n- Linux: `./build/bin/samples`\n- macOS: `./build/bin/Release/samples`\n\n## Building for Visu
FAQ (5)
トラブル対応Box3Dで多数のボクセル形状のボックスハルを作成する際に、b3AddHullToDatabaseが非常に遅くなるのはなぜですか?
この低速化は、深刻なハッシュテーブルの衝突によって引き起こされています。従来のdjb2スタイルのハルハッシュは、0.25fの倍数のような規則的な間隔で並んだfloat座標を十分に混合できず、バケット選択にはハッシュの下位ビット(hash & buckets_mask)のみが使用されていました。その結果、数千のボクセルハルが同じバケットチェーンにマッピングされ、ハルの繰り返し比較と過剰なテーブル拡大を余儀なくされていました。これはPR #126で、改良された64ビットハルハッシュを使用することで修正されました。Box3DをそのPRを含むバージョンに更新してください。報告された3,000ハルの再現例では、この修正により時間が約159.9 msから3.9 msに、バケット数が2,097,152から4,096に削減されました。一時的な回避策として、1.0e-4fのような小さな固有のジッターをハルオフセットに追加する方法がありますが、これはコライダージオメトリを変更するため、正確なボクセルアライメントが必要な場合は避けるべきです。
トラブル対応Box3D ワールドをステップ実行する際に b3FreeElement で発生する UBSan の misaligned address パニックは、どうすれば修正できますか?
クラッシュが発生する原因は、b3Manifold が 268 バイトであることです。奇数個のマニフォールドが連続して配置されると、次の要素が 8 バイト境界から 4 バイトずれた位置から始まる可能性がありますが、b3FreeElement はそこに void* を格納するため、8 バイトアライメントが要求されます。
b3CreateBlockAllocator(block_allocator.c)内で、各アロケータの要素サイズをポインタアライメントに切り上げることで修正します:
elementSize = (elementSize + sizeof(void *) - 1) & ~(sizeof(void *) - 1);
この処理は、要素サイズがブロック/フリーリストの初期化に使用される前に適用してください。影響を受ける 64 ビットプラットフォームでは sizeof(void *) の使用で十分です。64 バイトのキャッシュラインサイズへの切り上げでも動作しますが、より多くの領域を無駄にします。
Box3D v0.1.0 では、このアライメントパッチを適用するか、一時的な回避策として Box3D ターゲットに対してアライメントチェックのみを無効化してください:
-fno-sanitize=alignment
すべてのサニタイゼーションを無効にしてもパニックは回避できますが、パッチが適用されるまでは ASan/UBSan を有効に保ち、アライメントのみを抑制する方が望ましいです。
トラブル対応collideConnectedをfalseに設定してジョイントを作成した後も、2つのBox3Dボディが依然として衝突する場合、どうすれば修正できますか?
これは、ジョイントの作成により将来の衝突フィルタリングは変更されますが、2つのボディ間にすでに存在する b3Contact オブジェクトは破棄されないために発生します。この問題は Box3D PR #157 で正式に修正されたため、そのPRを含む Box3D のバージョンに更新してください。古いバージョンでの回避策として、ジョイントを作成した直後、次のシミュレーションステップの前に、接続されたボディ間のコンタクトを明示的に破棄してください。例えば、jointDef.collideConnected == false の場合に b3DestroyContactsBetweenBodies(world, bodyA, bodyB) を呼び出します。
トラブル対応Box3D の b3World_Step が深く重なり合った動的ボディを薄い静的壁へ押し通してしまう問題の修正方法
これは Box3D のバグではなく、ソルバーの想定どおりの動作です。「速度をゼロに設定し、b3World_Step を呼び出し、これを繰り返す」というパターンは、サポートされている準静的な貫通解消手法ではありません。大きな動的ボディの中心が薄い壁の反対側を越えてしまうと、コンタクトソルバーはどちら側を「部屋の内側」と意図したのかを推論できなくなります。ソルバーは現在のコンタクト法線に沿って解決を行いますが、その法線は反対側を向いている可能性があるため、繰り返される補正が累積し、オブジェクトをさらに外側へ押し出してしまいます。
次のいずれかのアプローチを使用してください。
1. **ステップ実行前に深い重なりを防ぐ。** スポーン時、またはドラッグされたポーズを受け入れる前に、壁コライダーに対してオーバーラップ/シェイプキャストクエリを実行します。b3World_Step を呼び出す前に、候補のポーズを拒否するか、正しい壁面にクランプしてください。
2. **進入側を明示的に追跡する。** オブジェクトが内側にあった場合は、interiorWallFace - objectHalfExtent に投影して戻します。中心が壁を越えた後に、ソルバーがその側を選んでくれることに依存してはいけません。
3. **モータージョイントでドラッグを駆動する。** 動的アイテム用のモータージョイントを作成し、ポインターのターゲットに向けてターゲットトランスフォーム/線形オフセットを更新します。十分な maxForce と maxTorque を設定し、コンタクト拘束によって壁で停止させます。b3Body_SetLinearVelocity の後に速度ゼロのステップを実行する方法を、位置の緩和手段として使用してはいけません。
4. **すでに無効になっている状態を手動で修復する。** ボディがすでに深く貫通しているか、壁の中心線を越えている場合は、ステップ実行前に既知の非貫通トランスフォームへ戻してください。
連続衝突判定を有効にすると高速のトンネリング防止に役立ちますが、初期時点で無効な、深く重なった配置を解決するものではありません。この動作はコミット 3fc20f5b45 および 30c67b5e6d で確認されており、メンテナーはオーバーラップ検証とモータージョイントの使用を推奨しています。
トラブル対応moverが垂直に近い角度や浅い角度で移動する際に、メッシュの三角形エッジでスタックしてしまうのはなぜですか?
これは、moverのシェイプキャスト中に三角形の裏面との衝突が発生することが原因です。この問題はPR #130で修正されています。そのPRを含む物理エンジンのビルドに更新して、リビルドしてください。シェイプキャストは、レイキャストの動作と同様に、メッシュおよびハイトフィールドの三角形の裏面との衝突を無視するようになり、moverの衝突にはより滑らかな接触に必要な三角形の情報が含まれるようになりました。カスタムメッシュを定義している場合は、三角形のワインディングを確認し、新しいb3MeshDefのclockwiseオプション(およびstride)を正しく設定してください。