Pastebin launched a little side project called VERYVIRAL.com, check it out ;-) Want more features on Pastebin? Sign Up, it's FREE!
Guest

Untitled

By: a guest on Apr 26th, 2012  |  syntax: C#  |  size: 9.36 KB  |  views: 30  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. #region File Description
  2. //-----------------------------------------------------------------------------
  3. // ChaseCamera.cs
  4. //
  5. // Microsoft XNA Community Game Platform
  6. // Copyright (C) Microsoft Corporation. All rights reserved.
  7. //-----------------------------------------------------------------------------
  8. #endregion
  9.  
  10. #region Using Statements
  11. using System;
  12. using System.Collections.Generic;
  13. using Microsoft.Xna.Framework;
  14. #endregion
  15.  
  16. namespace ChaseCameraSample
  17. {
  18.     public class ChaseCamera
  19.     {
  20.         #region Chased object properties (set externally each frame)
  21.  
  22.         /// <summary>
  23.         /// Position of object being chased.
  24.         /// </summary>
  25.         public Vector3 ChasePosition
  26.         {
  27.             get { return chasePosition; }
  28.             set { chasePosition = value; }
  29.         }
  30.         private Vector3 chasePosition;
  31.  
  32.         /// <summary>
  33.         /// Direction the chased object is facing.
  34.         /// </summary>
  35.         public Vector3 ChaseDirection
  36.         {
  37.             get { return chaseDirection; }
  38.             set { chaseDirection = value; }
  39.         }
  40.         private Vector3 chaseDirection;
  41.  
  42.         /// <summary>
  43.         /// Chased object's Up vector.
  44.         /// </summary>
  45.         public Vector3 Up
  46.         {
  47.             get { return up; }
  48.             set { up = value; }
  49.         }
  50.         private Vector3 up = Vector3.Up;
  51.  
  52.         #endregion
  53.  
  54.         #region Desired camera positioning (set when creating camera or changing view)
  55.  
  56.         /// <summary>
  57.         /// Desired camera position in the chased object's coordinate system.
  58.         /// </summary>
  59.         public Vector3 DesiredPositionOffset
  60.         {
  61.             get { return desiredPositionOffset; }
  62.             set { desiredPositionOffset = value; }
  63.         }
  64.         private Vector3 desiredPositionOffset = new Vector3(0, 2.0f, 2.0f);
  65.  
  66.         /// <summary>
  67.         /// Desired camera position in world space.
  68.         /// </summary>
  69.         public Vector3 DesiredPosition
  70.         {
  71.             get
  72.             {
  73.                 // Ensure correct value even if update has not been called this frame
  74.                 UpdateWorldPositions();
  75.  
  76.                 return desiredPosition;
  77.             }
  78.         }
  79.         private Vector3 desiredPosition;
  80.  
  81.         /// <summary>
  82.         /// Look at point in the chased object's coordinate system.
  83.         /// </summary>
  84.         public Vector3 LookAtOffset
  85.         {
  86.             get { return lookAtOffset; }
  87.             set { lookAtOffset = value; }
  88.         }
  89.         private Vector3 lookAtOffset = new Vector3(0, 2.8f, 0);
  90.  
  91.         /// <summary>
  92.         /// Look at point in world space.
  93.         /// </summary>
  94.         public Vector3 LookAt
  95.         {
  96.             get
  97.             {
  98.                 // Ensure correct value even if update has not been called this frame
  99.                 UpdateWorldPositions();
  100.  
  101.                 return lookAt;
  102.             }
  103.         }
  104.         private Vector3 lookAt;
  105.  
  106.         #endregion
  107.  
  108.         #region Camera physics (typically set when creating camera)
  109.  
  110.         /// <summary>
  111.         /// Physics coefficient which controls the influence of the camera's position
  112.         /// over the spring force. The stiffer the spring, the closer it will stay to
  113.         /// the chased object.
  114.         /// </summary>
  115.         public float Stiffness
  116.         {
  117.             get { return stiffness; }
  118.             set { stiffness = value; }
  119.         }
  120.         private float stiffness = 1800.0f;
  121.  
  122.         /// <summary>
  123.         /// Physics coefficient which approximates internal friction of the spring.
  124.         /// Sufficient damping will prevent the spring from oscillating infinitely.
  125.         /// </summary>
  126.         public float Damping
  127.         {
  128.             get { return damping; }
  129.             set { damping = value; }
  130.         }
  131.         private float damping = 600.0f;
  132.  
  133.         /// <summary>
  134.         /// Mass of the camera body. Heaver objects require stiffer springs with less
  135.         /// damping to move at the same rate as lighter objects.
  136.         /// </summary>
  137.         public float Mass
  138.         {
  139.             get { return mass; }
  140.             set { mass = value; }
  141.         }
  142.         private float mass = 50.0f;
  143.  
  144.         #endregion
  145.  
  146.         #region Current camera properties (updated by camera physics)
  147.  
  148.         /// <summary>
  149.         /// Position of camera in world space.
  150.         /// </summary>
  151.         public Vector3 Position
  152.         {
  153.             get { return position; }
  154.         }
  155.         private Vector3 position;
  156.  
  157.         /// <summary>
  158.         /// Velocity of camera.
  159.         /// </summary>
  160.         public Vector3 Velocity
  161.         {
  162.             get { return velocity; }
  163.         }
  164.         private Vector3 velocity;
  165.  
  166.         #endregion
  167.  
  168.  
  169.         #region Perspective properties
  170.  
  171.         /// <summary>
  172.         /// Perspective aspect ratio. Default value should be overriden by application.
  173.         /// </summary>
  174.         public float AspectRatio
  175.         {
  176.             get { return aspectRatio; }
  177.             set { aspectRatio = value; }
  178.         }
  179.         private float aspectRatio = 4.0f / 3.0f;
  180.  
  181.         /// <summary>
  182.         /// Perspective field of view.
  183.         /// </summary>
  184.         public float FieldOfView
  185.         {
  186.             get { return fieldOfView; }
  187.             set { fieldOfView = value; }
  188.         }
  189.         private float fieldOfView = MathHelper.ToRadians(45.0f);
  190.  
  191.         /// <summary>
  192.         /// Distance to the near clipping plane.
  193.         /// </summary>
  194.         public float NearPlaneDistance
  195.         {
  196.             get { return nearPlaneDistance; }
  197.             set { nearPlaneDistance = value; }
  198.         }
  199.         private float nearPlaneDistance = 1.0f;
  200.  
  201.         /// <summary>
  202.         /// Distance to the far clipping plane.
  203.         /// </summary>
  204.         public float FarPlaneDistance
  205.         {
  206.             get { return farPlaneDistance; }
  207.             set { farPlaneDistance = value; }
  208.         }
  209.         private float farPlaneDistance = 100000.0f;
  210.  
  211.         #endregion
  212.  
  213.         #region Matrix properties
  214.  
  215.         /// <summary>
  216.         /// View transform matrix.
  217.         /// </summary>
  218.         public Matrix View
  219.         {
  220.             get { return view; }
  221.         }
  222.         private Matrix view;
  223.  
  224.         /// <summary>
  225.         /// Projecton transform matrix.
  226.         /// </summary>
  227.         public Matrix Projection
  228.         {
  229.             get { return projection; }
  230.         }
  231.         private Matrix projection;
  232.  
  233.         #endregion
  234.  
  235.  
  236.         #region Methods
  237.  
  238.         /// <summary>
  239.         /// Rebuilds object space values in world space. Invoke before publicly
  240.         /// returning or privately accessing world space values.
  241.         /// </summary>
  242.         private void UpdateWorldPositions()
  243.         {
  244.             // Construct a matrix to transform from object space to worldspace
  245.             Matrix transform = Matrix.Identity;
  246.             transform.Forward = ChaseDirection;
  247.             transform.Up = Up;
  248.             transform.Right = Vector3.Cross(Up, ChaseDirection);
  249.  
  250.             // Calculate desired camera properties in world space
  251.             desiredPosition = ChasePosition +
  252.                 Vector3.TransformNormal(DesiredPositionOffset, transform);
  253.             lookAt = ChasePosition +
  254.                 Vector3.TransformNormal(LookAtOffset, transform);
  255.         }
  256.  
  257.         /// <summary>
  258.         /// Rebuilds camera's view and projection matricies.
  259.         /// </summary>
  260.         private void UpdateMatrices()
  261.         {
  262.             view = Matrix.CreateLookAt(this.Position, this.LookAt, this.Up);
  263.             projection = Matrix.CreatePerspectiveFieldOfView(FieldOfView,
  264.                 AspectRatio, NearPlaneDistance, FarPlaneDistance);
  265.         }
  266.  
  267.         /// <summary>
  268.         /// Forces camera to be at desired position and to stop moving. The is useful
  269.         /// when the chased object is first created or after it has been teleported.
  270.         /// Failing to call this after a large change to the chased object's position
  271.         /// will result in the camera quickly flying across the world.
  272.         /// </summary>
  273.         public void Reset()
  274.         {
  275.             UpdateWorldPositions();
  276.  
  277.             // Stop motion
  278.             velocity = Vector3.Zero;
  279.  
  280.             // Force desired position
  281.             position = desiredPosition;
  282.  
  283.             UpdateMatrices();
  284.         }
  285.  
  286.         /// <summary>
  287.         /// Animates the camera from its current position towards the desired offset
  288.         /// behind the chased object. The camera's animation is controlled by a simple
  289.         /// physical spring attached to the camera and anchored to the desired position.
  290.         /// </summary>
  291.         public void Update(GameTime gameTime)
  292.         {
  293.             if (gameTime == null)
  294.                 throw new ArgumentNullException("gameTime");
  295.  
  296.             UpdateWorldPositions();
  297.  
  298.             float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds;
  299.  
  300.             // Calculate spring force
  301.             Vector3 stretch = position - desiredPosition;
  302.             Vector3 force = -stiffness * stretch - damping * velocity;
  303.  
  304.             // Apply acceleration
  305.             Vector3 acceleration = force / mass;
  306.             velocity += acceleration * elapsed;
  307.  
  308.             // Apply velocity
  309.             position += velocity * elapsed;
  310.  
  311.             UpdateMatrices();
  312.         }
  313.  
  314.         #endregion
  315.     }
  316. }