Would handedness affect quaternions, vectors and matrices?
I am now porting an openGL column major based application to directx 9?
Having some difficulties with that...For example
What I can interpret is the line x = cross(z,up) must be written as x = cross(up,z) for dx. Does it sound right?
The whole bunch of source code is.... would you please help me correct the ones that are wrong? I gave up after looking at it for 2 nights. Thanks a lot
I am having difficulties understanding the inverse function done by the author. Can I assume that he was using pivoting for a 4x4 matrix? I am cross-checking it with a reference, but not too sure how he did that. Thanks Jack
Quote:Original post by lucky6969b I am having difficulties understanding the inverse function done by the author. Can I assume that he was using pivoting for a 4x4 matrix? I am cross-checking it with a reference, but not too sure how he did that. Thanks Jack
Try to look up Cramer's_rule, that's what he seems to be doing. There is probably no pivoting going on, only computation of several determinants.
Quote:Original post by lucky6969b I am having difficulties understanding the inverse function done by the author. Can I assume that he was using pivoting for a 4x4 matrix? I am cross-checking it with a reference, but not too sure how he did that. Thanks Jack
Try to look up Cramer's_rule, that's what he seems to be doing. There is probably no pivoting going on, only computation of several determinants.
Thanks for your reply. I found this on the web http://en.wikipedia.org/wiki/Cramer%27s_rule#Finding_inverse_matrix However, still not understand it... can you explain it with more details?
Like this very first section, what does he want to achieve?
Just a quick comment on the 'handedness' issue. Generally speaking, the (geometric) handedness of the coordinate system used should not affect your math library code (by which I mean code that constructs or manipulates vectors, matrices, quaternions, and so on). In other words (for example) a function that builds a rotation matrix or quaternion or computes the cross product of two vectors should be exactly the same regardless of the handedness of the coordinate system being used.
Projection transforms and 'view' transforms (e.g. a 'look at' transform) are exceptions in that they're generally constructed differently for left- and right-handed systems. The differences actually have to do with which direction is considered 'forward' in view space, but are also an indirect result of the coordinate system handedness and the convention that the positive x axis should point to the right in view space.
As for computing cross products, with a typical orthonormal basis the relationships between the vectors should be:
x = yXzy = zXxz = xXy
If you're seeing the arguments flipped around depending on handedness, you might be looking at a 'look at' function (where the flipping is related to which direction is to be considered forward in view space).
Even though most functions should be unaffected by handedness, you may find that the results of applying said functions change when switching handedness. For example, triangle windings may flip, models may be mirrored, and rotations may appear to go the 'wrong' way. In these cases though it's the input data that should be changed, not the functions that work with the data.
Also, keep in mind that the DirectX/D3D and OpenGL APIs differ in a few other ways as well, most notably matrix layout (row major vs. column major), vector notation (row vs. column vectors) and the near plane distance for the canonical view volume (zero vs. negative one). The issues of matrix layout, vector notation, and coordinate system handedness are often confused with each other, but in fact they are three separate and unrelated issues (although they can interact with each other in ways that can be quite confusing).
Quote:So the conclusion is I don't need to change anything.. Is that right? :)
No, not necessarily. As I mentioned earlier, you may have to make adjustments for the differing view space and projection transform conventions, and you may also have to make adjustments to your data so that the visual results are consistent between the two APIs.
There also may be cases where you'll need to take matrix layout and/or vector notation conventions into account (note however that despite the different conventions used, D3D and OpenGL matrices are actually arranged in memory the same way in that the elements of the basis vectors are stored contiguously).
Quote:So the conclusion is I don't need to change anything.. Is that right? :)
No, not necessarily. As I mentioned earlier, you may have to make adjustments for the differing view space and projection transform conventions, and you may also have to make adjustments to your data so that the visual results are consistent between the two APIs.
There also may be cases where you'll need to take matrix layout and/or vector notation conventions into account (note however that despite the different conventions used, D3D and OpenGL matrices are actually arranged in memory the same way in that the elements of the basis vectors are stored contiguously).
Thanks jyk, Actually, at first blush, I am most concerned about the code that I post would work or not... :) sorry for making you repeat again. You really gave me a lot of good info.... but would you mind checking the code for me? I just really need to know if the source code would work on Direct3D or not.... Thanks Jack
Quote:You really gave me a lot of good info.... but would you mind checking the code for me? I just really need to know if the source code would work on Direct3D or not....
I'd certainly like to be able to help, but it would take me a long time to proof the code that you posted with any real accuracy. (I did spot a couple of things though - for example, it looks to me like you might indeed need to transpose the upper-left 3x3 portion of your 'look at' matrix, as the comment indicates.)
IMO, the best way to confirm the correctness of this sort of code is to gain a solid understanding of the underlying algorithms so that you can proof the implementations yourself. (You can also use reliable references, such as books, articles, or source code that you know works correctly, as a sanity check.)
Here are a couple of tips:
1. Make your code as clean and well-formated as possible. Avoid unclear and unnecessarily terse variable names (for example, there's little reason to name a variable bet instead of beta), and don't cram lots of code onto one line (for example, don't put an 'if' statement and the block of code associated with it all on the same line). The code you posted isn't bad, by the way (I've seen a lot worse), but it could still use some cleaning up.
2. Use 2-d indexing for matrix element access rather than 1-d indexing. Storage order is an implementation detail that should be kept out of the actual 'math' code. (That is, when you're writing a function to build a rotation matrix, you shouldn't be thinking about whether the matrix is row- or column-major, since that has nothing to do with the math.) Using 1-d indexing also makes the code harder to proofread (for yourself and for others) since you have to convert the indices in your head as you go, and because you have to know what the storage order is in order to know which elements are being accessed. (Actually, you're already doing this with your E** macros, but only in some places. Also, I'd recommend using an inline function rather than a macro.)
(The above is all IMO, by the way.)
If there are particular functions you're unsure of, perhaps you could clean them up and post them individually; that might make the task of proofing them seem a little less daunting :)
Now to convert the original Vec, Quat and Mat data to DirectX formats, you will probably need the following (I'm assuming the native types were OpenGL right-handed):
where the vector u is the up vector { 0, 1, 0 } and the vector l is the look vector that points into the plane of the screen and the vector r is the cross product of u x l, and of course p is the position vector in the world.
Assuming openGL 4x4's use this same naming system, here's what I did with them to get them to display correctly under DirectX:
In openGL the y and z coordinates are transposed (i.e. for them z is up/down and y is into the monitor), which also means the up and look vectors are transposed in the 4x4.
For quaternions I had to do the following:
DirectX:
{ x, y, z, w } or { ._41, ._42, ._43, -w } if taken from a 4x4 converted from openGL to directX and then converted to a quaternion using D3DXQuaternionRotationMatrix().
openGL:
{ x, z, y, w }
!! IMPORTANT !!
For triangles, I had to change the winding order from {v1, v2, v3} to {v3, v2, v1}.
For (u, v) coordinates I left them the same as I had them before.