SkinningSample.cs 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. #region File Description
  2. //-----------------------------------------------------------------------------
  3. // SkinningSample.cs
  4. //
  5. // Microsoft XNA Community Game Platform
  6. // Copyright (C) Microsoft Corporation. All rights reserved.
  7. //-----------------------------------------------------------------------------
  8. #endregion
  9. #region Using Statements
  10. using System;
  11. using Microsoft.Xna.Framework;
  12. using Microsoft.Xna.Framework.Content;
  13. using Microsoft.Xna.Framework.Graphics;
  14. using Microsoft.Xna.Framework.Input;
  15. using SkinnedModel;
  16. #endregion
  17. namespace SkinningSample
  18. {
  19. /// <summary>
  20. /// Sample game showing how to display skinned character animation.
  21. /// </summary>
  22. public class SkinningSampleGame : Microsoft.Xna.Framework.Game
  23. {
  24. #region Fields
  25. GraphicsDeviceManager graphics;
  26. KeyboardState currentKeyboardState = new KeyboardState();
  27. GamePadState currentGamePadState = new GamePadState();
  28. Model currentModel;
  29. AnimationPlayer animationPlayer;
  30. float cameraArc = 0;
  31. float cameraRotation = 0;
  32. float cameraDistance = 100;
  33. #endregion
  34. #region Initialization
  35. public SkinningSampleGame()
  36. {
  37. graphics = new GraphicsDeviceManager(this);
  38. Content.RootDirectory = "Content";
  39. #if WINDOWS_PHONE
  40. // Frame rate is 30 fps by default for Windows Phone.
  41. TargetElapsedTime = TimeSpan.FromTicks(333333);
  42. graphics.IsFullScreen = true;
  43. #endif
  44. }
  45. /// <summary>
  46. /// Load your graphics content.
  47. /// </summary>
  48. protected override void LoadContent()
  49. {
  50. // Load the model.
  51. currentModel = Content.Load<Model>("dude");
  52. // Look up our custom skinning information.
  53. SkinningData skinningData = currentModel.Tag as SkinningData;
  54. if (skinningData == null)
  55. throw new InvalidOperationException
  56. ("This model does not contain a SkinningData tag.");
  57. // Create an animation player, and start decoding an animation clip.
  58. animationPlayer = new AnimationPlayer(skinningData);
  59. AnimationClip clip = skinningData.AnimationClips["Take 001"];
  60. animationPlayer.StartClip(clip);
  61. }
  62. #endregion
  63. #region Update and Draw
  64. /// <summary>
  65. /// Allows the game to run logic.
  66. /// </summary>
  67. protected override void Update(GameTime gameTime)
  68. {
  69. HandleInput();
  70. UpdateCamera(gameTime);
  71. animationPlayer.Update(gameTime.ElapsedGameTime, true, Matrix.Identity);
  72. base.Update(gameTime);
  73. }
  74. /// <summary>
  75. /// This is called when the game should draw itself.
  76. /// </summary>
  77. protected override void Draw(GameTime gameTime)
  78. {
  79. GraphicsDevice device = graphics.GraphicsDevice;
  80. device.Clear(Color.CornflowerBlue);
  81. Matrix[] bones = animationPlayer.GetSkinTransforms();
  82. // Compute camera matrices.
  83. Matrix view = Matrix.CreateTranslation(0, -40, 0) *
  84. Matrix.CreateRotationY(MathHelper.ToRadians(cameraRotation)) *
  85. Matrix.CreateRotationX(MathHelper.ToRadians(cameraArc)) *
  86. Matrix.CreateLookAt(new Vector3(0, 0, -cameraDistance),
  87. new Vector3(0, 0, 0), Vector3.Up);
  88. Matrix projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4,
  89. device.Viewport.AspectRatio,
  90. 1,
  91. 10000);
  92. // Render the skinned mesh.
  93. foreach (ModelMesh mesh in currentModel.Meshes)
  94. {
  95. foreach (SkinnedEffect effect in mesh.Effects)
  96. {
  97. effect.SetBoneTransforms(bones);
  98. effect.View = view;
  99. effect.Projection = projection;
  100. effect.EnableDefaultLighting();
  101. effect.SpecularColor = new Vector3(0.25f);
  102. effect.SpecularPower = 16;
  103. }
  104. mesh.Draw();
  105. }
  106. base.Draw(gameTime);
  107. }
  108. #endregion
  109. #region Handle Input
  110. /// <summary>
  111. /// Handles input for quitting the game.
  112. /// </summary>
  113. private void HandleInput()
  114. {
  115. currentKeyboardState = Keyboard.GetState();
  116. currentGamePadState = GamePad.GetState(PlayerIndex.One);
  117. // Check for exit.
  118. if (currentKeyboardState.IsKeyDown(Keys.Escape) ||
  119. currentGamePadState.Buttons.Back == ButtonState.Pressed)
  120. {
  121. Exit();
  122. }
  123. }
  124. /// <summary>
  125. /// Handles camera input.
  126. /// </summary>
  127. private void UpdateCamera(GameTime gameTime)
  128. {
  129. float time = (float)gameTime.ElapsedGameTime.TotalMilliseconds;
  130. // Check for input to rotate the camera up and down around the model.
  131. if (currentKeyboardState.IsKeyDown(Keys.Up) ||
  132. currentKeyboardState.IsKeyDown(Keys.W))
  133. {
  134. cameraArc += time * 0.1f;
  135. }
  136. if (currentKeyboardState.IsKeyDown(Keys.Down) ||
  137. currentKeyboardState.IsKeyDown(Keys.S))
  138. {
  139. cameraArc -= time * 0.1f;
  140. }
  141. cameraArc += currentGamePadState.ThumbSticks.Right.Y * time * 0.25f;
  142. // Limit the arc movement.
  143. if (cameraArc > 90.0f)
  144. cameraArc = 90.0f;
  145. else if (cameraArc < -90.0f)
  146. cameraArc = -90.0f;
  147. // Check for input to rotate the camera around the model.
  148. if (currentKeyboardState.IsKeyDown(Keys.Right) ||
  149. currentKeyboardState.IsKeyDown(Keys.D))
  150. {
  151. cameraRotation += time * 0.1f;
  152. }
  153. if (currentKeyboardState.IsKeyDown(Keys.Left) ||
  154. currentKeyboardState.IsKeyDown(Keys.A))
  155. {
  156. cameraRotation -= time * 0.1f;
  157. }
  158. cameraRotation += currentGamePadState.ThumbSticks.Right.X * time * 0.25f;
  159. // Check for input to zoom camera in and out.
  160. if (currentKeyboardState.IsKeyDown(Keys.Z))
  161. cameraDistance += time * 0.25f;
  162. if (currentKeyboardState.IsKeyDown(Keys.X))
  163. cameraDistance -= time * 0.25f;
  164. cameraDistance += currentGamePadState.Triggers.Left * time * 0.5f;
  165. cameraDistance -= currentGamePadState.Triggers.Right * time * 0.5f;
  166. // Limit the camera distance.
  167. if (cameraDistance > 500.0f)
  168. cameraDistance = 500.0f;
  169. else if (cameraDistance < 10.0f)
  170. cameraDistance = 10.0f;
  171. if (currentGamePadState.Buttons.RightStick == ButtonState.Pressed ||
  172. currentKeyboardState.IsKeyDown(Keys.R))
  173. {
  174. cameraArc = 0;
  175. cameraRotation = 0;
  176. cameraDistance = 100;
  177. }
  178. }
  179. #endregion
  180. }
  181. #region Entry Point
  182. /// <summary>
  183. /// The main entry point for the application.
  184. /// </summary>
  185. static class Program
  186. {
  187. static void Main()
  188. {
  189. using (SkinningSampleGame game = new SkinningSampleGame())
  190. {
  191. game.Run();
  192. }
  193. }
  194. }
  195. #endregion
  196. }