|
kurt miller's homepage
( My development journal and homepage has moved to a new system here: kurtm.flipcode.com ) |
|||
Everytime I start working on a 3D project, be it a game or general renderer, I find myself debating over how to represent orientations for objects in my scenes. In particular, which interface I find most intuitive. In my very first engine (many years ago), I used Euler angles for everything. At the time I was aware of problems such as gimbal lock, but I was focusing on a simple 'first-person-ish' engine with simple rotations (about 2 axes.) I wasn't overly concerned about losing a degree of freedom, or even correctness. But I must say the interface for this was easily the most enjoyable to work with. Storing a snapshot of an object's orientation with 3 angles is very convenient, and manipulating those angles in-engine or from script is very intuitive. The problem of course is that Euler angle representations are rather limited when you're trying to write a general purpose 3D engine due to things like Gimbal lock and ordering of rotation concerns. Eventually I moved on to direct 3x3 matrix representations, with the columns effectively representing 3 unit vectors that make up an orthonormal base. I did rotations to the matrix directly, and 'renormalized' it every now and again to make sure round-off errors didn't warp it. The interface for this was a bit kludgier, resulting in a lot of matrix multiplications, and the storage for orientations (9 floats) was much larger. There were some perks though, such as the fact that there was never a 'convert to matrix' stage since it was already a matrix. It was also easy to visualize the orientation. My mental image always had those little x/y/z arrows that you see in 3D modeling programs. While I enjoy(ed) the direct matrix approach, I did find the interface just a little klunky, and renormalizing felt kind of hacky. Its also very easy to mess up a 'down to the bone' matrix since there are really no constraints. Next came quaternions. I can't say I found much pleasure in working with quaternions. This sort of representation is very clever, powerful and compact, but I find it entirely non-intuitive and often just plain confusing. This might be a personal thing though. My approach to 3D programming is very visual, and trying to visualize higher dimensions makes me hurt all over. Quaternions are awesome though for interpolation between orientations, and I still use them for that purpose. In cases where I need that however, I generally convert to a quaternion representation, interpolate, then quickly convert the result back before enduring too much pain in quaternion land. Granted that's a little less efficient than using a quaternion representation to start with, but hey. Next up I experimented a little with the axis-angle approach, where you've got a unit vector and a rotation angle about that vector. glRotate from OpenGL used this approach, so I'd grown familiar with it ages ago. Like quaternions, axis-angle pairs are rather compact (4 floats) compared to the direct matrix approach. And they're a lot easier to visualize. But for some reason I've always found this representation rather awkward. To me it always felt like a useful step towards building an orientation, not an orientation representation itself. Kind of like glRotate's purpose. That's likely just me being weird though, since its a perfectly valid way to represent orientation. In any case, I generally only use axis/angles for glRotate-ish operations these days. So where does that leave us? All of the above approaches (except Eulers) are reasonable ways to represent orientations. A robust, general purpose engine should really support them all I suppose. But which to use for general purpose scene work? In my latest test engine, I've been using an approach very similiar to coordinate frames for most things. Every entity in a scene, even the camera, has an orthonormal base (3 vectors) and an origin. I like this approach because its easy to visualize, very simple to "convert" (ahem) to matrix form, and can easily be built with an intuitive interface for common game-ish operations. For instance in game programming we often come across problems like needing to move entities into the spaces of others, such as moving a model to the camera's space or vice versa. Having a coordinate system per entity makes this simple and intuitive. Now you might be thinking: when we're talking about orientations alone, this approach seems a whole lot like the direct matrix approach. Don't worry, that's just because it is :). What matters is how you actually use them though. This is primarily an interface issue to me, which is how I started this journal entry in the first place! All in all, its nice to have options in a 3D engine, and I think orientation interfaces might be something of a personal thing. I've been pretty happy with entity coordinate systems, but who knows what I'll be using tommorow ;). References:
|
|||
| Site Contents Copyright (c) 2002-2004 Kurt Miller. Please do not reprint this jibberish anywhere. |