Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #region File Description
- //-----------------------------------------------------------------------------
- // ChaseCamera.cs
- //
- // Microsoft XNA Community Game Platform
- // Copyright (C) Microsoft Corporation. All rights reserved.
- //-----------------------------------------------------------------------------
- #endregion
- #region Using Statements
- using System;
- using System.Collections.Generic;
- using Microsoft.Xna.Framework;
- #endregion
- namespace ChaseCameraSample
- {
- public class ChaseCamera
- {
- #region Chased object properties (set externally each frame)
- /// <summary>
- /// Position of object being chased.
- /// </summary>
- public Vector3 ChasePosition
- {
- get { return chasePosition; }
- set { chasePosition = value; }
- }
- private Vector3 chasePosition;
- /// <summary>
- /// Direction the chased object is facing.
- /// </summary>
- public Vector3 ChaseDirection
- {
- get { return chaseDirection; }
- set { chaseDirection = value; }
- }
- private Vector3 chaseDirection;
- /// <summary>
- /// Chased object's Up vector.
- /// </summary>
- public Vector3 Up
- {
- get { return up; }
- set { up = value; }
- }
- private Vector3 up = Vector3.Up;
- #endregion
- #region Desired camera positioning (set when creating camera or changing view)
- /// <summary>
- /// Desired camera position in the chased object's coordinate system.
- /// </summary>
- public Vector3 DesiredPositionOffset
- {
- get { return desiredPositionOffset; }
- set { desiredPositionOffset = value; }
- }
- private Vector3 desiredPositionOffset = new Vector3(0, 2.0f, 2.0f);
- /// <summary>
- /// Desired camera position in world space.
- /// </summary>
- public Vector3 DesiredPosition
- {
- get
- {
- // Ensure correct value even if update has not been called this frame
- UpdateWorldPositions();
- return desiredPosition;
- }
- }
- private Vector3 desiredPosition;
- /// <summary>
- /// Look at point in the chased object's coordinate system.
- /// </summary>
- public Vector3 LookAtOffset
- {
- get { return lookAtOffset; }
- set { lookAtOffset = value; }
- }
- private Vector3 lookAtOffset = new Vector3(0, 2.8f, 0);
- /// <summary>
- /// Look at point in world space.
- /// </summary>
- public Vector3 LookAt
- {
- get
- {
- // Ensure correct value even if update has not been called this frame
- UpdateWorldPositions();
- return lookAt;
- }
- }
- private Vector3 lookAt;
- #endregion
- #region Camera physics (typically set when creating camera)
- /// <summary>
- /// Physics coefficient which controls the influence of the camera's position
- /// over the spring force. The stiffer the spring, the closer it will stay to
- /// the chased object.
- /// </summary>
- public float Stiffness
- {
- get { return stiffness; }
- set { stiffness = value; }
- }
- private float stiffness = 1800.0f;
- /// <summary>
- /// Physics coefficient which approximates internal friction of the spring.
- /// Sufficient damping will prevent the spring from oscillating infinitely.
- /// </summary>
- public float Damping
- {
- get { return damping; }
- set { damping = value; }
- }
- private float damping = 600.0f;
- /// <summary>
- /// Mass of the camera body. Heaver objects require stiffer springs with less
- /// damping to move at the same rate as lighter objects.
- /// </summary>
- public float Mass
- {
- get { return mass; }
- set { mass = value; }
- }
- private float mass = 50.0f;
- #endregion
- #region Current camera properties (updated by camera physics)
- /// <summary>
- /// Position of camera in world space.
- /// </summary>
- public Vector3 Position
- {
- get { return position; }
- }
- private Vector3 position;
- /// <summary>
- /// Velocity of camera.
- /// </summary>
- public Vector3 Velocity
- {
- get { return velocity; }
- }
- private Vector3 velocity;
- #endregion
- #region Perspective properties
- /// <summary>
- /// Perspective aspect ratio. Default value should be overriden by application.
- /// </summary>
- public float AspectRatio
- {
- get { return aspectRatio; }
- set { aspectRatio = value; }
- }
- private float aspectRatio = 4.0f / 3.0f;
- /// <summary>
- /// Perspective field of view.
- /// </summary>
- public float FieldOfView
- {
- get { return fieldOfView; }
- set { fieldOfView = value; }
- }
- private float fieldOfView = MathHelper.ToRadians(45.0f);
- /// <summary>
- /// Distance to the near clipping plane.
- /// </summary>
- public float NearPlaneDistance
- {
- get { return nearPlaneDistance; }
- set { nearPlaneDistance = value; }
- }
- private float nearPlaneDistance = 1.0f;
- /// <summary>
- /// Distance to the far clipping plane.
- /// </summary>
- public float FarPlaneDistance
- {
- get { return farPlaneDistance; }
- set { farPlaneDistance = value; }
- }
- private float farPlaneDistance = 100000.0f;
- #endregion
- #region Matrix properties
- /// <summary>
- /// View transform matrix.
- /// </summary>
- public Matrix View
- {
- get { return view; }
- }
- private Matrix view;
- /// <summary>
- /// Projecton transform matrix.
- /// </summary>
- public Matrix Projection
- {
- get { return projection; }
- }
- private Matrix projection;
- #endregion
- #region Methods
- /// <summary>
- /// Rebuilds object space values in world space. Invoke before publicly
- /// returning or privately accessing world space values.
- /// </summary>
- private void UpdateWorldPositions()
- {
- // Construct a matrix to transform from object space to worldspace
- Matrix transform = Matrix.Identity;
- transform.Forward = ChaseDirection;
- transform.Up = Up;
- transform.Right = Vector3.Cross(Up, ChaseDirection);
- // Calculate desired camera properties in world space
- desiredPosition = ChasePosition +
- Vector3.TransformNormal(DesiredPositionOffset, transform);
- lookAt = ChasePosition +
- Vector3.TransformNormal(LookAtOffset, transform);
- }
- /// <summary>
- /// Rebuilds camera's view and projection matricies.
- /// </summary>
- private void UpdateMatrices()
- {
- view = Matrix.CreateLookAt(this.Position, this.LookAt, this.Up);
- projection = Matrix.CreatePerspectiveFieldOfView(FieldOfView,
- AspectRatio, NearPlaneDistance, FarPlaneDistance);
- }
- /// <summary>
- /// Forces camera to be at desired position and to stop moving. The is useful
- /// when the chased object is first created or after it has been teleported.
- /// Failing to call this after a large change to the chased object's position
- /// will result in the camera quickly flying across the world.
- /// </summary>
- public void Reset()
- {
- UpdateWorldPositions();
- // Stop motion
- velocity = Vector3.Zero;
- // Force desired position
- position = desiredPosition;
- UpdateMatrices();
- }
- /// <summary>
- /// Animates the camera from its current position towards the desired offset
- /// behind the chased object. The camera's animation is controlled by a simple
- /// physical spring attached to the camera and anchored to the desired position.
- /// </summary>
- public void Update(GameTime gameTime)
- {
- if (gameTime == null)
- throw new ArgumentNullException("gameTime");
- UpdateWorldPositions();
- float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds;
- // Calculate spring force
- Vector3 stretch = position - desiredPosition;
- Vector3 force = -stiffness * stretch - damping * velocity;
- // Apply acceleration
- Vector3 acceleration = force / mass;
- velocity += acceleration * elapsed;
- // Apply velocity
- position += velocity * elapsed;
- UpdateMatrices();
- }
- #endregion
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement