root/src/BRAINSFramework/Locomotion/LocomotionController.cs

User picture

Author: conkerjo

Revision: 30 («Previous)


File Size: 4.08 KB

(July 01, 2009 23:02 UTC) Almost 3 years ago


  

 
Show/hide line numbers
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;

namespace Brains.Framework.Locomotion
{
    /// <summary>
    /// Need to rename this class. 
    /// </summary>
    public class LocomotionController
    {
        private float _speed=0;
        private Vector2 _velocity=Vector2.Zero;
        
        /// <summary>
        /// Gets or sets the maximum speed the agent can travel at
        /// </summary>
        public float MaxSpeed 
        { 
            get; set; 
        }
       
        /// <summary>
        /// Gets or sets the maximum amount an Agent can rotate per second
        /// </summary>
        /// <remarks>Value is in radians</remarks>
        public float MaxRotation 
        { 
            get; set; 
        }
       
        /// <summary>
        /// Gets or sets the owning Agent
        /// </summary>
        public Agent Owner 
        { 
            get; set;
        }
       
        /// <summary>
        /// Gets the current speed of the Agent
        /// </summary>
        public float Speed 
        {
            get { return _speed; } 
        }
       
        /// <summary>
        /// Gets the velocity as a Vector2 of the Agent
        /// </summary>
        public Vector2 Velocity 
        { 
            get { return _velocity; } 
        }
       
        /// <summary>
        /// Gets or sets the value of wether the Agent will move
        /// </summary>
        public bool Stationary 
        { 
            get; set;
        }

        /// <summary>
        /// Initializes a new instance of LocomotionController
        /// </summary>
        public LocomotionController()
        {
            
        }
        
        /// <summary>
        /// The Update method is called every update of an Agent.
        /// </summary>
        /// <param name="gameTime"></param>
        public virtual void Update(GameTime gameTime)
        {
            if (Stationary)
                return;


            float desiredChangeRaw = Vector2.Dot(Owner.Orientation, Owner.DesiredOrientation);
            float desiredChange = (float)Math.Acos(desiredChangeRaw);
            float timeFactor = gameTime.GetElapsed();

            if (timeFactor == 0.0f)
                return;

            if (desiredChange > MaxRotation * timeFactor)
            {
                // determine if we rotating clock or counter-clock wise,
                // then aply maxRotation only

                //create vector perpendicular to the desired direction;
                Vector3 _perpendicular = new Vector3();
                Vector3 _up = new Vector3(0, 0, 1);
                Vector3 _des = Owner.DesiredOrientation.ToVector3();
                if (_des != Vector3.Zero)
                    _des.Normalize();

                Vector3.Cross(ref _des, ref _up, out _perpendicular);

                bool clockWise = (Vector3.Dot(Owner.Orientation.ToVector3(), _perpendicular) >= 0.0f);
                
                Matrix rotation = Matrix.Identity;
                
                if (clockWise)
                    Matrix.CreateRotationZ(MaxRotation * timeFactor, out rotation);
                else
                    Matrix.CreateRotationZ(-MaxRotation * timeFactor, out rotation);

                _des = Vector3.Transform(Owner.Orientation.ToVector3(), rotation);
                if (_des != Vector3.Zero)
                    _des.Normalize();

                Owner.Orientation = _des.ToVector2();
            }
            else
            {
                Owner.Orientation = Owner.DesiredOrientation;
            }

            if (desiredChangeRaw < 0.0f)
                desiredChangeRaw = 0.0f;

            if (MaxSpeed > 0)
            {
                _speed = (1 + desiredChangeRaw) * 0.5f * MaxSpeed;
                _velocity = Owner.Orientation * _speed;
                Owner.Position += _velocity * timeFactor;
            }
            else
                _speed = MaxSpeed;

        }
    }
}