Full freedom of movement without 'gimbal lock'

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
AW111
Posts: 82
Joined: Fri Jul 16, 2010 4:49 pm

Full freedom of movement without 'gimbal lock'

Post by AW111 »

Is there any code available that adjusts the camera for movement in any direction (as in a spacecraft simulation) without the 'gimbal lock' problem ?
macron12388
Posts: 126
Joined: Wed Sep 29, 2010 8:23 pm

Post by macron12388 »

Use quaternions, they're not too hard to get used to, and even though they might seem odd to represent rotations, you'll find they're a lot better and don't have any of those problems Eulers have with Gimbal lock.
lymantok
Posts: 67
Joined: Mon Dec 31, 2007 6:13 am

Post by lymantok »

AW111
Posts: 82
Joined: Fri Jul 16, 2010 4:49 pm

Post by AW111 »

Yes, I already posted to that thread asking for an alternative version that doesn't create the gimbal lock problem, since that code does.
AW111
Posts: 82
Joined: Fri Jul 16, 2010 4:49 pm

Post by AW111 »

macron12388 wrote:Use quaternions, they're not too hard to get used to, and even though they might seem odd to represent rotations, you'll find they're a lot better and don't have any of those problems Eulers have with Gimbal lock.
I assume that just means using a vector plus rotation - (x,y,z) + angle ?
Is there any code available so I don't have to reinvent the wheel and try to understand the lightly-documented Irrlicht quaternion library?
Mikhail9
Posts: 54
Joined: Mon Jun 29, 2009 8:41 am

Post by Mikhail9 »

BindTargetAndRotation. Then use this on the camera scene node (call it cameraNode).

Code: Select all

// localRotate
// Rotate a node on its own X,Y,Z axes
void localRotate(const core::vector3df& v3dfRot)
{
   core::matrix4 m = cameraNode->getRelativeTransformation();
   core::matrix4 n;
   n.setRotationDegrees(v3dfRot);
   m *= n;
   core::vector3df    v3dfRotDeg(m.getRotationDegrees());
   cameraNode->setRotation(v3dfRotDeg);

   return;
}
Pass a vector which represents how you want to rotate in pitch, roll, and yaw. The rotation will occur about the camera's own axes, not the global ones; hence, no gimbal lock.

The rotations are relative to your current orientation, of course, which is generally what you want when you are flying a spacecraft.
lazerblade
Posts: 194
Joined: Thu Mar 18, 2010 3:31 am
Contact:

Post by lazerblade »

Phooey, Mikhail9 beat me to it. BUT, it should be noted that bind target and rotation didn't work for me. :P
I had to set up a set of child nodes and do a bunch of I-don't-remember-because-I-only-ever-use-the-class-I-wrote-to-do-it-for-me's.

Assuming it doesn't work for you, (and in the interest of making my class more popular) it can be found here: http://irrlicht.sourceforge.net/phpBB2/ ... 5&start=15
LazerBlade

When your mind is racing, make sure it's not racing in a circle.

3d game engine: http://sites.google.com/site/lazerbladegames/home/ray3d
lazerBlade blog: http://lazerbladegames.blogspot.com/
Mikhail9
Posts: 54
Joined: Mon Jun 29, 2009 8:41 am

Post by Mikhail9 »

lazerblade wrote:BUT, it should be noted that bind target and rotation didn't work for me. I had to set up a set of child nodes and do a bunch of I-don't-remember-because-I-only-ever-use-the-class-I-wrote-to-do-it-for-me's.
I never tried it (BindTargetAndRotation), because it didn't exist when I created my camera class. I've heard varying tales of success and failure using it.

For completeness here in the forum, here's a way to do without:

1. Create a camera scene node (cameraNode). It's at x=0,y=0,z=0 by default.
2. Attach an empty scene node (targetNode) right in front of cameraNode via addEmptySceneNode. Make it a child of cameraNode. "right in front" means at x=0,y=0,z=1.
3. Attach an empty scene node (upNode) right on top of cameraNode. Make it a child of cameraNode as well. "right on top" means at x=0,y=1,z=0.

Now you can rotate the cameraNode any way you like using the code I posted above. The "up" and "target" children stay in position relative to it (i.e. "above" and "in front", respectively).

Before drawing the scene, set the up-vector and target-vector easily like this:

Code: Select all

cameraNode->updateAbsolutePosition();  // these appear important
targetNode->updateAbsolutePosition();
upNode->updateAbsolutePosition();

cameraNode->setTarget(targetNode->getAbsolutePosition() - cameraNode->getAbsolutePosition());
cameraNode->setUpVector(upNode->getAbsolutePosition() - cameraNode->getAbsolutePosition());
There. A complete recipe between our three posts.
AW111
Posts: 82
Joined: Fri Jul 16, 2010 4:49 pm

Post by AW111 »

I need to be able to not only rotate the camera, but also move the user in any direction & orientation without problems at certain angles. Surely there's some code out there that will do this basic task...
lazerblade
Posts: 194
Joined: Thu Mar 18, 2010 3:31 am
Contact:

Post by lazerblade »

You could try putting the ship in front of the camera and making the ship the camera's child. That would leave pretty strict movement of the ship to the point that you were always looking at it from the same angle though.

As to there being code out there, I don't know. If I had about a week I bet I could whip some pretty upstanding stuff up though. But this kind of thing needs to be more rampant in the code snippets board. You'll probably end up writing code yourself, just when you do make sure you put it here so that everyone else doesn't have to rewrite the code again. ;)
LazerBlade

When your mind is racing, make sure it's not racing in a circle.

3d game engine: http://sites.google.com/site/lazerbladegames/home/ray3d
lazerBlade blog: http://lazerbladegames.blogspot.com/
AW111
Posts: 82
Joined: Fri Jul 16, 2010 4:49 pm

Post by AW111 »

lazerblade wrote:You could try putting the ship in front of the camera and making the ship the camera's child. That would leave pretty strict movement of the ship to the point that you were always looking at it from the same angle though.
As to there being code out there, I don't know. If I had about a week I bet I could whip some pretty upstanding stuff up though. But this kind of thing needs to be more rampant in the code snippets board. You'll probably end up writing code yourself, just when you do make sure you put it here so that everyone else doesn't have to rewrite the code again. ;)

I need to allow a first-person perspective, so your suggestion isn't an option. I'm amazed that there isn't any standard code for this very basic task.
In my own code (which just uses simple trigonometry stuff), I've only had problems occur when moving past an 89.9 degree angle either straight up or straight down, and I assume I should be able to just put in checks for those two cases (>= 90 etc) and compensate? Or is it more complicated than that?
bitplane
Admin
Posts: 3204
Joined: Mon Mar 28, 2005 3:45 am
Location: England
Contact:

Post by bitplane »

What's wrong with just using quaternions? It's not like you have to deal with the mathematics, you just say "rotate around a given axis by N radians" and pull out the result.
Submit bugs/patches to the tracker!
Need help right now? Visit the chat room
lazerblade
Posts: 194
Joined: Thu Mar 18, 2010 3:31 am
Contact:

Post by lazerblade »

So you want two kinds of cameras then?
Like First Person 360 degrees and follow object cam?

My class works well for any kind of first person control, I don't know what to tell you about following or third person though.
LazerBlade

When your mind is racing, make sure it's not racing in a circle.

3d game engine: http://sites.google.com/site/lazerbladegames/home/ray3d
lazerBlade blog: http://lazerbladegames.blogspot.com/
AW111
Posts: 82
Joined: Fri Jul 16, 2010 4:49 pm

Post by AW111 »

Since I'm writing a very general 3D system that has to be usable for a number of different applications, I need a method that isn't tied to a specific way of tricking Irrlicht into rotating the camera correctly.
lazerblade
Posts: 194
Joined: Thu Mar 18, 2010 3:31 am
Contact:

Post by lazerblade »

I'm not sure why it matters HOW we trick Irrlicht into rotating the camera.

If you want to dump gimbal lock on regular rotation, then quats or my class both work.

If you want a complete abstract camera framework, you'll either have to build it yourself or use what's there. The whole point of abstracting camera control to something like a chase view/third person view is that it's tied to doing just that. Code to do free flight isn't going to do first person.
Every layer of abstraction creates a layer of non-flexibility.

What I've seen some do, is create several different kinds of camera handlers. E.G: Chase view, FPS, transformable, etc. That's how WYSIWYG game engines like Blender work.



As far as I know, everyone wants something different. That's why there isn't already code out there. Because trying to write code to do exactly what every person is going to want can become quite a task. ;)
LazerBlade

When your mind is racing, make sure it's not racing in a circle.

3d game engine: http://sites.google.com/site/lazerbladegames/home/ray3d
lazerBlade blog: http://lazerbladegames.blogspot.com/
Post Reply