TwixEmma's picture

How to rotate a direction vector by a quaternion?

Hi, I'm probably doing something noobishly stupid, but I'm new to OpenTK and direct matrix math.
My problem is the bottom code, it belongs to my engines camera class. When I alter the rotation of the camera, the scene is rotated, that works. When I change the rotation it also precomputes the forward facing direction vector, currently used for moving throughout the scene using the arrow keys. The problem is that this code doesn't alter the UnitZ vector value, which I believe is (0,0,1)? which in my engine is equivelant to forward. I added the CreateScale part just incase that mattered, but to no prevail. for instance, if I rotate 90 degrees around the Y axis, I should get a vector similar to (1,0,0) either direction, negative where appropriate. But instead it's just returning the original vector value, (0,0,1). :3 please help!

private Quaternion _rot;
        public Quaternion rotation
        {
            get { return _rot; }
            set
            {
                _rot = value;
                Vector3 direction = Vector3.UnitZ;
                Matrix4 rot = Matrix4.CreateFromQuaternion(_rot) * Matrix4.CreateScale(1,1,1);
                Vector3 newDirection;
                Vector3.TransformVector(ref direction, ref rot, out newDirection);
                forward = newDirection;
            }
        }
 
        public Vector3 forward { get; private set; }

Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
TwixEmma's picture

Ok another case of self solving, but I'm still not sure if the solution I have is the correct way to do this. I realized that the vector was changing, because when I moved through the scene it wasn't just back and forth like I thought it was. I discovered that the scale line I added is important, by reversing the x axis with a -1 value. It now works. But is this correct?

aeroson's picture

Wasted so much time on this. It works if you invert the rotation matrix. No idea why though.

  public Quaternion rotation
        {
            get { return _rot; }
            set
            {
                _rot = value;
                Vector3 direction = Vector3.UnitZ;
                Matrix4 rot = Matrix4.Invert( Matrix4.CreateFromQuaternion(_rot) );
                Vector3 newDirection;
                Vector3.TransformVector(ref direction, ref rot, out newDirection);
                forward = newDirection;
            }
        }
flopoloco's picture

Hey Emma and aeroson welcome to OpenTK forums.

OpenGL by design suggests that positive Z is backwards and negative Z is forward.
http://www.falloutsoftware.com/tutorials/gl/cartesian.gif

That means that if you want to go forward you will have to move in the negative direction. Flipping the Z axis is very common thing for people because they want to have more meaningful representation of the coordinate system.

So, any way that performs this feature is welcomed as long as it works (there are lots of ways for doing this).

My approach was something like this.

			// I want to move a bit on the right 5 units, and a bit behind the Zero position 10 units.
			// matrixView = Matrix4.LookAt(new Vector3(5f, 10f, 10f), Vector3.Zero, Vector3.UnitY);
 
			// So to establish my own convention is like this.
			// http://www.gamedev.net/topic/154836-inverted-z-axis-/
			// I move backwards 10 units provided that I multiply with an inverted X axis.
			matrixView = Matrix4.LookAt(new Vector3(5f, 10f, -10f), Vector3.Zero, Vector3.UnitY) * Matrix4.CreateScale(-1f, 1f, 1f);