6 degrees of freedom

Started by
16 comments, last by pulpfist 18 years, 4 months ago
1. How does old games like Descent implement 6 degrees of freedom? I have managed to make a Quake like movement, but as soon as I do something as a loop in game, the directions is messed up. I know the rotation matrix I am using only deal with two of the three axis. Could I add some magic to it to get full freedom, or do I need a bigger/more matrixes 2. Could collision detection in such a game be as simple as testing bounding boxes for all 3 dimesions?
Advertisement
1. Sounds like gimbal lock. One way to solve it is to use quaternions to represent your rotations. Reference

2. Sure.
Orin Tresnjak | Graphics ProgrammerBethesda Game StudiosStandard Disclaimer: My posts represent my opinions and not those of Bethesda/Zenimax, etc.
Quote:Original post by pulpfist
1.
How does old games like Descent implement 6 degrees of freedom?
I have managed to make a Quake like movement, but as soon as I do something as a loop in game, the directions is messed up. I know the rotation matrix I am using only deal with two of the three axis. Could I add some magic to it to get full freedom, or do I need a bigger/more matrixes

2.
Could collision detection in such a game be as simple as testing bounding boxes for all 3 dimesions?
Some code for 6dof motion can be found in this thread. Briefly, you don't need anything 'special' to do this sort of motion - it can be done with a single 3x3 matrix, or even just vectors - but you have to take a different approach than in a standard FPS setting. Specifically, you must maintain your orientation from frame to frame and update it incrementally, rather than creating it from scratch each frame using Euler angles. The code sample I linked to illustrates all this.

As for collision detection, that's kind of a different topic. I'm not sure what you mean by testing a bounding box for all 3 dimensions, but typical choices for bounding volumes are boxes, axis-aligned boxes, and spheres. I've studied the Descent code, but I can't remember how coldet was handled. AABBs or spheres can be good choices for 6dof however, since they're invariant under rotation and therefore you won't collide with things while trying to turn (perfectly possible in real life, but usually avoided in games).
Yes, it sounds like gimbal lock. The key to avoiding gimbal lock is to avoid storing the orientation using Euler angles (i.e. yaw, pitch, and roll). lancekt suggests using a quaternion, but I think it would be easier and more convenient for you to use a 4x4 matrix or orientation and translation.
John BoltonLocomotive Games (THQ)Current Project: Destroy All Humans (Wii). IN STORES NOW!
It isn't gimbal lock. Gimbal lock is a situation where the product of two rotation matrices loses rank and becomes singular. It's really mostly applicable to inverse kinematics.... it's pretty rare to see it actually become a problem in the context of video games. The problem you're seeing here is simply a misunderstanding of euler angles.

A set of euler angles is a block of information used to encode an arbitrary rotation. It is not a useful representation for directly specified orientation input from the user, unless the user's desired control scheme happens to match up perfectly to the method by which a final rotation matrix is calculated from euler angles (which is the case in many FPSes). You need to keep the rotation around so that you can change it, but you can't simply add or subtract the euler angles; you have to do an actual composition of rotations. This is why quaternions are useful, because they are simpler to compose than euler angles and more stable than rotation matrices. Nevertheless, as JB said, storing the rotation as a matrix should work fine.
The main difference between Descent style movement and quake style is the way turning side to side is done. In Quake when you move the mouse left/right you rotate around the world Y axis. However in Descent you would rotate around the players local Y axis. I suspect you are rotating around the worlds Y because you say "as soon as I do something as a loop in game, the directions is messed up" I take this to mean when you rotate upside down the left/right directions become reversed. Which is exactly what happens when you are upside down and are rotating around the global Y axis.

I assume you have a method for generating rotation matrices for rotation about an arbitrary axis. You need to look in the code where you are creating the incremental rotation matrix and give it the Y column of your player’s orientation matrix instead of the global Y.
One thing to keep in mind if you're going to go the route of continually updating a matrix is that you will probably need to expend some effort keeping the matrix from losing orthogonality (is that a word?) due to floating point errors.
Well I think you are right about my Y axis. Its something wrong with it.

Here is my rotation code.
Most of this is from a book example
...// Update the player if in the zoneif(PlayerInfo.iZone == iZone) {    vGetVelocity(PlayerInfo.fangy,fx,fz);    vGetVelocity(PlayerInfo.fangx,fy,tmp); // I added this    PlayerInfo.vecCurPos.x += (float)(fx*PlayerInfo.fVelocity) * -1;    PlayerInfo.vecCurPos.y -= (float)(fy*PlayerInfo.fVelocity) * -1; // I added this    PlayerInfo.vecCurPos.z += (float)(fz*PlayerInfo.fVelocity) * -1;...}


The code worked fine for X and Z rotation.
I knew that the lines I added would not solve the problem, I just wanned to see some kind of Y rotation.
It works until my "ship" is heading straight up, but if I loop further than that either the X or Z movement will not "turn" as it should.

I see that I probably should catch up on quaternions, even though I was hoping to solve it the easy way, something like JB says; using 4x4 matrix.
But I wouldnt know what functions to use in what matrix slot (If you know what I mean)

Anyway, thanks for the replies, I should have all I need now =)

EDIT:
Here is the vGetVelocity for referance
// Name: vGetVelocity()// Desc: Retrieves the X and Y vector for a given angle//-----------------------------------------------------------------------------void vGetVelocity( float fAngle, float &vx, float &vz ){	double	fRad;	// Convert to radians	fRad = Deg2Rad(fAngle);	// Figure the vector	vx = (float)sin(fRad);	vz = (float)cos(fRad);}
You’re not handling rotation the way I expected. Could you link to your entire project and code? Or post it if it’s not too big. I'll try and hunt down the problem.



Also what book said to do rotations like this?
Its too darn big man ^^
The Book is called "Multplayer Game Programming" and is written by Todd Barron.
The example I am playing around with is a tiny MORPG, with 3 small levels, and a camera I can move around. However, the book does not try to explain 6dof, it only multiplies the X and Z components of the cameras Y-angle with sin/cos respectively, and leaves the Y rotation out entirely.

Besides I was thinking of doing it the "6dof" way in OpenGL so I just used this DirectX code as an example

This topic is closed to new replies.

Advertisement