ボール遊び場ベータ
数千個のボールを注いで弾いて爆発させる物理遊び
このツールはまだ安定化中のベータ版です。結果に違和感があればお知らせください。
キャンバスを押したまま動かしてみてください。「箱を揺らす」モードではドラッグで揺らし、Shift+ドラッグかホイールで回転できます。
処理中…
0.0
停止していません。計算が終わると結果が表示されます。
ボール遊び場について
このサンドボックスの物体はすべて円だ。円は速度を別に持たず、今の位置と1つ前の位置だけを持ち(位置ベルレ積分)、1フレーム(1/60秒)を6つの部分ステップに分けて動く。部分ステップごとに重力・空気抵抗・ポインターの力で位置を動かし、速い円は移動区間をなぞって最初に触れる円で止め、壁の外に出た円を跳ね返して戻したあと、重なった円どうしを押し離す処理を2回くり返す。
最大6000個を扱うには、すべての組を比べるわけにはいかない。画面を最大の円の直径ほどのマスに分け、各円は自分のマスと隣のマスにある円とだけ重なりを調べる(一様格子によるブロードフェーズ)。円がまんべんなく散らばっていれば、調べる量は円の数にほぼ比例する。
円は回転せず、表面の摩擦もない。転がるボールや積み上げたレンガのような剛体ゲームエンジンの機能はここにはない。このツールが見せるのは、何千もの粒がぶつかり合って流れる様子と、それを安く速く計算する方法の長所と短所だ。
重なりを押し離す方式と「壁の弾性」スライダー
2つの円が重なると、重なった深さの分だけ中心を結ぶ方向に互いを引き離す。質量は面積(半径²)に比例するとみなし、軽い円ほど大きく動く。衝突の瞬間の速度は計算せず位置だけを直す方式で、Jakobsen(2001)が「衝突と貫通を射影で処理する」と説明した方法だ。位置の修正量がそのまま次のステップの速度になるので、速度を別に合わせる必要がない。
その代わり、円どうしの衝突はほとんど弾まない。重なった分だけ戻すと近づく速さは消えるが、逆向きに跳ね返る速さは生まれないからだ。「壁の弾性」スライダー(反発係数)は壁と床にだけ効く。0.6なら壁にぶつかった速さの60%で戻り、落とした円は毎回前の高さの0.6² = 36%まで跳ね上がる。円どうしの衝突が砂や穀物のように鈍く見えるのはこのためだ。
トンネリング:速い物体が壁を抜ける理由
部分ステップの終わりに「今重なっているか」だけで衝突を判定すると、1ステップの間に相手を丸ごと通り過ぎた物体は衝突を見逃す。これをトンネリングという。Box2D のようなエンジンは、前の位置から新しい位置まで形状を掃引する連続衝突判定(CCD)で防ぎ、特に速い物体は「bullet」に指定できる。
このツールは簡単なCCD(円をなぞる検査)を使う。1つの部分ステップ(1/360秒)で自分の半径より長く動いた円は、前の位置から新しい位置までの区間全体を他の円と比べ、途中で最初に触れる円があればその接触位置で止まり、ぶつかった方向の相対速度を質量の比で分けて消す(円どうしの衝突と同じく非弾性)。2つの円がどちらも半径以下しか動かなければ、相対移動は半径の和を超えず互いを飛び越せないので、検査しない。そのため爆発の強さを最大にしても円どうしはすり抜けない。壁は座標を切り詰めて戻すので抜けない。ただし円は今も回転せず、摩擦もない。
積もった山が少し柔らかい理由
ある組を引き離すと隣の組がまた重なるので、重なりを解き切るには何度もくり返す必要がある。このツールは部分ステップごとに全組の重なり解消を2回くり返す。半径5 pxの円2000個を細い箱に積むと、いちばん深い重なりは1回だけのとき約10 px(円の直径ぶん)だったのが1 px前後まで減る。4回にするともう少し減るが、円6000個では1フレームの計算がさらに約2倍かかるので2回にした。部分ステップを増やしても減るが、計算もその分増える。ゲームエンジンが反復回数や部分ステップ数を設定項目として出しているのも同じ理由だ。
円に摩擦がないので、山は斜面を保てない。本物の砂は一定の安息角を保って積もるが、ここでは傾けると水のように平らに広がる。
例
壁の反発係数0.6で落とす
- 入力
壁の弾性0.6、空気抵抗は無視、高さhから落下- 結果
跳ね上がる高さ:0.36h → 0.13h → 0.047h
速さが毎回0.6倍になり、高さは速さの2乗に比例するので、0.36倍ずつ減る。空気抵抗(既定値0.15/s)があると少し低くなる。
移動区間をなぞって検査する速さ
- 入力
半径3 pxの円、部分ステップ1/360秒- 結果
3 px × 360 = 1080 px/sより速いと、移動区間全体を他の円と比べる
それより遅い円どうしは1ステップの相対移動が半径の和を超えず、互いを飛び越せないので、終わりの位置の重なりだけを見る。
使い方
- 流し込む・引き寄せる・押しのける・爆発・揺らすのいずれかを選ぶ。
- 画面を押すかドラッグして円を流し込んだり力を加えたりする。
- 重力・壁の弾性・大きさ・強さ・傾きを変えてみる。スマートフォンでは端末を傾けて重力の向きを変えられる。
主な用語
- ブロードフェーズ
- すべての組を調べる前に、接触しそうな組だけを選び出す段階。ここでは一様格子を使う。
- トンネリング
- 1ステップで動きすぎて衝突を飛び越えてしまう現象。
- 反発係数
- 衝突後に離れる速さ ÷ 衝突前に近づく速さ。1ならエネルギーを失わずに跳ね返る。
よくある質問
壁の弾性を1にしても円どうしはあまり跳ねない。
名前のとおり壁と床にだけ効く。円どうしの衝突は重なった位置を直すだけなので、ほぼ非弾性のように振る舞う。
速い円はほかの円をすり抜ける?
すり抜けない。1つの部分ステップで半径より長く動く円は移動区間全体を検査し、最初に触れた円で止まってその円を押し出す。壁も座標を切り詰めて戻すので抜けない。
円が増えると遅くなるのはなぜ?
格子のおかげで調べる量は円の数にほぼ比例するが、1か所に密集すると1マスの円が増えて調べる組が増える。上限は6000個。
出典
- Thomas Jakobsen, Advanced Character Physics, GDC 2001 (CMU course mirror)
- Box2D documentation — Simulation (tunneling, continuous collision, bullets, restitution threshold)
基準日: