1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using Microsoft.Xna.Framework;
  5. using Microsoft.Xna.Framework.Audio;
  6. using Microsoft.Xna.Framework.Content;
  7. using Microsoft.Xna.Framework.GamerServices;
  8. using Microsoft.Xna.Framework.Graphics;
  9. using Microsoft.Xna.Framework.Input;
  10. using Microsoft.Xna.Framework.Media;
  11.  
  12. namespace MouseClickMovement
  13. {
  14.     /// <summary>
  15.     /// This is the main type for your game
  16.     /// </summary>
  17.     public class Game1 : Microsoft.Xna.Framework.Game
  18.     {
  19.         GraphicsDeviceManager graphics;
  20.         SpriteBatch spriteBatch;
  21.  
  22.         //Used this for some debugging
  23.         SpriteFont debugFont;
  24.         //string debugText;
  25.  
  26.         //Reserve memory for the mouse states
  27.         MouseState newMouseState, oldMouseState;
  28.  
  29.         //Reserve memory for the models
  30.         Model myModel;
  31.         Model Ground;
  32.  
  33.         // Reserve memory to move and rotate the model
  34.         float myModelRotation;
  35.         Vector3 myModelPosition;
  36.          
  37.         //used to calculate the amount of rotation of the camera
  38.         float totalCamPitch = 0f;
  39.         float totalCamYaw = 0f;
  40.  
  41.         //the final camera position
  42.         Vector3 finalCameraPosition;
  43.  
  44.         // the camera rotation matrix
  45.         Matrix cameraRotation;
  46.  
  47.         public Game1()
  48.         {
  49.             graphics = new GraphicsDeviceManager(this);
  50.             Content.RootDirectory = "Content";
  51.             //Gets rid of the jaggy edges of your model
  52.             graphics.PreferMultiSampling = true;
  53.             //set mouse vissible
  54.             IsMouseVisible = true;
  55.         }
  56.  
  57.         /// <summary>
  58.         /// Allows the game to perform any initialization it needs to before starting to run.
  59.         /// This is where it can query for any required services and load any non-graphic
  60.         /// related content.  Calling base.Initialize will enumerate through any components
  61.         /// and initialize them as well.
  62.         /// </summary>
  63.         protected override void Initialize()
  64.         {
  65.             // TODO: Add your initialization logic here
  66.  
  67.             base.Initialize();
  68.         }
  69.  
  70.         /// <summary>
  71.         /// LoadContent will be called once per game and is the place to load
  72.         /// all of your content.
  73.         /// </summary>
  74.         protected override void LoadContent()
  75.         {
  76.             // Create a new SpriteBatch, which can be used to draw textures.
  77.             spriteBatch = new SpriteBatch(GraphicsDevice);
  78.  
  79.             // TODO: use this.Content to load your game content here
  80.             debugFont = Content.Load<SpriteFont>("debugFont");
  81.  
  82.             //Loads models, import your own and point to the right file locations
  83.             myModel = Content.Load<Model>("frigate");
  84.             Ground = Content.Load<Model>("groundplane");
  85.  
  86.             //Sets my model's position
  87.             myModelPosition = Vector3.Zero;
  88.             //Rotates my model to the right angle
  89.             myModelRotation = MathHelper.ToRadians(-90f);
  90.  
  91.             // Sets initial camera pitch
  92.             totalCamPitch = -35;
  93.              
  94.  
  95.         }
  96.  
  97.         /// <summary>
  98.         /// UnloadContent will be called once per game and is the place to unload
  99.         /// all content.
  100.         /// </summary>
  101.         protected override void UnloadContent()
  102.         {
  103.             // TODO: Unload any non ContentManager content here
  104.         }
  105.  
  106.         /// <summary>
  107.         /// Allows the game to run logic such as updating the world,
  108.         /// checking for collisions, gathering input, and playing audio.
  109.         /// </summary>
  110.         /// <param name="gameTime">Provides a snapshot of timing values.</param>
  111.         protected override void Update(GameTime gameTime)
  112.         {
  113.             // Allows the game to exit
  114.             if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
  115.                 this.Exit();
  116.              
  117.  
  118.             oldMouseState = newMouseState;
  119.             newMouseState = Mouse.GetState();
  120.  
  121.             // CAMERA ORBIT CODE
  122.  
  123.             // sets the camera a little to the back of the model, since my model is small i use a small number in Z
  124.             Vector3 cameraOffset = new Vector3(0, 0, 50);
  125.  
  126.             //if mouse button is pressed
  127.             if (newMouseState.LeftButton == ButtonState.Pressed)
  128.             {
  129.                 //set mouse invissible (not really needed)
  130.                 IsMouseVisible = false;
  131.  
  132.                 //Simply set the total camera pitch and yaw to the difference in mouseposition, use -= to invert
  133.                 totalCamPitch += (oldMouseState.Y - newMouseState.Y);
  134.                 totalCamYaw += (oldMouseState.X - newMouseState.X);
  135.  
  136.                 //Set maximum pith to 89 degree's, read Google gimbal lock if you want to know why.
  137.                 if (totalCamPitch >= 89)
  138.                 {
  139.                     totalCamPitch = 89;
  140.                 }
  141.                 if (totalCamPitch <= -89)
  142.                 {
  143.                     totalCamPitch = -89;
  144.                 }
  145.             }
  146.             else
  147.             {
  148.                 // put mouse back on if mouse button is released.
  149.                 IsMouseVisible = true;
  150.             }
  151.  
  152.             //sets the camera rotation x and y equal to the total yaw and pitch
  153.             cameraRotation = Matrix.CreateRotationX(MathHelper.ToRadians(totalCamPitch)) *
  154.                 Matrix.CreateRotationY(MathHelper.ToRadians(totalCamYaw));
  155.  
  156.             // sets the camera position.
  157.             Vector3 cameraRotatedPosition = Vector3.Transform(cameraOffset, cameraRotation);
  158.  
  159.             // finally sets the camera position behind the player
  160.             finalCameraPosition = cameraRotatedPosition + myModelPosition;
  161.  
  162.             //debugText = "TotalCamPitch" + totalCamPitch;
  163.  
  164.             base.Update(gameTime);
  165.         }
  166.  
  167.         /// <summary>
  168.         /// This is called when the game should draw itself.
  169.         /// </summary>
  170.         /// <param name="gameTime">Provides a snapshot of timing values.</param>
  171.         protected override void Draw(GameTime gameTime)
  172.         {
  173.             GraphicsDevice.Clear(Color.CornflowerBlue);
  174.  
  175.             // TODO: Add your drawing code here
  176.              
  177.             Matrix[] transforms = new Matrix[myModel.Bones.Count];
  178.             myModel.CopyAbsoluteBoneTransformsTo(transforms);
  179.  
  180.  
  181.             //draw the mymodel with the camera attached to it.
  182.             foreach (ModelMesh mesh in myModel.Meshes)
  183.             {
  184.                 foreach (BasicEffect effect in mesh.Effects)
  185.                 {
  186.                     effect.EnableDefaultLighting();
  187.  
  188.                     effect.World = transforms[mesh.ParentBone.Index]
  189.                         * Matrix.CreateRotationY(myModelRotation)
  190.                         * Matrix.CreateTranslation(myModelPosition);
  191.  
  192.                     effect.View = Matrix.CreateLookAt(finalCameraPosition, myModelPosition, Vector3.Up);
  193.  
  194.                     effect.Projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(45f),
  195.                         graphics.GraphicsDevice.Viewport.AspectRatio, 1, 10000);
  196.                 }
  197.                 mesh.Draw();
  198.             }
  199.              
  200.             //draws the ground and anything else with the rotation and position given.
  201.             ModelDraw(Ground, 0f, new Vector3(0, -100, 0));
  202.  
  203.             base.Draw(gameTime);
  204.         }
  205.  
  206.  
  207.         /// <summary>
  208.         /// Draws a model on the screen
  209.         /// </summary>
  210.         /// <param name="model">The model</param>
  211.         /// <param name="rotation">Sets the rotation of the model in the world</param>
  212.         /// <param name="position">Sets the position of the model in the world</param>
  213.         private void ModelDraw(Model model,float rotation, Vector3 position)
  214.         {
  215.             Matrix[] transforms = new Matrix[model.Bones.Count];
  216.             model.CopyAbsoluteBoneTransformsTo(transforms);
  217.  
  218.             foreach (ModelMesh mesh in model.Meshes)
  219.             {
  220.                 foreach (BasicEffect effect in mesh.Effects)
  221.                 {
  222.                     effect.EnableDefaultLighting();
  223.                     effect.World = transforms[mesh.ParentBone.Index] *
  224.                         Matrix.CreateScale(1f) *                        
  225.                         Matrix.CreateRotationY(rotation) *
  226.                         Matrix.CreateTranslation(position);
  227.  
  228.                     effect.View = Matrix.CreateLookAt(finalCameraPosition, myModelPosition, Vector3.Up);
  229.  
  230.                     effect.Projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(45f),
  231.                         graphics.GraphicsDevice.Viewport.AspectRatio, 1, 10000);
  232.                 }
  233.                 mesh.Draw();
  234.             }
  235.  
  236.         }
  237.     }
  238. }