작성자: 김영현(["erunc0"]), 최광식(["woodpage"])[[BR]] "Advanced 3D Game Programming using DirectX" - study. ---- [[TableOfContents]] GameLibrary( http://www.zeropage.org/~erunc0/study/d3d/GameLib.zip )를 만들어 가면서 책의 내용을 본다는.. 뭐뭐뭐.. [[BR]] 말만 그렇지, library부분은 대충 하는 느낌이 드는건 왜인지. [[BR]] 뭐, library부분은 api 초기화 루틴 부분정도이고, DX 도 역시 초기화 부분정도를 [[BR]] 묶어 놓은 정도이기 때문에 이해하는데 어려움은 없었다. --;; [[BR]] Game 쪽 책을 사서 D3D를 본후, 3D를 공부하려는 마음으로 샀다. 무리없이 예제를 보는식으로 할것임.[[BR]] == 목표 == 3D를 이용한 오락 만들기. [[BR]] 구체적인건 둘이서 생각해 볼것임. [[BR]] -- v. == 진행 상황 == === 1월 8일 === * [영현] 음.. 맘에 들지 않는다. 무슨 소리인지 갈피를 잡지 못하는게 현실이다. 관련 책이라도 좀 봐야 하겠다.[[BR]]약간은 설명이 미흡한것 같다. 내가 모자르기 때문일수도 있지만, ㅋㅋㅋ[[BR]]아직까지, 예제다운 예제를 못보다. 3D object를 본적이 없음. 아직까지.. --; - 232p/602p... * [광식] 이책 덮은지 한 20된거 같다. 되층되층 봐가지고 기억이 안난다. 니가적어논거를 보는거로 시작한다. === 1월 9일 === * potential function에 대해서만 봤다.. 약간 쓸만한 알고리즘(?) 인것 같다. ㅋㅋㅋ[[BR]]다음에 나오는 PathPlan에 관한얘기는 쉬운것 같은데. 장난이 아니다.[[BR]]머리 아프다. - 249p/602p... * 전에도 느낀거지만 이책의 D3D초보자에게는 좀 아닌거 같다. 오늘 도서관에가서 책좀 빌려야겠다 [광식] * 책비르러 간다. 3D에 관한책.. --+ 무신 책이 겜 초보자를 위한게 아닌거 같어.. --+ 짱나 짱나.. [영현] === 1월 10일 === * 이런 어제 책 못빌렸다 오늘 빌려야겠다 --; [광식] === 1월 11일 === * 잠시 외도. 광식이한테 빌린 책으로 3D를 공부. {{{~cpp 쿠쿠.. 열심이구나.. ^^a.. DX 공부하면 나줌 갈켜다오.. 헤헤.. 나두 지금 하구 있는거.. 시간되면 여기다(위키..) 쓸께.. 너네두 곧 필요해질 내용이 있을테니.. 근데 지금은 내코가 좀 석자라서.. 시간에 쫓기는 관계로.. 언젠가.. 꼭.. ^^;; - 해성 }}} 오옷.. 해성이가 글을 썼다! --석천 == Direct 3D == === Chapter 1. === 이런 종류의 책들이 다 그렇듯이, winapi를 사용한다.[[BR]] 그렇기 때문에, 초반의 한 chapter는 거의다 winapi를 사용해서 [[BR]] "Hello, World!"를 찍는 source를 넣어 준다. --; [[BR]] === Chapter 2. === DX 초기화 루틴과, game loop(message loop)를 포함한 library를 실제로 만든다.[[BR]] 그리고, 예제 source 1개정도.. 여기 까지 봤음.. - 곧 update , 01.06.2002 Sun[[BR]] ...[[BR]] 슬슬 책이 짜증나려고 한다. --+ 그냥 간단하게 책에서 제공하는 library를 쓰면 chapter2는 솔직히[[BR]] 보지 않아도 될것 같다. 무슨 소리들을 하는지. 전부 초기화.. --+ 함수 설명 뿐이네. 흐미.. 그냥..[[BR]] 일반적인 3D이야기를 살것을.. Game쪽을 사서.. T-T 아무튼 보기는 다 봐야지. DX 는 할것이 정말 초기화 뿐이던가? [[BR]] chapter 3 부터는 수학이랍니다.. --;;[[BR]] * Chapter 2: skip. 초기화 부분정도. 횡성 수설임. 무슨 소리하는지 못알아 먹을 정도임. '''광식아 Chapter2 좀 니가 정리해라. 난 보는게 짜증나서 못해 먹겠다. 후후후. 같이 하니 이게 편하군.. 케케''' 이거 정리하는건 무리다--; {{{~cpp 추천 도서: Inside DirectX (필요로 한다면 말하시오. 전자책으로 있어요. --;;) Tricks of the Windows Game Programming Gurus : Fundamentals of 2D and 3D Game Programming. (DirectX, DirectMusic, 3D sound) }}} === Chapter 3. 3D 수학적 기초 (50%~60%) === 이 chapter는 math3D라는 library를 만드는 chapter이다[[BR]] .. 1월 8일 현재.. 이 부분은 엄청난 변화가 요구.. --a[[BR]] 책의 내용중 모르는 것이 너무 많다. 아니, 말이 어려운것 같다. [[BR]] ==== 점 ==== 점은 3D 그래픽에서 가장 중요한 요소랍니다. 책에서 그러데요. [[BR]] ''- 점은 3D 공간에서의 하나의 위치이고, 벡터는 3D공간 내에서 원점으로부터 하나의 위치를 잇는 직선이다. - ''[[BR]] vector(3D 공간상의 점이 있는 일정한 거리)의 크기 (magnitude)를 구하는 공식은 [[BR]] {{{~cpp 다들 알고 계시져? --;; 하하.. }}} 단위 벡터- 세개의 주요 축들의 방향을 나타내기 위한 벡터.[[BR]] '''''i<1,0,0>, j<0,1,0>, k<0,0,1>'''''[[BR]] i, j, k벡터의 선형 조합으로 3D내의 어떠한 점이라도 나타낼수 있다. [[BR]] '''a''' = <3, 5, 2>[[BR]] '''a''' = '''3i'''+'''5j'''+'''2k'''[[BR]] 그리고, 이 특성으로 인해 행렬과 행렬을 표현하는 공간을 설명할 때 매우 중요시 된다.[[BR]] ==== point3 구조체 ==== 3D점을 캡슐화 하기위한 구조체. {{{~cpp struct point3 { union // use union - 메모리를 공유하는 성분들에 이름을 지정하는데 사용. { // y변수와 v[1]변수는 같은 메모리 조각을 나타낸다. struct { float x, y, z; // 구조체의 이름이 정의되지 않았지 때문에 x,y,z 성분을 원자 단위로 사용. }; float v[3]; } point3 () {} point3 (float X, float Y, float Z) : x(X), y(Y), z(Z) {} // 초기화 목록을 사용. (compiler가 작업을 더 잘 수행할 수 있도록 해준다더군.) // ... }; }}} ==== point3의 연산자와 기본적 함수 ==== {{{~cpp struct point3 { ... point3 operator +(point3 const &a, point3 const &b); point3 operator -(point3 const &a, point3 const &b); point3 operator *(point3 const &a, float const &b); point3 operator *(float const &a, point3 const &b); point3 operator /(point3 const &a, float const &b); ... }; // 좌표 할당 inline void point3::Assign (float X, float Y, float Z) { x = X; y = Y; z = Z; } // vector 값 inline float point3::Mag () const { return (flaot)sqrt (x*x + y*y + z*z); } // 거리의 제곱 값 inline float point3::MagSquared () const { return (x*x + y*y + z*z); } // Normalize inline void point3::Normailze () { float foo = 1/Mag (); x *= foo; y *= foo; z *= foo; } }}} ==== 벡터 동등 ==== float이나 double이 나타낼수 있는 부동소수점의 한계로 인해 vector끼리 동등한지 아닌지를 잘 처리하지 못한다.[[BR]] 그래서, epsilon (이 책에서는 0.001로 정의)이라는 것을 두어 그 문제를 해결한다고 한다. [[BR]] {{{~cpp // point3의 등가 연산자 #define EPSILON 0.001 inline bool operator ==(point3 const &a, point3 const &b) { if (fabs (a.x - b.x) < EPSILON) { if (fabs (a.y - b.y) < EPSILON) { if (fabs (a.z - b.z) < EPSILON) { return true; } } } return false; } }}} ==== 내적 & 외적 ==== {{{~cpp // 내적 inline float operator *(point3 const &a, point3 const &b) { return a.x*b.x + a.y*b.y + a.z*b.z; } // 외적 inline point3 operator ^(point3 const &a, point3 const &b) { return point3 ( (a.y*b.z - a.z*b.y), (a.z*b.x - a.x*b.z), (a.x*b.y - a.y*b.x) ); } }}} --; 고덩학교때 배웠던 내적과 외적. 지금보니 무슨 소리인지.. ㅎㅎㅎ 그냥 적어 봤음. --; ==== 폴리곤 ==== 폴리곤은 개체의 테두리를 표현하는데 사용된다.[[BR]] - http://www.gameschool.co.kr/cyberhtm/3dPolygon.htm - 폴리곤에 관한 page {{{~cpp template struct polygon { int nElem; // number of elements in the polygon int maxElem; type *pList; polygon() { nElem = 0; maxElem = 0; pList = NULL; } polygon( int maxSize ) { maxElem = maxSize; pList = new type[maxSize]; } polygon( const polygon &in ) { CloneData( in ); } ~polygon() { DestroyData(); } void CloneData( const polygon &in ) { if( !in.pList ) return; pList = new type[in.maxElem]; maxElem = in.maxElem; nElem = in.nElem; for( int i=0; i &in ) { if( &in != this ) { DestroyData(); CloneData( in ); } return *this; } }; }}} ==== 면 ==== 3D에서 면은 2D의 선과같다. [[BR]] 면을 정의하는 식 {{{~cpp ax + by + cz + d = 0 }}} 삼원쌍 는 면의 법선(법선: 그 면내의 모든 점들에 대해 수직인 벡터), d는 면에서 원점까지의 거리[[BR]] 위의 식을 만족하는 모든 점의 삼원쌍 는 바로 면에 존재하는 모든 점들이다[[BR]] 면을 정의하는 구조체 {{{~cpp struct plane3 { point3 n; // Normal of the plane float d; // Distance along the normal to the origin plane3( float nX, float nY, float nZ, float D) : n( nX, nY, nZ ), d( D ) { // All done. } plane3( const point3& N, float D) : n( N ), d( D ) { // All done. } // Construct a plane from three 3-D points plane3( const point3& a, const point3& b, const point3& c); // Construct a plane from a normal direction and a point on the plane plane3( const point3& norm, const point3& loc); // Construct a plane from a polygon plane3( const polygon& poly ); plane3() { // Do nothing } // Flip the orientation of the plane void Flip(); }; }}} ==== 변환 ==== 3D의 위치이동이나 회전 등이 행렬로 이루어 진다는 얘기.[[BR]] 위치 이동이야 더해주고 빼주면 되는건 다 아는 사실이니.. 쩝.. --; 회전이나 알면 될것 같음. [[BR]] ...[[BR]] 회전을 돕는 세가지 표준 행렬. (Euler 회전) {{{~cpp Rx (r) = | 1 0 0 | | 0 cos(r) sin(r) | | 0 -sin(r) cos(r) | Ry (r) = | cos(r) 0 -sin(r)| | 0 1 0 | | 0 sin(r) cos(r) | Rz (r) = | cos(r) sin(r) 0 | | -sin(r) cos(r) 0 | | 0 0 1 | ex ) v0 = <2, 0, 0>을 z에 관해 시계 방향으로 45도 회전 v1 = Rz(45)v0 v1이 v0를 z에 관해 시계 방향으로 45도 회전시킨 지점이다. // 문제점 // x, y, z축으로 회전시킨 행렬들을 하나로 결합하기위한 표준 방법이 없다. // ?? }}} 일정한 회전을 주기위해 해야할 일은 단지 필요한 이련의 변환을 알아내고 [[BR]] 모델의 각 점에 이들 변환을 적용하는 것이다.[[BR]] {{{~cpp - 특정한 점 p에 존재하는 개체를 z축을 따라 회전시키려는 경우 - v = vT(-p) // 원점으로 위치이동 v = vRz(파이/2) // 파이.. 뭔지는 알겠지.. ㅡㅡ; v = vT(p) // 다시 전 p로 이동. }}} but, 각점들 마다 이런 연산을 수행하려면 너무 느리다. [[BR]] 그래서 말인데, 행렬에 있어서 좋은 점은 곱하기 전에 그 점들을 결합할 수 있다는 점이다.[[BR]] 두 가지 회전, 즉, A와 B를 수행해야 할 경우 결합 법칙에 따라 다음과같이 할 수 있다.[[BR]] {{{~cpp v` = (vA)B => v` = v(AB) // 오!~ }}} ==== 축-각도 회전 ==== 무슨 소리인지... [[BR]] 앞에서본 Euler회전의 문제점을 보안한 회전행렬.[[BR]] {{{~cpp | xx(1-cos(r)) + cos (r) yx(1-cos(r)) + z sin(r) xz(1-cos(r)) - y sin(r) 0 | | xy(1-cos(r)) + z sin(r) yy(1-cos(r)) + cos(r) yz(1-cos(r)) - x sin(r) 0 | | xz(1-cos(r)) + y sin(r) yz(1-cos(r)) + x sin(r) zz(1-cos(r)) - cos(r) 0 | | 0 0 0 1 | }}} === Chapter 4. 인공 지능 (Artificail Intelligence) === ==== 출발점 ==== '' * 어떻게 개체를 움직이고, 어떻게 돌고, 어떻게 걷느냐는 움직임에 관한문제 (locomotion or motor skills) * 개체가 어떻게 장애물 및 다른 개체들을 피하면서 A에서 B로 이동할 것인가? (task generation) * 실제사고, 개체들이 무엇을 할 것인지 스스로 결정하고 움직이는 능력을 이용하며 하고자 하는 바를 행할 계획을 세우는것 (acion steering) '' ==== 조종 - about move 1 ==== '''1.추적'''[[BR]] 간단히 적을 따라가는 것. 뭐 알고리즘 같은건 있지도 않을것 같다. [[BR]] '''2.탈출'''[[BR]] ... 할말 없음. [[BR]] '''3.패턴 (기본)'''[[BR]] ... 할말 없음. [[BR]] ==== 조종 - 2 ==== '''전위 함수''' 우리는 명벽하게 장애물 2보다는 장애물 1을 피하기를 더 원할 것이다.[[BR]] 즉, 장애물 2는 훨씬 더 멀리 떨어져 있기 때문이다.[[BR]] {{{~cpp -------------- | obstacle 2 | | goal | -------------- -------------- | obstacle 1 | -------------- |creature.| }}} 우리는 이 서술을 하나의 등식으로 바꿀 수 있다. 최초 우리의 방향은 [[BR]] 목표 지점을 향한 평균화된 벡터이다(or 목표 지점의 위치에서 현재 위치를 뺀 것) [[BR]] 그리고, 각각의 장애물에 대해 곧장 도망갈 수 있도록 하는 평균 벡터를 찾아낸다. [[BR]] 이 평균 벡터를 하나의 상수로 곱한 다음 다시 장애물로부터의 거리의 [[BR]] 제곱으로 나누다. 그리고 나서는 물체가 방향 벡터로서 이용해야될 하나의 벡터를 얻는다.[[BR]] ... 흠흠. 뭔소린지. 나는 알지~ ^^ [[BR]] 공식] [[BR]] http://zp.cse.cau.ac.kr/~erunc0/study/d3d/potential.bmp {{{~cpp // 실제 사용 예. bool Process() { point3 goalVec = g_goalLoc - m_loc; if( goalVec.Mag() < g_creatureSpeed ) return false; // goal까지 도착했다. point3 dirVec = goalVec / goalVec.Mag(); float k = .1f; // 각각의 obstacle과 검사 for( int i=0; i