이번에는 바로 이전 예제의 타이어를 굴리는 예제를 만들어보겠습니다.
이를 위해 카메라와 피규어라는 클래스를 만들어야 하고,
Game1.cs에서는 키 조작에 관한 코드를 작성하게 됩니다.
먼저 Camera.cs입니다.
카메라 클래스에서는 시점에 따라 유지할 정보를 가지고 있는데요,
이러한 정보에 대해 살펴보면,
- 뷰 매트릭스
n 카메라 위치
n 참조점
n UP벡터
- 사영 매트릭스
n 시야각
n aspect비
n NearClip면의 거리
n FarClip면의 거리
가 있습니다.
Camera.cs |
using System; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; //카메라 public class Camera { //뷰 매트릭스 private Matrix view; public Matrix View { get { return view; } } //사영 매트릭스 private Matrix projection; public Matrix Projection { get { return projection; } } //카메라 위치 private Vector3 position; public Vector3 Position { set { position = value; Update(); } get { return position; } } public float PositionX { set { position.X = value; Update(); } get { return position.X; } } public float PositionY { set { position.Y = value; Update(); } get { return position.Y; } } public float PositionZ { set { position.Z = value; Update(); } get { return position.Z; } } //참조점 private Vector3 look; public Vector3 Look { set { look = value; LookAt(position, look, Vector3.Up); } get { return look; } } //방향 public Vector3 Direction { get { Vector3 direction = look - position; direction.Normalize(); return direction; } } //횡위치 private float yaw; public float Yaw { set { yaw = value; Update(); } get { return yaw; } } //높이 private float pitch; public float Pitch { set { pitch = value; Update(); } get { return pitch; } } //롤 private float roll; public float Roll { set { roll = value; Update(); } get { return roll; } } public Camera(float aspectRatio) { //뷰 매트릭스 yaw = 0.0f; pitch = 0.0f; roll = 0.0f; position = new Vector3(0.0f, 0.0f, 3.0f); Update(); //사영 매트릭스 PerspectiveFieldOfView( MathHelper.ToRadians(45.0f), aspectRatio, 0.005f, 1000.0f ); } //뷰 매트릭스 갱신 private void Update() { Vector3 vec = new Vector3(0, 0, -1); Matrix trans = Matrix.CreateFromYawPitchRoll(yaw, pitch, roll); Vector3 look = Vector3.Transform(vec, trans) + position; LookAt(position, look, Vector3.Up); } //뷰 매트릭스 설정 public void LookAt(Vector3 position, Vector3 look, Vector3 up) { this.position = position; this.look = look; view = Matrix.CreateLookAt(position, look, up); } //사영 매트릭스 설정 public void PerspectiveFieldOfView(float fieldOfView, float aspectRatio, float near, float far) { projection = Matrix.CreatePerspectiveFieldOfView( fieldOfView, aspectRatio, near, far); } } |
다음은 피규어 클래스입니다.
피규어 클래스에서 취급하는 정보는,
- 위치정보
n X좌표
n Y좌표
n Z좌표
- 회전정보
n X축 회전
n Y축 회전
n Z축 회전
- 스케일정보
n X축 스케일
n Y축 스케일
n Z축 스케일
위와 같습니다.
Figure.cs |
using System; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; //피규어 형태데이터 public class Figure { //모델 private Model model; //위치 private Vector3 position; public Vector3 Position { get { return position; } set { position = value; } } public float PositionX { get { return position.X; } set { position.X = value; } } public float PositionY { get { return position.Y; } set { position.Y = value; } } public float PositionZ { get { return position.Z; } set { position.Z = value; } } //X축회전 private float rotateX; public float RotateX { get { return rotateX; } set { rotateX = value; } } //Y축회전 private float rotateY; public float RotateY { get { return rotateY; } set { rotateY = value; } } //Z축회전 private float rotateZ; public float RotateZ { get { return rotateZ; } set { rotateZ = value; } } //스케일 private Vector3 scale; public Vector3 Scale { get { return scale; } set { scale = value; } } public float ScaleX { get { return scale.X; } set { scale.X = value; } } public float ScaleY { get { return scale.Y; } set { scale.Y = value; } } public float ScaleZ { get { return scale.Z; } set { scale.Z = value; } } public Figure(Model model) { this.model = model; position = new Vector3(0.0f, 0.0f, 0.0f); rotateX = 0.0f; rotateY = 0.0f; rotateZ = 0.0f; scale = new Vector3(1.0f, 1.0f, 1.0f); } //그리기 public void Draw(Camera camera) { //모델 설정 Matrix world = Matrix.CreateRotationX(rotateX) * Matrix.CreateRotationY(rotateY) * Matrix.CreateRotationZ(rotateZ) * Matrix.CreateScale(scale) * Matrix.CreateTranslation(position); foreach (ModelMesh mesh in model.Meshes) { foreach (BasicEffect effect in mesh.Effects) { effect.EnableDefaultLighting(); effect.World = world; effect.View = camera.View; effect.Projection = camera.Projection; } } //모델 그리기 foreach (ModelMesh mesh in model.Meshes) { mesh.Draw(); } } } |
마지막으로 Game1.cs입니다.
Game1.cs |
using System; using System.Collections.Generic; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Audio; using Microsoft.Xna.Framework.Content; using Microsoft.Xna.Framework.GamerServices; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; using Microsoft.Xna.Framework.Net; using Microsoft.Xna.Framework.Storage; namespace Wheeler { public class Game1 : Microsoft.Xna.Framework.Game { //시스템 private GraphicsDeviceManager graphics; //그래픽스 private SpriteBatch spriteBatch;//스프라이트 //피규어 private Camera camera; //카메라 private Figure wheel;//바퀴 ㅋㅋ public Game1() { graphics = new GraphicsDeviceManager(this); Content.RootDirectory = "Content"; } //초기화 protected override void Initialize() { //Elapse Time 설정 IsFixedTimeStep = true; TargetElapsedTime = new TimeSpan(200000); Window.Title = "Wheeler - 에헤.."; //베이스 초기화 base.Initialize(); } //그래픽 컨텐츠 불러오기 protected override void LoadContent() { //폰트생성 spriteBatch = new SpriteBatch(GraphicsDevice); //카메라 생성 camera = new Camera( (float)GraphicsDevice.Viewport.Width / (float)GraphicsDevice.Viewport.Height); //바퀴 생성 wheel = new Figure(Content.Load<Model>("wheel")); } //그래픽컨텐츠 놓아주기 protected override void UnloadContent() { } //업데이트 protected override void Update(GameTime gameTime) { //키 설정 KeyboardState keyState = Keyboard.GetState(); //키 조작 if (keyState.IsKeyDown(Keys.Left)) { wheel.PositionX -= 0.1f; wheel.RotateZ += 0.2f; } else if (keyState.IsKeyDown(Keys.Right)) { wheel.PositionX += 0.1f; wheel.RotateZ -= 0.2f; } else if (keyState.IsKeyDown(Keys.Up)) { wheel.PositionY += 0.1f; wheel.RotateX += 0.2f; } else if (keyState.IsKeyDown(Keys.Down)) { wheel.PositionY -= 0.1f; wheel.RotateX -= 0.2f; } //베이스 업데이트 base.Update(gameTime); } //그리기 protected override void Draw(GameTime gameTime) { //배경색 graphics.GraphicsDevice.Clear(Color.CornflowerBlue); //피규어 그리기 wheel.Draw(camera); //베이스 그리기 base.Draw(gameTime); } } } |
이번 예제는 방향키에 맞춰 포지션과 로테이션 값을 지정해줌으로써 3D모델인 wheel이 움직이는
예제였는데요, 해당프로젝트를 첨부파일로 올려놓겠습니다.
적당히 축을 움직이며 상하좌우로 이동하는 모습도 나름 재미있는 동작이 된 것 같습니다......?
'프로그래밍' 카테고리의 다른 글
문자열관련 STL 함수 만들어보기 (0) | 2009.07.16 |
---|---|
SWAP작성과 포인터,배열,함수포인터 (0) | 2009.07.16 |
[3.0] 3D 모델 표시하기 (0) | 2009.07.14 |
텍스쳐 어둡게 하기 (0) | 2009.07.14 |
텍스쳐를 붙인 3D프리미티브 표시하기 (0) | 2009.07.14 |
댓글