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(); } } } } |
'프로그래밍' 카테고리의 다른 글
3D프리미티브 표시하기 (0) | 2009.07.14 |
---|---|
커스텀쉐이더 이용하기 (0) | 2009.07.14 |
간단한 버튼이나 메뉴 키이벤트 처리 방법 (0) | 2009.07.14 |
How To XNA : 2. 비어있는 게임 화면과 구조 (0) | 2009.07.14 |
XNA 2.0 주요 변경사항: 요구사항 (0) | 2009.07.14 |
댓글