Getting Physics to work in BaseGame

Hello, I am trying, as the topic suggests, to get JME physics to work in BaseGame.



Here is the code I am working with:


package Main;

import java.util.logging.Logger;

import Player.Player;

import Zone_Test.Test_World;

import com.jme.app.BaseGame;
import com.jme.bounding.BoundingBox;
import com.jme.image.Texture;
import com.jme.input.InputSystem;
import com.jme.input.KeyBindingManager;
import com.jme.input.KeyInput;
import com.jme.input.action.InputAction;
import com.jme.input.action.InputActionEvent;
import com.jme.light.DirectionalLight;
import com.jme.math.Vector3f;
import com.jme.renderer.Camera;
import com.jme.renderer.ColorRGBA;
import com.jme.renderer.Renderer;
import com.jme.scene.CameraNode;
import com.jme.scene.Node;
import com.jme.scene.shape.Box;
import com.jme.scene.shape.Sphere;
import com.jme.scene.state.LightState;
import com.jme.scene.state.TextureState;
import com.jme.scene.state.ZBufferState;
import com.jme.system.DisplaySystem;
import com.jme.system.JmeException;
import com.jme.util.TextureManager;
import com.jme.util.Timer;

// these imports are for the physics. physics space is the space we are working in
// dynamic node is a moveable physics object while static is a solid non moving physics
// object like the terrain or a building
import com.jmex.physics.PhysicsDebugger;
import com.jmex.physics.PhysicsSpace;
import com.jmex.physics.DynamicPhysicsNode;
import com.jmex.physics.StaticPhysicsNode;
import com.jmex.physics.geometry.PhysicsBox;
/**
 * Tutorial 2 shows how to build our own Application
 * framework for Flag Rush.
 * For Flag Rush Tutorial Series.
 * @author Mark Powell
 */
public class start_game extends BaseGame {
   protected Timer timer;
   //this is the camera which will follow players around
   private Camera cam;
   //this is the main node which will hold all information such as players and the world
   private Node rootNode;
   //display attributes for the window. We will keep these values
   //to allow the user to change them
   private int width, height, depth, freq;
   private boolean fullscreen;
   public CameraNode camNode;
   //this is the physics space that the game will be working off
   public PhysicsSpace physicsSpace;
   //sets the speed of the physics
   private float physicsSpeed = 1;
   protected boolean showPhysics;
    /**
     * boolean for toggling the simpleUpdate and geometric update parts of the
     * game loop on and off.
     */
    protected boolean pause;
   
   //the players physics node
   public DynamicPhysicsNode PlayerPhysicsNode;
   /**
    * Main entry point of the application
    */
   public static void main(String[] args) {
      start_game app = new start_game();
      //We will load our own "fantastic" Flag Rush logo. Yes, I'm an artist.
      app.setConfigShowMode(ConfigShowMode.AlwaysShow,
                                      start_game.class.getResource("/res/FlagRush.png"));
      app.start();
   }
 
   /**
    * During an update we only look for the escape button and update the timer
    * to get the framerate.
    */
   protected void update(float interpolation) {
      //has something to do with updating the physics
      getPhysicsSpace().update(interpolation);
      //update the time to get the framerate
      timer.update();
      interpolation = timer.getTimePerFrame();
      //if escape was pressed, we exit
      if (KeyBindingManager.getKeyBindingManager().isValidCommand("exit")) {
         finished = true;
      }
      
   }
 
   /**
    * draws the scene graph
    */
   protected void render(float interpolation) {
      Renderer r = display.getRenderer();
      //Clear the screen
      r.clearBuffers();
 
      r.draw(rootNode);
      doDebug(r);
   }
   
    protected void doDebug(Renderer r) {       
        if ( showPhysics ) {
            PhysicsDebugger.drawPhysics( getPhysicsSpace(), r );
        }
    }
   /**
    * initializes the display and camera.
    */
   protected void initSystem() {
      //store the properties information
      width = settings.getWidth();
      height = settings.getHeight();
      depth = settings.getDepth();
      freq = settings.getFrequency();
      fullscreen = settings.isFullscreen();
 
      try {
         display = DisplaySystem.getDisplaySystem(settings.getRenderer());
         display.createWindow(width, height, depth, freq, fullscreen);
 
         cam = display.getRenderer().createCamera(width, height);
      } catch (JmeException e) {
         e.printStackTrace();
         System.exit(1);
      }
 
      //set the background to black
      display.getRenderer().setBackgroundColor(ColorRGBA.black);
 
      //initialize the camera
      cam.setFrustumPerspective(45.0f, (float)width / (float)height, 1, 1000);
      Vector3f loc = new Vector3f(0.0f, 0.0f, 25.0f);
      Vector3f left = new Vector3f(-1.0f, 0.0f, 0.0f);
      Vector3f up = new Vector3f(0.0f, 1.0f, 0.0f);
      Vector3f dir = new Vector3f(0.0f, 0f, -1.0f);
       //Move our camera to a correct place and orientation.
      cam.setFrame(loc, left, up, dir);
      /** Signal that we've changed our camera's location/frustum. */
      cam.update();
 
      /** Get a high resolution timer for FPS updates. */
           timer = Timer.getTimer();
 
                display.getRenderer().setCamera(cam);
 
      KeyBindingManager.getKeyBindingManager().set("exit",
            KeyInput.KEY_ESCAPE);
      
      
   }
 
   /**
    * initializes the scene
    */
   protected void initGame() {
      //builds the physics space
      physicsSpace = PhysicsSpace.create();
      // this shows the bounds of the physics created
        showPhysics = true;

   
      //creates the root node for the entire scene
      rootNode = new Node("All Mesh Information");
      //ZBufferState tells objects to be displayed in the order they are over eachother
      ZBufferState buf = display.getRenderer().createZBufferState();
      buf.setEnabled(true);
      buf.setFunction(ZBufferState.TestFunction.LessThanOrEqualTo);
      //sets ZbufferState onto the rootnode the the entire game gets ordered correctly
      rootNode.setRenderState(buf);

 

       
        buildPlayer();
      buildCamera();      
      buildZone();
      
      //update the scene graph for rendering
      rootNode.updateGeometricState(0.0f, true);
      rootNode.updateRenderState();
      
   }
   
   /////////////////////////////////////////////////////
   /////////////////////////////////////////////////////
   /////////////////////////////////////////////////////
   /**
    *
    *  Physics Initializing stuff
    */
    protected void setPhysicsSpace(PhysicsSpace physicsSpace)
    {
        if (physicsSpace != this.physicsSpace)
        {
            if ( this.physicsSpace != null )
            {
                this.physicsSpace.delete();
                this.physicsSpace = physicsSpace;
            }
        }
    }
   
    public PhysicsSpace getPhysicsSpace(){
        return physicsSpace;
    }
   
    /**
     * @return speed set by {@link #setPhysicsSpeed(float)}
     */
    public float getPhysicsSpeed() {
        return physicsSpeed;
    }

    /**
     * The multiplier for the physics time. Default is 1, which means normal speed. 0 means no physics processing.
     * @param physicsSpeed new speed
     */
    public void setPhysicsSpeed( float physicsSpeed ) {
        this.physicsSpeed = physicsSpeed;
    }
    /////////////////////////////////////////////////
    /////////////////////////////////////////////////
    /////////////////////////////////////////////////
 
   /**
    * will be called if the resolution changes
    *
    */
   protected void reinit() {
      display.recreateWindow(width, height, depth, freq, fullscreen);
   }
 
   /**
    * clean up the textures.
    *
    */
   protected void cleanup() {

 
   }
   
   
   //builds the cameranode to be applied to follow the player
   public void buildCamera(){   
      // attach the CameraNode to the player node
      camNode = new CameraNode("cam node", cam);
      camNode.setCamera(cam);
      // moves the camera x,y,z coordinates currently 0,220,1 *edited need fix
      camNode.setLocalTranslation(0, 220, -800);
      PlayerPhysicsNode.attachChild(camNode);
      //used to tell the camera where to look at
      camNode.lookAt(PlayerPhysicsNode.getLocalTranslation(), PlayerPhysicsNode.getLocalTranslation());

   }
   
    public void buildZone() {
       Test_World tc = new Test_World();
        StaticPhysicsNode staticWorldNode = getPhysicsSpace().createStaticNode();
       
        //the texture state
        TextureState ts = display.getRenderer().createTextureState();
        ts.setEnabled(true);
        ts.setTexture(TextureManager.loadTexture(start_game.class
                .getClassLoader().getResource("Media/Textures/Zones/Test Zone/testzone.jpg"),
                Texture.MinificationFilter.BilinearNearestMipMap, Texture.MagnificationFilter.Bilinear));
        ts.getTexture().setWrap(Texture.WrapMode.Repeat);
       
        tc.buildScene();
        tc.scene.setRenderState(ts);
        staticWorldNode.attachChild(Test_World.scene);
       
        rootNode.attachChild( staticWorldNode );

        staticWorldNode.getLocalTranslation().set( 0, -50, 0 );
        staticWorldNode.updateGeometricState( 0, false );

        staticWorldNode.generatePhysicsGeometry();
       
        //currently sets up the lighting
       
          /** Set up a basic, default light. */
           DirectionalLight light = new DirectionalLight();
           light.setDiffuse(new ColorRGBA(1.0f, 1.0f, 1.0f, 1.0f));
           light.setAmbient(new ColorRGBA(0.5f, 0.5f, 0.5f, 1.0f));
           light.setDirection(new Vector3f(1,-1,0));
           light.setEnabled(true);
    
             /** Attach the light to a lightState and the lightState to rootNode. */
           LightState lightState = display.getRenderer().createLightState();
           lightState.setEnabled(true);
           lightState.attach(light);
           rootNode.setRenderState(lightState);
   
    }
   
    public void buildPlayer(){
      //creates an instance of player.java to allow dynamic calling instead of static
      Player player = new Player();
      //builds the player mesh
       PlayerPhysicsNode = getPhysicsSpace().createDynamicNode();
      player.buildPlayer();
      PlayerPhysicsNode.attachChild(player.playerMesh);
      //attaches the player node to the scene from player.java      
        PlayerPhysicsNode.getLocalTranslation().set( 0, 50, 0 );
        PlayerPhysicsNode.updateGeometricState( 0, true);
        PlayerPhysicsNode.generatePhysicsGeometry();
        rootNode.attachChild(PlayerPhysicsNode);
       
    }
   
}




Basically what is happening is I have a box and a sphere.
The sphere is a dynamicphysicsnode while the box is a staticphysicsnode
The sphere is above the box, but it doesnt fall down.

ShowPhysics is proving to me that the physics geometry is there but it just seems like no gravity is being applied or that the physics isnt being started or something.

I have been working with BaseSimpleGame and SimplePhysicsGame to bring in the proper code to get it working but I dont understand what I am missing. If anyone could help me out I would appreciate it alot.

Here is a screenshot of what it looks like.

Thanks for any help, I am going to continue to try to get this working, if anyone could give me any pointers I would appreciate it.

Here is a screenshot of what it looks like

Hello.



I am expanding this now, and I have ran into another problem that I hope isnt too complicated.



Basically, my ball falls down into a little arena I made in a 3d modeling program.

This arena has little ramps and cylinders in it for the ball to roll on.



I have run into a problem though, the collisions made for this object are boxy and not true to the shape of the model.



the ramp is treated as though it is a box and the ball cannot roll up it, i have to jump up to get ontop of the ramp and be floating over the air.



for my 3d model I made here is the code I am using to load it,


        tc.scene.setRenderState(ts);
        staticWorldNode.attachChild(Test_World.scene);
        staticWorldNode.getLocalTranslation().set( 0, -50, 2 );       
        staticWorldNode.updateGeometricState( 0, true );
        staticWorldNode.generatePhysicsGeometry();
        rootNode.attachChild( staticWorldNode );



Is there a way to set physics geometry on a per face basis rather than shape??

Any help is much appreciated!! Thanks

Try

player.setAffectedByGravity(true);


and/or

physicsSpace.setGravity(new Vector3f(0,9.81f,0));



to see if this is a feature or a bug ;)

thanks for the reply.



I have solved this problem, here is what I did:



I was missing this code about updating the rootNode (silly me it had nothing to do with the physics)


      if ( !pause ) {
            float tpf = this.tpf;
            if ( tpf > 0.2 || Float.isNaN( tpf ) ) {
                Logger.getLogger( PhysicsSpace.LOGGER_NAME ).warning( "Maximum physics update interval is 0.2 seconds - capped." );
                tpf = 0.2f;
            }
            getPhysicsSpace().update( tpf * physicsSpeed );
        }
      if ( firstFrame )
        {
            // drawing and calculating the first frame usually takes longer than the rest
            // to avoid a rushing simulation we reset the timer
            timer.reset();
            firstFrame = false;
        }
      /** Update controllers/render states/transforms/bounds for rootNode. */
        rootNode.updateGeometricState(tpf, true );




But now that I have solved this problem I am delving into uncharted territory for myself.

When I run the test, compared to Lesson1 from the JMEphysics tutorials, my ball falls very slow compared to their ball . I actually even have to turn up my physics speed to 3!! just to get the same type of gravity pull down on my box, but in Lesson1 it is using physics speed 1

Why is my sphere acting so slow like this?

Also, 1 other problem, my staticphysicsnode box which should be immobile isnt static. When the ball falls onto it gets pushed down and then comes back up to try to go to its previous position, and the box and the ball fight to be located at the origin. Why wont the box just be static like it was told to be?

Thanks so much for taking the time to help me on this, I know its a pain to read through all the code. Thanks so much.

EDIT::

after starring at my game running, I realised something. The camera is attached to the sphere, so its not the sphere hitting the static node and pushing the static node, its the sphere bouncing. lol.

For your first issue,

print out physicsSpace.getGravity(), just to see if gravity is set to the right value.



For the second…

I've no idea, but make sure you don't have any Joints!

I am using Jme2, it doesnt seem to recognize getGravity()


The method is called

getDirectionalGravity(Vector3f store);



so just invoke:

System.out.println("Gravity: " + physicsSpace.getDirectionalGravity(null).toString());

well according to what you posted as what I should set gravity, than I believe my gravity is correct



Gravity: com.jme.math.Vector3f [X=0.0, Y=-9.81, Z=0.0]





so basically, I guess I just need to turn up my physics speed then? Why does the tutorial1 of JME physics drop the box so fast and my sphere drops so slow on the same physics speed?

Well, your player is at (0, 50, 0) while the

DynamicPhysicsNode in the lesson1 physics tutorial is at (0, 5, 0) :wink:



It's not slow, it just seems so.



Try to set location of your player to (0,5,0) and see what happen…

or try to set location of the sphere in the tutorial to (0, 50,0) and compare…

ooohhh. my sphere is much bigger which means it is traveling at the same speed, just covering more distance and since i am pulled back so far it gives it the sense of being slower.



ok, thanks for helping me figure that out, thats a weird one to wrap your head around.

Yes it is… :wink:



No problem though :smiley:

Hi again.



You have to generatePhysicsGeometry(); by triangle accuracy

so try staticWorldNode.generatePhysicsGeometry( true ); instead



Hope that helps!