본문 바로가기
프로그래밍

[3.0] 3D모델 이동하기

by 건우아빠유리남편 2009. 7. 14.
반응형

이번에는 바로 이전 예제의 타이어를 굴리는 예제를 만들어보겠습니다.

 

이를 위해 카메라와 피규어라는 클래스를 만들어야 하고,

 

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이 움직이는

 

예제였는데요,  해당프로젝트를 첨부파일로 올려놓겠습니다.

 

적당히 축을 움직이며 상하좌우로 이동하는 모습도 나름 재미있는 동작이 된 것 같습니다......?

반응형

댓글