Apologies if this is on the wrong board
Hello,
I’m aiming to acheive a simplistic spaceship thust movement. Similar to Elite, Freelancer, X3, that kind of thing. Probably newtonian and just with keyboard input for now. I guess the most important aspect to mention is lack of friction, once you start moving along a vector, you’ll keep moving until a force affects it.
I realise this subject is exhaustively discussed on this forum and Google (I think I’ve read most of it now) but I’d like some specific advice from some kindly soul on how this should be best accomplished with JMonkeyEngine, using its built-in functions appropriately, rather than avoiding them (which one resource suggested).
Ive already setup a basic scene that displays a shuttlecraft-esque model. I’ve applied a RigidBody control to it, setup the bullet phsyics space, set global gravity to zero - all stuff I’ve learned from the tutorials and other sources.
I’ve got key input working via an Analog listener - rotation of the vessel is currently handled thusly:
[java]if(name.equals(“Up”)) { ship01.getControl(RigidBodyControl.class).applyTorque(new Vector3f(1, 0, 0)); }
if(name.equals(“Down”)) { ship01.getControl(RigidBodyControl.class).applyTorque(new Vector3f(-1, 0, 0)); }
if(name.equals(“Left”)) { ship01.getControl(RigidBodyControl.class).applyTorque(new Vector3f(0, 1, 0)); }
if(name.equals(“Right”)) { ship01.getControl(RigidBodyControl.class).applyTorque(new Vector3f(0, -1, 0)); }[/java]
Forward / backward thrust is:
[java]… ship01.getControl(RigidBodyControl.class).applyImpulse(new Vector3f(0, 0, 1), new Vector3f(0, 0, 0)); …
… ship01.getControl(RigidBodyControl.class).applyImpulse(new Vector3f(0, 0, -1), new Vector3f(0, 0, 0)); …[/java]
This is great, except that I realise I’m applying these forces on a world-position basis; i.e when i rotate the vessel right and then rotate up - the up rotation is not correct respective to the orientation of the vessel - it still rotates it based on world axis. Hope that makes sense.
I think what I should be doing is some sort of conversion to local coords/rotations and applying an impulse with the resulting vector.
However I’m not clear on how to do that conversion, or where to do it. Or even if I’m right.
I read in the documentation somewhere aboutApplyPhysicsLocal() and have attempted to use it:
ship01.getControl(RigidBodyControl.class).setApplyPhysicsLocal(true);
It doesnt seem to have any affect though. I’m starting to read about ‘Pivot nodes’ now - perhaps that is the way to go?
Could someone point me in the right direction?
Thanks and um…hello everyone
Dave
The full class is here:
[java]public class Game extends SimpleApplication {
private Spatial ship01;
private BulletAppState bulletAppState;
public static void main(String[] args) {
Game app = new Game();
app.start();
}
@Override
public void simpleInitApp() {
bulletAppState = new BulletAppState();
stateManager.attach(bulletAppState);
ship01 = assetManager.loadModel("Models/spaceframe-01.obj");
Material mat_default = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
mat_default.setTexture("ColorMap", assetManager.loadTexture("Textures/Spaceframes/0001.jpg"));
ship01.setMaterial(mat_default);
rootNode.attachChild(ship01);
DirectionalLight sun = new DirectionalLight();
sun.setDirection(new Vector3f(-0.1f, -0.7f, -1.0f));
rootNode.addLight(sun);
CollisionShape colShape = CollisionShapeFactory.createDynamicMeshShape(ship01);
ship01.addControl(new RigidBodyControl(colShape, 1.0f));
ship01.getControl(RigidBodyControl.class).setApplyPhysicsLocal(true);
bulletAppState.getPhysicsSpace().add(ship01);
bulletAppState.getPhysicsSpace().setGravity(Vector3f.ZERO);
initInput();
}
private void initInput() {
inputManager.addMapping("Up", new KeyTrigger(KeyInput.KEY_UP));
inputManager.addMapping("Down", new KeyTrigger(KeyInput.KEY_DOWN));
inputManager.addMapping("Left", new KeyTrigger(KeyInput.KEY_LEFT));
inputManager.addMapping("Right", new KeyTrigger(KeyInput.KEY_RIGHT));
inputManager.addMapping("Back", new KeyTrigger(KeyInput.KEY_Q));
inputManager.addMapping("Forward", new KeyTrigger(KeyInput.KEY_E));
inputManager.addListener(analogListener, new String[]{"Up", "Down", "Left", "Right", "Back", "Forward"});
flyCam.setEnabled(false);
}
private AnalogListener analogListener = new AnalogListener() {
public void onAnalog(String name, float value, float tpf) {
if(name.equals("Up")) {
System.out.println("Up");
ship01.getControl(RigidBodyControl.class).applyTorque(new Vector3f(1, 0, 0));
}
if(name.equals("Down")) {
System.out.println("Down");
ship01.getControl(RigidBodyControl.class).applyTorque(new Vector3f(-1, 0, 0));
}
if(name.equals("Left")) {
System.out.println("Left");
ship01.getControl(RigidBodyControl.class).applyTorque(new Vector3f(0, 1, 0));
}
if(name.equals("Right")) {
System.out.println("Right");
ship01.getControl(RigidBodyControl.class).applyTorque(new Vector3f(0, -1, 0));
}
if(name.equals("Back")) {
System.out.println("Back");
ship01.getControl(RigidBodyControl.class).applyImpulse(new Vector3f(0, 0, 1), new Vector3f(0, 0, 0));
}
if(name.equals("Forward")) {
System.out.println("Forward");
ship01.getControl(RigidBodyControl.class).applyImpulse(new Vector3f(0, 0, -1), new Vector3f(0, 0, 0));
}
}
};
}[/java]