RyanM 122 Report post Posted November 29, 2005 Hi I am kind of new to the world of 3d programing and I am still trying to get my head around everything. Anyway after looking at a few tutorials on the internet I have come up with the code listed below it works fine however I want to be able to rotate an object around its own axis not the global axis. The way it does the translations is in the following order x => y => z therefore if I rotate around the x axis then the object will roll fine, if for instance I had an aircraft the x axis will be the wings rolling. The y axis moves the nose left to right, and the z axis moves the nose up and down. If I rotate around the x axis 90 degrees however the y axis suddenly becomes the objects z axis therefore the y axis controls the pitch of the nose wheras the z axis controls the left to right rotation of the nose. This wouldnt be so complcated except because the x axis is always computed first the aircraft can roll correctly at any point reguardless of the rotation around the y and z axis or put another way the wings will always roll reguardless of the other axis, the y axis has priority over the z axis in a similar way except for when its at the mercy of the x axis. Therefore if I want the objects axis to rotate with the object I need to take into acount the rotation around the x axis in the case of y and the rotation around the x and y axis in the case of z. I can do this either when computing the vertices point in 3d space or when translating the inputs into the angles to rotate. The problem is that I am really strugling to maintain a grasp on whats happening as is so any tips will be most appreciated. The code below is in actionscript however it shouldnt be too disimilar to Java or C++. It is based heavily on code that was posted in a tutorial by a guy named senocar. p is the original point and does not change, r is the rotational transformation required for that point. Thanks - Ryan public function Transform3DPoints(p, r) { var sinx = Math.sin(r.x); var cosx = Math.cos(r.x); var siny = Math.sin(r.y); var cosy = Math.cos(r.y); var sinz = Math.sin(r.z); var cosz = Math.cos(r.z); var x = p.x; var y = p.y; var z = p.z; var xy = cosx*y-sinx*z; // cos(r.x) * y - sin(r.x) var xz = sinx*y+cosx*z; // sin(r.x) * y + cos(r.x) * z var yx = siny*xz+cosy*x; // sin(r.y) * (sin(r.x) * y + cos(r.x) * z) * x var yz = cosy*xz-siny*x; // cos(r.y) * (sin(r.x) * y + cos(r.x) * z) - sin(r.y) * x var zx = cosz*yx-sinz*xy; // cos(r.z) * sin(r.y) * (sin(r.x) * y + cos(r.x) * z) * x) - sin(r.z) * cos(r.x) * y - sin(r.x) var zy = sinz*yx+cosz*xy; // sin(r.z) * (sin(r.y) * (sin(r.x) * y + cos(r.x) * z) * x) + cos(r.z) * (cos(r.x) * y - sin(r.x)) scaleRatio = focalLength/(focalLength+yz); x = zx*scaleRatio; y = zy*scaleRatio; z = yz; var transformed = make3DPoint(z,y,z); return transformed; } 0 Share this post Link to post Share on other sites
jyk 2094 Report post Posted November 29, 2005 I didn't study the code, but the problems you described are more or less unavoidable with Euler angles (e.g. yaw, pitch, and roll, like you're using). Sometimes you can get the behavior you want by reversing the order in which the rotations are applied, but for maximum flexibility you may want incremental local-axis rotations (as you suggested). To do this you need to maintain your rotation matrix (or quaternion) from frame to frame, orthogonalizing occasionally to prevent drift. To rotate about a local axis, you can construct an axis-angle matrix from the local axis and rotation angle and multiply on one side, or multiply by the corresponding global-axis rotation matrix on the other. Which side to multiply on depends on whether you're using row or column vectors.That's just a brief overview, but maybe it will point you in the right direction. 0 Share this post Link to post Share on other sites
Trienco 2555 Report post Posted November 30, 2005 Now I'm back to wondering about applying multiple rotations as a collective rotation where they basically all happen at the same time. What would happen if you interpolate the axes based on the angle? Completely unoptimized, say:x:30°y:45°z:15°The axis would be 30/45,45/45,15/45 the angle 45° and the result.. something. Hm, I'm pretty sure math books should have a formula to collapse rotations in an order independent way. But then, "looking" right for small to medium rotations would be fine enough. 0 Share this post Link to post Share on other sites
FlyingDemon 112 Report post Posted November 30, 2005 You seem to be suffering from gimble lock.One way around this is to use matricies or quaternions, by constructing a rotation matrix/quaternion with the eular angles relative to the objects axis and then multiplying the point by the given rotation matrix/quaternion. 0 Share this post Link to post Share on other sites
RyanM 122 Report post Posted November 30, 2005 Ok thanks for the help, I cant say I am perfectly clear on everything but I have some keywords to google for now. 0 Share this post Link to post Share on other sites
Trienco 2555 Report post Posted December 1, 2005 Don't worry, the only think to keep in mind is: euler angles, aka "the dreadful let's-just-store-three-angles"-approach is usually worthless for anything but simple fps shooters. As you noticed, the order in which you applied all your rotations is important, but will be completely lost by storing just some angles.Using a matrix is simple and straight forward. 3x3, with the parts of it being nothing but the right/up/fwd axes of the object. When you apply a rotation to it all axes are changed accordingly, so rotating around right (or x) will always rotate around whatever is "right" for the model/camera at this time. Plus, by applying it from the other side it basically happens "before" the rotations already applied and is hence using the global or world coordinate system.Comment on Quaternions: don't. Unless you need to save every byte of memory you can. Some like them a lot because they look small and harmless (4 components compared to a matrix with 9). However, rotating a vector/point by a quaternion requires 2 quat. multiplications which require a) a lot more and b) less "intuitive" operations. Multiplying with a matrix is basically three dot products, screaming SSE. And funny enough, if you write out the two quat multiplications and break them down enough you get exactly the same as with converting back to a matrix and using that. Just with extra work for the conversion. The only advantage I can think of is that they might be a bit more robust when interpolating rotations close to 180° and concatenating them is 4 instead of 6 dot products (though probably not as nicely to use SSE for).Have a look at them when you get around to it and have time, but if anyone claims they promise eternal life and happiness or can do things that matrices can't, then I would assume the person just doesn't know what matrices can do. Figure out where they are cheaper and where they are more expensive (and where the benefit justifies the hassle). They are a bit like pluecker coordinates. Looking really nice and cool for certain things, but also introducing extra work that may or may not negate whatver benefit they bring. 0 Share this post Link to post Share on other sites
jyk 2094 Report post Posted December 1, 2005 Quote:Original post by TriencoHave a look at them when you get around to it and have time, but if anyone claims they promise eternal life and happiness or can do things that matrices can't, then I would assume the person just doesn't know what matrices can do. Figure out where they are cheaper and where they are more expensive (and where the benefit justifies the hassle). They are a bit like pluecker coordinates. Looking really nice and cool for certain things, but also introducing extra work that may or may not negate whatver benefit they bring.Quoted for truth :) 0 Share this post Link to post Share on other sites
AndyTX 806 Report post Posted December 1, 2005 Quote:Original post by TriencoHave a look at them when you get around to it and have time, but if anyone claims they promise eternal life and happiness or can do things that matrices can't, then I would assume the person just doesn't know what matrices can do.For sure: both matrices and quaternions are a complete description of orientation in 3D space. I wouldn't so quickly write off either though.The advantages I see of quaternions:1) Interpolation! Slerp is by far the biggest reason for using quaternions for animation, and I have seen no good derivation of it that uses matrices. Since it is so natural and cheap to do with quaternions, I also doubt that the matrix equivalent would be simpler OR faster.2) Composing rotations is cheaper - with matrices it requires 9 (!) dot products, and quaternions only require a handlefull of mads.3) Renormalizing a quaternion is much cheaper than reorthogonalizing a 3x3 matrix.4) Their most natural geometric analog is the axis/angle representation, which is intuitive. Going between the two is very cheap for quaternions, and much more expensive for matrices.5) Less storage/redundancy... not very significant in modern engines though.Anyways I discount storage as a very valid comparison metric in most cases, and for the most part even performance is irrelivent (I've not yet come across a game engine that is CPU geometry transform limitted... maybe for software skinning, but that's probably better done in hardware nowadays).That said I guess what it comes down to with quaternions is that there aren't many DISADVANTAGES of using them instead of rotation matrices. If you ever require the rotation matrix, they are readily converted cheaply. Composing quaternions is easy and cheap, renormalizing is very cheap, and most of all, with a nicely coded quaternion class, they are a drop-in replacement for 3x3 rotation matrices.In any case I don't think it matters much which one you use, but I can see no compelling argument against using quaternions (even if you don't understand the math (which isn't really too difficult), there are plenty of FAQs that go as far as giving you the code to use...), and as far as I know, quaternions still have the interpolation card to play, which is huge once your engine stops just showing static scenes :) 0 Share this post Link to post Share on other sites
jyk 2094 Report post Posted December 1, 2005 Quote:Original post by AndyTXQuote:Original post by TriencoHave a look at them when you get around to it and have time, but if anyone claims they promise eternal life and happiness or can do things that matrices can't, then I would assume the person just doesn't know what matrices can do.For sure: both matrices and quaternions are a complete description of orientation in 3D space. I wouldn't so quickly write off either though.The advantages I see of quaternions:1) Interpolation! Slerp is by far the biggest reason for using quaternions for animation, and I have seen no good derivation of it that uses matrices. Since it is so natural and cheap to do with quaternions, I also doubt that the matrix equivalent would be simpler OR faster.2) Composing rotations is cheaper - with matrices it requires 9 (!) dot products, and quaternions only require a handlefull of mads.3) Renormalizing a quaternion is much cheaper than reorthogonalizing a 3x3 matrix.4) Their most natural geometric analog is the axis/angle representation, which is intuitive. Going between the two is very cheap for quaternions, and much more expensive for matrices.5) Less storage/redundancy... not very significant in modern engines though.Anyways I discount storage as a very valid comparison metric in most cases, and for the most part even performance is irrelivent (I've not yet come across a game engine that is CPU geometry transform limitted... maybe for software skinning, but that's probably better done in hardware nowadays).That said I guess what it comes down to with quaternions is that there aren't many DISADVANTAGES of using them instead of rotation matrices. If you ever require the rotation matrix, they are readily converted cheaply. Composing quaternions is easy and cheap, renormalizing is very cheap, and most of all, with a nicely coded quaternion class, they are a drop-in replacement for 3x3 rotation matrices.In any case I don't think it matters much which one you use, but I can see no compelling argument against using quaternions (even if you don't understand the math (which isn't really too difficult), there are plenty of FAQs that go as far as giving you the code to use...), and as far as I know, quaternions still have the interpolation card to play, which is huge once your engine stops just showing static scenes :)Just wanted to comment quickly on the above. Just as an aside, you actually can interpolate rotation matrices just as you can with quats, but as you might expect it's a bit of a hack and, indeed, is neither simpler nor faster :)Basically, pretty much everything you said in the above post it true, so I wanted to clarify why I suggested earlier that people not use quats, at least in certain circumstances. Part of the problem is the 'plenty of FAQs that go as far as giving you the code to use...' bit. It seems to me that any internet search for info on quaternions turns up as much misinformation and outright nonsense as it does useful material. My argument is that using quaternions rather than matrices should be an informed decision, based on a thorough understanding of the relative advantages and disadvantages of the degree evidenced in your post. It seems though that people often adopt quats without understanding them, which leads to, for example, the expectation of a magical cure for gimbal lock even when using Euler angles, or the misapplication of quats to a simple problem such as two-angle FPS camera movement. IMO this sort of ill-informed usage of quats does not help, and can be harmful in the sense that it perpetuates confusion and obscures the real issues involved.So I just wanted to elaborate on that a little. But you're absolutely correct that for the informed user quats have many advantages over matrices. 0 Share this post Link to post Share on other sites
Trienco 2555 Report post Posted December 1, 2005 Quote:Original post by AndyTX1) Interpolation! Slerp is by far the biggest reason for using quaternions for animation, and I have seen no good derivation of it that uses matrices. Since it is so natural and cheap to do with quaternions, I also doubt that the matrix equivalent would be simpler OR faster.Not faster, but getting the axis and angle and building a new rotation from the interpolated angle is still simple and intuitive.Quote:2) Composing rotations is cheaper - with matrices it requires 9 (!) dot products, and quaternions only require a handlefull of mads.But seeing how many cross products are happening all over the place with quaternions it would be fair play to drop one axis and reduce it to a 2x3 matrix, only calculating the missing vector once when needed. So counting the ops it's 4 dots vs. 6, but the quat is wildly permutating it's components which might make it harder to get it done in parallel.Quote:3) Renormalizing a quaternion is much cheaper than reorthogonalizing a 3x3 matrix.True, but shouldn't be necessary too often.Quote:4) Their most natural geometric analog is the axis/angle representation, which is intuitive. Going between the two is very cheap for quaternions, and much more expensive for matrices.I wouldn't say much. 18 mults, 9 adds, 1 sin, 1 cos vs. 1 div, 3 mults, 1 sin, 1 cos.. if the compiler makes good use of SSE instructions the difference should be just a few ops.Let's take a skeleton as a good use for quaternions because concatenating them is easier. Ignore hardware skinning, because with a variable number of bones per vertex it is pretty messy. Once you actually start transforming the vertices you can either stick with quats and probably spend more extra operations than you saved up to this time or you convert them all back to matrices, which will also eat up a good bit of time. With two boxes that return the same result if you feed them the same input they must be doing the same thing. And that means that if you break it down as far as you can and optimize away you will most likely end up with exactly the same formula/code. 0 Share this post Link to post Share on other sites
AndyTX 806 Report post Posted December 1, 2005 Quote:Original post by jykMy argument is that using quaternions rather than matrices should be an informed decision, based on a thorough understanding of the relative advantages and disadvantages of the degree evidenced in your post.I agree with that completely :) I'd venture that there's a sizable portion of people that don't understand rotation matrices, but I'm willing to believe that the proportion is higher for quaternions.Quote:Original post by TriencoNot faster, but getting the axis and angle and building a new rotation from the interpolated angle is still simple and intuitive.Sure, but for any advantage of rotation matrices, I could make the same argument: converting a quaternion to a matrix is simple and fast. Thus I still count interpolation as one of the primary advantages of quaternions.Quote:Original post by TriencoBut seeing how many cross products are happening all over the place with quaternions...Quaternion multiplation (composed rotation) is effectively four dot products with a few negations (depending on your internal representation). No cross products necessary...Quote:Original post by TriencoI wouldn't say much. 18 mults, 9 adds, 1 sin, 1 cos vs. 1 div, 3 mults, 1 sin, 1 cos.. if the compiler makes good use of SSE instructions the difference should be just a few ops.Incidentally the formula for building a rotation matrix around an arbitrary axis is exactly the formula for converting a quaternion to a rotation matrix.Quote:Original post by TriencoIgnore hardware skinning, because with a variable number of bones per vertex it is pretty messy.Unrelated, but not with Sh (http://libsh.org) ;)Anyways I'm not opposed to converting quaternions to matrix form very early in the process - for example at each transform hierarchy node (in a scene graph) to compose a local affine transformation. That way you can keep the interpolation and composition advantages where they help, and pay a rather negligable cost (only need to convert to matrix form on update AND can be done lazily wrt the scene node).Moreover take the performance advantages/disadvantages with a grain of sal; as I mentioned I've yet to see these operations bottleneck a modern computer.To summarize, I totally agree that you could get away without ever touching quaternions. However one has to admit that they make some things similar and perform at least as well as matrices. Because the conversion process is simple though, you can get the best of both worlds in almost all cases :) 0 Share this post Link to post Share on other sites
Trienco 2555 Report post Posted December 2, 2005 Quote:Original post by AndyTXThus I still count interpolation as one of the primary advantages of quaternions.Though after doing the whole skeletal animation things with quaternions and comparing it to how I would do it without them the advantage is nice, but far from crucial.I'll be going even further off topic here. A common thing seems to be to multiply a vertex with two matrices, then weigh the results and sum them up. Everybody knows that interpolating the matrices would screw them up, but not so many realize that it is still mathematically exactly the same. So the same square root used to renormalize a quaternion after interpolating it could be used to stretch the resulting vector to its original length. The result should be same: path is fine, velocity is wrong. Only angles close to 180° would be a problem. Hence I somewhere posted that quats should be more robust. Spherical interpolation is already involving a good bit of trig, so the extra cross and dot products for the vector based interpolation look a bit more harmless.If you know you will be doing a lot per frame that's faster with quats and only convert once that would be the best case. Else wrapping your head around quats would have no benefit except for having learned something new.Quote:Quaternion multiplation (composed rotation) is effectively four dot products with a few negations (depending on your internal representation). No cross products necessary...Because it's not showing when you "spell it out" for the function. It's already mixed in and where all the negations are coming from.Quote:Incidentally the formula for building a rotation matrix around an arbitrary axis is exactly the formula for converting a quaternion to a rotation matrix.True, but in the same way rotating a vector around a quaternion ends up as exactly the same as converting to a matrix and using that (meaning you don't use the existing quat multiplication, but write them as one). The difference above is more about finding the axis in the first place, though there should be a more efficient way than calculating the transformed vector for both and do the cross product. Skimming over the formula to extract the axis directly from a matrix doesn't look so tempting. Might be missing a shortcut though. Risky and lame trick would be to so save some work by always rotating (1,0,0) and praying that it doesn't happen to lie on the axis (or repeat for (0,1,0) and compare results, but here it starts to become really pointless.Quote:Unrelated, but not with Sh (http://libsh.org) ;)Might have to have a look at that. But with different numbers per vertex in a single batch I can't see a technical solution that doesn't involve the newest cards with real loops and branching.Though in that case, quaternions would at least allow to store more bones in the registers. Some extra code to decide if they should be converted or not and which shader to use based on the number of bones/registers shouldn't hurt too much.The main reason I'm sticking with them for now is this whole "but what if I want really complex skeletons, better be prepared for everything"-feeling. That and having to store inverse bind pose, relative transformation to parent and final transformation used on vertices. Storing multiple positions for vertices AND losing the option to interpolate quats/matrices instead of transformation results sounds like it's worth some overly bloated bone structs. 0 Share this post Link to post Share on other sites
AndyTX 806 Report post Posted December 2, 2005 Quote:Original post by TriencoThough after doing the whole skeletal animation things with quaternions and comparing it to how I would do it without them the advantage is nice, but far from crucial.I agree - both methods can be employed in almost all cases with good results. They really aren't *that* different. The only point that I disagree on is that we should summarily dismiss quaternions as a graphics tool. We've agreed that they do some things better, and I see no reason to eliminate them as potentially the best tool for some jobs.Quote:Original post by TriencoElse wrapping your head around quats would have no benefit except for having learned something new.I can't speak to this personally since I don't find quaternions very hard to understand at all (I suppose being in Math does help ;). That said, they're still perfectly usable even if you don't understand them. In my current scene graph engine, one could change a single typedef to make all quaternions 3x3 matrices and everything would still work. The constructors and operators are all identical, only the internals differ.Quote:Original post by TriencoBecause it's not showing when you "spell it out" for the function. It's already mixed in and where all the negations are coming from.My point was that they quaternion multiplation can be accelerated with SIMD (if required) just like vector operations. I was only responding to your initial comment to the contrary.Quote:Original post by TriencoTrue, but in the same way rotating a vector around a quaternion ends up as exactly the same as converting to a matrix and using that (meaning you don't use the existing quat multiplication, but write them as one).Again, I was merely pointing out that quaternions are not disadvantaged in this case.Quote:Original post by TriencoMight have to have a look at that. But with different numbers per vertex in a single batch I can't see a technical solution that doesn't involve the newest cards with real loops and branching.Sure, but there are a few answers to that: one, the newest SM3.0 cards do loops and branching quickly enough to be useful in the general case. If you don't have that support though, you can write a single shader in Sh and have it generate whatever combinations you need (this extends to things like combining your animation shaders with surface and light shaders as well).Quote:Original post by TriencoStoring multiple positions for vertices AND losing the option to interpolate quats/matrices instead of transformation results sounds like it's worth some overly bloated bone structs.Sure, that sounds completely reasonable to me. However I think there are also completely reasonable situations to use quaternions in. Moreover you often don't have to make the choice to use one OR the other - a mix is often possible. 0 Share this post Link to post Share on other sites