軸平行ボックスと視錐台の衝突判定

frustum-aabox.png

理論の説明

intersect.png
  • 正の半空間….平面の側空間 内側
  • 負の半空間….平面の側空間 外側
  1. 軸平行ボックス正の頂点負の頂点を決めておく。参照平面に最も近い点、遠い点
  2. 視錐台の各平面と軸平行ボックスの正の頂点、負の頂点との距離を計算。

結果は次の通り

  1. 正の頂点との距離が0未満だったらボックスは視錘台の外
  2. 正の頂点との距離が0以上だったら(さらにテスト 内側・交差2つの可能性がある状態)
    1. 負の頂点と平面の距離が0以上だったら視錐台の内側
    2. 負の頂点と平面の距離が0未満だったら視錐台と交差している

ソースコード

一部を抜粋。フルソースコードはfrustum.h(git)

負の頂点、正の頂点の計算

負の頂点を得るコード 正の頂点を得るコード
        vec3<T> getVertexN(const vec3<T> &normal) const{//Negative
                vec3<T> res = corner;
        //軸境界ボックスの中で最小値を持つの頂点
                if (normal.x < 0)
                        res.x += x;
                if (normal.y < 0)
                        res.y += y;
                if (normal.z < 0)
                        res.z += z;
                return(res);
        }
        vec3<T>  getVertexP(const vec3<T>  &_normal)const {//Positive
                vec3<T> res = corner;
                if (_normal.x > 0)
                        res.x += x;
                if (_normal.y > 0)
                        res.y += y;
                if (_normal.z > 0)
                        res.z += z;      
                return(res);
        }
        int boxInFrustum(aabox<T> &_b) {
                int result = INSIDE;
                for(int i=0; i < 6; i++) {
 
                        if (plane[i].getDistance(_b.getVertexP(plane[i].normal)) < 0){//P for positive
                                return OUTSIDE;}
                        else if (plane[i].getDistance(_b.getVertexN(plane[i].normal)) < 0){//N for negative
                                result =  INTERSECT;
                        }
                }
                return result;
        }

ベクトルと平面の距離

float getDistance(vec3<T> &_p) {//ベクトルと平面の距離
                        float result = distance + normal.innerProduct(_p);
                        return (result);
                }

aabb frustum

サポートサイト Wikidot.com aabbfrustum