5 Replies - 636 Views - Last Post: 02 November 2013 - 04:16 PM Rate Topic: -----

#1 oyyou  Icon User is offline

  • D.I.C Head

Reputation: 27
  • View blog
  • Posts: 184
  • Joined: 26-April 10

Image Rotation

Posted 17 October 2013 - 06:43 AM

So my problem is rotation.

I want to be able to rotate my ship depending on which thruster is going. The image I have below only has 2 thrusters, but I want the choice of multiple, is several locations and different angles.

My problem is I don't know how to make it work. I believe I may need to take in the account of the thrusters angel.. But I really don't know.

Here if my current way, which works fine for the example below.. But ya know.. Expanding and all that.
if(up key pressed)
{
   velocity.X = (float)Math.Cos(rotation) * 5;
   velocity.Y = (float)Math.Sin(rotation) * 5;
}



I'm working on XNA, which makes things easier. But I it's not an XNA specific problem.

Thanks!
Posted Image

This post has been edited by oyyou: 17 October 2013 - 06:47 AM


Is This A Good Question/Topic? 0
  • +

Replies To: Image Rotation

#2 BBeck  Icon User is offline

  • Here to help.
  • member icon


Reputation: 570
  • View blog
  • Posts: 1,270
  • Joined: 24-April 12

Re: Image Rotation

Posted 18 October 2013 - 03:23 PM

Boy, you know how to open up a can of worms. ;-)

Believe it or not, this has been one of my priorities since you posted this. I've been working on it for two days and there's still a bug in it somewhere. I had it "sort of" working, but it wasn't quite right. I made it worse while trying to fix it.

I kind of wanted to dig into this anyway, because I wanted to solve it for 3D work that I want to do and it's a lot easier to work out in 2D like this. So, I've made it a big priority.

Unfortunately, I think I'm out of time available to work on it until next week. But here's what I've got so far.


using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace ShipTorque2D
{
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        SpriteEffects Effect;
        Vector2 ShipSpriteSize;
        KeyboardState KB;
        KeyboardState PrevKB;
        Texture2D Ship;
        SpriteFont Font;
        int PortEngineThrotle; 
        int StarboardEngineThrotle;
        float PortEngineThrust;
        float StarboardEngineThrust;
        
        Vector2 ShipsPosition;
        Vector2 ShipsVelocity;    //In meters per second in a given direction.
        Vector2 ShipsFacing;   //In radians.
        Vector2 ShipsHeading;   //In radians.

        float ShipsAngularVelocity;   //In radians per frame. (We'll assume 60 fps.)

        const int FramesPerSecond = 60;
        const float EngineTorqueArm = 16f;  //Distance from center of gravity to engine's tangent in pixels (or meters).
        const float EngineForce = 4000f;  //Maximum force exerted by a single engine in Newtons (kilogram meters per second each second).
        const float ShipsMass = 18143.7f;    //In kilograms. 20 short tons =18143.7kg.
        //const float ShipsMomentOfInertia = ShipsMass * EngineTorqueArm * EngineTorqueArm;
        const float ShipsEngineMaxAcceleration = (EngineForce / ShipsMass)/FramesPerSecond;   //In meters per second each second divided by FPS to give meters per second each frame.


        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            graphics.PreferredBackBufferWidth = 1280;   //Screen width horizontal
            graphics.PreferredBackBufferHeight = 720;   //Screen width vertical
            graphics.IsFullScreen = false;   //Set to false when debugging.
            graphics.ApplyChanges();
            Content.RootDirectory = "Content";

            Effect = new SpriteEffects();
        }

        
        protected override void Initialize()
        {
            ShipsPosition = new Vector2(200f, 200f);
            PortEngineThrust = 0;
            StarboardEngineThrust = 0;
            ShipsAngularVelocity = 0f;  // MathHelper.PiOver4 / 60f;
            ShipsFacing = Vector2.UnitX;  //Start with ship heading towards right side of the screen.
            ShipsHeading = Vector2.UnitX;  //Start with ship heading towards right side of the screen.
            ShipSpriteSize = new Vector2(192f, 256f);
            base.Initialize();
        }

        
        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);
            Ship = Content.Load<Texture2D>("SquarishShip");
            Font = Content.Load<SpriteFont>("SpriteFont1");

        }

        
        protected override void UnloadContent()
        {
        
        }

        
        protected override void Update(GameTime gameTime)
        {
            //float ShipsAngularMomentum;
            //float PortEngineAngularForce;
            float AngularAcceleration;
            float ShipsAcceleration =0f;


            PrevKB = KB;
            KB = Keyboard.GetState();
            // Allows the game to exit
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();
            if (KB.IsKeyDown(Keys.Escape)) this.Exit();

            if (KB.IsKeyDown(Keys.A)) PortEngineThrotle += 1;
            if (KB.IsKeyDown(Keys.Z)) PortEngineThrotle -= 1;
                        
            if (KB.IsKeyDown(Keys.D)) StarboardEngineThrotle += 1;
            if (KB.IsKeyDown(Keys.C)) StarboardEngineThrotle -= 1;

            if (PortEngineThrotle < 0) PortEngineThrotle = 0;
            if (PortEngineThrotle > 100) PortEngineThrotle = 100;

            if (StarboardEngineThrotle < 0) StarboardEngineThrotle = 0;
            if (StarboardEngineThrotle > 100) StarboardEngineThrotle = 100;

            PortEngineThrust = ShipsEngineMaxAcceleration * (PortEngineThrotle / 100f); //Div by 100 to turn into a percentage.
            StarboardEngineThrust = ShipsEngineMaxAcceleration * (StarboardEngineThrotle / 100f); 
            AngularAcceleration = 0f;
            
            if (PortEngineThrust == StarboardEngineThrust)
            {
                ShipsAcceleration += (PortEngineThrust + StarboardEngineThrust)/60f;
            }
            else
            {
                if (PortEngineThrust > StarboardEngineThrust)
                {
                    ShipsAcceleration += StarboardEngineThrust/60f;
                }
                else
                {
                    ShipsAcceleration += PortEngineThrust/60f;
                }
                AngularAcceleration = ((PortEngineThrust - StarboardEngineThrust) / 60f) / EngineTorqueArm;
                //ShipsHeading = Vector2.Transform(ShipsHeading, Matrix.CreateRotationZ((MathHelper.Min(PortEngineThrust, StarboardEngineThrust) )  ShipsAngularVelocity));   
            }
            ShipsVelocity += (ShipsHeading * ShipsAcceleration);
            ShipsAngularVelocity += AngularAcceleration;
            ShipsFacing = Vector2.Transform(ShipsFacing, Matrix.CreateRotationZ(ShipsAngularVelocity));   //Rotate ships heading by angular velocity per frame.
            //ShipsHeading = Vector2.Transform(ShipsHeading, Matrix.CreateRotationZ(ShipsAngularVelocity));   //Rotate ships heading by angular velocity per frame.
            ShipsPosition += ShipsVelocity;

            base.Update(gameTime);
        }

        
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.Black);


            spriteBatch.Begin();
            spriteBatch.DrawString(Font, "Port:" + PortEngineThrotle.ToString()+"%", new Vector2(10f, 10f), Color.Yellow);
            spriteBatch.DrawString(Font, "Starboard:" + StarboardEngineThrotle.ToString()+"%", new Vector2(10f, 30f), Color.Yellow);
            spriteBatch.Draw(Ship, ShipsPosition, null, Color.White, VectorToAngle(ShipsFacing), ShipSpriteSize/2, 0.25f, Effect, 0f);
            spriteBatch.End();
            base.Draw(gameTime);
        }


        private Vector2 AngleToVector(float angle)
        {
            return new Vector2((float)Math.Sin(angle), -(float)Math.Cos(angle));
        }

        private float VectorToAngle(Vector2 vector)
        {
            return (float)Math.Atan2(vector.X, -vector.Y);
        }





    }
}



Was This Post Helpful? 0
  • +
  • -

#3 BBeck  Icon User is offline

  • Here to help.
  • member icon


Reputation: 570
  • View blog
  • Posts: 1,270
  • Joined: 24-April 12

Re: Image Rotation

Posted 18 October 2013 - 05:24 PM

I think I got the problem worked out in my head now, if I can just get some time to look at the code.
Was This Post Helpful? 0
  • +
  • -

#4 BBeck  Icon User is offline

  • Here to help.
  • member icon


Reputation: 570
  • View blog
  • Posts: 1,270
  • Joined: 24-April 12

Re: Image Rotation

Posted 21 October 2013 - 02:56 PM

Here's the code I have so far. It appears to work with the two engines. However, I haven't dealt with the question of how to handle additional "vectored" engines. It probably won't be too hard to add them to this.

I'm not 100% certain that I'm correct with this. But this is my own "theory" anyway.

Since the engines are fixed, the problem is greatly simplified. Maybe even simplified too much. The engines basically only push straight forward. That's easy when both engines push forward with the same force. The "tricky" part is when one engine pushes unevenly. If only one engine is on, then I believe that 100% of that force will go to torque rather than forward acceleration. The amount of torque is multiplied by the lever arm, or torque arm. I figure if the engine were mounted directly behind the center of gravity, then even one engine would cause acceleration, rather than torque.

Now technically, I think the torque to acceleration ratio increases as it moves to the side of the center of gravity. But I think I kind of cheated here and said that it's always going 100% to torque when the engine is off-center. Which with these engines, they are always both off center, so they always create torque except when they both act in unison.

So, to make a long story short, I take the difference between the force of the two engines. The portion where they match each other goes 100% to forward acceleration. The portion where one engine dominates the other, goes 100% to torque.

So, if you turn one engine on it will just sit and spin. You can stop the spin by switching to the other engine. And when both engines are on together, it will accelerate the ship forward.

This little bugger is not easy to fly. I would suggest keeping the throtle on both engines below about 10% until you get the hang of it. Remember that you want both engines equal power to move forward. The first thing I would do is about a 1 second blast on both engines to see forward movement. You'll have to turn the ship in the opposite direction and use the engines to slow down. But you can take it for a test drive with the code below. If you let it go off screen, you're probably best off just killing the program and starting over as its almost impossible to steer it back onto the screen without seeing how its currently oriented.

I'll keep working on it to come up with additional "vectored" engines that you can point. Although really, just with 2 fixed engines its a bugger to control; I think its mostly going to just get worse adding more engines that don't even have a fixed direction. Still, I want to see how it would work. So, I'll keep trying to figure it out.

Oh. And by the way, I like your YouTube channel.

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace ShipTorque2D
{
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        SpriteEffects Effect;
        Vector2 ShipSpriteSize;
        KeyboardState KB;
        KeyboardState PrevKB;
        Texture2D Ship;
        SpriteFont Font;
        int PortEngineThrotle; 
        int StarboardEngineThrotle;
        float PortEngineThrust;
        float StarboardEngineThrust;
        
        Vector2 ShipsPosition;
        Vector2 ShipsVelocity;    //In meters per second in a given direction.
        Vector2 ShipsFacing;   //In radians.
        //Vector2 ShipsHeading;   //In radians.

        float ShipsAngularVelocity;   //In radians per frame. (We'll assume 60 fps.)

        const int FramesPerSecond = 60;
        const float EngineTorqueArm = 16f;  //Distance from center of gravity to engine's tangent in pixels (or meters).
        const float EngineForce = 4000f;  //Maximum force exerted by a single engine in Newtons (kilogram meters per second each second).
        const float ShipsMass = 18143.7f;    //In kilograms. 20 short tons =18143.7kg.
        //const float ShipsMomentOfInertia = ShipsMass * EngineTorqueArm * EngineTorqueArm;
        const float ShipsEngineMaxAcceleration = (EngineForce / ShipsMass)/FramesPerSecond;   //In meters per second each second divided by FPS to give meters per second each frame.


        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            graphics.PreferredBackBufferWidth = 1280;   //Screen width horizontal
            graphics.PreferredBackBufferHeight = 720;   //Screen width vertical
            graphics.IsFullScreen = false;   //Set to false when debugging.
            graphics.ApplyChanges();
            Content.RootDirectory = "Content";

            Effect = new SpriteEffects();
        }

        
        protected override void Initialize()
        {
            ShipsPosition = new Vector2(200f, 200f);
            PortEngineThrust = 0;
            StarboardEngineThrust = 0;
            ShipsAngularVelocity = 0f;  
            ShipsFacing = Vector2.UnitX;  //Start with ship heading towards right side of the screen.
            ShipSpriteSize = new Vector2(192f, 256f);   //Scale ship's icon.
            base.Initialize();
        }

        
        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);
            Ship = Content.Load<Texture2D>("SquarishShip");
            Font = Content.Load<SpriteFont>("SpriteFont1");

        }

        
        protected override void UnloadContent()
        {
        
        }

        
        protected override void Update(GameTime gameTime)
        {
            float AngularAcceleration;
            float ShipsAcceleration =0f;


            PrevKB = KB;
            KB = Keyboard.GetState();
            // Allows the game to exit
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();
            if (KB.IsKeyDown(Keys.Escape)) this.Exit();

            if (KB.IsKeyDown(Keys.A)) PortEngineThrotle += 1;
            if (KB.IsKeyDown(Keys.Z)) PortEngineThrotle -= 1;
                        
            if (KB.IsKeyDown(Keys.D)) StarboardEngineThrotle += 1;
            if (KB.IsKeyDown(Keys.C)) StarboardEngineThrotle -= 1;

            if (PortEngineThrotle < 0) PortEngineThrotle = 0;
            if (PortEngineThrotle > 100) PortEngineThrotle = 100;

            if (StarboardEngineThrotle < 0) StarboardEngineThrotle = 0;
            if (StarboardEngineThrotle > 100) StarboardEngineThrotle = 100;

            PortEngineThrust = ShipsEngineMaxAcceleration * (PortEngineThrotle / 100f); //Div by 100 to turn into a percentage.
            StarboardEngineThrust = ShipsEngineMaxAcceleration * (StarboardEngineThrotle / 100f); 
            AngularAcceleration = 0f;
            
            if (PortEngineThrust == StarboardEngineThrust)
            {
                ShipsAcceleration += (PortEngineThrust + StarboardEngineThrust);
            }
            else
            {
                if (PortEngineThrust > StarboardEngineThrust)
                {
                    ShipsAcceleration += StarboardEngineThrust;
                }
                else
                {
                    ShipsAcceleration += PortEngineThrust;
                }
                AngularAcceleration = ((PortEngineThrust - StarboardEngineThrust)) / EngineTorqueArm;
            }
            
            ShipsAngularVelocity += AngularAcceleration;
            ShipsFacing = Vector2.Transform(ShipsFacing, Matrix.CreateRotationZ(ShipsAngularVelocity));   //Rotate ships heading by angular velocity per frame.
            ShipsVelocity += (ShipsFacing * ShipsAcceleration);
            ShipsPosition += ShipsVelocity;

            base.Update(gameTime);
        }

        
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.Black);


            spriteBatch.Begin();
            spriteBatch.DrawString(Font, "Port:" + PortEngineThrotle.ToString()+"%", new Vector2(10f, 10f), Color.Yellow);
            spriteBatch.DrawString(Font, "Starboard:" + StarboardEngineThrotle.ToString()+"%", new Vector2(10f, 30f), Color.Yellow);
            spriteBatch.Draw(Ship, ShipsPosition, null, Color.White, VectorToAngle(ShipsFacing), ShipSpriteSize/2, 0.25f, Effect, 0f);
            spriteBatch.End();
            base.Draw(gameTime);
        }


        private Vector2 AngleToVector(float angle)
        {
            return new Vector2((float)Math.Sin(angle), -(float)Math.Cos(angle));
        }

        private float VectorToAngle(Vector2 vector)
        {
            return (float)Math.Atan2(vector.X, -vector.Y);
        }



    }
}



This post has been edited by BBeck: 21 October 2013 - 03:09 PM

Was This Post Helpful? 0
  • +
  • -

#5 BBeck  Icon User is offline

  • Here to help.
  • member icon


Reputation: 570
  • View blog
  • Posts: 1,270
  • Joined: 24-April 12

Re: Image Rotation

Posted 25 October 2013 - 12:22 PM

So, I'm still working on this. This week (really this month) has just been insane and the insanity isn't going to end at least until Sunday. So, I haven't had much time to look at this. But I think its an important problem, because its the foundation for all vehicle movement, if not all movement in 3D as far as realistic physics.

And in this particular problem you have the real core of the problem isolated. So, it's kind of the perfect "first step".

Well anyway, after looking at the problem, I think my last submission was a bit off. It's close and maybe close enough, but if one engine torques the ship clockwise and the other engine torques the ship counter clockwise then that energy is just wasted because of the oposition. And I don't think that's really reflected in the example above.

I still plan on coding what I've got going on with this, but since I don't have the time to actually get the code done right now, I thought maybe I should kind of mention what I'm thinking at this point, in case you also are still working on the problem. So here's what I'm currently thinking.

Basically, if you push towards the center of gravity of an object, the object will gain velocity/speed in that direction. We're talking about "in space" here where you don't have the added complication of other forces like wind resistance. The ship's engine provides a push, or force. If that is a straight line to the center of gravity the ship increases its speed by that much in that direction. Theoretically, the engine could be attached to the ship anywhere and could be pushing towards the center of gravity from any desired direction and therefore could push the ship in any direction, including those that are different from the direction the ship is facing.

Now, where it starts to get complicated is when you push in a direction that is not perfectly aligned with the center of gravity. The most extreme example would be a push that is completely tangent, or 90 degrees, away from the push line. If the push is 90 degrees off of the center of gravity line, it becomes a torque. It becomes a rotational acceleration rather than a linear acceleration. Or in english, "it causes it to spin". A push, no matter what direction it is in, is an acceleration that makes the ship move faster, but there's a world of difference between rotational acceleration and linear acceleration.

All of the energy from the push (probably measured as an accleration in meters per second each second), either adds to the rotational speed or the linear speed. Zero degrees on the line between the push point on the object's surface and the object's center of gravity, means speed is increased by the amount of the push/acceleration in the direction of the line. If the push is 90 degrees off of that line, then all of the acceleration goes to rotational speed.

Now, I believe you could use Sine or Cosine to turn the exact angle into a percentage between linear acceleration and rotational acceleration. So, I believe 45 degrees off that line would be 70.7% forward acceleration and 70.7% rotational acceleration.

That could be a linear percentage where 45 degrees would be half way in between and therefore 50%. But I'm thinking that it's circular and therefore uses Sine and Cosine.

Anway, I'm imagining it like this:

Vector2 EngineAcceleration = new Vector(4f,4f);  //Direction and amount of engine push per second (needs to be changed to per frame and I'm skipping all the math to calculate the angle between this and the center of gravity line). 
float LinearAcceleration;  //Movement in direction of the engine push. Meters per second each second.
float RotationalAcceleration;  //Increase in spin caused by the push.
float AngleOfPushDeviationFromThePushLine = MathHelper.PiOver4;  //The angle between the actual direction of push and the line from the push point to the center of gravity in radians.

LinearAcceleration = Math.Cos(AngleOfPushDeviationFromThePushLine) * EngineAcceleration.Length();
RotationalAcceleration = Math.Sin(AngleOfPushDeviationFromThePushLine) * EngineAcceleration.Length();



I'm basing, this off the idea that the actual EngineAcceleration vector forms a rectangle, or 2 triangles, where one side of the triangle is the amount of linear/forward movement and the other is the amount of rotational movement.

Anyway, I thought you might still be working on this, and wanted to share my current thoughts. Hopefully, I'll have a chance to fully code this next week.
Was This Post Helpful? 0
  • +
  • -

#6 BBeck  Icon User is offline

  • Here to help.
  • member icon


Reputation: 570
  • View blog
  • Posts: 1,270
  • Joined: 24-April 12

Re: Image Rotation

Posted 02 November 2013 - 04:16 PM

Ok. Almost a month later I have not only figured out the answer to your question, but built an example program.

http://virtuallyprog...f2DObjects.html

The example code is 3 XNA projects. The first project is basically the code above and is sort of a "cheat" to do a more simplified version. The startup project is the optimized code that's been cleaned up basically like if you were using it in your own program (and feel free to use any or all of this in your own programs). Then there is another project included in the solution that is maybe a bit more verbose and easier to explain (and now that I think about it, it may contain a few errors since I fixed a few bugs in the final version especially multiplying the torque arm instead of dividing it and then dividing by frames per second).

The web page has a detailed explanation of the theory behind this. I worked on this so much that I'm convinced that I actually understand this now, enough to write a tutorial on my website for it.

The example program is kind of fun to play with, but you may want to run the engines conservatively so that the ship doesn't get out of control. Every action has to be stopped by an equal but opposite action. And once the ship goes off the screen it's nearly impossible to get it back on the screen again (generally because it went off the screen in the first place because you lost control).

But I believe this is the foundation for pretty much all vehicle physics in both 2D and 3D. This doesn't delve off into 3D, but I think 3D is basically the same thing but adding another dimension. And accelerations are basically just "pushes" on an object. So this applies to everything that pushes on a vehicle from wheels to sails to propellers.

Anyway, I hope you find this useful.

For anyone following along that doesn't want to download the code, here is the method that does 98% of the work:
        private void EngineAcceleration(ref Vector2 LinearAcceleration, ref float AngularAcceleration, ref int ThrotlePercent,
            Vector2 EnginePosition, Vector2 EngineDirection, float MaxEngineAcceleration, Vector2 ShipsHeading)
        {
            Vector2 RelativeEnginePosition;
            double AngleFromCoGLine;
            float EngineActualAcceleration; //Acceleration created by the engine ignoring what part is linear and what part is Angular.
            float EngineTorqueArm;


            EngineTorqueArm = EnginePosition.Length();
            //Correct the throtle amount if outside of range.
            if (ThrotlePercent < 0) ThrotlePercent = 0;
            if (ThrotlePercent > 100) ThrotlePercent = 100;

            RelativeEnginePosition = PositionRelativeToHeading(-EnginePosition, ShipsHeading);  //Positions on the ship move as the ship moves. Correct for actual heading. Reverse vector direction.
            EngineDirection.Normalize();
            AngleFromCoGLine = AngleBetweenTwoVectors(RelativeEnginePosition, EngineDirection);  //Vector/line pointing from engine position to the ships center of gravity.

            //Engine acceleration after applying the throtle.
            EngineActualAcceleration = MaxEngineAcceleration * (ThrotlePercent /100f);  //Throtle is stored as an int. Convert it to a real number and apply that % to the maximum engine acceleration the engine is capable of.

            //Portion of engine aceleration going towards linear acceleration as a vector.
            LinearAcceleration += ((float)Math.Cos(AngleFromCoGLine) * (float)EngineActualAcceleration) * EngineDirection;

            AngularAcceleration += (float)Math.Sin(AngleFromCoGLine) * EngineActualAcceleration * EngineTorqueArm; //Not converted to a vector since its angular(circular).
        }


        private Vector2 PositionRelativeToHeading(Vector2 Position, Vector2 Heading)
        {
            return RotateVector(Position, VectorToAngle(Heading));
        }



This post has been edited by BBeck: 03 November 2013 - 12:56 PM

Was This Post Helpful? 1
  • +
  • -

Page 1 of 1