본문 바로가기
프로그래밍

3D모델 조작하기

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

이번은 3D모델을 조작하는 프로젝트 입니다. 그러나 이미 저번 프로젝트에서 일부를 다뤘다는..!

그래도 참고삼아 보셨으면 좋겠네요.

 

 

3D모델 조작하기

3D모델을 Xbox360컨트롤러로 이동시키는 프로그램을 작성한다. 왼쪽 조이스틱으로 모델을 좌우회전시키고 A버튼으로 모델정보를 리셋, 오른쪽 트리거로 전진시킨다. 전진 중에 컨트롤러는 진동한다.

 

 

리소스 추가

이번 프로그램에서는 3D모델 하나와 텍스쳐 한 장과 효과 하나를 사용합니다.

모델과 텍스쳐는 XNA Creators Club 에서 가지고 왔습니다.

폴더구성은 다음과 같습니다.

1.     프로젝트를 생성한다.

2.     프로젝트이름을 우 클릭하여 추가->새로운폴더 를 선택하여 Content폴더를 생성하여 그 아래에 같은 방법으로 Models폴더 Textures폴더를 생성한다.

3.     Models폴더를 우 클릭하여 추가->이미 있는 항목을 선택하여 p1_wedge.fbx  를 추가한다.

4.     Textures폴더를 우 클릭하여 추가->이미 있는 항목 을 선택하여 wedge_p1_diff_v1.tga
추가한다. 프로그램에서 읽어 들일 수 없기 때문에, 솔루션탐색기에서는 지워둔다.
Wedge_p1_diff_v1.tga
를 우 클릭하여 프로젝트로부터 제거를 선택한다.(디렉토리엔 남는

거 알죠??)

 

소스 코드 편집

Game.cs를 편집한다.

 

Game.cs

using System;

using Microsoft.Xna.Framework;

using Microsoft.Xna.Framework.Content;

using Microsoft.Xna.Framework.Graphics;

using Microsoft.Xna.Framework.Input;

using Microsoft.Xna.Framework.Audio;

 

//3D모델 조작하기

namespace ModelControlEx {

    public class Game1 : Microsoft.Xna.Framework.Game {

        //그래픽스

        private GraphicsDeviceManager graphics; //그래픽스

        private ContentManager        content;  //컨텐트

 

        //모델

        private Model   model;                  //모델

        private Vector3 modelPos = Vector3.Zero; //모델 위치

        private Vector3 modelVel = Vector3.Zero; //모델 속도

        private float   modelRot = 0.0f;        //모델 회전

 

        //카메라

        private float   aspectRatio; //종횡도

        private Vector3 cameraPos;  //카메라위치

 

        //constructor

        public Game1() {

            //그래픽스

            graphics = new GraphicsDeviceManager(this);

            content  = new ContentManager(Services);

 

            //화면사이즈

            graphics.PreferredBackBufferWidth  = 853;

            graphics.PreferredBackBufferHeight = 480;

        }

 

        //초기화

        protected override void Initialize() {

            base.Initialize();

        }

 

        //그래픽스 컨텐츠 로드

        protected override void LoadGraphicsContent(bool loadAllContent) {

            if (loadAllContent) {

                //모델읽어오기

                model = content.Load<Model>("Content\\Models\\p1_wedge");

            }

 

            //카메라 초기화

            aspectRatio = (float)graphics.GraphicsDevice.Viewport.Width /

                graphics.GraphicsDevice.Viewport.Height;  //종횡도

            cameraPos = new Vector3(0.0f, 50.0f, 5000.0f); //카메라

        }

 

        //그래픽스 컨텐츠 해방

        protected override void UnloadGraphicsContent(bool unloadAllContent) {

            if (unloadAllContent) content.Unload();

        }

 

        //업뎃

        protected override void Update(GameTime gameTime) {

            //종료

            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed) {

                this.Exit();

            }

 

            //입력을 통한 갱신

            UpdateInput();

 

            //위치업뎃

            modelPos += modelVel;

 

            //속도 낮추기

            modelVel *= 0.95f;

 

            //베이스업뎃

            base.Update(gameTime);

        }

 

        //입력에 의한 업뎃

        protected void UpdateInput() {

            //키 상태 얻어오기

            GamePadState currentState = GamePad.GetState(PlayerIndex.One);

            if (currentState.IsConnected) {

                //모델좌우회전

                modelRot -= currentState.ThumbSticks.Left.X * 0.10f;

 

                //모델 속도가산치

                Vector3 modelVelAdd = Vector3.Zero;

                modelVelAdd.X = -(float)Math.Sin(modelRot);

                modelVelAdd.Z = -(float)Math.Cos(modelRot);

 

                //오른쪽 트리거ON/OFF로 가산여부를 결정

                modelVelAdd *= currentState.Triggers.Right;

 

                //모델 속도 업뎃

                modelVel += modelVelAdd;

 

                //오른쪽 트리거ON/OFF로 진동여부를 결정

                GamePad.SetVibration(PlayerIndex.One,

                    currentState.Triggers.Right,

                    currentState.Triggers.Right);

 

                //모델정보를 리셋

                if (currentState.Buttons.A == ButtonState.Pressed) {

                    modelPos = Vector3.Zero;

                    modelVel = Vector3.Zero;

                    modelRot = 0.0f;

                }

            }

        }

 

        //그리기

        protected override void Draw(GameTime gameTime) {

            //배경색지정

            graphics.GraphicsDevice.Clear(Color.CornflowerBlue);

 

            //부모 트랜스폼 카피

            Matrix[] transforms = new Matrix[model.Bones.Count];

            model.CopyAbsoluteBoneTransformsTo(transforms);

 

            //모델 그리기

            foreach (ModelMesh mesh in model.Meshes) {

                //효과 지정

                foreach (BasicEffect effect in mesh.Effects) {

                    //광원

                    effect.EnableDefaultLighting();

 

                    //월드 매트릭스

                    effect.World =

                        transforms[mesh.ParentBone.Index] *

                        Matrix.CreateRotationY(modelRot) * //모델Y축회전

                        Matrix.CreateTranslation(modelPos); //모델 위치

 

                    //뷰 매트릭스

                    effect.View = Matrix.CreateLookAt(

                        cameraPos,   //카메라위치

                        Vector3.Zero, //참조점

                        Vector3.Up); //UP벡터

 

                    //사영 매트릭스

                    effect.Projection = Matrix.CreatePerspectiveFieldOfView(

                        MathHelper.ToRadians(45.0f), //시야각(라디안단위)

                        aspectRatio,                //종횡도

                        1.0f,                       //니아 클립 면의 거리

                        10000.0f);                 //파 클립 면의 거리

                }

                //베이스그리기

                mesh.Draw();

            }

        }

    }

}

 


반응형

댓글