Physics Game States

I was just looking through the code for PhysicsGameState and PhysicsMultiThreadedGameState – what is the real difference? Lets say that I wanted to create a multithreaded application which could create physics spheres at the same time or at different times – would I have to use PhysicsMultiThreadedGameState? I see a PhysicsMultithreadedGameState commented out in TestStressPhysics – just trying to figure out why it was originally there.

I created both of those if I recall.  I believe the PhysicsMultiThreadedGameState was designed to run the physics updates in a different thread than the OpenGL thread.

I'm sorry, I just saw this post: http://www.jmonkeyengine.com/jmeforum/index.php?topic=4683.0 from exactly a year ago. I am getting some of the same ODE errors that were shown in the screenshots. Darkfrog, did you figure a way around the ODE issues?

Man, this place is a treasure trove of information – just found this explanation (http://www.jmonkeyengine.com/jmeforum/index.php?topic=5645.0) for one of the errors that I'm getting. Looks like I'll have to look back at my code and try to fix it. Is there an explanation anywhere on how and when to use locks? I am basically just trying to make a simple app which makes physics spheres all at the same time to prove the multithreaded nature to myself (and get things right before I move on). Any suggestions, links? I will contribute to the wiki once I gain enough knowledge of everything. Right now I am just a beginner :).

I'm not sure if there's anything talking about when to use locks…I'm assuming you mean StandardGame's lock()?



The purpose of that lock method is to allow you to do modifications to the scenegraph safely without causing any concurrency issues.  When possible you should always use locking when modifying the scene-graph from another thread, but depending on what you're doing it may sometimes be necessary to push it to GameTaskQueue instead.

if you modify the Scenegraph inside the GameStates update method, there is no need to use lock() at all, because the GameStates update and render methods are automatically executed inside the OpenGl thread.

Secondly, in a physics based game, you should (but you don't have to) move your objects using forces instead of modifying the translation manually.



Where do you call the Methods makeBall and moveBall ?

I'm just experiencing a lot of lagginess in my "Sphere App". I made a StandardGame called "game" and two GameStates – a PhysicsGameState called "physics" and a DebugGameState called "visual"…



private StandardGame game;
private PhysicsGameState physics;
private DebugGameState visual;



In my main...


      // Start the physics gamestate
      physics = new PhysicsGameState("PhysicsState");
      GameStateManager.getInstance().attachChild(physics);
      physics.setActive(true);

      // Start the visual gamestate
      visual = new DebugGameState();
      visual.setActive(true);
      GameStateManager.getInstance().attachChild(visual);



Now I am trying to call two principle methods -- one which makes a ball and one which moves a ball. The first, which makes a ball, checks to see if there is anything already in the location where I want to make a ball. If it finds something, then it renames the ball, otherwise it makes a new ball...


public void makeBall(String guid, float x, float y, float p) {
      // normalize x and y
      x = x - aspect / 2f;
      y = y - 1 / 2f;

      // check to see if there is a ball already at x,y
      PickResults pr = new BoundingPickResults();
      Ray touchRay = new Ray(new Vector3f(x, y, -20), new Vector3f(0, 0, 1));
      pr.clear(); // might not need this
      visual.getRootNode().findPick(touchRay, pr);

      // if a ball isn't already there, create one
      System.out.println(pr.getNumber());
      if (pr.getNumber() < 1) {
         MaterialState randColor = game.getDisplay().getRenderer()
               .createMaterialState();
         randColor.setDiffuse(ColorRGBA.randomColor());

         game.lock();
         Sphere ballVisual = new Sphere("ball", new Vector3f(), 63, 50, 1);
         ballVisual.setModelBound(new BoundingSphere());
         ballVisual.updateModelBound();
         ballVisual.setRenderState(randColor);

         DynamicPhysicsNode ball = physics.getPhysicsSpace()
               .createDynamicNode();
         ball.setName(guid);
         ball.setAffectedByGravity(false);
         ball.attachChild(ballVisual);
         ball.generatePhysicsGeometry();
         ball.setLocalTranslation(x, y, 0);
         ball.setMaterial(Material.WOOD);
         ball.computeMass();
         ball.setLocalScale(p / 2000f);
         
         ball.updateGeometricState(0, true);
         visual.getRootNode().attachChild(ball);
         visual.getRootNode().updateRenderState();
         game.unlock();
      }
      // otherwise change the name of the ball to the new guid
      else {
         pr.getPickData(0).getTargetMesh().getParentGeom().getParent()
               .setName(guid);
      }
   }



My second method moves a ball which has already been created...


   public void moveBall(String guid, float x, float y) {
      // normalize x and y
      x = x - aspect / 2f;
      y = y - 1 / 2f;

      Spatial s = visual.getRootNode().getChild(guid);
      game.lock();
      s.setLocalTranslation(x, y, 0);
      s.updateGeometricState(0, true);
      game.unlock();
   }



By using the locks, I am now no longer getting any ODE errors, and things work already if I just move one ball at a time. If I try to move two balls at the same time, then they balls update veeerrrry slowly to the point where things crash. What am I doing wrong?!?
Core-Dump said:

if you modify the Scenegraph inside the GameStates update method, there is no need to use lock() at all, because the GameStates update and render methods are automatically executed inside the OpenGl thread.


I'm not sure what you mean by this -- do you mean make my own class which extends GameState?

Core-Dump said:

Secondly, in a physics based game, you should (but you don't have to) move your objects using forces instead of modifying the translation manually.


Yes, I realized this, but I am trying to make an app which multiple users can interact with online. The idea is that the sphere will follow another user's mouse input. Hence why I have made my own move method to accept the x,y coordinates of another user's mouse and translate the ball accordingly.

Core-Dump said:

Where do you call the Methods makeBall and moveBall ?


I am calling these methods from a separate thread in order to execute several of the same methods at the same time (don't want to post my adaptation data, too much of it). Basically I create a ball in one thread and move it (there are several hundred calls to move, to update the position of the mouse). In another thread I create another ball and move it using the same principle (but in a different direction). This is how I am debugging/familiarizing myself with things for now.

Ah ok now i understand.



I am not sure if its a good idea to have multiple threads, which lock your main thread that often.

Thats pretty sure the cause of the lagginess you experience when using more than one ball at the same time.



But I'm not sure whats the best solution to this.

Maybe you could setup a GameState which collects the coordinates from the different Users/Thread and make all updates to the Scenegraph in there.