Movement lags Keystroke in Physics Applet - SOLVED

Hello. I have been playing with Physics and trying to make the various examples work in an applet. I found this test example posted by skul3r, here:



http://www.jmonkeyengine.com/forum/index.php?topic=8417.msg65447#msg65447



I managed to port it to an applet, but the control for the car lags the key press. Any suggestions on improving this and overall performance?



TIA



The applet:


import java.util.HashMap;

import com.jme.bounding.BoundingBox;
import com.jme.bounding.BoundingSphere;
import com.jme.input.ChaseCamera;
import com.jme.input.InputHandler;
import com.jme.input.KeyInput;
import com.jme.input.action.InputAction;
import com.jme.input.action.InputActionEvent;
import com.jme.input.thirdperson.ThirdPersonMouseLook;
import com.jme.math.FastMath;
import com.jme.math.Vector3f;
import com.jme.renderer.Camera;
import com.jme.renderer.ColorRGBA;
import com.jme.scene.shape.Box;
import com.jme.scene.shape.Cylinder;
import com.jme.scene.state.MaterialState;
import com.jme.util.Timer;
import com.jmex.awt.applet.SimpleJMEApplet;
import com.jmex.physics.DynamicPhysicsNode;
import com.jmex.physics.Joint;
import com.jmex.physics.JointAxis;
import com.jmex.physics.PhysicsSpace;
import com.jmex.physics.StaticPhysicsNode;
import com.jmex.physics.material.Material;

public class TestPhysicsCarApplet extends SimpleJMEApplet {
   
   private static final long serialVersionUID = 1L;
   private PhysicsSpace physicsSpace;
   private ChaseCamera chaser;
   private Box car;
   Camera cam;
   
   @Override
   public void init() {      
      super.init();
   }
      
   @Override
   public void simpleAppletRender() {
   }
   
   @Override
   public void simpleAppletSetup() {
      physicsSpace = PhysicsSpace.create();
      buildGround();
      buildObstacles();
      
      final DynamicPhysicsNode chassis = physicsSpace.createDynamicNode();
      
      //car = new Box("Chassis", Vector3f.ZERO, .5f, 1f, .5f);//static orig
      car = new Box("Chassis", new Vector3f(0,0,0), .5f, 1f, .5f);
      car.setModelBound(new BoundingBox());
      car.updateModelBound();
      car.setLocalTranslation(0f, .7f, 0f);
      chassis.attachChild(car);
      chassis.setLocalScale(new Vector3f(1, 0.3f, 1));
      chassis.generatePhysicsGeometry();
      chassis.setMaterial(Material.IRON);
      chassis.setMass(100);
      getRootNode().attachChild(chassis);
      //MaterialState wheel = display.getRenderer().createMaterialState();
      final MaterialState wheel = getRenderer().createMaterialState();
      wheel.setDiffuse(ColorRGBA.black);
      wheel.setSpecular(ColorRGBA.gray);
      wheel.setShininess(10f);
      buildChaseCamera();
      
      for (int i = 0; i < 4; i++) {
         //DynamicPhysicsNode tire = getPhysicsSpace().createDynamicNode();
         final DynamicPhysicsNode tire = physicsSpace.createDynamicNode();
         tire.setMaterial(Material.RUBBER);
         final Cylinder wheel2 = new Cylinder("wheel", 10, 25, 1, 1, true);
         wheel2.setModelBound(new BoundingSphere());
         wheel2.updateModelBound();
         wheel2.setRenderState(wheel);
         tire.attachChild(wheel2);
         tire.setLocalScale(0.3f);
         tire.getLocalTranslation().set((0.5f - (i & 1)), 0,
               (1 - (i & 2)) * 0.5f);
         tire.generatePhysicsGeometry();
         tire.computeMass();
         tire.setMass(50);
         getRootNode().attachChild(tire);
         //Joint joint = getPhysicsSpace().createJoint();
         final Joint joint = physicsSpace.createJoint();
         joint.attach(chassis, tire);
         joint.setAnchor(tire.getLocalTranslation());
         final JointAxis axis1 = joint.createRotationalAxis();
         axis1.setDirection(new Vector3f(0, 1, 0));
         if (i == 2 || i == 0) {
            axis1.setPositionMinimum(-0.5f);
            axis1.setPositionMaximum(0.5f);
         } else {
            axis1.setPositionMinimum(-0f);
            axis1.setPositionMaximum(0f);
         }
         axis1.setAvailableAcceleration(100);
         axis1.setDesiredVelocity(0);
         final JointAxis axis2 = joint.createRotationalAxis();
         axis2.setDirection(new Vector3f(0, 0, 1));
         axis2.setAvailableAcceleration(100);
         axis2.setRelativeToSecondObject(true);
         if ((i & 1) == 0) {
            getInputHandler().addAction(new SteerAction(axis1, 10),
                  InputHandler.DEVICE_KEYBOARD, KeyInput.KEY_J,
                  InputHandler.AXIS_NONE, false);
            getInputHandler().addAction(new SteerAction(axis1, -10),
                  InputHandler.DEVICE_KEYBOARD, KeyInput.KEY_G,
                  InputHandler.AXIS_NONE, false);
         }
         getInputHandler().addAction(new SteerAction(axis2, 20),
               InputHandler.DEVICE_KEYBOARD, KeyInput.KEY_Y,
               InputHandler.AXIS_NONE, false);
         getInputHandler().addAction(new SteerAction(axis2, -20),
               InputHandler.DEVICE_KEYBOARD, KeyInput.KEY_H,
               InputHandler.AXIS_NONE, false);
      }

      //fpsNode.setCullMode(Node.CULL_ALWAYS);
   }
   
   @Override
   public void simpleAppletUpdate() {
      super.simpleAppletUpdate();      
      physicsSpace.update(Timer.getTimer().getTimePerFrame());
      Timer.getTimer().update();
      //chaser.update(tpf);   
      //chaser.update(getTimePerFrame());
   }
   
   private void buildChaseCamera() {
        final Vector3f targetOffset = new Vector3f();
        targetOffset.y = ((BoundingBox) car.getWorldBound()).yExtent * 3f;
        final HashMap<String, Object> props = new HashMap<String, Object>();
        props.put(ThirdPersonMouseLook.PROP_MAXROLLOUT, "6");
        props.put(ThirdPersonMouseLook.PROP_MINROLLOUT, "3");
        props.put(ThirdPersonMouseLook.PROP_MAXASCENT, ""+45 * FastMath.DEG_TO_RAD);
        props.put(ChaseCamera.PROP_INITIALSPHERECOORDS, new Vector3f(5, 0, 30 * FastMath.DEG_TO_RAD));
        props.put(ChaseCamera.PROP_TARGETOFFSET, targetOffset);
        //chaser = new ChaseCamera(cam, car, props);
        chaser = new ChaseCamera(cam, car, props);
        chaser.setMaxDistance(8);
        chaser.setMinDistance(2);
    }
   
   private void buildObstacles() {
      //final DynamicPhysicsNode chassis = getPhysicsSpace()
            //.createDynamicNode();
      
      final DynamicPhysicsNode chassis = physicsSpace.createDynamicNode();
      Box thebox;
      //thebox = new Box("aaa", Vector3f.ZERO, .5f, 1f, .5f);
      thebox = new Box("aaa", new Vector3f(0,0,0), .5f, 1f, .5f);
      //carro = new Box("Chassis", new Vector3f(0,0,0), .5f, 1f, .5f);
      thebox.setLocalTranslation(0f, 5f, 0f);
      chassis.attachChild(thebox);
      chassis.setLocalScale(new Vector3f(1, 0.3f, 1));
      chassis.generatePhysicsGeometry();
      chassis.setMaterial(Material.IRON);
      chassis.setMass(100);
      getRootNode().attachChild(chassis);
   }

   private void buildGround() {
      //final StaticPhysicsNode staticNode = getPhysicsSpace()
            //.createStaticNode();//orig
      final StaticPhysicsNode staticNode = physicsSpace.createStaticNode();
      Box ground;
      ground = new Box("ground", new Vector3f(0, -1, 0), 50f, .2f, 50f);
      //MaterialState redgreen = display.getRenderer().createMaterialState();
      final MaterialState redgreen = getRenderer().createMaterialState();
      redgreen.setDiffuse(ColorRGBA.red);
      redgreen.setShininess(10f);
      ground.setRenderState(redgreen);
      staticNode.attachChild(ground);
      staticNode.generatePhysicsGeometry();
      staticNode.setMaterial(Material.CONCRETE);
      getRootNode().attachChild(staticNode);
   }
   
   private static class SteerAction extends InputAction {

      private final JointAxis axis1;
      private final float velocity;

      public SteerAction(final JointAxis axis1, final float velocity) {
         this.axis1 = axis1;
         this.velocity = velocity;
      }

      public void performAction(final InputActionEvent evt) {
         if (evt.getTriggerPressed()) {
            axis1.setDesiredVelocity(velocity);
         } else {
            axis1.setDesiredVelocity(0);
         }
      }
   }
}

Don't use SimpleJMEApplet, use SimpleApplet.  That might help a bit.

Thx. I am trying it now.

SomethingNew said:

Don't use SimpleJMEApplet, use SimpleApplet.  That might help a bit.


Thank you. That did help and it is working now. I made a few tweeks like

physicsSpace.update(Timer.getTimer().getTimePerFrame());

to make it work as an applet.

I also used the suggestion from orelero to change all of the static values of Vector3f to help lessen the camera "jitters". Here is the working applet:

package aliencuisine;

import java.util.HashMap;
import com.jme.bounding.BoundingBox;
import com.jme.math.Vector3f;
import com.jme.scene.shape.Box;
import com.jme.util.Timer;
import com.jmex.awt.applet.SimpleApplet;
import com.jmex.awt.applet.SimpleJMEApplet;
import com.jmex.physics.DynamicPhysicsNode;
import com.jmex.physics.PhysicsSpace;
import com.jmex.physics.StaticPhysicsNode;
import com.jmex.physics.material.Material;
import com.jme.bounding.BoundingBox;
import com.jme.bounding.BoundingSphere;
import com.jme.input.ChaseCamera;
import com.jme.input.InputHandler;
import com.jme.input.KeyInput;
import com.jme.input.action.InputAction;
import com.jme.input.action.InputActionEvent;
import com.jme.input.thirdperson.ThirdPersonMouseLook;
import com.jme.math.FastMath;
import com.jme.math.Vector3f;
import com.jme.renderer.Camera;
import com.jme.renderer.ColorRGBA;
import com.jme.scene.Node;
import com.jme.scene.shape.Box;
import com.jme.scene.shape.Cylinder;
import com.jme.scene.state.MaterialState;
import com.jmex.physics.DynamicPhysicsNode;
import com.jmex.physics.Joint;
import com.jmex.physics.JointAxis;
import com.jmex.physics.StaticPhysicsNode;
import com.jmex.physics.material.Material;
import com.jmex.physics.util.SimplePhysicsGame;

public class TestPhysicsCarApplet extends SimpleApplet {

   private static final long serialVersionUID = 1L;
   private PhysicsSpace physicsSpace;
   private ChaseCamera chaser;
   private Box car;

   public void simpleUpdate() {
      physicsSpace.update(Timer.getTimer().getTimePerFrame());
      super.simpleUpdate();
      chaser.update(tpf);
   }

   private void buildChaseCamera() {
      Vector3f targetOffset = new Vector3f();
      targetOffset.y = ((BoundingBox) car.getWorldBound()).yExtent * 3f;
      HashMap<String, Object> props = new HashMap<String, Object>();
      props.put(ThirdPersonMouseLook.PROP_MAXROLLOUT, "6");
      props.put(ThirdPersonMouseLook.PROP_MINROLLOUT, "3");
      props.put(ThirdPersonMouseLook.PROP_MAXASCENT, "" + 45
            * FastMath.DEG_TO_RAD);
      props.put(ChaseCamera.PROP_INITIALSPHERECOORDS, new Vector3f(5, 0,
            30 * FastMath.DEG_TO_RAD));
      props.put(ChaseCamera.PROP_TARGETOFFSET, targetOffset);
      // chaser = new ChaseCamera(cam, car, props);
      chaser = new ChaseCamera(cam, car, props);
      chaser.setMaxDistance(8);
      chaser.setMinDistance(2);
   }

   @Override
   protected void simpleInitGame() {

      physicsSpace = PhysicsSpace.create();
      buildGround();
      buildObstacles();

      final DynamicPhysicsNode chassis = physicsSpace.createDynamicNode();
      car = new Box("Chassis", new Vector3f(0,0,0), .5f, 1f, .5f);
      car.setModelBound(new BoundingBox());
      car.updateModelBound();
      car.setLocalTranslation(0f, .7f, 0f);
      chassis.attachChild(car);
      chassis.setLocalScale(new Vector3f(1, 0.3f, 1));
      chassis.generatePhysicsGeometry();
      chassis.setMaterial(Material.IRON);
      chassis.setMass(100);
      rootNode.attachChild(chassis);
      // MaterialState wheel = display.getRenderer().createMaterialState();
      MaterialState wheel = display.getRenderer().createMaterialState();
      wheel.setDiffuse(ColorRGBA.black);
      wheel.setSpecular(ColorRGBA.gray);
      wheel.setShininess(10f);
      buildChaseCamera();
      for (int i = 0; i < 4; i++) {
         // DynamicPhysicsNode tire = getPhysicsSpace().createDynamicNode();
         DynamicPhysicsNode tire = physicsSpace.createDynamicNode();
         tire.setMaterial(Material.RUBBER);
         Cylinder wheel2 = new Cylinder("wheel", 10, 25, 1, 1, true);
         wheel2.setModelBound(new BoundingSphere());
         wheel2.updateModelBound();
         wheel2.setRenderState(wheel);
         tire.attachChild(wheel2);
         tire.setLocalScale(0.3f);
         tire.getLocalTranslation().set((0.5f - (i & 1)), 0,
               (1 - (i & 2)) * 0.5f);
         tire.generatePhysicsGeometry();
         tire.computeMass();
         tire.setMass(50);
         rootNode.attachChild(tire);
         // Joint joint = getPhysicsSpace().createJoint();
         Joint joint = physicsSpace.createJoint();
         joint.attach(chassis, tire);
         joint.setAnchor(tire.getLocalTranslation());
         final JointAxis axis1 = joint.createRotationalAxis();
         axis1.setDirection(new Vector3f(0, 1, 0));
         if (i == 2 || i == 0) {
            axis1.setPositionMinimum(-0.5f);
            axis1.setPositionMaximum(0.5f);
         } else {
            axis1.setPositionMinimum(-0f);
            axis1.setPositionMaximum(0f);
         }
         axis1.setAvailableAcceleration(100);
         axis1.setDesiredVelocity(0);
         final JointAxis axis2 = joint.createRotationalAxis();
         axis2.setDirection(new Vector3f(0, 0, 1));
         axis2.setAvailableAcceleration(100);
         axis2.setRelativeToSecondObject(true);
         if ((i & 1) == 0) {
            input.addAction(new SteerAction(axis1, 10),
                  InputHandler.DEVICE_KEYBOARD, KeyInput.KEY_J,
                  InputHandler.AXIS_NONE, false);
            input.addAction(new SteerAction(axis1, -10),
                  InputHandler.DEVICE_KEYBOARD, KeyInput.KEY_G,
                  InputHandler.AXIS_NONE, false);
         }
         input.addAction(new SteerAction(axis2, 20),
               InputHandler.DEVICE_KEYBOARD, KeyInput.KEY_Y,
               InputHandler.AXIS_NONE, false);
         input.addAction(new SteerAction(axis2, -20),
               InputHandler.DEVICE_KEYBOARD, KeyInput.KEY_H,
               InputHandler.AXIS_NONE, false);
      }
   }

   private void buildObstacles() {
      // final DynamicPhysicsNode chassis = getPhysicsSpace()
      // .createDynamicNode();
      DynamicPhysicsNode chassis = physicsSpace.createDynamicNode();
      Box box2;
      box2 = new Box("thebox", new Vector3f(0,0,0), .5f, 1f, .5f);
      box2.setLocalTranslation(0f, 5f, 0f);
      chassis.attachChild(box2);
      chassis.setLocalScale(new Vector3f(1, 0.3f, 1));
      chassis.generatePhysicsGeometry();
      chassis.setMaterial(Material.IRON);
      chassis.setMass(100);
      rootNode.attachChild(chassis);
   }

   private void buildGround() {
      // final StaticPhysicsNode staticNode = getPhysicsSpace()
      // .createStaticNode();
      StaticPhysicsNode staticNode = physicsSpace.createStaticNode();
      Box box1;
      box1 = new Box("box1", new Vector3f(0, -1, 0), 50f, .2f, 50f);
      // MaterialState redgreen = display.getRenderer().createMaterialState();
      MaterialState redgreen = display.getRenderer().createMaterialState();
      redgreen.setDiffuse(ColorRGBA.red);
      redgreen.setShininess(10f);
      box1.setRenderState(redgreen);
      staticNode.attachChild(box1);
      staticNode.generatePhysicsGeometry();
      staticNode.setMaterial(Material.CONCRETE);
      rootNode.attachChild(staticNode);
   }

   private static class SteerAction extends InputAction {

      private final JointAxis axis1;
      private float velocity;

      public SteerAction(JointAxis axis1, float velocity) {
         this.axis1 = axis1;
         this.velocity = velocity;
      }

      public void performAction(InputActionEvent evt) {
         if (evt.getTriggerPressed()) {
            axis1.setDesiredVelocity(velocity);
         } else {
            axis1.setDesiredVelocity(0);
         }
      }
   }
}