What is the proper way to apply thrust in the direction an object is facing?

I thought I had this figured out all fine and dandy until my model crashed into something (on purpose). At the time the model crashed into the object it was kicked off kilter from the impact (like it should) but the thrust I applied after that didn’t seem to line up properly any more.



This is what I execute during the physics tick.



[java]

Vector3f thrust = new Vector3f(speed,0,0);

Quaternion direction = new Quaternion();

direction.fromAngles(shipControl.getPhysicsRotation().getX(), shipControl.getPhysicsRotation().getY(), shipControl.getPhysicsRotation().getZ());

thrust = direction.mult(thrust);

shipControl.applyCentralForce(thrust);

[/java]



I adjust the rotation of the model with this code in onAnalog in my SimpleApplication



[java]

Quaternion q = new Quaternion();

shipControl.setPhysicsRotation(shipControl.getPhysicsRotation().mult(q.fromAngleAxis(0.05f, Vector3f.UNIT_Y)));

[/java]



There’s also dampening going on on the model however I was certain that asking the model for the specifics of how it had turned would negate this.



Halp!

[java]Vector3f direction = shipControl.getPhysicsRotation().mult(Vector3f.UNIT_Z);

[/java]

https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:math_for_dummies



If you set rotations and locations on a physics object you cannot expect proper results btw. check the manual about physics.

Ya. I went through the tutorial. Clearly I didn’t follow it properly. I’ll try again thanks Normen.



Mind you I just tried what you suggested there and it doesn’t seem to react properly. But! I shall perceiver through the math tutorial again. Thanks for your time.

UNIT_Z is “forward”. By multiplying the quaternion with that vector you rotate it in the direction that the quaternion indicates, so thats the local “forward” of the physics object at that moment. The code I posted is correct for the purpose normally :slight_smile: Maybe something else goes wrong?

You know. It’s probably because I’ve just hosed up the directions in my game elsewhere. Sounds like something I’d do. :stuck_out_tongue:

Be very careful you never xLocal the main Vector3f.UNIT_? objects…that can make things get real messy.

Holy Hanna. I’d like to offer up an apology to you guys. I’ve been rather dense. Sheesh.



So ya. Finally came up with this solution that works perfectly



[java]

Vector3f direction=new Vector3f(speed,0,0);

shipControl.getPhysicsRotation().multLocal(direction);

shipControl.applyCentralForce(direction);

[/java]



Now that I see it I’m kinda pissed that I didn’t figure it out sooner. Oh well.



My ONLY slight complain is that although the jme math for dummies helped clarify what the hell was going on I was still a bit unsure as to how to actually apply it in a real world sense. I guess one could say that this is a case of teaching someone to fish instead of just handing the solution out (Being in IT I can totally appreciate that sentiment), but a tutorial with some small snippets for some of this basic stuff might not go amiss as it were.



Heck once I get a bit further with my game I may take a crack at writing a tutorial that applies to more of the space based game variety.



Thanks again!

It’s interesting that your ship points down the X-axis. Keep this in mind when dealing with JME because many things expect the Z axis to be “forward” and you may have to translate.

@thecyberbob said:
[java]
Vector3f direction=new Vector3f(speed,0,0);
shipControl.getPhysicsRotation().multLocal(direction);
shipControl.applyCentralForce(direction);
[/java]


There still doing 2 things wrong with this, i'm afraid

#1 - your calling multLocal on a getter! for the rotation, when you should be setting a new one
#2 - don't use setPhysicsRotation, you should be using applyTorque

And here I thought I had sorted it all out! :stuck_out_tongue:



I’m doing applyTorque now. Looks pretty good for some movements although I think working on my next algorithm it could present some fun challenges (Get the ship to self right to a plane).



And I’ll go ahead and do your #1 there but I’m curious. Why is that bad per say? It seems like adding an extra step.

@pspeed said:
It's interesting that your ship points down the X-axis. Keep this in mind when dealing with JME because many things expect the Z axis to be "forward" and you may have to translate.


Ya. I may fix that soon. Just looking through the documentation etc and it'll just confuse things for me in the long run if I don't right that.
@thecyberbob said:
And I'll go ahead and do your #1 there but I'm curious. Why is that bad per say? It seems like adding an extra step.

In this special case it does nothing, you just set a value on a temp vector. If it was a spatial you'd set a value that would be overwritten in one of the next update steps as you only correctly set the value with setLocalTranslation/Rotation.

Ok. I think I follow. Thanks for the clarification. I’m going to leave myself a note in my code then that if things get hinky refer to this again.



Thanks again. :slight_smile:

If you have an object with a list in it and keep a count of the list size yourself (really shitty example :p). You might implement an add method to add to the list and update the counter variable. But you also have a function of your object to get the list. And assuming you didn’t make it unmodifiable you can modify the list yourself directly. You may add an item to it (via a get).



But this have now bypassed all your logic in your object and your count variable is now invalid. Setters which can do validation, and other needed stuff before modifying the member variable. Hence for good practice always use Set.

Gotcha. So this is more “Get in the practice of doing it this way or else you’ll run into pain later” thing. Sounds reasonable. Thanks!