I am told repeatedly that XNA Game Studio uses a right-handed coordinate system, and I understand the difference between a right-handed and left-handed coordinate system. But given that you can use a method like Matrix.CreateOrthographicOffCenter to create your own custom projection matrix, specifying the left, right, top, bottom, zNear and zFar values, when does XNA's coordinate system come into play?
For example, I'm told that in a right-handed coordinate system, increasingly negative Z values go "into" the screen. But I can easily create my projection matrix like this:
Matrix.CreateOrthographicOffCenter(left, right, bottom, top, 0.1f, 10000f);
I've now specified a lower value for the near Z than the far Z, which, as I understand it, means that positive Z now goes into the screen. I can similarly tweak the values of left/right/top/bottom to achieve similar results.
If specifying a lower zNear than zFar value doesn't affect the Z direction of the coordinate system, what does it do? And when is the right-handed coordinate system enforced?
The reason I ask is that I'm trying to implement a 2.5D camera that supports zooming and rotation, and I've spent two full days encountering one unexpected result after another.
Answer
Okay, a couple of questions here, so I'll do my best to explain them all.
Coordinate System
The coordinate system of anything affects more than just the orthographic projection. It affects translation and rotation as well.
For example, set up your camera projection as you have described. Now create an object and set it to move either toward you or away from you. It will move toward the camera when you increase the Z-value of the object's coordinate and move away from the camera when you decrease the Z-value.
Now if you rotate your camera around the scene (for gameplay reasons, or whatever you like) then the world's Z-axis stays the same, so this time increasing or decreasing the Z-value will affect the object in a different way (depending on the orientation of your camera.
Rotation
Now for rotation:
Rotating around the X, Y and Z axis is slightly different in right-hand systems than left-hand systems.
I refer you to this picture:
The left image shows rotations in a left-handed system and the right shows rotations in a right-handed system (although not very well, but it was the only picture I could find relatively quickly from Wikipedia)
The easiest way to explain it is using your hands. If you put up your right hand when your thumb and index finger make an L-shape with your palm facing towards you, your thumb is the positive X direction and your index finger is the positive Y direction.
Now bend your middle finger so it is point towards you, this is the positive Z direction in a right handed system (I'm getting to rotations, honest! Just wanted to make everything clear)
Make a thumbs up and point your thumb towards your face. The direction in which your fingers coil is the POSITIVE direction for a rotation about the Z-axis.
So lets add +45 degrees of rotation to the Z axis on the object and it will dip its left side down and its right side up.
Phew, hope that explains rotations in a right-handed system.
Projection
Now to answer your projection matrix questions. No, creating a projection does not change the world's Z-axis. All it does is is creates a view frustum (Best explained here: Viewing Frustum)
To work with this rule enforcement, it might be best to have LOCAL axes for your world objects (including your camera).
I usually have Heading, Right and Up normalized vector members for each of my world objects to help me out in this respect. So whenever you translate an object, instead of adding X, Y or Z values, I simply map it relative to the vectors (e.g. If I press forward, then my camera moves towards it heading, if I press right, it moves when its right vector is pointing).
Zoom
I know you didn't ask about zooming, but I thought I'd nip it in the bud since you want your camera to support it too.
Personally, I do a cheap zooming effect by changing the FieldOfView member of the view frustum. This is usually set to around 45-60 degrees. Play around with this until you get the effect you want.
I think that's everything, hope it helps! :)
No comments:
Post a Comment