I discovered that the jitter occurs when I derive my gamestate from PhysicsGameState.
I'm doing the following:
import com.jme.renderer.Camera;
import com.jme.renderer.ColorRGBA;
import com.jme.renderer.Renderer;
import com.jme.system.DisplaySystem;
import com.jme.util.Timer;
import com.jme.input.KeyBindingManager;
import com.jme.input.KeyInput;
import com.jme.input.controls.GameControl;
import com.jme.input.controls.GameControlManager;
import com.jme.input.controls.binding.KeyboardBinding;
import com.jme.input.controls.binding.MouseAxisBinding;
import com.jme.input.controls.controller.Axis;
import com.jme.input.controls.controller.RotationController;
import com.jme.input.controls.binding.MouseOffsetBinding;
import com.jme.light.DirectionalLight;
import com.jme.math.Vector3f;
import com.jme.scene.shape.Box;
import com.jme.scene.state.LightState;
import com.jmex.editors.swing.settings.GameSettingsPanel;
import com.jmex.game.StandardGame;
import com.jmex.game.state.GameStateManager;
import com.jmex.physics.DynamicPhysicsNode;
import com.jmex.physics.StaticPhysicsNode;
import com.jmex.physics.callback.FrictionCallback;
import com.jmex.physics.geometry.PhysicsBox;
import com.jmex.physics.util.states.PhysicsGameState;
public class TestPhysicsRotation extends PhysicsGameState{
private Renderer renderer = DisplaySystem.getDisplaySystem().getRenderer();
private Camera cam;
private Timer timer;
private GameControlManager gameControlManager;
private FrictionCallback frictCallback = new FrictionCallback();
private DynamicPhysicsNode playerNode;
public TestPhysicsRotation(String name){
super(name);
initSystem();
initGame();
}
private void initSystem(){
cam=renderer.getCamera();
timer=Timer.getTimer();
KeyBindingManager.getKeyBindingManager().add("exit",KeyInput.KEY_ESCAPE);
}
private void initGame(){
gameControlManager=new GameControlManager();
getPhysicsSpace().addToUpdateCallbacks(frictCallback);
playerNode=getPhysicsSpace().createDynamicNode();
rootNode.attachChild(playerNode);
PhysicsBox playerBox=playerNode.createBox("playerBox");
playerBox.setLocalScale(new Vector3f(1,1,1));
playerNode.setAffectedByGravity(false);
frictCallback.add(playerNode,50,50);
GameControl yawLeft = gameControlManager.addControl("yawLeft");
yawLeft.addBinding(new MouseOffsetBinding(MouseAxisBinding.AXIS_X,true));
GameControl yawRight = gameControlManager.addControl("yawRight");
yawRight.addBinding(new MouseOffsetBinding(MouseAxisBinding.AXIS_X,false));
RotationController yawControl = new RotationController(playerNode, yawLeft, yawRight, 0.5f, Axis.Y);
playerNode.addController(yawControl);
GameControl rollLeft = gameControlManager.addControl("rollLeft");
rollLeft.addBinding(new KeyboardBinding(KeyInput.KEY_LEFT));
GameControl rollRight = gameControlManager.addControl("rollRight");
rollRight.addBinding(new KeyboardBinding(KeyInput.KEY_RIGHT));
RotationController rollControl = new RotationController(playerNode, rollRight, rollLeft, 0.5f, Axis.Z);
playerNode.addController(rollControl);
GameControl pitchUp = gameControlManager.addControl("pitchUp");
pitchUp.addBinding(new MouseOffsetBinding(MouseAxisBinding.AXIS_Y, false));
GameControl pitchDown = gameControlManager.addControl("pitchDown");
pitchDown.addBinding(new MouseOffsetBinding(MouseAxisBinding.AXIS_Y, true));
RotationController pitchControl = new RotationController(playerNode, pitchDown, pitchUp, 0.5f, Axis.X);
playerNode.addController(pitchControl);
GameControl forward = gameControlManager.addControl("forward");
forward.addBinding(new KeyboardBinding(KeyInput.KEY_UP));
GameControl backward = gameControlManager.addControl("backward");
backward.addBinding(new KeyboardBinding(KeyInput.KEY_DOWN));
PhysicsThrustController thrustControl = new PhysicsThrustController(playerNode, Axis.Z, forward, backward, 1, 100, 20, 20);
playerNode.addController(thrustControl);
buildEnvironment();
buildLighting();
rootNode.updateGeometricState(0,true);
rootNode.updateRenderState();
}
private void buildLighting(){
DirectionalLight light=new DirectionalLight();
light.setDiffuse(new ColorRGBA(1f,1f,1f,1));
light.setAmbient(new ColorRGBA(5f,5f,5f,1));
light.setSpecular(new ColorRGBA(1.0f, 0.0f, 0.0f, 1.0f));
light.setDirection(new Vector3f(150,100,150));
light.setEnabled(true);
LightState lightState=this.renderer.createLightState();
lightState.attach(light);
this.rootNode.setRenderState(lightState);
}
private void buildEnvironment(){
StaticPhysicsNode staticNode=getPhysicsSpace().createStaticNode();
for(int i=0;i<=20;i++){
Box box=new Box("box"+i,new Vector3f(),1,1,1);
box.setLocalTranslation(new Vector3f(i*i,-5,5+i*10));
staticNode.attachChild(box);
}
staticNode.generatePhysicsGeometry();
rootNode.attachChild(staticNode);
}
public void update(float tpf){
super.update(tpf);
timer.update();
tpf = timer.getTimePerFrame();
cam.setLocation(playerNode.getWorldTranslation());
cam.setAxes(playerNode.getLocalRotation());
cam.update();
rootNode.updateGeometricState(tpf, true);
if(KeyBindingManager.getKeyBindingManager().isValidCommand("exit")){
System.exit(0);
}
}
public static void main(String[] args){
StandardGame testGame=new StandardGame("testGame");
try{
GameSettingsPanel.prompt(testGame.getSettings());
testGame.getSettings().setSamples(4);
testGame.start();
}catch(Exception e){}
TestPhysicsRotation inGameState = new TestPhysicsRotation("ingamestate");
GameStateManager.getInstance().attachChild(inGameState);
inGameState.setActive(true);
}
}
I've taken the concept from Stardust, so I think I missed something?