AvatarAnimationBlendingSample.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
  1. #region File Description
  2. //-----------------------------------------------------------------------------
  3. // AvatarAnimationBlendingSample.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 System.Collections.ObjectModel;
  12. using Microsoft.Xna.Framework;
  13. using Microsoft.Xna.Framework.GamerServices;
  14. using Microsoft.Xna.Framework.Graphics;
  15. using Microsoft.Xna.Framework.Input;
  16. #endregion
  17. namespace AvatarAnimationBlendingSample
  18. {
  19. /// <summary>
  20. /// This sample demonstrates how to blend multiple avatar animations
  21. /// </summary>
  22. public class AvatarAnimationBlendingGame : Microsoft.Xna.Framework.Game
  23. {
  24. #region Fields
  25. GraphicsDeviceManager graphics;
  26. SpriteBatch spriteBatch;
  27. SpriteFont font;
  28. // Description, renderer, and animation for
  29. // loading and drawing an animated avatar
  30. AvatarDescription avatarDescription;
  31. AvatarRenderer avatarRenderer;
  32. AvatarBlendedAnimation blendedAnimation;
  33. AvatarAnimation[] avatarAnimations;
  34. AvatarAnimation noBlendingAnimation;
  35. // Should we use blending?
  36. bool useAnimationBlending = true;
  37. // matrices used to draw the avatar
  38. Matrix world;
  39. Matrix view;
  40. Matrix projection;
  41. // the current input states. These are updated in the HandleInput function,
  42. // and used primarily in the UpdateCamera function.
  43. GamePadState currentGamePadState;
  44. GamePadState lastGamePadState;
  45. // the following constants control the speed at which the camera moves
  46. // how fast does the camera move up, down, left, and right?
  47. const float CameraRotateSpeed = .1f;
  48. // how fast does the camera zoom in and out?
  49. const float CameraZoomSpeed = .01f;
  50. // the camera can't be further away than this distance
  51. const float CameraMaxDistance = 10.0f;
  52. // and it can't be closer than this
  53. const float CameraMinDistance = 2.0f;
  54. // the following constants control the camera's default position
  55. const float CameraDefaultArc = 30.0f;
  56. const float CameraDefaultRotation = 0;
  57. const float CameraDefaultDistance = 3.0f;
  58. // Camera control values
  59. float cameraArc = CameraDefaultArc;
  60. float cameraRotation = CameraDefaultRotation;
  61. float cameraDistance = CameraDefaultDistance;
  62. #endregion
  63. #region Initialization
  64. /// <summary>
  65. /// Constructor.
  66. /// </summary>
  67. public AvatarAnimationBlendingGame()
  68. {
  69. graphics = new GraphicsDeviceManager(this);
  70. Content.RootDirectory = "Content";
  71. graphics.PreferredBackBufferWidth = 1280;
  72. graphics.PreferredBackBufferHeight = 720;
  73. graphics.PreferMultiSampling = true;
  74. // Avatars require GamerServices
  75. Components.Add(new GamerServicesComponent(this));
  76. }
  77. /// <summary>
  78. /// Load your graphics content.
  79. /// </summary>
  80. protected override void LoadContent()
  81. {
  82. spriteBatch = new SpriteBatch(GraphicsDevice);
  83. font = Content.Load<SpriteFont>("Font");
  84. // Create random avatar description and load the renderer and animation
  85. avatarDescription = AvatarDescription.CreateRandom();
  86. avatarRenderer = new AvatarRenderer(avatarDescription);
  87. // Load 4 of the preset animations
  88. avatarAnimations = new AvatarAnimation[4];
  89. avatarAnimations[0] = new AvatarAnimation(AvatarAnimationPreset.Stand0);
  90. avatarAnimations[1] = new AvatarAnimation(AvatarAnimationPreset.Celebrate);
  91. avatarAnimations[2] = new AvatarAnimation(AvatarAnimationPreset.Clap);
  92. avatarAnimations[3] = new AvatarAnimation(AvatarAnimationPreset.Wave);
  93. // Create new blended animation
  94. blendedAnimation = new AvatarBlendedAnimation(avatarAnimations[0]);
  95. noBlendingAnimation = avatarAnimations[0];
  96. // Initialize the rendering matrices
  97. world = Matrix.CreateRotationY(MathHelper.Pi);
  98. projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4,
  99. GraphicsDevice.Viewport.AspectRatio,
  100. .01f, 200.0f);
  101. }
  102. #endregion
  103. #region Update and Draw
  104. /// <summary>
  105. /// Allows the game to run logic.
  106. /// </summary>
  107. protected override void Update(GameTime gameTime)
  108. {
  109. HandleInput();
  110. UpdateCamera(gameTime);
  111. // Set avatar rendering matrices
  112. avatarRenderer.World = world;
  113. avatarRenderer.View = view;
  114. avatarRenderer.Projection = projection;
  115. // Update the current animation and world space bones
  116. if (avatarRenderer.State == AvatarRendererState.Ready)
  117. {
  118. if (useAnimationBlending)
  119. {
  120. blendedAnimation.Update(gameTime.ElapsedGameTime, true);
  121. }
  122. else
  123. {
  124. noBlendingAnimation.Update(gameTime.ElapsedGameTime, true);
  125. }
  126. }
  127. base.Update(gameTime);
  128. }
  129. /// <summary>
  130. /// This is called when the game should draw itself.
  131. /// </summary>
  132. protected override void Draw(GameTime gameTime)
  133. {
  134. GraphicsDevice.Clear(Color.CornflowerBlue);
  135. string message = "Blending: " + (useAnimationBlending ? "On" : "Off") +
  136. "\n(Left Shoulder Button)";
  137. // Draw the text
  138. spriteBatch.Begin();
  139. spriteBatch.DrawString(font, message, new Vector2(161, 161), Color.Black);
  140. spriteBatch.DrawString(font, message, new Vector2(160, 160), Color.White);
  141. spriteBatch.End();
  142. // Draw the avatar
  143. if (useAnimationBlending)
  144. avatarRenderer.Draw(blendedAnimation);
  145. else
  146. avatarRenderer.Draw(noBlendingAnimation);
  147. base.Draw(gameTime);
  148. }
  149. #endregion
  150. #region Input and Camera
  151. /// <summary>
  152. /// Handles input for quitting the game.
  153. /// </summary>
  154. void HandleInput()
  155. {
  156. lastGamePadState = currentGamePadState;
  157. currentGamePadState = GamePad.GetState(PlayerIndex.One);
  158. // Check for exit.
  159. if (currentGamePadState.Buttons.Back == ButtonState.Pressed)
  160. {
  161. Exit();
  162. }
  163. // Check to see if we need to change blending bool
  164. if (currentGamePadState.Buttons.LeftShoulder == ButtonState.Pressed &&
  165. lastGamePadState.Buttons.LeftShoulder != ButtonState.Pressed)
  166. {
  167. useAnimationBlending = !useAnimationBlending;
  168. }
  169. // Check to see if we should load another random avatar
  170. if (currentGamePadState.Buttons.RightShoulder == ButtonState.Pressed &&
  171. lastGamePadState.Buttons.RightShoulder != ButtonState.Pressed)
  172. {
  173. avatarDescription = AvatarDescription.CreateRandom();
  174. avatarRenderer = new AvatarRenderer(avatarDescription);
  175. }
  176. // Check to see if we need to play another animation
  177. if (currentGamePadState.Buttons.A == ButtonState.Pressed &&
  178. lastGamePadState.Buttons.A != ButtonState.Pressed)
  179. {
  180. blendedAnimation.Play(avatarAnimations[1]);
  181. noBlendingAnimation = avatarAnimations[1];
  182. }
  183. else if (currentGamePadState.Buttons.B == ButtonState.Pressed &&
  184. lastGamePadState.Buttons.B != ButtonState.Pressed)
  185. {
  186. blendedAnimation.Play(avatarAnimations[2]);
  187. noBlendingAnimation = avatarAnimations[2];
  188. }
  189. else if (currentGamePadState.Buttons.X == ButtonState.Pressed &&
  190. lastGamePadState.Buttons.X != ButtonState.Pressed)
  191. {
  192. blendedAnimation.Play(avatarAnimations[0]);
  193. noBlendingAnimation = avatarAnimations[0];
  194. }
  195. else if (currentGamePadState.Buttons.Y == ButtonState.Pressed &&
  196. lastGamePadState.Buttons.Y != ButtonState.Pressed)
  197. {
  198. blendedAnimation.Play(avatarAnimations[3]);
  199. noBlendingAnimation = avatarAnimations[3];
  200. }
  201. }
  202. /// <summary>
  203. /// Handles input for moving the camera.
  204. /// </summary>
  205. void UpdateCamera(GameTime gameTime)
  206. {
  207. float time = (float)gameTime.ElapsedGameTime.TotalMilliseconds;
  208. // should we reset the camera?
  209. if (currentGamePadState.Buttons.RightStick == ButtonState.Pressed)
  210. {
  211. cameraArc = CameraDefaultArc;
  212. cameraDistance = CameraDefaultDistance;
  213. cameraRotation = CameraDefaultRotation;
  214. }
  215. // Check for input to rotate the camera up and down around the model.
  216. cameraArc += currentGamePadState.ThumbSticks.Right.Y * time *
  217. CameraRotateSpeed;
  218. // Limit the arc movement.
  219. cameraArc = MathHelper.Clamp(cameraArc, -90.0f, 90.0f);
  220. // Check for input to rotate the camera around the model.
  221. cameraRotation += currentGamePadState.ThumbSticks.Right.X * time *
  222. CameraRotateSpeed;
  223. // Check for input to zoom camera in and out.
  224. cameraDistance += currentGamePadState.Triggers.Left * time
  225. * CameraZoomSpeed;
  226. cameraDistance -= currentGamePadState.Triggers.Right * time
  227. * CameraZoomSpeed;
  228. // clamp the camera distance so it doesn't get too close or too far away.
  229. cameraDistance = MathHelper.Clamp(cameraDistance,
  230. CameraMinDistance, CameraMaxDistance);
  231. Matrix unrotatedView = Matrix.CreateLookAt(
  232. new Vector3(0, 0, cameraDistance), new Vector3(0, 1, 0), Vector3.Up);
  233. view = Matrix.CreateRotationY(MathHelper.ToRadians(cameraRotation)) *
  234. Matrix.CreateRotationX(MathHelper.ToRadians(cameraArc)) *
  235. unrotatedView;
  236. }
  237. #endregion
  238. }
  239. #region Entry Point
  240. /// <summary>
  241. /// The main entry point for the application.
  242. /// </summary>
  243. static class Program
  244. {
  245. static void Main()
  246. {
  247. using (AvatarAnimationBlendingGame game = new AvatarAnimationBlendingGame())
  248. {
  249. game.Run();
  250. }
  251. }
  252. }
  253. #endregion
  254. }