PhysicsSystem and FixedLogicrateGame issues

I just switched my game over to FixedLogicRateGame from SimpleGame to try and keep the updates per second consistent. Without a fixed update rate the reponsivness of the physics varies depending on how fast the machine can loop through update.



I’ve come across a problem which I haven’t been able to figure out. I’m not quite sure if it’s a physics system thing or a general jME thing so I put the question here.



Right now I am using the default FixedLogicRateGame which is 60 updates per second. That means 60 times a second my update method gets called and the position of objects are updated as well as keyboard input polled. (at least that’s how I understand the FixedLogicrateGame works)



The strange thing is that as I fly my ship around (which is a PhysicsObject and has forces applied to it) the thrusters attached to it start to fall behind. In other words they don’t say attached to the ship. I update the position of the thrusters using a controller attached to the ship. My guess is that the PhysicsSystem is updating the position of the ship faster than 60 updates per second. Therefore, the thrusters have their position updated only 60 times per second and can’t keep up with the ships position which is being updated more often.



I thought I could solve this by having the PhysicsWorld update rate match that of my games update rate. So I went in and did



PhysicsWorld.getInstance().setUpdateRate(60);
PhysicsWorld.getInstance().setStepSize(2/100f);



The idea was that the physics sytem and the game update() call will now update at the same rate and the syncing problem between the thrusters and the ship would go away.

The problem now is that the ship stutters everywhere. It violently vibrates as it moves around and it seems like the thrusters are still lagging behind.

If I use BaseGame then I have no problems other than the fact that everything slows down as I add more overhead to the update calls.

Thank you for any advice and help

Me and per are very aware of this problem! And frankly, its getting very very annoying!



The PhysicsSystem’s update method is controlled by two pathways. The first is the frequency of the AbstractGame’s update(float time) method. And secondly, by its own internal timer.



It seems the only way around this stuttering behaviour is this:



PhysicsWorld.create();
PhysicsWorld.getInstance().setStepSize(2 / 60f);



Notice the lack of a setUpdateRate(...) call. This will actually disable the internal timer of the physics system and let it run as fast as possible. I.e only restricted by the outter AbstractGame timer...

This seems to give me a solid and smooth simulation. E.g. Our GDC demo uses this method (however, it uses FixedFramerateGame, i just tried it with FixedLogicrateGame and the solution is still the same).

I think i know the solution to the problem (the internal timer is out of sync with the external one), so i think you can probably see a change soon.

DP

Right, I havn’t liked that internal jme timer anyway :slight_smile:



I think we can do the timing by just putting an elapsedTime variable in PhysicsWorld. This would of course require the update method to take the time since the last frame as an argument.

Ok, committed… could you see if it makes your problem go away? Note: this will break your code as you now have to pass a “time since last frame” parameter to the update method. This shoudln’t be a problem though, since it’s just a one line change: update(tpf)… not rocket science :wink:



Also, is it just me? or does the tests actually run smoother? :o

Hi DarkProphet,

Thanks for your response.


PhysicsWorld.create();
PhysicsWorld.getInstance().setStepSize(2 / 60f);



This got rid of the stuttering but now I have the problem where the thrusters on the ship lag behind.

Basically I have a ship which is a geom and a physicsObject for that ship. Then using a modified version of per's ship thruster code (he posted it in another forum) I create a jetEffect controller and attach that to the ship. The jetEffect controller has an update method that adjusts the thrusters position to always be right at the back of the ship.

If I extend BaseGame and disable the PhysicsSystem internal timer (i.e., no setUpdateRate()) then everything works peachy. No stuttering, no thrusters lagging behind. If I switch to FixedLogicrateGame then the thrusters lag (although the stuttering went away)

My guess is the update call for the jetEffect controller is getting called less often then the ship location is getting updated so it begins to fall behind.

Any idea why this might be happening?

Whoops sorry Per



I didn’t see your last post up there :// Trying your fix now.

I connected to cvs and got the newest source but I’m not sure how to use it 8-O



Is there an easy to way to build a new jar? (I’m using eclipse) or maybe just point eclipse at the new project and tell it look their for any files it needs?

Is there an easy to way to build a new jar? (I'm using eclipse) or maybe just point eclipse at the new project and tell it look their for any files it needs?

Yes! If you checked out jme-physics as a java project, the latter can be achieved by right clicking on your game project and then choose Properties -> Java Build Path -> Projects and check the jme-physics project. And you're done :)

If you want to create a jar, there are several ways to go, among others you can use the jar command. However, I find it easiest done by just creating a zip file from the directories involved, and then change the suffix to .jar (zip and jar use the same compression).

Note: make sure to remove the old physicsSystem.jar from your path!

That’s odd … the jmePhysics project I checked out doesn’t appear in the projects list despite being there in the resource view.



When I right click on the jmePhysics project I noticed it’s missing a lot of options that the other projects have such as Java Build Path and Java Compiler etc.



Do I have to explicitly tell Eclipse that jmePhysics is a project?

When checking out in CVS make sure you do a checkout as… and then select Java Project.

Thanks mojo … that worked out. One last problem (I hope). How do I set the top folder for a package? In other words right now the project is set up as



src

-|

—com

----|


jmex
|
physics

Eclipse complains that all the package names are invalid because they all start as com.jmex.physics instead of src.com.jmex.physics

How can I set it up so that the src folder is ignore as part of the package naming?

Thank you!

Uhh… it should be by default… did you check the "create separate source and output folders"?

Sweet. It worked. Thank you Per.



Of course now everything is totally broken cause I have to go through and change to DynamicPhysicsObjects and StaticPhysicsObjects but I was gonna have to do that at some point anyway. Might as well be now :slight_smile:



I’ll let you know if the update thing fixed everything once I get everything converted over.

okay … I switched over to the newest build of the PhysicsSystem and have some problems.



The first problem is the same problem I’ve had all along with the thrusters not staying attached to the ship. For example, if you just move straight up with your ship the thruster slowly starts lagging behind in the back and seperates farther and farther.



The second problem is my ship won’t rotate anymore. I didn’t really change any code other than change all my PhysicsObjects to DynamicPhysicsObects and do the casting. (I"m not rotating using the PhysicsSystem but just rotating the actual geometry)



Here is the rotation code which was taken from the RotateKeyNodeAction class.


    public void performAction(InputActionEvent evt) {
        System.out.println("In Right SPin");
        GameEntity shipEntity = GameSystem.getInstance().getEntityWithName("my ship");
        DynamicPhysicsObject shipObject = (DynamicPhysicsObject)shipEntity.getPhysicsObj();
       incr.loadIdentity();
        if (lockAxis == null) {
            incr.fromAxisAngle(shipObject.getSpatial().getLocalRotation().getRotationColumn(1,
                    tempVa), -speed * evt.getTime());
        } else {
            incr.fromAxisAngle(lockAxis, -speed * evt.getTime());
        }
        shipObject.getSpatial().getLocalRotation().fromRotationMatrix(
                incr.mult(shipObject.getSpatial().getLocalRotation().toRotationMatrix(tempMa),
                        tempMb));
        shipObject.getSpatial().getLocalRotation().normalize();
        shipObject.syncWithGraphical(false);
      }



Am I missing something or do I have to do something different with the new PhysicsSystem? I know the method is getting called and that the correct objects are being used since I printed out the names before. Also I know the PhysicsObject is dynamic cause I printed out the results of isStatic() which was false.

Just for kicks I tried changing the translation of the object in the above code. So I added

shipGeometry.setLocalTranslation(shipGeometry.getLocalTranslation().add(1,0,0));



This actually made my ship move to the right like it should. So either my rotation code is broken or something is wrong with the PhysicsSystem that doesn't allow it to update on rotations. My guess is it's my code cause my code is always suspect. I'm looking more closely right now at the rotation code.

This works for me:



public class Test extends SimpleGame {
   
   private static final Vector3f tempVa = new Vector3f();
    private static final Matrix3f incr = new Matrix3f();
    private static final Matrix3f tempMa = new Matrix3f();
    private static final Matrix3f tempMb = new Matrix3f();
   
   private DynamicPhysicsObject obj;
   
   protected void simpleUpdate() {
      PhysicsWorld.getInstance().update(tpf);
      
      incr.loadIdentity();
      incr.fromAxisAngle(new Vector3f(0, 1, 0), -2 * tpf);
      
      obj.getSpatial().getLocalRotation().fromRotationMatrix(
                incr.mult(obj.getSpatial().getLocalRotation().toRotationMatrix(tempMa),
                        tempMb));
      obj.getSpatial().getLocalRotation().normalize();
      
      obj.syncWithGraphical(false);
   }

   protected void simpleInitGame() {
      PhysicsWorld.create();
      PhysicsWorld.getInstance().setUpdateRate(100);
      PhysicsWorld.getInstance().setStepSize(2/100f);
      
      Box floor = new Box("Floor", new Vector3f(), 50, 1, 50);
      floor.getLocalTranslation().y = -2;
      StaticPhysicsObject floorObj = new StaticPhysicsObject(floor);
      
      Box rotatinBox = new Box("Rotating Box", new Vector3f(), 1, 1, 1);
      rotatinBox.getLocalTranslation().y = 3f;
      obj = new DynamicPhysicsObject(rotatinBox, 1f);
      
      PhysicsWorld.getInstance().addObject(floorObj);
      PhysicsWorld.getInstance().addObject(obj);
      
      rootNode.attachChild(floor);
      rootNode.attachChild(rotatinBox);
   }

   /**
    * @param args
    */
   public static void main(String[] args) {
      Test app = new Test();
      app.setDialogBehaviour(ALWAYS_SHOW_PROPS_DIALOG);
      app.start();
   }

}



DP

Actually, when looking through the code I see that we actually have broken synchronization of the rotation.



However, it was an easy fix that I just committed. Please see if it works for ya :slight_smile:

That wasn’t the problem. The problem is with the PhysicsSystem 8-O



I changed the syncWithGraphical from the current


       phyObject.setPosition(jmeObject.getLocalTranslation());

      
      phyObject.getQuaternion().w = jmeObject.getLocalRotation().w;
      phyObject.getQuaternion().x = jmeObject.getLocalRotation().x;
      phyObject.getQuaternion().y = jmeObject.getLocalRotation().y;
      phyObject.getQuaternion().z = jmeObject.getLocalRotation().z;



to


        phyObject.setPosition(jmeObject.getLocalTranslation());
        phyObject.setQuaternion(jmeObject.getLocalRotation());
        System.out.println("Modified syncWithGraphical");



just as a test and then it works. I think the getQuaternion call isn't working the way it's supposed to or something.

whoops sorry. I didn’t see your post Per. You beat me to it. Getting the new version now hehe.

yar, and i can’t find a single dark corner to go and shrivel up in…



Per’s fixed it, its in CVS.

Has it been committed? I’m checking the CVS repository now and the syncWithGraphical method stills seems to be the same.



In eclipse I was just right clickin the jmePhysics Project going to Team and then going to Update.



Am I doing something wrong there?





Thanks for the speedy patching by the way. :smiley:



----



I just fixed the line in my local version for now





The thruster still slowly detaches itself from the model which seems to suggest that the physicsModel and Geometry model still aren’t in sync. I’m using the newest version of the PhysicsSystem where you pass the tpf to the update call and don’t throttle the PhysicsUpdates at all.