Get An Object's Local X-Axis Rotation

Hey, I’m working on a simple camera system and I’ve gotten most of the basics working. However I’m still running into (what I believe is called) gimball lock- when the empty the camera is parented to rotates >= 90 degrees, it gets confused and starts to rotate in the opposite direction.

I’m trying to write a simple Python script to limit the rotation to 89 degrees (and probably 1 degree in the other direction to keep the camera from molesting the ground plane) on its x-axis to avoid this issue, but I’m having trouble finding the correct function to do this. I’ve looked at the BGE API reference and found one function that returns a 3x3 matrix of an object’s orientation (which is lost on me, as I have no working knowledge of linear algebra) and another of which I don’t quite understand the description.

Is there any way to get the x-axis rotation directly, or do I have to use some linear algebra sorcery to obtain it from this matrix? (They didn’t teach this in high school; we were told to just “punch matrix problems into the calculator.” : / )

Thanks in advance for any insight into this problem :slight_smile: Let me know if the Python script didn’t pack correctly.

EDIT:
I forgot to mention for anyone playing around with the .blend, the controls are:

Up Arrow: Look Up
Down Arrow Look Down
Left Arrow: Look Left
Right Arrow: Look Right

Q: Zoom In
A: Zoom Out

Attachments

camtest.blend (414 KB)

I don’t know much about matrix math and such, unfortunately (like you, I would like to know more about matrices, but Wikipedia’s a very general reference on the subject). I could sit down and figure it out, but I usually use Eulers, since they’re easier to deal with. To convert an orientation matrix into a euler (X, Y, and Z) angled rotation, you can use:

e = obj.orientation.to_euler()

Set the values with:

e.x = 3.1415

And then reset the orientation:

obj.orientation = e

You can also create a Euler angle with the mathutils module (if you don’t want to convert the original orientation every game frame). You may still experience locking, but at least you’ll be able to see what you’re doing if you have such a problem, and it will be easier to fix.

@Solar Lune: lol I guess I should have just PMed you again. Thanks though, I guess I owe you three.

Is that pseudo-code? I can’t find the to_euler() method in the API reference. I assume it would be in the bge.types module?

Here’s the url I’ve been using. http://www.blender.org/documentation/blender_python_api_2_57_release/

If You klick mathutils.Matrix after Type: in the docs You will find out what You can do with a Matrix out of the box.

Oh cool, I thought I was limited to only the modules under the game engine section. So can I also use all of the “vanilla” Blender Python functionality on that page in realtime in the BGE?

No, not the blender internal modules - but mathutils are external (standalone)… and You can use just about any standalone python 3.2 module :slight_smile:

No, that’s actual code. LaH is correct that the mathutils module is external, and so isn’t exclusive to either the BGE or Blender. That’s actual code above - to get a Euler, you can either use obj.orientation.to_euler(), or create a new one by importing the mathutils module and then saying e = mathutils.Euler(). You may need a value to create the Euler value to.

EDIT: Oh, and if you want to get the local rotation, you should be able to use obj.localOrientation.to_euler().

Oh ok, so everything under external are…external modules. facepalm Thanks guys, I’ll give it a shot as soon exams are over and I can get back to my development machine.