using System; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; namespace Utility { public class CompactTexture { #region Variables protected Texture2D tex; protected Vector2 ori; protected Vector2 sca; protected Vector2 dim; protected Vector2 factor; protected Vector2 offset; #endregion #region Accessors public Texture2D Texture { get{ return tex; } set{ tex = value; Resolve(); } } public Vector2 Origin { get{ return ori; } set{ ori = value;} } public Vector2 Scale { get { return sca; } set { sca = value; } } /// /// The target pixel dimensions. /// public Vector2 Factor { get { return ori; } set { ori = value; Resolve(); } } /// /// Relative origin offset from center. /// public Vector2 Offset { get { return sca; } set { sca = value; Resolve(); } } public int Width { get{ return tex.Width; } } public int Height { get { return tex.Height; } } #endregion #region System public CompactTexture( Texture2D tex ) : this( tex, new Vector2( tex.Width, tex.Height), Vector2.Zero ) { } public CompactTexture( Texture2D tex, float factor ) : this( tex, new Vector2(factor, factor), Vector2.Zero ) { } public CompactTexture(Texture2D tex, float factor, Vector2 offset) : this(tex, new Vector2(factor, factor), offset) { } public CompactTexture(Texture2D tex, Vector2 factor) : this(tex, factor, Vector2.Zero) { } public CompactTexture( Texture2D tex, Vector2 factor, Vector2 offset) { this.tex = tex; this.factor = factor; this.offset = offset; Resolve(); } #endregion #region Methods protected void Resolve() { dim = new Vector2( tex.Width, tex.Height ); sca = factor / dim; ori = dim * .5f * ( Vector2.One + offset * sca * 2f ); } #endregion } public class Timer { #region Variables float seed; float val; bool ready; #endregion #region Accessors public bool Ready { get { return ready; } } public float Seed { get { return seed; } set { seed = value; } } public float Value { get { return val; } set { val = value; } } #endregion #region System public Timer( float seed ) { this.seed = seed; val = seed; } public bool Update( GameTime gameTime ) { val = Math.Max(-1f, val - (float)gameTime.ElapsedGameTime.TotalSeconds); ready = ( val < 0f ); return ready; } #endregion #region Methods public float Reset() { val = seed; return val; } #endregion } class LinearSmoother { #region Variables Vector2 actual; Vector2 target; Vector2 tester; float spring; float thresh; #endregion #region Accessors public Vector2 Vector { get { return actual; } } public Vector2 Target { set { tester = value; } } #endregion #region System public LinearSmoother( Vector2 vec, float spring, float thresh ) { this.actual = vec; this.target = vec; this.tester = vec; this.spring = spring; this.thresh = thresh; } void Update( GameTime gameTime ) { } #endregion } class QuaternalSmoother { #region Variables Quaternion quat; Vector2 actual; Vector2 target; Vector2 tester; float length; float angle; float thresh; float spring; #endregion #region Accessors public Vector2 Vector { get { return actual; } } public Vector2 Target { set { tester = value; } } public float Angle { get { return angle; } } public float Length { get { return length; } } #endregion #region System public QuaternalSmoother(Vector2 vec, float spring, float threshold) { this.actual = vec; this.target = vec; this.tester = vec; this.spring = spring; this.thresh = threshold; this.length = vec.Length(); actual.Normalize(); angle = (float)Math.Acos(Vector2.Dot(Vector2.UnitY, actual ) ); if (target.Y < 0.0f) angle = -angle; Vector3 axis = Vector3.UnitZ; Quaternion.CreateFromAxisAngle( ref axis, angle, out quat ); } public void Update(GameTime gameTime) { length = tester.Length(); if (length > thresh) { target = tester; } target.Normalize(); float temp = (float)Math.Acos(Vector2.Dot(Vector2.UnitX, target ) ); if ( target.Y > 0f ) temp = -temp; Quaternion test; Vector3 axis = Vector3.UnitZ; Quaternion.CreateFromAxisAngle( ref axis, temp, out test ); quat = Quaternion.Lerp( quat, test, spring ); Vector3 vec = QuaternionToEuler( quat ); angle = vec.Z; actual.X = (float)Math.Cos( angle ); actual.Y = (float)Math.Sin( angle ); actual.Normalize(); } #endregion #region Methods private Vector3 QuaternionToEuler(Quaternion rotation) { float q0 = rotation.W; float q1 = rotation.Y; float q2 = rotation.X; float q3 = rotation.Z; //In Radians Vector3 angles = new Vector3(); angles.X = (float)Math.Atan2(2 * (q0 * q1 + q2 * q3), 1 - 2 * (Math.Pow(q1, 2) + Math.Pow(q2, 2))); angles.Y = (float)Math.Asin(2 * (q0 * q2 - q3 * q1)); angles.Z = (float)Math.Atan2(2 * (q0 * q3 + q1 * q2), 1 - 2 * (Math.Pow(q2, 2) + Math.Pow(q3, 2))); return angles; } #endregion } class RotationalSmoother { #region Variables Vector2 actual; Vector2 target; Vector2 tester; float length; float angle; float spring; float thresh; #endregion #region Accessors public Vector2 Vector { get{ return actual; } } public Vector2 Target { set { tester = value; } } public float Angle { get{ return angle; } } public float Length { get{ return length; } } #endregion #region System public RotationalSmoother( Vector2 vec, float spring, float threshold ) { this.actual = vec; this.target = vec; this.tester = vec; this.spring = spring; this.thresh = threshold; this.length = vec.Length(); } public void Update( GameTime gameTime ) { length = tester.Length(); if ( length > thresh ) { target = tester; } actual += spring * (target - actual); actual.Normalize(); angle = (float)Math.Acos(-actual.Y); if (actual.X < 0.0f) angle = -angle; } #endregion } }