간단한 충돌 판정

8783 단어 충돌 판정게임

소개



 
이번은 최근 3D를 만지기 시작했기 때문에 3D의 충돌 판정에 대해 쓰려고 생각합니다.

자기소개



HAL 오사카 게임학과 2년의 게임 프로그래머 목표로 하고 있는 사람입니다.
@ 이 쥬냐 에 어드벤트 캘린더에 초대되어 쓰게 되었습니다.
어드벤트 캘린더는 이번이 처음입니다.

경계 볼륨( Bounding Volume,BV)



경계 볼륨( Bounding Volume,BV)이란?



단순한 볼륨으로 복잡한 오브젝트를 감싸고 판정을 간단하게 하는 것입니다.
단순한 볼륨을 사용하면 복잡한 객체에 비해 중첩 판정에 걸리는 시간이 짧습니다.

좋은 경계 볼륨


  • 교차 판정 비용이 들지 않음
  • 오브젝트의 형태에 밀착
  • 계산에 시간이 걸리지 않음
  • 회전과 이동이 쉽습니다
  • 작은 메모리 만 사용

  • 축 평행 경계 박스(AABB:Axis-Aligned Bounding Box)



    축 평행 경계 박스(AABB:Axis-Aligned Bounding Box)란?



    축 평행 경계 박스(AABB:Axis-Aligned Bounding Box)는 가장 일반적인 경계 볼륨의 하나입니다.
    직방체 3D의 경우는 6개, 2D에서는 4개의 면을 가지는 박스형으로, 각 면의 방향은 그 면의 법선이 항상 좌표계의 축에 대해 평행하게 되어 있습니다. AABB의 가장 큰 특징은 중첩 판정이 고속으로 이루어질 수 있다는 것입니다.



    AABB(1)
    struct AABB {
      D3DXVECTOR3 max;
      D3DXVECTOR3 min;
    };
    

    AABB(2)
    struct AABB {
      D3DXVECTOR3 min;
      float d[3];
    };
    

    AABB(3)
    struct AABB {
      D3DXVECTOR3 center;
      D3DXVECTOR3 r[3];
    };
    

    코드로 하면 이런 느낌입니다.

    구현



    (1)의 최소-최대 판정을 간단히 써 보았다.
    이 코드의 쓰기는 맛있고,,,,
    굳이, 최대치와 최소치와 당 판정을 취하고 싶은 오브젝트의 좌표를 건네줍니다.
    객체가 이동하면 update에서 객체의 좌표를 전달하여 바운딩 볼륨을 업데이트합니다.
    intersectAABB로 판정하고 싶은 AABB를 건네주셔서 끝입니다.

    AABB.h
    struct AABB {
        D3DXVECTOR3 min;            //      最大値
        D3DXVECTOR3 max;            //      最小値
        D3DXVECTOR3 actorOldPos;         //      前の座標値
        AABB() = default;
        ~AABB() = default;
        AABB(D3DXVECTOR3 minValue, D3DXVECTOR3 maxValue, D3DXVECTOR3 actorPos) {
            min = minValue;
            max = maxValue;
            actorOldPos = actorPos;
        }
    // 更新
        void update(const D3DXVECTOR3& actorPosition) {
            D3DXVECTOR3 diff =  actorPosition - actorOldPos;
            min += diff;
            max += diff;
            actorOldPos= actorPosition;
        }
    };
    // AABBとAABBの衝突判定
    inline bool intersectAABB(const AABB& box1,const AABB& box2) {
        if (box1.min.x > box2.max.x) return false;
        if (box1.max.x < box2.min.x) return false;
        if (box1.min.y > box2.max.y) return false;
        if (box1.max.y < box2.min.y) return false;
        if (box1.min.z > box2.max.z) return false;
        if (box1.max.z < box2.min.z) return false;
      return true;   // 衝突!!
    }
    



    더 써야했는데 ()

    참고문헌



    좀 더 도움이 될 최고의 기술서
    게임 프로그래밍을 위한 실시간 충돌 판정
    게임 3D 수학
    게임 앱의 수학 Unity에서 배우는 기초부터 셰이더까지
    게임 프로그래밍을 위한 3D 그래픽 수학

    좋은 웹페이지 즐겨찾기