학원

DirectX 3D SphereCollision

Srff5123 2023. 10. 28. 03:51
728x90

마우스를 구에 두었을때 충돌이 일어나는지에 대한 구현

 

충돌은 게임 프로그래밍에서 굉장히 자주쓰고 중요한 요소이다.

충돌처리 구현

 

Scene폴더에 새로운 CollisionScene 헤더를 추가한다.

다음 새로운 Scene에 필요한 함수들을 적어주고 cpp파일을 만들어준다.

 

다음 GameManager로 이동하여 새로 만든 Scene을 추가해준다.

 

다음 Framework폴더에 Collision폴더를 만들어주고 그 안에

BoxCollider와 Capsule Collider , Sphere Collider 파일을 미리 만들어준다.

 

충돌구현은 크게 Sphere(구), Box, Capsule이 있고, 마지막으로는 Polygon으로 직접적으로 충돌

하는 방식이있다.

 

연산속도는 Sphere > Capsule > Box > Polygon이다 가장빠른것이 Sphere이라   Sphere을 이용해서 충돌처리를 하면 좋지만

이것은 오브젝트의 모양와 용도에 따라 어떤 충돌처리를 할것인지 정한다.

 

오늘은 Sphere를 통한 충돌처리를 구현할 예정이다.

 

Sphere.h로 이동하여 Box Sphere, Capsule 만들어주고

 

Struct로 반직선 Ray를 pos(위치)와 dir(방향)만들어준다.

다음 반직선이랑 충돌을 하였을때 얻을수있는 정보를 얻을 Struct Contact를 하나 만들어준다.

충돌 위치와 거리를 얻는다.

 

다음 Virtual bool로 Ray, Box, Sphere, Capsule 충돌함수를 만들어준다.

그러고 나서 Color값을 얻기위해 Setcolor함수 또한 추가해준다.

(충돌이 일어났을경우 색깔로 변화를 주기 위함)

 member변수 type와 mesh를 추가한다.

 

다음 Collider.cpp을 만들어 줄건데 이렇게만 정의를 해주고

나머지는 자식들에 재정의를 할것이다.

 

다음 shaders폴더에있는 Basic폴더에 Collider.hlsl을 꼭지점으로 추가해주고

Grid.hlsl에 있는 VS코드를 가져오고 수정을 해준다.

 

 

Collider cpp로 와서 색깔을 초록색으로 만들어주고

소멸자에서 mesh를 delete한다.

Render에서는 setRender로 불러오고 Draw로 그려준다.

선으로 그릴것이기 떄문에 LINELIST로 해준다.

 

다음 마지막으로 IsCollision

충돌 여부 검사이기 때문에

switch문으로 검사를한다.

이러면 공통적으로 Collider툴을만들었다.

 

글로벌 스케일 반환하는 방법을 만들어 주기 위해 Transform 헤더에 관련된 것들을 추가해준다.

 

 

이제 ShereColiion.h로 이동하여 계산에 필요한 변수를 채운다.

 

다음 cpp로 이동하여 매개변수를 채워주고

type = SPHERE로 받아주고

MakeMesh와 Create 호출하고

 

MakeMesh()에

Scene에 출력할 Sphere를 그려준다. 저번에 그렸던 Sphere이 있기 때문에 코드를 가져와서

살짝 수정을 한다.

 

 

 

다음 테스트 출력을 위해 ColliderScene 파일로 이동하여 생성자와

소멸자와 함수에 다음과 같이 추가를해준다.

실행을 해주면 Sphere이 두개 만들어진걸 확인할수있다. 

 

다음 Update에 충돌이 일어났을때의 효과를 부여해준다.

if문을 활용하여 0번과 1번 두 Sphere이 충돌하면 SetColor를 이용하여 색을 빨간색으로

바꾸어주고 아니라면 다시 초록색으로 만들어준다.

 

 

이제 충돌을 구현해주자.

 

우선 vector 계산을 편하게 하기위해 연산자 오버로딩을 Vector.h에 추가해주고

길이도 또한 같이 추가를 해준다.

 

다음 SphereScene.cpp로 이동하  두 Sphere  거리를 구해주고

if문으로 거리를 비교해주어 충돌을 구분해준다.

 

실행을하면 구가 붙어있을떄 빨간색으로 표시되는것을 볼수있다.

 

이제 마우스 커서가 닿아있을떄 충돌을 표현해주자.

이것을 만들기 위해서는 마우스커서를 카메라로 생각을하고 반직선을 그었을때 구에 닿았는지

않았는지에 대한 조건을 얻어야하는데 

 

우선 이것을 구현할때 Projection행렬이 필요하기 때문에 Environment.h에 Matrix projection을

만들어준다

 

그 다음 cpp파일 CreateProjection으로 이동하여 

projection을 멤버변수로 빼주어 수정한다.

 

그다음 헤더에서 GetProjection으로 값을 받아준다.

 

다음 Camera.h로 이동하여 projection을 들고오고,

Ray함수를 하나 만들어준다. 마우스 좌표 = screenPoint

 

cpp로 이동하여 Update에 추가하고

 

마우스를 정규화된 값에 2를 곱하고 1을 빼주면 -1 ~ 1사이의 좌표값을 만들어주는데

이것은 indices좌표와 같다. 이런식으로 x,y를 indices 좌표계 잡아준다.

그다음 projection행렬의 11번 값이 너비에 대한 비율의 정보를 가지고있는데 indices좌표에서

나누어 주면 원점기준에서 지점으로 가는 벡터를 얻을수있다.

벡터를 얻었으면 screenpoint와 world(카메라의 행렬)을 곱해주면 우리가원하는 반직선의 방향이

나오게 된다.

다음 그것을 정규화해서 Return한다.

이제 이 Ray를 이용하여 충돌처리를 하자

 

 

카메라의 위치를 P , 방향을 D, 원의 중심은 C로 두

D-C는 두개의 벡터의 계산을 A로 임의로 설정한다

다음 정리한 파란색 식을 위의 공식에 대입을 해주면 주황색이 되고

주황색식을 노란색으로 풀어주어 근의공식에 대입을 해주

이것을 코드로 구현한다.

 

SphereCollder.cpp파일에 IsRayCollision으로 이동하여

위의 식에서 사용하였던 정보들을 넣어준다.

 

다음 Framework.h에서 define추가를 해준다

 

CollsionScene.cpp 로 돌아와 update에 cam을 설정해주고 테스트를 해준다.

그런 다음 실행해주면 마우스를 올렸을때 빨간색이 들어오는 것을 볼 수 있다.

 

728x90