Bullet Physicsとの壁の衝突時のジッター:接触/貫通許容度?


7

私はPanda3dを通じて弾丸物理エンジンを使用しています。

私のシーンはまだ非常にシンプルです。「Wolfenstein3d」を考えてください。タイルベースで、壁は立方体です。

壁がプレイヤーをブロックすることを期待し、通常の発生率でない場合、プレイヤーは壁に沿ってスライドすることを期待します。

私が得るものは、私が期待するものですが、1つの違いがあります。壁に無理に入れようとすると、2つの位置の間でフレームがすばやく点滅します。これらは約0.04単位の距離で異なります。これは私のゲームでは4 cmに相当します。

私は他の場所で4 cmに気づきました。休憩しているとき、私のプレイヤーカプセルの底は地面の下4 cmです。

接触と衝突を区別するために、Bulletエンジンのどこかにデフォルトの0.04単位長の許容誤差があるということですか?もしそうなら、私は何をすべきですか?これらの0.04単位が0.4 cmに対応するようにゲームのスケールを変更して、ジッターを10倍小さくする必要がありますか?または、弾丸の許容値をより小さい値に変更するように要求できますか?

編集する

これは私が得るジッタです:6.155-6.118 = 0.036

LPoint3f(0, 6.11694, 0.835)
LPoint3f(0, 6.15499, 0.835)
LPoint3f(0, 6.11802, 0.835)
LPoint3f(0, 6.15545, 0.835)
LPoint3f(0, 6.11817, 0.835)
LPoint3f(0, 6.15726, 0.835)
LPoint3f(0, 6.11876, 0.835)
LPoint3f(0, 6.15911, 0.835)
LPoint3f(0, 6.11937, 0.835)

setMarginメソッドを見つけました。壁のBoxShapeとプレーヤーのCapsuleシェイプの両方で5 mmに設定しました。このログ(11.117-11.082 = 0.035)が示すように、それでも約35 mmジッターします。

LPoint3f(0, 11.0821, 0.905)
LPoint3f(0, 11.1169, 0.905)
LPoint3f(0, 11.082, 0.905)
LPoint3f(0, 11.117, 0.905)
LPoint3f(0, 11.082, 0.905)
LPoint3f(0, 11.117, 0.905)
LPoint3f(0, 11.0821, 0.905)
LPoint3f(0, 11.1175, 0.905)
LPoint3f(0, 11.0822, 0.905)
LPoint3f(0, 11.1178, 0.905)
LPoint3f(0, 11.0823, 0.905)
LPoint3f(0, 11.1183, 0.905)

カプセルのマージンは床への浸透を変更しましたが、私は少し高くなっています(0.835ではなく0.905)。しかし、壁と衝突しても何も変わりませんでした。

どうすれば壁​​との衝突のジッタを軽減できますか?

次の日の編集:

さらに調査した結果、動的オブジェクトは正常に動作しているようです。私の問題は、キャラクターの移動に使用するbtKinematicCharacterControllerに起因しています。インターネット全体によると、それらは完全にバグがあります。

回答:


4

これは、浮動小数点の不正確さによる数値の不安定さのように聞こえます。ベンダーの推奨に従って、シーン/オブジェクトのスケール係数を使用していますか?


編集:

物理エンジンジッタの一般的なチェックリスト

  • 正しい倍率を使用していることを確認してください
  • 数量が適切であることを確認してください(例:10m、80kgなど)。
  • これが内部フォースのないオブジェクトである場合(つまり、コントローラー/フォースジェネレーターがない場合)、スリープを有効にします。
  • レイキャスティングに関連するすべての設定を確認します。問題のもっともらしい原因
  • いくつかの浸透を可能にするために侵入深さの許容範囲をリラックス問題の原因となる可能性があります


†これにより、カメラが壁を「透けて」見える可能性があります。壁の前に薄い見えない物体を置くか、AABBを拡張してバッファーとして機能させることで解決できます。


あなたは私の3Dモデルの規模の話(したがって衝突ボックス/形状)している場合、それらはすべて1です
Niriel

そして、大まかにどのようなサイズと距離が働いていますか?
awdz9nld 2012

1単位は1メートルに相当します。
Niriel、2012

1

エンジンが絶えずそのオブジェクトのパラメーターを更新しようとしているように聞こえます。オブジェクトは、Bulletが「安定」であると判断した状態に到達すると、位置が固定されます。それ以外の場合、数値エラーが原因で正確な衝突処理が行われず、その結果、ジッターモーションが発生します(最終的に力が蓄積し、オブジェクトが再び浸透し、振動が発生します)。ここではいくつかのアイデアについて説明します。「睡眠問題」の調査を始めます。おそらく、このエンジンの実務経験がある人が、あなたのケースで効率的に睡眠閾値を設定する方法を提供できるでしょう。


さらに調査した結果、動的オブジェクトは正常に動作しているようです。私の問題は、キャラクターの移動に使用するbtKinematicCharacterControllerに起因しています。インターネット全体によると、それらは完全にバグを含んでいます。
Niriel、2012年

申し訳ありませんが、私はBulletのエキスパートではないため、そのメカニズムを確認する機会がありませんでした。観察の1つは、移動中のキャラクターが「フリーズ/スリープ」モードから抜け出す強制的な更新を常に取得する必要があるため、「スリープモード」に入ることができなかったことです。
teodron

将来的には、この「スリープモード」の概念を忘れないでください。法線もチェックする必要があります。両面ポリゴンがあるのでしょうか。
ニリエル

0

あなたが調べたいと思うかもしれない一つのことはCCDオプションです。一部の物理エンジンでは、「連続衝突検出」を有効にするオプションを使用できます。

より多くのリソースを必要としますが、各タイムステップではい/いいえとして衝突を解決するのではなく、実際の衝突ポイントを見つけてそこで停止します。

私は弾丸エンジンに精通していませんが、それはあなたに探すべきものを与えるかもしれません。興味深いことに、壁の貫通を防ぐために、弾丸のようなものに最も頻繁に使用されます。


継続的かどうかにかかわらず、浮動小数点は遅かれ早かれ醜い頭を
再成長させます
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.