Jump to content
  • Advertisement
Sign in to follow this  
Stefan Fischlschweiger

C# Spaceship steering problem

This topic is 502 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey guys. I haven't been here for a long time. Reason being that I didn't really code in that time. Now I've returned to my project and ran into some problem.

Last time I've worked on it, I've switched my physics engine from bullet to jitter due to unresolvable problems, but there's now an issue with my steering code.

In essence, depending on what direction I'm facing relative to the initial orientation the actual change in direction differs more or less from the actual input. 

For example, I'f I turn 90 degrees left or right it becomes impossible to turn up or down.

Now, in order to make the spaceship turn, this is the code for it:

 

Within InputSystem I calculate cursor offset from the screen center and then from it a multiplier that is then used by MovementSystem:

var mouseOffsetMagnitude = Math.Abs(_mouseOffset.Length());

                    if(mouseOffsetMagnitude < 10)
                        rot.TurnMultiplier = Vector3.Zero;
                    else if (mouseOffsetMagnitude > _screenCenter.Y*0.8)
                    {
                        rot.TurnMultiplier = Vector3.Zero;
                    }
                    else
                    {
                        var multiX = _mouseOffset.X/(_screenCenter.Y*0.8);
                        var multiY = _mouseOffset.Y/(_screenCenter.Y*0.8);

                        rot.TurnMultiplier = new Vector3((float) multiY, (float) -multiX, 0);
                    }

MovementSystem takes this multiplier, which is then multiplied by the ships steering torque and a constant to get the torque vector for steering. The torque vector is also transformed by the ships orientation to ensure it's facing the correct way and then fed into Jitter to make the ship actually turn:

var torqueVector = Vector3.Transform(rot.TurnMultiplier*phys.SteeringTorque*0.00025f, body.Orientation.FromJMatrix());
            body.AddTorque(new JVector(0.0f, torqueVector.Y, -torqueVector.X)); 

Currently roll is not used, hence the 0 value in the last line.

Share this post


Link to post
Share on other sites
Advertisement

I can't be sure from the details you've provided, but your description sure sounds a heck of a lot like Gimbal Lock.

Share this post


Link to post
Share on other sites

It sounds like gimbal lock, but looking at the code I think that the high level concept of constructing a torque to apply should work like you want it to, regardless of orientation.

My initial thought is that the transform step is somehow cancelling out the resulting torque whenever orientation starts significantly differing from your starting value (which is likely Identity?).  Perhaps the torque needs to be applied in local space?  Try just removing the Vector3.Transform line and pass (rot.TurnMultiplier*phys.SteeringTorque*0.00025f) directly to AddTorque and see what happens.

Edited by Nypyren

Share this post


Link to post
Share on other sites

Update:  OK, I examined the physics engine source code and it looks like it expects torques in world space.

Looking at your code again, I'm worried about how you're manipulating the transformed vector on the AddTorque line.  The fact that you're discarding the Z component could be what's causing the gimbal lock (see below for thought experiment).  Ideally I think that your post-transformed torque vector should be passed directly to AddTorque with no further modifications, which means you should be making your tweaks before you transform it.

Thought experiment:  Torque vectors point along the axis of rotation that they would cause.  If you want to rotate the nose to the left/right (yaw), your torque vector will be along the up/down axis of your ship.  If you want to rotate the nose up/down (pitch), your torque vector will be along the ship's right/left axis.  Assuming your base orientation is X=left/right, Y=up/down, and Z=forward/backward axis, if you put your ship into a 90 degree left/right orientation, your ship's front-back will be along the X axis and your ship's left-right axis will now correspond to world space Z axis.  That means if you want to pitch up, your torque vector will need to be along the Z axis.  But since you're zeroing out the Z component when you call AddTorque, this will result in zeroing out your torque vector completely and no torque will be applied.

Edited by Nypyren

Share this post


Link to post
Share on other sites

Yes, thanks, that did the trick. I probably had it wrong in my head because earlier iterations of my movement system, both physics and non-physics based required the Z component to be zeroed out here to prevent unwanted rolling.

The vector components being out of order in the AddTorque line has a reason though. It's required so that steering input from the mouse and actual turning match up in direction

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!