Skip to main content

箱(AABB)と球の当たり判定

箱(AABB)と球の当たり判定 by チョコミント

こんにちは、チョコミントです。
今回は箱(AABB)と球の当たり判定についてです。

AABB,OBBとは

AABBとOBBについて聞きなれてない人も多いと思うので簡単に説明します。

  • AABBとは軸平行境界ボックスといって箱の各面の法線が座標軸と平行なものです。
    箱の横と縦と奥へのベクトルそれぞれがXYZと平行ということですね。
  • OBBとは有向境界ボックスといって箱の各面の法線が座標軸と平行ではないも のです。
    なんとなく理解できたでしょうか。
    AABBとOBBでは当たり判定をする際の処理速度がかなり変わってきます。
    OBBについての当たり判定もいつか記事に書く予定です。

AABBと点の距離

さて本題に入っていきましょう。

画像6.png

上の図にある通り、AABBと球の当たり判定を行うにはAABBと点の距離が分かればいいのです。(図に書いてあるdです)
AABBと点の距離を調べるには、AABBの各軸(XYZ)で点がどのくらいAABBからはみ出ているかを調べればいいのです。

画像8.png

上の図ではAABBのX軸、Y軸で点がはみ出ている分、vx、vyでベクトルを作ってみました。
あれこの形どこかで見たことある人いませんか??
そうです、点と点の距離を求めるのとそっくりですね。
つまりvx、vy、vz(図にはない3Dの場合)の合成ベクトルを求めればAABBと点の距離になるのです!!簡単ですね!!

//AABBの各軸
    XMVECTOR boxX = { 1,0,0 };
    XMVECTOR boxY = { 0,1,0 };
    XMVECTOR boxZ = { 0,0,1 };

    //AABBの各軸の大きさ
    float boxXSize = 0.5f;
    float boxYSize = 0.5f;
    float boxZSize = 0.5f;

    //AABBの中点と点の位置
    XMFLOAT3 boxPos = { 0,0,0 };
    XMFLOAT3 pointPos = { 1,1,1 };

    //各軸での距離を調べる
    float x = fabs(boxPos.x - pointPos.x);
    float y = fabs(boxPos.y - pointPos.y);
    float z = fabs(boxPos.z - pointPos.z);
     
    //最終的な距離を表すベクトル
    XMVECTOR dis = XMVectorZero();

    //各軸のはみだし距離をdisに加算
    if(x > boxXSize)
        dis += boxX * (x - boxXSize);
    if(y > boxYSize)
        dis += boxY * (y - boxYSize);
    if(z > boxZSize)
        dis += boxZ * (z - boxZSize);

    //disの長さがAABBと点の距離
    return XMVectorGetX(XMVector3Length(dis));

サンプルコードです。
ここまでくればAABBと球の当たり判定はちょこっとたすだけです!
AABBと点の距離が球体の半径以下だったら衝突していることになりますね!!

//半径以下なら
if (radius >= XMVectorGetX(XMVector3Length(dis))
{
    //衝突している
}

これでAABBと球の当たり判定は完璧です!

最後に

今回はAABBと球の当たり判定についての記事でした。
分からないことや質問などがあれば気軽にコメント待っています!!