[Solved] Rigid body rotation lock not being respected after a time.

Hello,

So, I’m making a little pocket 2.5D spaceship shooter, and I’m running into a funny bug/issue with the physics.

It’s basically as the title says, rotation lock (under properties panel>physics) works for a short time(30-120 seconds) after which collisions begin to additively askew the playable entity every which way. Oddly enough, translation lock is still being respected, it’s just the rotation that gives out. Character Motion is simulated as an accumulating force local to the ship model, thus, orientation is critical to stable sane player control. Making control global is not an option, for obvious reasons.

This issue can be reproduced as follows…
(keep in mind this is intentionally brief, you may need to play by ear abit)

(1 Create a new default project.) Switch the render engine to Blender Game.

(2 add a floor)
Add a plane. Scale The X axis to biblical proportions, make it a static physics object.

(3 add a ship)
Add a cone. Make it a rigid body, lock X and Z rotation, and Y translation, collision box is “triangle mesh”
(Cone insertion will default with the tip pointing +Z. Various reasons suggest that +Y should be the front/forward.)
Tab Into edit mode, R key + Ctrl to rotate the cone geometry -90 deg on X. Re-locate the origin sanely.

(4 add controls: Game Logic Layout>Logic editor. Mark all as LOCAL. 10-25 damping frames.)
Add a “simple motion” for the forward key of your choice. Set the Y force to 1<->10.
Add a “simple motion” for the left key of your choice. Set the Z angular velocity to positive 2-5.
Do the last step again, but for right roll control. Make the Z angular velocity 2-5 negative.

(5 Orient the camera)
Zero the camera’s location and rotation. Rotation X 90deg, translate on Y a sane negative amount.
Parent the camera to a vertex of the cone, the tip is an obvious choice.

(6 Numpad 0 into camera, then P to play.)

The issue/bug will manifest in less than 5 mins of flying around. It behooves you to add a background and more walls, this makes it easier to tell when and where you are moving, and prevents you from veering off into nowhere.

Actually…

OK, I’ve just gone ahead and taken the initiative of creating a for instance blend file that demonstrates the problem. It follows the above with a few tweaks; mostly adding minor aesthetics for a navigation frame of reference. My system could be corrupt in some way, so it still might be better to follow along, rather than open a potentially broken file, but it certainly should get the point across. Just open it up, P into play mode, use WADS to fly around, crash into a few things, and in a few mins the cone should get cattywompus causing you to lose control.

(Dev.envi. need-to-know)
Blender 2.74 RC2. Hash: 1f547c1
Win7 Ult.UAC On. Updates enabled. (AMD x64 dual-core ~3Ghz, ATI HD 3800 series GPU, Triple head/monitor)

Thanks for your time.
-Charlie

Attachments

rotlock_bug.blend (2.15 MB)

The physics system does not strictly respect the translation/rotation locks all the time. Excessive ‘pushing’ of the object against other things can cause it to become unlocked.

Have an always sensor on your cone (game logic) that noodles to a python Controller. Have that controller run the following code:


from bge import logic
cont = logic.getCurrentController()
own = cont.owner

own.alignAxisTo([0,-1,0],2,1)

Here’s a good no-nonsense run-down of alignAxisTo() It is for a very old version of blender, but still accurate.
In this case, we’re aligning your ship’s Z axis to the world’s -Y axis, with a speed of ‘instant’. We do that every frame, so if it ever gets bumped around, it will instantly snap back into proper alignment.

Cool, seems to be the ticket. Though, FYI, I did have to change a few things to make it really work.

Added “import bge” to the top. (this was probably implied)
Changed alignAxisTo() to alignAxisToVect() as required.
Default Always sensor didn’t seem to actually loop the script. So I made it a pulse, so it retriggers every tick or so.

Also, am I right to assume that using alignAxisToVect(), in addition to being the only way that works right, will also be less expensive than doing the same using the physics settings? My gut says that calling a simple alignment once a frame shouldn't be very expensive, whereas a full physic calculation might be. That being said, i'm getting some jitter that I would like to do away with. Using the physics on top of this script might fix that. (Though it does kinda give a neat over speed effect)

Ok, I haven’t had any problems losing translation lock, but I decided to apply the same logic to that too for good measure.

Here is the final code.

 import bge 
from bge import logic
cont = logic.getCurrentController()
Ship = cont.owner

#keep rotation
Ship.alignAxisToVect([0,-1,0],2,1)

#keep translation
Ship.worldPosition = [a*b for a,b in zip(Ship.worldPosition,[1.0, 0.0, 1.0])]

I also guess I can mark this thread as [Solved] since the specific issue has been addressed.

Thanks again.