E D R , A S I H C RSS

D3D

작성자: 김영현(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를 공부하려는 마음으로 샀다. 무리없이 예제를 보는식으로 할것임.

1. 목표

3D를 이용한 오락 만들기.

구체적인건 둘이서 생각해 볼것임.

-- v.

2. 진행 상황

2.1. 1월 8일

  • 음.. 맘에 들지 않는다. 무슨 소리인지 갈피를 잡지 못하는게 현실이다. 관련 책이라도 좀 봐야 하겠다.
    약간은 설명이 미흡한것 같다. 내가 모자르기 때문일수도 있지만, ㅋㅋㅋ
    아직까지, 예제다운 예제를 못보다. 3D object를 본적이 없음. 아직까지.. --; - 232p/602p...
  • 광식 이책 덮은지 한 20된거 같다. 되층되층 봐가지고 기억이 안난다. 니가적어논거를 보는거로 시작한다.

2.2. 1월 9일

  • potential function에 대해서만 봤다.. 약간 쓸만한 알고리즘(?) 인것 같다. ㅋㅋㅋ
    다음에 나오는 PathPlan에 관한얘기는 쉬운것 같은데. 장난이 아니다.
    머리 아프다. - 249p/602p...
  • 전에도 느낀거지만 이책의 D3D초보자에게는 좀 아닌거 같다. 오늘 도서관에가서 책좀 빌려야겠다 광식
  • 책비르러 간다. 3D에 관한책.. --+ 무신 책이 겜 초보자를 위한게 아닌거 같어.. --+ 짱나 짱나..

2.3. 1월 10일

  • 이런 어제 책 못빌렸다 오늘 빌려야겠다 --; 광식

2.4. 1월 11일

  • 잠시 외도. 광식이한테 빌린 책으로 3D를 공부.

~cpp 
쿠쿠.. 열심이구나.. ^^a.. DX 공부하면 나줌 갈켜다오.. 헤헤.. 나두 지금 하구 있는거.. 시간되면 여기다(위키..) 쓸께..
너네두 곧 필요해질 내용이 있을테니.. 근데 지금은 내코가 좀 석자라서.. 시간에 쫓기는 관계로.. 언젠가.. 꼭.. ^^;; - 해성
오옷.. 해성이가 글을 썼다! --석천

3. Direct 3D

3.1. Chapter 1.

이런 종류의 책들이 다 그렇듯이, winapi를 사용한다.

그렇기 때문에, 초반의 한 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 부터는 수학이랍니다.. --;;

  • 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)

3.3. Chapter 3. 3D 수학적 기초 (50%~60%)

이 chapter는 math3D라는 library를 만드는 chapter이다

.. 1월 8일 현재.. 이 부분은 엄청난 변화가 요구.. --a

책의 내용중 모르는 것이 너무 많다. 아니, 말이 어려운것 같다.

3.3.1.

점은 3D 그래픽에서 가장 중요한 요소랍니다. 책에서 그러데요.

- 점은 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로 정의)이라는 것을 두어 그 문제를 해결한다고 한다.

~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
~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의 선과같다.

면을 정의하는 식
~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 회전)
~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회전의 문제점을 보안한 회전행렬.

~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. Chapter 4. 인공 지능 (Artificail Intelligence)

3.4.1. 출발점

''
  • 어떻게 개체를 움직이고, 어떻게 돌고, 어떻게 걷느냐는 움직임에 관한문제 (locomotion or motor skills)
  • 개체가 어떻게 장애물 및 다른 개체들을 피하면서 A에서 B로 이동할 것인가? (task generation)
  • 실제사고, 개체들이 무엇을 할 것인지 스스로 결정하고 움직이는 능력을 이용하며 하고자 하는 바를 행할 계획을 세우는것 (acion steering)
''

3.4.2. 조종 - about move 1

1.추적

간단히 적을 따라가는 것. 뭐 알고리즘 같은건 있지도 않을것 같다.

2.탈출

... 할말 없음.

3.패턴 (기본)

... 할말 없음.

3.4.3. 조종 - 2

전위 함수
우리는 명벽하게 장애물 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




  • 야외의 경우와 같은 물리적 장애물이 드문 경우에는 잘된다.
  • 장애물들이 스스로 움직일 수도 있다는 것.


  • 장애물들이 너무 가까이 밀집해서 붙어 있다면 그것을 빠져 나올수 없다.
Valid XHTML 1.0! Valid CSS! powered by MoniWiki
last modified 2021-02-07 05:23:04
Processing time 0.1075 sec