Posted by 랜스.

Leave your greetings here.

게임수학책을 보면서 행렬을 공부하다가
이것 저것 현재 벡터와 행렬 클래스를 만들어보면서 해골책의 행렬부분에 적용을 하고있는데
투영부분에서 약간 애먹은 부분이 있어서 다른분들에게 도움이 되고자 글을씁니다.

직교투영(Orthographic Projection)
사용자 삽입 이미지
직교 투영을 할려면 DX9 함수로 D3DXMatrixOrthoLH 라는 함수를 사용합니다.
이함수는 밑의 값을 리턴값으로 반환해줍니다.
2/w           0               0              0
0             2/h              0              0
0               0         1/(zf-zn)         0
0               0       -zn/(zn-zn)        1

레퍼런스엔 조금 다른식으로 설명되있습니다만, 레퍼런스에 있는대로 하면않되길래 책보며 했습니다.
@대부분의 서적과 자료에는  _33이 1이고 _44가 0인데 실제론 _33이 0이고 _44가 1이더라구요
실제로했을때만 정상 처리되고 _33을 1주고 _44를 0줬을땐 프로젝션이 제대로않된것같습니다.
(*잘못된점있다면 댓글 부탁드립니다.)


원근투영(Orthographic Projection)



사용자 삽입 이미지
원근투영은 DX9에서 D3DXMatrixPerspectiveFovLH 라는 함수를 사용한다.
리턴값으로 밑의 값을 리턴한다.
w             0               0                 0
0               h              0                 0
0               0         zf/(zf-zn)          0
0               0       -zn*zf/(zf-zn)      1

w와 h값은 아래의 값을 넣어주면됩니다.
w = h / Aspect;
h = cot(fovY/2);
- Aspect는 뷰포트의 가로/세로비이구요.
-cot의 함수가 없던데 cot는 tan의 역함수이니 1/tan(fovY/2) 해주면됩니다.
[##_kaAmo_##]
Posted by 랜스.

Leave your greetings here.

Direct를 이용한 구의 충돌 테스트

Direct를 이용한 구의 충돌 테스트 -랜스


 원 과 구의 차이는 무엇일까요?
쉽게 생각해서 2D-> 3D 라고 할수있습니다.
2D에는 x,y 좌표만있지만 (깊이도있습니다만 수학적으로) 3D에서는 한가지더 z라는 값이 있죠.
 
그렇다면 원의 충돌체크와 구의충돌체크의 차이점도 구에 생긴 한가지 값을 이용한 연산을
해주면 되는걸까요?

 예 맞습니다. -_- 단지 그것만 해주면 구의 충돌체크가 됩니다.. 실로 매우 간단합니다..
왜냐하면 원의 방정식과 구의 방정식 둘다 각자 접할때와 겹칠때의 조건이 같기때문에
구에 추가된 Z값을 중점사이의 거리를 구하는데 사용해주면 구의 방정식에서 충돌이 성립합니다.
 
 아래는 참고용 소스입니다.  

bool isCollision(Sphere* m1,Sphere *m2)                
{                                                            
 중점사이의거리= sqrt((float)((m2->x-m1->x)*(m2->x-m1->x))
               +((m2->y-m1->y)*(m2->y-m1->y))            
               +((m2->z-m1->z)*(m2->z-m1->z)));         
 if(m1->r+m2->r>=중점사이의거리)                            
  return TRUE;                                             
 else                                                       
  return FALSE;                                            
}

 
[##_kaAmo_##]
Posted by 랜스.

Leave your greetings here.

  1. Comment RSS : http://lancekun.com/tc/rss/comment/31
  2. 닭도난다 2009/03/09 08:06  Modify/Delete  Reply  Address

    멋지군요! ㅎ

하나를 꺠우치면 열 혹은 그이상을 꺠우칠수있는 응용력이필요합니다...
그런고로 응용법을 생각해봅시다~

아래의 그림을 보면 '스트리트파이터4'라는 게임의 스크린샷인데
춘리라는 게임캐릭터가 공격을 시도하는 장면인데요. 이것을 가지고 예를 들어 설명해보겠습니다.
물론 스트리트파이터4는 3D로 제가 설명하는 방식의 충돌체크를 사용하지않습니다..
그리고 대부분의 2D격투게임들은 바운딩박스라는 방식으로 충돌체크를 합니다.
사용자 삽입 이미지
밑에 사진을 다시 보시면 원으로 충돌 체크를 할시에 필요한 원들이 보입니다.
부위별로 상하좌우 방어 공격 등등의 상태값을 가지겟죠. 그런데 이많은 원들을 항시로 체크해줄려면
프레임소모가 심합니다.
예를들면 충돌원을 1000개씩 가진 캐릭터가 떨어져있어도 1000000번의 충돌연산을 하게됩니다.
그런고로 아래사진처럼 가장큰원을 하나씩 잡고 충돌시 하위 계층의 충돌원과 충돌연산을 시켜주면됩니다.
사용자 삽입 이미지

한번 응용해봅시다.그래픽 불러오기 귀찮고 리소스생산해내기 귀찮으므로 원두개로 딸랑만들수있는 눈사람을 만들어보았습니다.
그리고 충돌체크시 충돌검사하는 갯수를 받아서 화면에 찍어주게하였습니다.



사용자 삽입 이미지
사용자 삽입 이미지
사용자 삽입 이미지
사용자 삽입 이미지
사용자 삽입 이미지
[##_kaAmo_##]
Posted by 랜스.

Leave your greetings here.

  1. Comment RSS : http://lancekun.com/tc/rss/comment/28
  2. 알콜코더 2009/03/05 10:24  Modify/Delete  Reply  Address

    스파4같은 격투게임은 바운딩 스피어의 충돌안에서 또다시 폴리곤 충돌까지 계산하죠. ^^

    • 랜스 2009/03/06 03:51  Modify/Delete  Address

      오호 ~ 그렇군요!! 바운딩스피어검출방법도 그리 어려운게 아닌데 D3D로 스피어2개뛰어 놓고 한번 해봐야겠습니다>_<

  3. cretom 2009/03/12 18:51  Modify/Delete  Reply  Address

    스파4는 개발 초기엔 일반적인 3D게임(ex:철권)처럼 3차원적으로 판정을 했지만
    후기에 가선 2D게임이였던 시절의 느낌을 살리기 위해 2차원 처리로 바꾸었다고 하네요..
    일반적인 3D게임의 경우는 알콜코더님의 말씀이 맞습니다.

중고등학교 수준의 수학을 공부하고도 사실 구현해내는 방법을 잘몰랐지만
다시한번 책을 보면서 생각해보니 "접한다","겹친다" => "충돌한다" 였던것이다.

그런고로 오늘은 원과 원의 충돌에 대해 구현을 해보았다.


bool isCollision(Circle* m1,Circle *m2)
{
 중점사이의거리= (float)sqrt((float)((m2->x-m1->x)*(m2->x-m1->x))+((m2->y-m1->y)*(m2->y-m1->y)));
 if(m1->r+m2->r>=중점사이의거리)
  return TRUE;
 else
  return FALSE;
}


사용자 삽입 이미지
사용자 삽입 이미지
사용자 삽입 이미지

















[##_kaAmo_##]
Posted by 랜스.

Leave your greetings here.