ArcBallCamera

Nov 7, 2011 at 4:06 PM
Edited Nov 8, 2011 at 2:52 AM

An ArcBallCamera for the framework since one is conspicuously missing, I'm not sure what the 2D equivalent should be, but if you let me know how it should behave i'll implement it.

 

    public class ArcBallCamera : Camera3D
    {
        private const float VERTICALROTATIONMIN = 0.01f;
        private const float VERTICALROTATIONMAX = MathHelper.Pi - 0.01f;

        public ISceneEntity TargetEntity { get; set; }
        private float _minRadius, _maxRadius;

        // Should we force these initial values to be supplied in the constructor ??
        private float _radius = 30f;
        private float _horizontalRotation = 0f;
        private float _verticalRotation = MathHelper.PiOver4;

        /// <summary>
        ///   Creates a new instance of the camera
        /// </summary>
        /// <param name = "aspectRatio"></param>
        /// <param name = "fieldOfView"></param>
        /// <param name = "nearPlaneDistance"></param>
        /// <param name = "farPlaneDistance"></param>
        public ArcBallCamera(float aspectRatio, float fieldOfView, float nearPlaneDistance, float farPlaneDistance, float minRadius, float maxRadius)
            : base(aspectRatio, fieldOfView, nearPlaneDistance, farPlaneDistance)
        {
            TargetPosition = Vector3.Forward;
            _minRadius = minRadius;
            _maxRadius = maxRadius;
        }

        /// <summary>
        /// Distance of camera from target
        /// </summary>
        public float Radius
        {
            get { return _radius; }
            set { _radius = MathHelper.Clamp(value, _minRadius, _maxRadius); }
        }

        /// <summary>
        /// Rotation of camera around vertical axis (Y)
        /// </summary>
        public float HorizontalRotation
        {
            get { return _horizontalRotation; }
            set
            {
                _horizontalRotation = value % MathHelper.TwoPi;
            }
        }

        /// <summary>
        /// Rotation of camera around horizontal axis (X)
        /// </summary>
        public float VerticalRotation
        {
            get { return _verticalRotation; }
            set
            {
                _verticalRotation = MathHelper.Clamp(value, VERTICALROTATIONMIN, VERTICALROTATIONMAX);
            }
        }

        /// <summary>
        ///   Override this method to catch input events and act on the camera
        /// </summary>
        /// <param name = "input">The current input instance</param>
        protected override void UpdateInput(InputManager input)
        {
            
        }

        protected override Matrix UpdateViewMatrix(GameTime gameTime)
        {
            Vector3 cameraPosition = Vector3.Multiply(Vector3.Up, Radius);
            cameraPosition = Vector3.Transform(cameraPosition, Matrix.CreateRotationX(_verticalRotation));
            cameraPosition = Vector3.Transform(cameraPosition, Matrix.CreateRotationY(_horizontalRotation));
            base.Position = base.TargetPosition + cameraPosition;
            return Matrix.CreateLookAt(base.Position, base.TargetPosition, Vector3.Up);
        }
    }
Coordinator
Nov 8, 2011 at 8:27 AM

Thanks for the code, I'll add it to the next IGF release right away.

A 2D Arcball camera wouldn't make sense in my opinion so no need for it. We don't have to provide cameras for each 2D and 3D space: only when it makes sense ;)

Philippe

Coordinator
Nov 8, 2011 at 8:28 AM
This discussion has been copied to a work item. Click here to go to the work item and continue the discussion.