/Engine/Cameras/ArcBallCamera.cs
https://bitbucket.org/tomas_vahalik/straiki-game-engine · C# · 266 lines · 208 code · 47 blank · 11 comment · 11 complexity · 03d7e3ad370d09dbc474916dcc5ce17a MD5 · raw file
- using System;
- using System.Collections.Generic;
- using System.Diagnostics;
- using System.Linq;
- using System.Text;
- using Microsoft.Xna.Framework;
-
- namespace StraikiEngine.Cameras
- {
- public class ArcBallCamera : TargetCamera
- {
- public Matrix Rotation = Matrix.Identity;
-
- private const float VerticalAngleMin = 0.01f;
- private const float VerticalAngleMax = MathHelper.Pi - 0.01f;
- private const float ZoomMin = 0.1f;
- private const float ZoomMax = 1500.0f;
-
- private static bool _positionOrRot = false;
-
-
-
-
-
- private float _zoom;
- public float Zoom
- {
- get
- {
- return _zoom;
- }
- set
- { // Keep zoom within range
- _viewMatrixDirty = true;
- _zoom = MathHelper.Clamp(value, ZoomMin, ZoomMax);
- }
-
- }
-
- public ArcBallCamera(GameScreen parent, Vector3 position) : base(parent, position)
- {
- }
-
- public ArcBallCamera(GameScreen parent, Vector3 position, float zoom) : this(parent, position, Vector3.Zero, zoom)
- {
- }
-
- public ArcBallCamera(GameScreen parent, Vector3 position, Vector3 target, float zoom) : base(parent, position, target)
- {
- Zoom = zoom;
- _position = position;
- Position = position;
- Yaw = DestYaw;
- Pitch = DestPitch;
- InitCam();
- }
-
-
- private float _horizontalAngle = MathHelper.PiOver2;
- public float HorizontalAngle
- {
- get
- {
- return _horizontalAngle;
- }
- set
- { // Keep horizontalAngle between -pi and pi.
- _horizontalAngle = value % MathHelper.Pi;
- }
- }
-
- private float _verticalAngle = MathHelper.PiOver2;
- public float VerticalAngle
- {
- get
- {
- return _verticalAngle;
- }
- set
- { // Keep vertical angle within tolerances
- _verticalAngle = MathHelper.Clamp(value, VerticalAngleMin, VerticalAngleMax);
- }
- }
-
- private readonly Vector3 _destination = new Vector3(140,0,205);
- private Vector3 _camStep;
- private const float DestYaw = 0.41f;
- private const float DestPitch = -0.57f;
-
- private bool _isMoving = false;
- private const int Iterations = 200;
- private int _iterDone;
-
- private void InitCam()
- {
- var diff = _destination - _lookAt;
- _camStep = diff/Iterations;
- _isMoving = true;
- _iterDone = Iterations;
- }
-
-
-
- public override void Update()
- {
- if (_isMoving)
- {
- if (_iterDone > 0)
- {
- _lookAt += _camStep;
- _iterDone--;
- }
- else
- {
- _isMoving = false;
- }
- ReCreateView();
- return;
- }
- if (!Active) return;
-
- _positionOrRot = Parent.Engine.Input.DoubleTap;
-
- Zoom += Parent.Engine.Input.ScaleChange;
-
- if (_positionOrRot)
- {
- if (Math.Abs(Parent.Engine.Input.MoveDelta.X - 0) > 0.0001)
- {
- Yaw += Parent.Engine.Input.MoveDelta.X;
-
- }
- if (Math.Abs(Parent.Engine.Input.MoveDelta.Y - 0) > 0.0001)
- {
- Pitch += Parent.Engine.Input.MoveDelta.Y;
-
- }
-
- if(_viewMatrixDirty)
- ReCreateView();
-
- }
- else
- {
- if (Math.Abs(Parent.Engine.Input.MoveDelta.X - 0) > 0.0001)
- MoveCameraRight(Parent.Engine.Input.MoveDelta.X*100);
- if (Math.Abs(Parent.Engine.Input.MoveDelta.Y - 0) > 0.0001)
- MoveCameraForward(Parent.Engine.Input.MoveDelta.Y*-100);
- if (_viewMatrixDirty)
- ReCreateView();
- }
-
- }
-
-
- private void ReCreateView()
- {
- //Calculate the relative position of the camera
- _position = Vector3.Transform(Vector3.Backward, Matrix.CreateFromYawPitchRoll(_yaw, _pitch, 0));
- //Convert the relative position to the absolute position
- _position *= Zoom;
- _position += _lookAt;
-
- //Calculate a new viewmatrix
- this.View = Matrix.CreateLookAt(_position, _lookAt, Vector3.Up);
- Position = _position;
- _viewMatrixDirty = false;
- }
-
- #region HelperMethods
-
- /// <summary>
- /// Moves the camera and lookAt at to the right,
- /// as seen from the camera, while keeping the same height
- /// </summary>
- public void MoveCameraRight(float amount)
- {
- var right = Vector3.Normalize(LookAt - ArcPosition); //calculate forward
- right = Vector3.Cross(right, Vector3.Up); //calculate the real right
- right.Y = 0;
- right.Normalize();
- LookAt += right * amount;
-
- }
-
- /// <summary>
- /// Moves the camera and lookAt forward,
- /// as seen from the camera, while keeping the same height
- /// </summary>
- public void MoveCameraForward(float amount)
- {
- Vector3 forward = Vector3.Normalize(LookAt - ArcPosition);
- forward.Y = 0;
- forward.Normalize();
- LookAt += forward * amount;
- }
-
- #endregion
-
- #region FieldsAndProperties
-
- private bool _viewMatrixDirty = true;
-
- public float MinPitch = -1f; //-MathHelper.PiOver2 + 0.3f;
- public float MaxPitch = -0.1f;//MathHelper.PiOver2 - 0.3f;
- private float _pitch;
- public float Pitch
- {
- get { return _pitch; }
- set
- {
- _viewMatrixDirty = true;
- _pitch = MathHelper.Clamp(value, MinPitch, MaxPitch);
- }
- }
-
- public float MinYaw = -0.55f; //-MathHelper.PiOver2 + 0.3f;
- public float MaxYaw = 0.55f;//MathHelper.PiOver2 - 0.3f;
- private float _yaw;
- public float Yaw
- {
- get { return _yaw; }
- set
- {
- _viewMatrixDirty = true;
- _yaw = MathHelper.Clamp(value, MinYaw, MaxYaw);
- }
- }
-
- private Vector3 _position;
- public Vector3 ArcPosition
- {
- get
- {
- if (_viewMatrixDirty)
- {
- ReCreateView();
- }
- return _position;
- }
- set { _position = value; }
- }
-
- private Vector3 _lookAt;
- public Vector3 LookAt
- {
- get { return _lookAt; }
- set
- {
- _viewMatrixDirty = true;
- _lookAt = value;
- }
- }
- #endregion
-
- #region ICamera Members
- public Matrix ViewProjectionMatrix
- {
- get { return View * Projection; }
- }
-
-
- #endregion
-
- }
- }