JMEPhysics 2 update rate issues

There was an old thread in this forum about some issues with stuttering the scene: http://www.jmonkeyengine.com/jmeforum/index.php?topic=1425.0



People were usind JMEPhysics 0.4 by that time. Now I'm having the same kind of problem with JMEPhysics 2.



I'm using a DebugGameState augumented with the PhysicsSpace. The update implementation takes car of updating the PhysicsSpace. Do I have to use a implementation of GameState with some form of fixed rate or can I get rid of the problem diferently?



I've tried to modify the OdePhysicsSpace implementation to not set the updateRate of the physics world. This seems to remove the stuttering but then the simulation speed and feeling depends on the machine speed.



I'll ommit some of the code here. The car implementation is much based on the vehicle demo included with the JMEPhysics 2 projetc. BTW, I use cvs versions of both JME and JMEPhysics.



Here is the code for my GameState:



package engine.gamestates;



import com.jme.input.ChaseCamera;

import com.jme.input.InputHandler;

import com.jme.input.KeyInput;

import com.jme.system.DisplaySystem;

import com.jmex.game.state.DebugGameState;

import com.jmex.physics.PhysicsDebugger;

import com.jmex.physics.PhysicsSpace;



import engine.model.terrain.Terrain;

import engine.model.vehicle.Car;



public class RaceGameState extends DebugGameState{



private PhysicsSpace pSpace;

private Terrain terrain = null;

private Car car;

private boolean showPhysics = false;



public RaceGameState() {

initializeBasics();

loadTerrain();

loadCar();

initializeInput();

//showPhysics = true;

getRootNode().updateRenderState();

}



private void initializeInput() {

input = new ChaseCamera(DisplaySystem.getDisplaySystem().getRenderer().getCamera(),car.getChassis());

input.addAction(new TractionAction(car, 300),InputHandler.DEVICE_KEYBOARD, KeyInput.KEY_UP, InputHandler.AXIS_NONE, false);

input.addAction(new TractionAction(car, -300),InputHandler.DEVICE_KEYBOARD, KeyInput.KEY_DOWN, InputHandler.AXIS_NONE, false);

input.addAction(new SteerAction(car, -400),InputHandler.DEVICE_KEYBOARD, KeyInput.KEY_LEFT, InputHandler.AXIS_NONE, false);

input.addAction(new SteerAction(car, 400),InputHandler.DEVICE_KEYBOARD, KeyInput.KEY_RIGHT, InputHandler.AXIS_NONE, false);

}



private void loadCar() {

car = new Car(pSpace);

getRootNode().attachChild(car);

}



private void initializeBasics() {

pSpace = PhysicsSpace.create();

}



private void loadTerrain() {

terrain = new Terrain();

terrain.buildPhysics(pSpace);

getRootNode().attachChild(terrain);

}



@Override

public void update(float tpf) {

pSpace.update(tpf);

super.update(tpf);

}



@Override

public void render(float tpf) {

super.render(tpf);

if (showPhysics)

PhysicsDebugger.drawPhysics( pSpace, DisplaySystem.getDisplaySystem().getRenderer() );

}



}

This seem to apply to StandardGame, does it? I did not have a look at that - darkfrog can you give some insights?

Yes, I'm using StandardGame and GameStates. Everything is working fine. Just the stuttering is annoing me.



I'm developing a 3D CarRobot simulator to be used as a plataform for teaching artificial intelligence. Much like robocode with a lot of graphic appeal and added dificulties, like balistics and 3D positioning of everything.



I plan to release it as an open source project as soon as it's stable enougth.

One last thing. I was having the same problem when still using the SimplePhysicsGame, so I don’t think is only StandardGame related. Am I missing something or the only way to go is fixing the logic update rate?



One screenshot of the project (public domain model of jeep and Skydome class found on this site):



Not really sure if this will solve the problem but you should change the update method to call super.update(tpf) before pSpace.update(tpf) I believe…



Everything else looks fine…I agree that this is probably not related to StandardGame.  The screenshot looks nice though. :slight_smile:

call super.update(tpf) before pSpace.update(tpf) I believe...

I tried that already Darkfrog.

When I was still using the SimplePhysicsGame I could fix the stuttering (even with JMEPHysics 2) by not setting the updateRate of the physicsWorld (modified the OdePhysicsSpace). But then I had variable physics simulation speed, depending on the machine load and clock.

I don't know if StandardGame has something similar with FixedLogicRateGame, but I'll check it to be certain. But anyway, is this the only way to solve this kind of issue (I'm talking about the old topic, mentioned in the first post in this topic)?

You can tell it to use a fixed frame-rate, vertical sync, or the typical "run as fast as you can" approach.  StandardGame will default to using vertical sync as it seems much smoother and better overall approach to me.



You're going to have to post more code in order to debug this further because I'm not seeing anything wrong with your code currently and I'm using StandardGame for a physics space in the game I'm currently developing and it's working very smoothly.

Is the stuttering youre referring to the way the car stutters at higher speeds? if so I was able to solve this by adding a custom chaser cam that gets updated right after the physics gets updated. Ignore this post if im off topic  :wink:

Yes, I think it's related. Actually that was my first gess for the problem: Very high speed and camera update, but gave up and followed the idea of lack of sync on the update rates after reading the other posts.



Can you share the ideas you developed for your ChaseCamera?

I've also had the stuttering thing on a camera attached to a physics-controlled node, in my case it was definitely that physics updates at a different rate to the game itself, although I have a different chase camera, so it was worse because there is more going on to do with camera updates in the non-physics updates. In my game, this is solved (more or less) by having the displayed player (actually a plane) be updated in the main game update, with the invisible physics node corresponding to the plane being quite loosely coupled to the plane. So although the physics node still stutters, you can't see it :slight_smile: This definitely wouldn't work for general purposes though.



You can use PhysicsUpdateCallback to watch the physics space updates. So (warning, convoluted solution incoming!) you can:


  1. Register a PhysicsUpdateCallback, which just counts physics updates it sees via afterStep. That is, give it a property which increments when afterStep is called, and which you can reset.
  2. In your "main loop", just call update() on your physics space
  3. After the physics space update() call, check whether your callback has registered any updates, then reset it. (We are talking REAL updates here - there may be 0, 1 or more real physics updates for every time you call the physics space update). If there have been real updates, then call your GAME update routine, to draw a new frame which will have the updated physics state (plus anything else that changes independently of physics).
  4. Carry on



    (ideally in step 4, you would sleep until just after your physics update should occur, to avoid busy wait. In fact, this whole thing would be nicer if you could call physicsSpace.waitForUpdate(), maybe you can, I dunno :wink: Such a method would wait until a REAL physics update is due, execute it, then return so you could draw your game frame and then wait again. If multiple physics updates were due when waitForUpdate() was called, it would immediately perform updates to get back up to date, then return.)



    I haven't actually tried this, and I could be completely wrong about the way physics works, but no doubt if I am Irrisor will point it out.

    The advantages of this over using some kind of fixed rate game are:


  5. Even if the fixed game frame rate is the same as the physics rate, odd little differences of timing will mess up synchronisation.
  6. You will get (at most) one game update and hence redraw per REAL physics update - AFAIK there's no real point in drawing more game frames than you have physics updates, since you won't see much (or any) difference between the frames, assuming most of your game is run by physics. Plus 100fps is pretty fast anyway :wink: Not drawing pointless frames saves resources for other threads, etc.
  7. If you can't keep up with physics (which is quite likely) then the game should degrade gracefully, since you will end up drawing once per 2, or 3, etc. physics updates, hopefully giving a stable frame rate that will display the physics nicely, without "beating" effects from the interaction of different game and physics update rates.



    I can't think of a better way of doing things without a physics engine supporting variable update intervals, but there probably is one :slight_smile:

i call this method in update() method just after physics update, its as simple as a chase camera can be

private void updateCamPositionToFollowBall() {
      
      
         cam.getLocation().set(dynamicBallNode.getLocalTranslation().x,
               dynamicBallNode.getLocalTranslation().y + .9f,
               dynamicBallNode.getLocalTranslation().z + 2.5f);

      
              cam.update();
      
   }

mud2005 I'm really grateful for your insights. After you having said you solved with a CustomChaser I had a look inside my brains and came up  with a solution I think is simple:



Extend ChaseCamera input controller and override the update method, making it doing nothing at all. Create a customUpdate method that calls the super.update(tpf);

Create a PhysicsUpdateCallback that calls this customUpdate from your input controller after every physics update.



I added this line to my initialization code:



pSpace.addToUpdateCallbacks(new CameraUpdate((CustomChaseCamera) input));



It worked like a charm for me.



Here is the source code for my CustomChaseCamera:



package engine.camera;



import com.jme.input.ChaseCamera;

import com.jme.renderer.Camera;

import com.jme.scene.Spatial;



public class CustomChaseCamera extends ChaseCamera {



public CustomChaseCamera(Camera cam, Spatial sp) {

super(cam, sp);

}



@Override

public void update(float tpf) {

//super.update(tpf);

}



public void customUpdate(float tpf){

super.update(tpf);

}



}



…and PhysicsUpdateCallback:



package engine.camera;



import com.jmex.physics.PhysicsSpace;

import com.jmex.physics.PhysicsUpdateCallback;





public class CameraUpdate implements PhysicsUpdateCallback {



private CustomChaseCamera camera;



public CameraUpdate(CustomChaseCamera camera) {

this.camera = camera;

}



public void afterStep(PhysicsSpace pSpace, float tpf) {

camera.customUpdate(tpf);

}



public void beforeStep(PhysicsSpace pSpace, float tpf) {

}



}



Thanks a lot for the responses irrisor, Darkfrog and mud2005. JME and JMEPhysics are wonderfully featured tools and I look forward to seeing more and more games developed with it.




I forgot to mention shingoki in my thanks list. Sorry for that.



Just for the record (conclusion):



When you have a Physics controlled node at some higher speeds, maybe you'll have some stuttering if you use some form of Chase camera (or any camera updated with the node movements).



This is caused (probably) by the lack of sync between the PhysicsSpace and StandardGame update timers.



You have different ways of correcting this disturbing effect, one of them is attaching the camera update with the PhysicsSpace instead of with the StandardGame.

HEllo !



Perick Did you encounter problems with left or right tires raising up when turning at high speed ? how did you resolve that ? (using JME Physics )





Kine

Hi Kine,



My car is really physically controlled, so it can jump, roll, etc, depending on the terrain geometry and speed. I still haven't tried lowering the center of mass or applying forces opposite to the inertia to avoid this behavior.



Actually I'm quite happy with the results I'm getting with the "raw" physics. You can try out my implementation by looking at this new post:

http://www.jmonkeyengine.com/jmeforum/index.php?topic=4889.0



Feel free to keep on this thread there. I'd really like to continue this discution over car physics.

Thanks !



:smiley: