XNA for C#
DirectX 9 for C#
DirectX 9 for C++
DirectX 9 for VB
Forum
   
My XNA Book
      
       Go to section on this site

Additional info


Latest Forum posts

 Account settings
  Posted by: Anonymous
  When: 07/05/2014 at 09:48:39

 forced subtitle
  Posted by: Applefly
  When: 07/05/2014 at 06:00:48

 convert DVD into PMS
  Posted by: Applefly
  When: 07/05/2014 at 05:55:25

 DVD to Digital Copy easily
  Posted by: VIKIVannessa
  When: 05/05/2014 at 06:52:29

 DVD on Xbox 360/Xbox One Console
  Posted by: VIKIVannessa
  When: 05/05/2014 at 06:51:47

 Extract .Srt Subtitles
  Posted by: Applefly
  When: 04/05/2014 at 03:54:38

 Encode Movie collection
  Posted by: Applefly
  When: 04/05/2014 at 03:52:41

 Convert DVD to WMV
  Posted by: Applefly
  When: 29/04/2014 at 05:53:50

 rip DVDs into digital files
  Posted by: Applefly
  When: 29/04/2014 at 05:51:20

 iTunes movies/music to Kindle Fire
  Posted by: ciciyu80
  When: 29/04/2014 at 05:10:20


Ads

회전과 위치 변경

이번 tutorial에서는 우리의 삼각형을 회전시켜 보겠습니다.

카메라의 움직임과 같이 객체를 회전하는 것도 월드 좌표계와 연관되어 있습니다.

코드로 들어가기 위해, 새 Windows Game 프로젝트를 생성합시다. 이전까지의 tutorial과 마찬가지로 마지막 tutorial에서 이어지므로 tutorial04에서 필요한 파일을 복사해 오도록 합시다.

회전이란 다시 말해 기울임의 연속입니다. 그리고 우리는 흔히 몇 도(angle)로 기울어졌다 라고 말하곤 합니다. 즉, 우리의 삼각형이 회전하기 위해서는 삼각형의 기울임을 표현해 줄 각도(angle)이 필요합니다.

기울임을 표현해 줄 전역 변수를 선언합시다.

 float angle = 0.0f; // 전역 변수 정의

앞서 회전이란 기울임의 연속이라고 설명했습니다. 각도(angle)가 시간이 흐름에 따라 증가하거나 혹은 감소한다면 이것을 연속한다 라고 말할 수 있겠죠. 따라서 우리의 삼각형을 회전시키기 위해 일정한 시간의 흐름에 따라 각도를 일정하게 증가시켜 줄 필요가 있습니다.

XNA는 Update함수를 통해 이러한 기능을 제공합니다. Update함수는 각 frame마다 호출되는 함수이고, 일반적으로 frame은 1초에 60번 반복됩니다. 일반적으로 어떤 게임은 60 frame이다 혹은 30 frame이다 라고 말할때 언급되는 것이 바로 frame입니다.

Update함수에 다음과 같이 코드를 추가 합시다.

 protected override void Update(GameTime gameTime)
 {
     // Allows the game to exit
     if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
         this.Exit();
 
     // TODO: Add your update logic here
 
     angle += 0.05f;
 
     base.Update(gameTime);
 }

이제 회전에 반영할 각도값인 angle은 각 frame마다 0.05f씩 증가하게 되었습니다. 더해주는 값이 커지면 각 frame마다 증가값이 커지니 빠르게 회전하고 작아지면 느리게 회전하겠네요. 음수로 해준다면 반대 방향으로 회전하겠죠. tutorial이 끝나고 값을 여러가지로 변경해서 그 결과를 확인해 봅시다.

이제 이 각도값을 월드 좌표계에 반영합시다. 다행히도 DirectX와 같이 matrix의 연산은 XNA또한 모두 제공합니다.

Draw함수의 effect.Begin() 라인 위에 다음과 같은 코드를 추가합니다.

 Matrix worldMatrix = Matrix.CreateRotationY(angle);
 effect.Parameters["xWorld"].SetValue(worldMatrix);

첫번째 라인은 Y축을 중심으로 회전하는 월드 좌표계를 생성합니다. 물론 회전하는 각도값은 미리 실정해둔 angle변수를 사용하며, angle변수는 설정한 바와 같이 frame당 0.05f씩 증가합니다. 초당 60 frame이 지나가니 1초가 지나면 우리의 삼각형은 3f만큼 회전해 있겠네요.
두번째 라인은 이렇게 생성된 월드 좌표계를 effect에 적용시키는 코드입니다.

디버그(F5)키를 눌러 실행시켜 봅시다. 우리의 삼각형이 Y축을 중심으로 일정한 속도로 회전함을 확인할 수 있습니다. 회전 속도를 변경 하고 싶다면 angle값을 조절하면 됩니다.



지금 우리의 삼각형은 원점 (0.0f, 0.0f, 0.0f)를 중심으로 회전하고 있습니다. 좀 더 보기 좋게 우리의 삼각형을 중앙에 위치시키고 삼각형 그 자체가 Z축으로도 회전하도록 수정해봅시다.

이 전까지는 우리의 삼각형의 위치를 변환하기 위해서는 vertex들을 수정해야 했지만, 이제 그릴 필요는 없습니다. vertex는 그대로 두고 좌표계를 이동시키면 간단하게 위치가 변환됩니다.

사실 이쯤에서 눈치를 챈 분도 있겠지만, 앞서 우리의 삼각형을 회전시킨 것 또한 삼각형이 회전했다기 보다는 삼각형의 좌표계가 회전했다고 보는 편이 옳습니다. 마찬가지로 위치를 변환할때도 좌표계를 이동시키면 우리눈에는 마치 삼각형의 위치가 변환된 것과 같이 보이게 됩니다.

앞서 Draw함수에 추가한 월드 좌표계를 생성하는 라인을 다음과 같이 바꿔 봅시다.

 Matrix worldMatrix = Matrix.CreateTranslation(-5, -10 * 1 / 3, 0) * Matrix.CreateRotationZ(angle);

이 코드는 삼각형이 좌표계의 원점 (0.0f, 0.0f, 0.0f)에 위치하도록 좌표계를 이동하고 Z축을 기준으로 회전하는 월드 좌표계를 생성합니다. 선형 대수학의 기초를 아는 분이라면 금방 아시겠지만, 두 좌표계를 동시에 적용하기 위해서는 각각의 좌표계 즉 행렬(matrix)를 곱하는 연산이 필요합니다.

디버그(F5)키를 눌러 실행하여 우리의 삼각형이 좌표계의 원점을 중심으로 하고 Z축을 기준으로 회전하고 있는지 확인해봅시다.



여기서 한가지 더 짚고 넘어가야 할 부분은 좌표계가 곱해지는 순서 입니다. 여기서는 월드 좌표계 = 위치 변경 좌표계 * Z축 기준 회전 좌표계를 사용했지만, 곱해지는 순서가 틀려지면 의도했던 것과 전혀 다른 결과가 나올 수 있습니다. 즉, M1 * M2의 결과는 M2 * M1의 결과와 다릅니다. 중요한 내용이니 꼭 기억해 두길 바랍니다.

방금 추가한 코드의 좌표계들이 곱해지는 순서를 바꿔 보면 그 차이를 명확히 알 수 있겠네요. 위의 코드를 다음과 같이 변경해 봅시다.

 Matrix worldMatrix = Matrix.CreateRotationZ(angle) * Matrix.CreateTranslation(-5, -10 * 1 / 3, 0);

이전의 코드가 우리의 삼각형의 중심이 원점으로 이동하도록 좌표계의 위치를 변경한 후, Z축을 기준으로 회전시키는 연산을 한 반면에, 지금의 코드는 먼저 우리의 삼각형을 Z축을 기준으로 회전시킨후 좌표계의 위치를 변경하였습니다.

얼핏 보기에는 별 차이가 없어 보이지만, 실행되었을때의 결과는 확연히 다릅니다. 반드시 위의 코드를 실행해보고 그 결과를 직접 확인해 보길 바랍니다.

이제 우리가 3D를 다루고 있다는 사실을 좀 더 몸으로 느껴보기 위해 우리의 삼각형을 Z축 뿐만이 아니라, X축은 물론 Y축을 기준으로도 회전시켜 보도록 합시다.

좌표계의 곱을 개념적으로 표현해보면 '월드 좌표계 = 좌표계 위치 변환 * X축 기준 회전 변환 자표계 * Y축 기준 회전 변환 좌표계 * Z축 기준 회전 좌표계' 로 표현할 수 있겠지만, XNA에서는 굳히 각 좌표축 기준 회전 변환 좌표계를 일일히 곱할 필요 없이 한번에 X, Y, Z축 기준 회전 변환 좌표계를 생성할 수 있는 함수를 제공합니다.

위의 코드를 다음과 같이 수정합니다.

 Vector3 rotAxis = new Vector3(3 * angle, 1 * angle, 2 * angle);
 rotAxis.Normalize();
 Matrix worldMatrix = Matrix.CreateTranslation(-5, -10 * 1 / 3, 0) * Matrix.CreateFromAxisAngle(rotAxis, angle);

첫번째 라인은 X, Y, Z축에 대해 우리의 삼각형의 회전축 vector을 만듭니다. 두번째 라인은 이 vector를 normalize하는 코드입니다. normalize란 vector와 좌표계 원점(0.0f, 0.0f, 0.0f)의 거리가 1이 되도록, 즉 vector의 크기가 1이 되도록 vector를 정규화 하는 것을 말합니다. 이렇게 normalize된 vector를 단위 벡터(unit vector)라고 부릅니다. 세번째 라인은 좌표계 위치 변환 후, 회전축 vector를 기준으로 각도값 만큼 회전하는 월드 좌표계를 생성합니다. Matrix.CreateFromAxisAngle 함수가 회전축 기준 회전 좌표계를 생성해 줍니다. parameter로 회전의 기준이 될 회전축(axis) vector와 얼마 만큼 회전할지 결정하는 각도값(angle)을 받아들입니다.

디버그(F5)키를 눌러 실행해보면 우리의 삼각형이 화면의 중앙에서 시간의 흐름에 따라 변하는 회전축을 기준으로 일정한 속도로 회전하고 있음을 확인할 수 있습니다.






Google
 
Webwww.riemers.net


If you appreciate the amount of time I spend creating and updating
these pages, feel free to donate -- any amount is welcome !



- Website design & XNA + DirectX code : Riemer Grootjans -
©2003 - 2011 Riemer Grootjans
Translations

This site in English
This site in Korean
This site in Czech

Microsoft MVP Award



2007 - 2011 MVP Award
DirectX - XNA

Contents

[Tutorials]
[XNA in C#]
Series 1: 지형
XNA의 시작
이펙트 파일
첫 번째 삼각형
월드 좌표계
회전, 위치 변환
인덱스
지형 생성의 기본
파일로부터 지형 생성
키보드 입력
[tut10]
[tut11]
[tut12]
[tut13]
-- Expand all --


Thank you!

Support this site --
any amount is welcome !

Stay up-to-date

I don't have the time to keep a News section, so stay informed about the updates by clicking on this RSS file!