Contents
GameLibrary( http://www.zeropage.org/~erunc0/study/d3d/GameLib.zip )를 만들어 가면서 책의 내용을 본다는.. 뭐뭐뭐..
말만 그렇지, library부분은 대충 하는 느낌이 드는건 왜인지.
뭐, library부분은 api 초기화 루틴 부분정도이고, DX 도 역시 초기화 부분정도를
묶어 놓은 정도이기 때문에 이해하는데 어려움은 없었다. --;;
Game 쪽 책을 사서 D3D를 본후, 3D를 공부하려는 마음으로 샀다. 무리없이 예제를 보는식으로 할것임.
2.4. 1월 11일 ¶
- 잠시 외도. 광식이한테 빌린 책으로 3D를 공부.
~cpp 쿠쿠.. 열심이구나.. ^^a.. DX 공부하면 나줌 갈켜다오.. 헤헤.. 나두 지금 하구 있는거.. 시간되면 여기다(위키..) 쓸께.. 너네두 곧 필요해질 내용이 있을테니.. 근데 지금은 내코가 좀 석자라서.. 시간에 쫓기는 관계로.. 언젠가.. 꼭.. ^^;; - 해성
오옷.. 해성이가 글을 썼다! --석천
3.1. Chapter 1. ¶
이런 종류의 책들이 다 그렇듯이, winapi를 사용한다.
그렇기 때문에, 초반의 한 chapter는 거의다 winapi를 사용해서
"Hello, World!"를 찍는 source를 넣어 준다. --;
그렇기 때문에, 초반의 한 chapter는 거의다 winapi를 사용해서
"Hello, World!"를 찍는 source를 넣어 준다. --;
3.2. Chapter 2. ¶
DX 초기화 루틴과, game loop(message loop)를 포함한 library를 실제로 만든다.
그리고, 예제 source 1개정도.. 여기 까지 봤음.. - 곧 update , 01.06.2002 Sun
...
슬슬 책이 짜증나려고 한다. --+ 그냥 간단하게 책에서 제공하는 library를 쓰면 chapter2는 솔직히
보지 않아도 될것 같다. 무슨 소리들을 하는지. 전부 초기화.. --+ 함수 설명 뿐이네. 흐미.. 그냥..
일반적인 3D이야기를 살것을.. Game쪽을 사서.. T-T 아무튼 보기는 다 봐야지. DX 는 할것이 정말 초기화 뿐이던가?
chapter 3 부터는 수학이랍니다.. --;;
이거 정리하는건 무리다--;
그리고, 예제 source 1개정도.. 여기 까지 봤음.. - 곧 update , 01.06.2002 Sun
...
슬슬 책이 짜증나려고 한다. --+ 그냥 간단하게 책에서 제공하는 library를 쓰면 chapter2는 솔직히
보지 않아도 될것 같다. 무슨 소리들을 하는지. 전부 초기화.. --+ 함수 설명 뿐이네. 흐미.. 그냥..
일반적인 3D이야기를 살것을.. Game쪽을 사서.. T-T 아무튼 보기는 다 봐야지. DX 는 할것이 정말 초기화 뿐이던가?
chapter 3 부터는 수학이랍니다.. --;;
- Chapter 2: skip. 초기화 부분정도. 횡성 수설임. 무슨 소리하는지 못알아 먹을 정도임.
이거 정리하는건 무리다--;
~cpp 추천 도서: Inside DirectX (필요로 한다면 말하시오. 전자책으로 있어요. --;;) Tricks of the Windows Game Programming Gurus : Fundamentals of 2D and 3D Game Programming. (DirectX, DirectMusic, 3D sound)
3.3. Chapter 3. 3D 수학적 기초 (50%~60%) ¶
이 chapter는 math3D라는 library를 만드는 chapter이다
.. 1월 8일 현재.. 이 부분은 엄청난 변화가 요구.. --a
책의 내용중 모르는 것이 너무 많다. 아니, 말이 어려운것 같다.
.. 1월 8일 현재.. 이 부분은 엄청난 변화가 요구.. --a
책의 내용중 모르는 것이 너무 많다. 아니, 말이 어려운것 같다.
3.3.1. 점 ¶
점은 3D 그래픽에서 가장 중요한 요소랍니다. 책에서 그러데요.
- 점은 3D 공간에서의 하나의 위치이고, 벡터는 3D공간 내에서 원점으로부터 하나의 위치를 잇는 직선이다. -
vector(3D 공간상의 점이 있는 일정한 거리)의 크기 (magnitude)를 구하는 공식은
i<1,0,0>, j<0,1,0>, k<0,0,1>
i, j, k벡터의 선형 조합으로 3D내의 어떠한 점이라도 나타낼수 있다.
a = <3, 5, 2>
a = 3i+5j+2k
그리고, 이 특성으로 인해 행렬과 행렬을 표현하는 공간을 설명할 때 매우 중요시 된다.
- 점은 3D 공간에서의 하나의 위치이고, 벡터는 3D공간 내에서 원점으로부터 하나의 위치를 잇는 직선이다. -
vector(3D 공간상의 점이 있는 일정한 거리)의 크기 (magnitude)를 구하는 공식은
~cpp 다들 알고 계시져? --;; 하하..단위 벡터- 세개의 주요 축들의 방향을 나타내기 위한 벡터.
i<1,0,0>, j<0,1,0>, k<0,0,1>
i, j, k벡터의 선형 조합으로 3D내의 어떠한 점이라도 나타낼수 있다.
a = <3, 5, 2>
a = 3i+5j+2k
그리고, 이 특성으로 인해 행렬과 행렬을 표현하는 공간을 설명할 때 매우 중요시 된다.
3.3.2. 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가 작업을 더 잘 수행할 수 있도록 해준다더군.) // ... };
3.3.3. 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; }
3.3.4. 벡터 동등 ¶
float이나 double이 나타낼수 있는 부동소수점의 한계로 인해 vector끼리 동등한지 아닌지를 잘 처리하지 못한다.
그래서, epsilon (이 책에서는 0.001로 정의)이라는 것을 두어 그 문제를 해결한다고 한다.
그래서, epsilon (이 책에서는 0.001로 정의)이라는 것을 두어 그 문제를 해결한다고 한다.
~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; }
3.3.5. 내적 & 외적 ¶
~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) ); }
--; 고덩학교때 배웠던 내적과 외적. 지금보니 무슨 소리인지.. ㅎㅎㅎ 그냥 적어 봤음. --;
3.3.6. 폴리곤 ¶
폴리곤은 개체의 테두리를 표현하는데 사용된다.
- http://www.gameschool.co.kr/cyberhtm/3dPolygon.htm - 폴리곤에 관한 page
- http://www.gameschool.co.kr/cyberhtm/3dPolygon.htm - 폴리곤에 관한 page
~cpp template <class type> 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.nElem; i++ ) { pList[i] = in.pList[i]; } } void DestroyData( ) { delete[] pList; pList = NULL; } polygon& operator=( const polygon<type> &in ) { if( &in != this ) { DestroyData(); CloneData( in ); } return *this; } };
3.3.7. 면 ¶
3D에서 면은 2D의 선과같다.
면을 정의하는 식
위의 식을 만족하는 모든 점의 삼원쌍 <x, y, z>는 바로 면에 존재하는 모든 점들이다
면을 정의하는 구조체
면을 정의하는 식
~cpp ax + by + cz + d = 0삼원쌍 <a, b, c>는 면의 법선(법선: 그 면내의 모든 점들에 대해 수직인 벡터), d는 면에서 원점까지의 거리
위의 식을 만족하는 모든 점의 삼원쌍 <x, y, z>는 바로 면에 존재하는 모든 점들이다
면을 정의하는 구조체
~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<point3>& poly ); plane3() { // Do nothing } // Flip the orientation of the plane void Flip(); };
3.3.8. 변환 ¶
3D의 위치이동이나 회전 등이 행렬로 이루어 진다는 얘기.
위치 이동이야 더해주고 빼주면 되는건 다 아는 사실이니.. 쩝.. --; 회전이나 알면 될것 같음.
...
회전을 돕는 세가지 표준 행렬. (Euler 회전)
모델의 각 점에 이들 변환을 적용하는 것이다.
그래서 말인데, 행렬에 있어서 좋은 점은 곱하기 전에 그 점들을 결합할 수 있다는 점이다.
두 가지 회전, 즉, A와 B를 수행해야 할 경우 결합 법칙에 따라 다음과같이 할 수 있다.
위치 이동이야 더해주고 빼주면 되는건 다 아는 사실이니.. 쩝.. --; 회전이나 알면 될것 같음.
...
회전을 돕는 세가지 표준 행렬. (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축으로 회전시킨 행렬들을 하나로 결합하기위한 표준 방법이 없다. // ??일정한 회전을 주기위해 해야할 일은 단지 필요한 이련의 변환을 알아내고
모델의 각 점에 이들 변환을 적용하는 것이다.
~cpp - 특정한 점 p에 존재하는 개체를 z축을 따라 회전시키려는 경우 - v = vT(-p) // 원점으로 위치이동 v = vRz(파이/2) // 파이.. 뭔지는 알겠지.. ㅡㅡ; v = vT(p) // 다시 전 p로 이동.but, 각점들 마다 이런 연산을 수행하려면 너무 느리다.
그래서 말인데, 행렬에 있어서 좋은 점은 곱하기 전에 그 점들을 결합할 수 있다는 점이다.
두 가지 회전, 즉, A와 B를 수행해야 할 경우 결합 법칙에 따라 다음과같이 할 수 있다.
~cpp v` = (vA)B => v` = v(AB) // 오!~
3.3.9. 축-각도 회전 ¶
무슨 소리인지...
앞에서본 Euler회전의 문제점을 보안한 회전행렬.
앞에서본 Euler회전의 문제점을 보안한 회전행렬.
~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 |
3.4.1. 출발점 ¶
''
- 어떻게 개체를 움직이고, 어떻게 돌고, 어떻게 걷느냐는 움직임에 관한문제 (locomotion or motor skills)
- 개체가 어떻게 장애물 및 다른 개체들을 피하면서 A에서 B로 이동할 것인가? (task generation)
- 실제사고, 개체들이 무엇을 할 것인지 스스로 결정하고 움직이는 능력을 이용하며 하고자 하는 바를 행할 계획을 세우는것 (acion steering)
3.4.2. 조종 - about move 1 ¶
1.추적
간단히 적을 따라가는 것. 뭐 알고리즘 같은건 있지도 않을것 같다.
2.탈출
... 할말 없음.
3.패턴 (기본)
... 할말 없음.
간단히 적을 따라가는 것. 뭐 알고리즘 같은건 있지도 않을것 같다.
2.탈출
... 할말 없음.
3.패턴 (기본)
... 할말 없음.
3.4.3. 조종 - 2 ¶
전위 함수
우리는 명벽하게 장애물 2보다는 장애물 1을 피하기를 더 원할 것이다.
즉, 장애물 2는 훨씬 더 멀리 떨어져 있기 때문이다.
목표 지점을 향한 평균화된 벡터이다(or 목표 지점의 위치에서 현재 위치를 뺀 것)
그리고, 각각의 장애물에 대해 곧장 도망갈 수 있도록 하는 평균 벡터를 찾아낸다.
이 평균 벡터를 하나의 상수로 곱한 다음 다시 장애물로부터의 거리의
제곱으로 나누다. 그리고 나서는 물체가 방향 벡터로서 이용해야될 하나의 벡터를 얻는다.
... 흠흠. 뭔소린지. 나는 알지~
공식]
http://zp.cse.cau.ac.kr/~erunc0/study/d3d/potential.bmp
장점
우리는 명벽하게 장애물 2보다는 장애물 1을 피하기를 더 원할 것이다.
즉, 장애물 2는 훨씬 더 멀리 떨어져 있기 때문이다.
~cpp -------------- | obstacle 2 | | goal | -------------- -------------- | obstacle 1 | -------------- |creature.|우리는 이 서술을 하나의 등식으로 바꿀 수 있다. 최초 우리의 방향은
목표 지점을 향한 평균화된 벡터이다(or 목표 지점의 위치에서 현재 위치를 뺀 것)
그리고, 각각의 장애물에 대해 곧장 도망갈 수 있도록 하는 평균 벡터를 찾아낸다.
이 평균 벡터를 하나의 상수로 곱한 다음 다시 장애물로부터의 거리의
제곱으로 나누다. 그리고 나서는 물체가 방향 벡터로서 이용해야될 하나의 벡터를 얻는다.
... 흠흠. 뭔소린지. 나는 알지~
공식]
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<g_obstacles.size(); i++ ) { // creature에서 obstacle까지의 vector point3 obstacleVec = m_loc - g_obstacles[i].m_loc; // obstacle과 creature사이의 실제 거리 float dist = obstacleVec.Mag() - g_obstacles[i].m_rad - m_rad; // this is the vector pointing away from the obstacle ?? obstacleVec.Normalize(); dirVec += obstacleVec * ( k / (dist * dist) ); // creature를 평행이동 시킬 행렬을 얻는다. 모든 obstacle을 검사 하면서... } dirVec.Normalize(); m_loc += g_creatureSpeed * dirVec; return true; // ok. obstacle을 피했다. }실행 파일: http://zp.cse.cau.ac.kr/~erunc0/study/d3d/potentialFunc.exe
장점
- 야외의 경우와 같은 물리적 장애물이 드문 경우에는 잘된다.
- 장애물들이 스스로 움직일 수도 있다는 것.
- 장애물들이 너무 가까이 밀집해서 붙어 있다면 그것을 빠져 나올수 없다.