More actions
작성자: 김영현(erunc0), 최광식(woodpage) "Advanced 3D Game Programming using DirectX" - study.
GameLibrary( http://www.zeropage.org/~erunc0/study/d3d/GameLib.zip )를 만들어 가면서 책의 내용을 본다는.. 뭐뭐뭐.. 말만 그렇지, library부분은 대충 하는 느낌이 드는건 왜인지. 뭐, library부분은 api 초기화 루틴 부분정도이고, DX 도 역시 초기화 부분정도를 묶어 놓은 정도이기 때문에 이해하는데 어려움은 없었다. --;; Game 쪽 책을 사서 D3D를 본후, 3D를 공부하려는 마음으로 샀다. 무리없이 예제를 보는식으로 할것임.
목표
3D를 이용한 오락 만들기. 구체적인건 둘이서 생각해 볼것임. -- v.
진행 상황
1월 8일
- 영현 음.. 맘에 들지 않는다. 무슨 소리인지 갈피를 잡지 못하는게 현실이다. 관련 책이라도 좀 봐야 하겠다.약간은 설명이 미흡한것 같다. 내가 모자르기 때문일수도 있지만, ㅋㅋㅋ아직까지, 예제다운 예제를 못보다. 3D object를 본적이 없음. 아직까지.. --; - 232p/602p...
- 광식 이책 덮은지 한 20된거 같다. 되층되층 봐가지고 기억이 안난다. 니가적어논거를 보는거로 시작한다.
1월 9일
- potential function에 대해서만 봤다.. 약간 쓸만한 알고리즘(?) 인것 같다. ㅋㅋㅋ다음에 나오는 PathPlan에 관한얘기는 쉬운것 같은데. 장난이 아니다.머리 아프다. - 249p/602p...
- 전에도 느낀거지만 이책의 D3D초보자에게는 좀 아닌거 같다. 오늘 도서관에가서 책좀 빌려야겠다 광식
- 책비르러 간다. 3D에 관한책.. --+ 무신 책이 겜 초보자를 위한게 아닌거 같어.. --+ 짱나 짱나.. 영현
1월 10일
- 이런 어제 책 못빌렸다 오늘 빌려야겠다 --; 광식
1월 11일
- 잠시 외도. 광식이한테 빌린 책으로 3D를 공부.
쿠쿠.. 열심이구나.. ^^a.. DX 공부하면 나줌 갈켜다오.. 헤헤.. 나두 지금 하구 있는거.. 시간되면 여기다(위키..) 쓸께.. 너네두 곧 필요해질 내용이 있을테니.. 근데 지금은 내코가 좀 석자라서.. 시간에 쫓기는 관계로.. 언젠가.. 꼭.. ^^;; - 해성 오옷.. 해성이가 글을 썼다! --석천
Direct 3D
Chapter 1.
이런 종류의 책들이 다 그렇듯이, winapi를 사용한다. 그렇기 때문에, 초반의 한 chapter는 거의다 winapi를 사용해서 "Hello, World!"를 찍는 source를 넣어 준다. --;
Chapter 2.
DX 초기화 루틴과, game loop(message loop)를 포함한 library를 실제로 만든다. 그리고, 예제 source 1개정도.. 여기 까지 봤음.. - 곧 update , 01.06.2002 Sun ... 슬슬 책이 짜증나려고 한다. --+ 그냥 간단하게 책에서 제공하는 library를 쓰면 chapter2는 솔직히 보지 않아도 될것 같다. 무슨 소리들을 하는지. 전부 초기화.. --+ 함수 설명 뿐이네. 흐미.. 그냥.. 일반적인 3D이야기를 살것을.. Game쪽을 사서.. T-T 아무튼 보기는 다 봐야지. DX 는 할것이 정말 초기화 뿐이던가? chapter 3 부터는 수학이랍니다.. --;;
- Chapter 2: skip. 초기화 부분정도. 횡성 수설임. 무슨 소리하는지 못알아 먹을 정도임.
광식아 Chapter2 좀 니가 정리해라. 난 보는게 짜증나서 못해 먹겠다. 후후후. 같이 하니 이게 편하군.. 케케 이거 정리하는건 무리다--;
추천 도서: 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이다 .. 1월 8일 현재.. 이 부분은 엄청난 변화가 요구.. --a 책의 내용중 모르는 것이 너무 많다. 아니, 말이 어려운것 같다.
점
점은 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 그리고, 이 특성으로 인해 행렬과 행렬을 표현하는 공간을 설명할 때 매우 중요시 된다.
point3 구조체
3D점을 캡슐화 하기위한 구조체.
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의 연산자와 기본적 함수
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끼리 동등한지 아닌지를 잘 처리하지 못한다. 그래서, epsilon (이 책에서는 0.001로 정의)이라는 것을 두어 그 문제를 해결한다고 한다.
// 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;
}
내적 & 외적
// 내적
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) );
}
--; 고덩학교때 배웠던 내적과 외적. 지금보니 무슨 소리인지.. ㅎㅎㅎ 그냥 적어 봤음. --;
폴리곤
폴리곤은 개체의 테두리를 표현하는데 사용된다.
- http://www.gameschool.co.kr/cyberhtm/3dPolygon.htm - 폴리곤에 관한 page
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;
}
};
면
3D에서 면은 2D의 선과같다. 면을 정의하는 식
ax + by + cz + d = 0
삼원쌍 <a, b, c>는 면의 법선(법선: 그 면내의 모든 점들에 대해 수직인 벡터), d는 면에서 원점까지의 거리 위의 식을 만족하는 모든 점의 삼원쌍 <x, y, z>는 바로 면에 존재하는 모든 점들이다 면을 정의하는 구조체
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();
};
변환
3D의 위치이동이나 회전 등이 행렬로 이루어 진다는 얘기. 위치 이동이야 더해주고 빼주면 되는건 다 아는 사실이니.. 쩝.. --; 회전이나 알면 될것 같음. ... 회전을 돕는 세가지 표준 행렬. (Euler 회전)
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축으로 회전시킨 행렬들을 하나로 결합하기위한 표준 방법이 없다. // ??
일정한 회전을 주기위해 해야할 일은 단지 필요한 이련의 변환을 알아내고 모델의 각 점에 이들 변환을 적용하는 것이다.
- 특정한 점 p에 존재하는 개체를 z축을 따라 회전시키려는 경우 - v = vT(-p) // 원점으로 위치이동 v = vRz(파이/2) // 파이.. 뭔지는 알겠지.. ㅡㅡ; v = vT(p) // 다시 전 p로 이동.
but, 각점들 마다 이런 연산을 수행하려면 너무 느리다. 그래서 말인데, 행렬에 있어서 좋은 점은 곱하기 전에 그 점들을 결합할 수 있다는 점이다. 두 가지 회전, 즉, A와 B를 수행해야 할 경우 결합 법칙에 따라 다음과같이 할 수 있다.
v` = (vA)B => v` = v(AB) // 오!~
축-각도 회전
무슨 소리인지... 앞에서본 Euler회전의 문제점을 보안한 회전행렬.
| 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.추적 간단히 적을 따라가는 것. 뭐 알고리즘 같은건 있지도 않을것 같다. 2.탈출 ... 할말 없음. 3.패턴 (기본) ... 할말 없음.
조종 - 2
전위 함수 우리는 명벽하게 장애물 2보다는 장애물 1을 피하기를 더 원할 것이다. 즉, 장애물 2는 훨씬 더 멀리 떨어져 있기 때문이다.
--------------
| obstacle 2 | | goal |
--------------
--------------
| obstacle 1 |
--------------
|creature.|
우리는 이 서술을 하나의 등식으로 바꿀 수 있다. 최초 우리의 방향은 목표 지점을 향한 평균화된 벡터이다(or 목표 지점의 위치에서 현재 위치를 뺀 것) 그리고, 각각의 장애물에 대해 곧장 도망갈 수 있도록 하는 평균 벡터를 찾아낸다. 이 평균 벡터를 하나의 상수로 곱한 다음 다시 장애물로부터의 거리의 제곱으로 나누다. 그리고 나서는 물체가 방향 벡터로서 이용해야될 하나의 벡터를 얻는다. ... 흠흠. 뭔소린지. 나는 알지~ ^^ 공식] http://zp.cse.cau.ac.kr/~erunc0/study/d3d/potential.bmp
// 실제 사용 예.
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
- 야외의 경우와 같은 물리적 장애물이 드문 경우에는 잘된다.
- 장애물들이 스스로 움직일 수도 있다는 것.
- 장애물들이 너무 가까이 밀집해서 붙어 있다면 그것을 빠져 나올수 없다.