NullPointerException With BulletAppState

Bellow you will find the code:

I want to point out, that I followed the beginner tutorial and I still get a nullpointerexception using the bulletAppState object created from the BulletAppState class.

What I want to do is make the chess blocks solid (or the floor) so that the chess pieces can fall onto them when released.

package mygame;

import com.jme3.app.SimpleApplication;
import com.jme3.bullet.BulletAppState;
import com.jme3.bullet.control.RigidBodyControl;
import com.jme3.collision.CollisionResult;
import com.jme3.collision.CollisionResults;
import com.jme3.input.MouseInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.MouseButtonTrigger;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Ray;
import com.jme3.math.Vector3f;
import com.jme3.renderer.queue.RenderQueue;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
import com.jme3.scene.shape.Box;
import com.jme3.scene.shape.Sphere;
import com.jme3.util.SkyFactory;
import mygame.CameraMode.RtsCam;

/**
 * test
 * @author normenhansen
 */
public class Main extends SimpleApplication {


    public static void main(String[] args){
        Main app = new Main();
        app.start();
    }

    private RtsCam myCam;

    private Node targetPool = new Node("Targetable");
    
    private Node currentTable = new Node("CurrentTable");

    //Node chessTable = new Node("ChessTable");

    private Vector3f blockSize = new Vector3f(10f, 1f, 10f);
    
    private BulletAppState bulletAppState;

    @Override
    public void simpleInitApp() {

        bulletAppState = new BulletAppState();

        flyCam.setEnabled(false);
        
        setDisplayFps(false);
        setDisplayStatView(false);      

        Spatial mySky = SkyFactory.createSky(assetManager, "Textures/Sky/Bright/BrightSky.dds", false);

        mySky.setName("Sky");

        mySky.setQueueBucket(RenderQueue.Bucket.Sky);

        mySky.setCullHint(Spatial.CullHint.Never);
        
        Spatial myTerrain = assetManager.loadModel("Scenes/myTerrainScene.j3o");

        Material myTerrainMats = new Material(assetManager, "Common/MatDefs/Misc/ColoredTextured.j3md");

        myTerrainMats.setTexture("ColorMap", assetManager.loadTexture("Textures/dirt.jpg"));

        myTerrain.setMaterial(myTerrainMats);

        myTerrain.setName("Ground");

        //RigidBodyControl myTerrain_phy = new RigidBodyControl(0.0f);

        //myTerrain.addControl(myTerrain_phy);
        
        //bulletAppState.getPhysicsSpace().add(myTerrain_phy);

        myCam = new RtsCam(RtsCam.UpVector.Y_UP);

        myCam.setDistance(265);

        stateManager.attach(myCam);

        currentTable.attachChild(makeTable("Table0", 70, 70, 2, 2, true, bulletAppState));

        targetPool.attachChild(currentTable);
        
        rootNode.attachChild(mySky);
        rootNode.attachChild(myTerrain);
        rootNode.attachChild(targetPool);

        initMark();
                
        inputManager.addMapping("LeftMouseButton", new MouseButtonTrigger(MouseInput.BUTTON_LEFT));
        inputManager.addMapping("RightMouseButton", new MouseButtonTrigger(MouseInput.BUTTON_RIGHT));

        inputManager.addListener(mouseSelectionEvent, "LeftMouseButton", "RightMouseButton");

    }

    private Node makeTable(String nodeName, float xOffset, float yOffset, float xSeparation, float ySeparation, boolean withBorder, BulletAppState bAppState){
        Node table = new Node(nodeName);
        if(withBorder){
            for(int z = 1; z <= 9; z++){
                for(int x = 1; x <= 9; x++){
                    Geometry block = null;
                    if(x==1&&z==1){
                        block = new Geometry("Bz"+(x)+""+(z), new Box(blockSize.x, blockSize.y, blockSize.z));
                        Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
                        block.setLocalTranslation(xOffset-blockSize.x*(x-1)*xSeparation, 1, yOffset-blockSize.z*(z-1)*ySeparation);
                        mat.setColor("Color", ColorRGBA.Yellow);
                        block.setMaterial(mat);
                    } else if(x>=2&&x<=9&&z==1){
                        block = new Geometry("Bz"+(x)+""+(z), new Box(blockSize.x, blockSize.y, blockSize.z));
                        Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
                        block.setLocalTranslation(xOffset-blockSize.x*(x-1)*xSeparation, 1, yOffset-blockSize.z*(z-1)*ySeparation);
                        mat.setColor("Color", ColorRGBA.Yellow);
                        block.setMaterial(mat);
                    } else if(x==1&&z>=2&&z<=9){
                        block = new Geometry("Bz"+(x)+""+(z), new Box(blockSize.x, blockSize.y, blockSize.z));
                        Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
                        block.setLocalTranslation(xOffset-blockSize.x*(x-1)*xSeparation, 1, yOffset-blockSize.z*(z-1)*ySeparation);
                        mat.setColor("Color", ColorRGBA.Yellow);
                        block.setMaterial(mat);
                    } else if(x>=2&&z>=2&&x<=9&&z<=9){
                        block = new Geometry("Bx"+(x-1)+""+(z-1), new Box(blockSize.x, blockSize.y, blockSize.z));
                        Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
                        block.setLocalTranslation(xOffset-blockSize.x*(x-1)*xSeparation, 1, yOffset-blockSize.z*(z-1)*ySeparation);
                        if(x%2==1&&z%2==1){
                            mat.setColor("Color", ColorRGBA.DarkGray);
                            block.setMaterial(mat);
                        } else if(x%2==0&&z%2==1){
                            mat.setColor("Color", ColorRGBA.White);
                            block.setMaterial(mat);
                        } else if(x%2==1&&z%2==0){
                            mat.setColor("Color", ColorRGBA.White);
                            block.setMaterial(mat);
                        } else if(x%2==0&&z%2==0){
                            mat.setColor("Color", ColorRGBA.DarkGray);
                            block.setMaterial(mat);
                        }
                    }
                    if(bAppState!=null&&block!=null){
                        RigidBodyControl rbody = new RigidBodyControl(0.0f);
                        block.addControl(rbody);
                        bAppState.getPhysicsSpace().add(rbody);
                    }
                    table.attachChild(block);
                }
            }
        } else {
            for(int z = 1; z <= 8; z++){
                for(int x = 1; x <= 8; x++){
                    Geometry block = new Geometry("Bx"+x+""+z, new Box(blockSize.x, blockSize.y, blockSize.z));
                    Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
                    block.setLocalTranslation(xOffset-blockSize.x*(x-1)*xSeparation, 1, yOffset-blockSize.z*(z-1)*ySeparation);
                    if(x%2==1&&z%2==1){
                        mat.setColor("Color", ColorRGBA.DarkGray);
                        block.setMaterial(mat);
                    } else if(x%2==0&&z%2==1){
                        mat.setColor("Color", ColorRGBA.White);
                        block.setMaterial(mat);
                    } else if(x%2==1&&z%2==0){
                        mat.setColor("Color", ColorRGBA.White);
                        block.setMaterial(mat);
                    } else if(x%2==0&&z%2==0){
                        mat.setColor("Color", ColorRGBA.DarkGray);
                        block.setMaterial(mat);
                    }
                    if(bAppState!=null&&block!=null){
                        RigidBodyControl rbody = new RigidBodyControl(0.0f);
                        block.addControl(rbody);
                        bAppState.getPhysicsSpace().add(rbody);
                    }
                    table.attachChild(block);
                }
            }
        }
        return table;
    }
    
    CollisionResults collisionState;
    private boolean leftMouseButtonDraggable = true;
    private boolean rightMouseButtonDraggable = true;

    @Override
    public void simpleUpdate(float tpf){

        rootNode.updateGeometricState();

        myCam.update(tpf);

        Vector3f origin    = cam.getWorldCoordinates(inputManager.getCursorPosition(), 0.0f);
 
        Vector3f direction = cam.getWorldCoordinates(inputManager.getCursorPosition(), 0.3f);
 
        direction.subtractLocal(origin).normalizeLocal();

        Ray ray = new Ray(origin, direction);
 
        collisionState = new CollisionResults();
 
        targetPool.collideWith(ray, collisionState);

        if (collisionState.size() > 0) {

            CollisionResult closest = collisionState.getClosestCollision();

            mark.setLocalTranslation(closest.getContactPoint());

            mark.setMaterial(closest.getGeometry().getMaterial());

            rootNode.attachChild(mark);

            if(leftMouseButtonPressed){
    
                if(leftMouseButtonDraggable){
                    
                    leftMouseButtonDraggable = false;
                } else {
                    System.out.println("Left Mouse Button Pressed Over: " + closest.getGeometry().getName());
                }

            } else {
                System.out.println("Left Mouse Button Released Over: " + closest.getGeometry().getName());
                leftMouseButtonDraggable = true;
            }
            if(rightMouseButtonPressed){
    
                if(rightMouseButtonDraggable){
                    
                    if(!leftMouseButtonDraggable){


                        leftMouseButtonDraggable = true;
                    }

                    rightMouseButtonDraggable = false;
                } else {
                    //System.out.println("Left Mouse Button Pressed Over: " + closest.getGeometry().getName());
                }

            } else {
                //System.out.println("Left Mouse Button Released Over: " + closest.getGeometry().getName());
                rightMouseButtonDraggable = true;
            }
        } else {

            rootNode.detachChild(mark);
 
        }

    }

    private Geometry mark;

    protected void initMark() {
 
        Sphere sphere = new Sphere(30, 30, 0.2f);
 
        mark = new Geometry("BOOM!", sphere);
 
        Material mark_mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
 
        mark_mat.setColor("Color", ColorRGBA.Red);
 
        mark.setMaterial(mark_mat);
 
    }

    public void chessTableScale(float scale){
        blockSize = blockSize.scaleAdd(scale, blockSize);
    }

    private boolean leftMouseButtonPressed = false;
    private boolean rightMouseButtonPressed = false;

    private ActionListener mouseSelectionEvent = new ActionListener(){

        public void onAction(String e, boolean isPressed, float tpf) {
            if(e.equals("LeftMouseButton")){
                leftMouseButtonPressed = isPressed;
            } else if(e.equals("RightMouseButton")){
                rightMouseButtonPressed = isPressed;
            }
        }
    
    };
}

So whats the exception message? In which line of your code does it happen? Its not easy to help when you don’t supply the actual information about your error.

And looking through your code… I don’t see you attaching your BulletAppState to the StateManager anywhere. You also call updateGeometricState() on the rootNode which is a big no-no. I don’t think any tutorial teaches you to do this so I don’t think its a problem of either the engine or the tutorials…

1 Like

I fixed it.

I was missing this line of code:

             stateManager.attach(bulletAppState);

But now I have a different problem.

Should I post in another topic, or can I post it here?

The problem is adding a solid object with (1f) mass that falls onto the rigid table.

but the sphere which I am using is falling through the table is not staying on top of it.

If thats the same code, you make the table object and attach it to your “table node” after you attach the physics control to the “table node”, the control creates the collision shape when its attached though. In the physics debug view you’d probably see that the table has no collision shape.

You know something, when I created the rigidbodycontrol, I created it for each individual table block, NOT the table Node.

So are you saying I should add the rigidbodycontrol also to the table Node? and also attach the SolidObject sphere to the Table Node?

No, all I’m saying is that the collision shape gets created when you attach the Control to the Spatial, based on whatever geometry is contained in that spatial at that moment. And that you should enable the physics debug view to actually see the collision shapes.

How do you enable the physics debug view to see the collision shapes?

bulletAppState.setDebugEnabled(true);
also check out the javadoc and list of object methods, you can see it when you press Ctrl-Space after typing in an object name followed by a dot, like “bulletAppState.[Ctrl-Space]”

I finally saw the collision shapes. Thank you.

However, I have posted the code as I have now, to see if you or someone can pint point where am I missing something that says, why my collision solidObject object, which is a blue spere is not colliding with the table, it is going right through it.

Update: Noticed that the pink blocks turn blue, does that mean the ball is colliding with the blocks?
Update: Another thing I noticed, is it does not matter how high I place the solid ball, it keeps falling from the same distance, and it keeps going through.

package mygame;

import com.jme3.app.SimpleApplication;
import com.jme3.bullet.BulletAppState;
import com.jme3.bullet.collision.shapes.CollisionShape;
import com.jme3.bullet.control.RigidBodyControl;
import com.jme3.bullet.util.CollisionShapeFactory;
import com.jme3.collision.CollisionResult;
import com.jme3.collision.CollisionResults;
import com.jme3.input.MouseInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.MouseButtonTrigger;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Ray;
import com.jme3.math.Vector3f;
import com.jme3.renderer.queue.RenderQueue;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
import com.jme3.scene.shape.Box;
import com.jme3.scene.shape.Sphere;
import com.jme3.util.SkyFactory;
import mygame.CameraMode.RtsCam;

/**
 * test
 * @author normenhansen
 */
public class Main extends SimpleApplication {


    public static void main(String[] args){
        Main app = new Main();
        app.start();
    }

    private RtsCam myCam;

    private Node targetPool = new Node("Targetable");
    
    private Node currentTable = new Node("CurrentTable");

    //Node chessTable = new Node("ChessTable");

    private Vector3f blockSize = new Vector3f(10f, 1f, 10f);
    
    private BulletAppState bulletAppState;

    @Override
    public void simpleInitApp() {

        bulletAppState = new BulletAppState();

        stateManager.attach(bulletAppState);
        
        bulletAppState.setDebugEnabled(true);
                
        flyCam.setEnabled(false);
        
        setDisplayFps(false);
        setDisplayStatView(false);      

        Spatial mySky = SkyFactory.createSky(assetManager, "Textures/Sky/Bright/BrightSky.dds", false);

        mySky.setName("Sky");

        mySky.setQueueBucket(RenderQueue.Bucket.Sky);

        mySky.setCullHint(Spatial.CullHint.Never);

        Spatial myTerrain = assetManager.loadModel("Scenes/myTerrainScene.j3o");

        Material myTerrainMats = new Material(assetManager, "Common/MatDefs/Misc/ColoredTextured.j3md");

        myTerrainMats.setTexture("ColorMap", assetManager.loadTexture("Textures/dirt.jpg"));

        myTerrain.setMaterial(myTerrainMats);

        myTerrain.setName("Ground");

        //RigidBodyControl myTerrain_phy = new RigidBodyControl(0.0f);

        //myTerrain.addControl(myTerrain_phy);
        
        //bulletAppState.getPhysicsSpace().add(myTerrain_phy);

        myCam = new RtsCam(RtsCam.UpVector.Y_UP);

        myCam.setDistance(265);

        stateManager.attach(myCam);

        currentTable.attachChild(makeTable("Table0", 70, 70, 2, 2, true, bulletAppState));

        ///creating the solid object
        Geometry solidObject = new Geometry("Sphere", new Sphere(30, 30, 10f));
        Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
        mat.setColor("Color", ColorRGBA.Blue);
        solidObject.setMaterial(mat);
        CollisionShape collisionShape = CollisionShapeFactory.createBoxShape(solidObject);
        RigidBodyControl solid_phy = new RigidBodyControl(collisionShape, 1f);
        solidObject.addControl(solid_phy);
        solidObject.setLocalTranslation(10f, 500f, 10f);

        bulletAppState.getPhysicsSpace().add(solid_phy);

        ///attaching the solidObject to the table node
        currentTable.attachChild(solidObject);
       
        targetPool.attachChild(currentTable);

        
        
        rootNode.attachChild(mySky);
        rootNode.attachChild(myTerrain);
        rootNode.attachChild(targetPool);
        rootNode.attachChild(solidObject);
        
        initMark();
                
        inputManager.addMapping("LeftMouseButton", new MouseButtonTrigger(MouseInput.BUTTON_LEFT));
        inputManager.addMapping("RightMouseButton", new MouseButtonTrigger(MouseInput.BUTTON_RIGHT));

        inputManager.addListener(mouseSelectionEvent, "LeftMouseButton", "RightMouseButton");

    }

    private Node makeTable(String nodeName, float xOffset, float yOffset, float xSeparation, float ySeparation, boolean withBorder, BulletAppState bAppState){
        Node table = new Node(nodeName);
        if(withBorder){
            for(int z = 1; z <= 9; z++){
                for(int x = 1; x <= 9; x++){
                    Geometry block = null;
                    if(x==1&&z==1){
                        block = new Geometry("Bz"+(x)+""+(z), new Box(blockSize.x, blockSize.y, blockSize.z));
                        Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
                        block.setLocalTranslation(xOffset-blockSize.x*(x-1)*xSeparation, 1, yOffset-blockSize.z*(z-1)*ySeparation);
                        mat.setColor("Color", ColorRGBA.Yellow);
                        block.setMaterial(mat);
                    } else if(x>=2&&x<=9&&z==1){
                        block = new Geometry("Bz"+(x)+""+(z), new Box(blockSize.x, blockSize.y, blockSize.z));
                        Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
                        block.setLocalTranslation(xOffset-blockSize.x*(x-1)*xSeparation, 1, yOffset-blockSize.z*(z-1)*ySeparation);
                        mat.setColor("Color", ColorRGBA.Yellow);
                        block.setMaterial(mat);
                    } else if(x==1&&z>=2&&z<=9){
                        block = new Geometry("Bz"+(x)+""+(z), new Box(blockSize.x, blockSize.y, blockSize.z));
                        Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
                        block.setLocalTranslation(xOffset-blockSize.x*(x-1)*xSeparation, 1, yOffset-blockSize.z*(z-1)*ySeparation);
                        mat.setColor("Color", ColorRGBA.Yellow);
                        block.setMaterial(mat);
                    } else if(x>=2&&z>=2&&x<=9&&z<=9){
                        block = new Geometry("Bx"+(x-1)+""+(z-1), new Box(blockSize.x, blockSize.y, blockSize.z));
                        Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
                        block.setLocalTranslation(xOffset-blockSize.x*(x-1)*xSeparation, 1, yOffset-blockSize.z*(z-1)*ySeparation);
                        if(x%2==1&&z%2==1){
                            mat.setColor("Color", ColorRGBA.DarkGray);
                            block.setMaterial(mat);
                        } else if(x%2==0&&z%2==1){
                            mat.setColor("Color", ColorRGBA.White);
                            block.setMaterial(mat);
                        } else if(x%2==1&&z%2==0){
                            mat.setColor("Color", ColorRGBA.White);
                            block.setMaterial(mat);
                        } else if(x%2==0&&z%2==0){
                            mat.setColor("Color", ColorRGBA.DarkGray);
                            block.setMaterial(mat);
                        }
                    }
                    table.attachChild(block);
                }
            }
        } else {
            for(int z = 1; z <= 8; z++){
                for(int x = 1; x <= 8; x++){
                    Geometry block = new Geometry("Bx"+x+""+z, new Box(blockSize.x, blockSize.y, blockSize.z));
                    Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
                    block.setLocalTranslation(xOffset-blockSize.x*(x-1)*xSeparation, 1, yOffset-blockSize.z*(z-1)*ySeparation);
                    if(x%2==1&&z%2==1){
                        mat.setColor("Color", ColorRGBA.DarkGray);
                        block.setMaterial(mat);
                    } else if(x%2==0&&z%2==1){
                        mat.setColor("Color", ColorRGBA.White);
                        block.setMaterial(mat);
                    } else if(x%2==1&&z%2==0){
                        mat.setColor("Color", ColorRGBA.White);
                        block.setMaterial(mat);
                    } else if(x%2==0&&z%2==0){
                        mat.setColor("Color", ColorRGBA.DarkGray);
                        block.setMaterial(mat);
                    }
                    table.attachChild(block);
                }
            }
        }

        //making the table solid
        if(bAppState!=null){
            CollisionShape collisionShape = CollisionShapeFactory.createBoxShape(table);
            RigidBodyControl rbody = new RigidBodyControl(collisionShape, 0.0f);
            table.addControl(rbody);
            bAppState.getPhysicsSpace().add(rbody);
        }

        return table;
    }
    
    CollisionResults collisionState;
    private boolean leftMouseButtonDraggable = true;
    private boolean rightMouseButtonDraggable = true;

    @Override
    public void simpleUpdate(float tpf){

        rootNode.updateGeometricState();

        bulletAppState.update(tpf);

        myCam.update(tpf);

        Vector3f origin    = cam.getWorldCoordinates(inputManager.getCursorPosition(), 0.0f);
 
        Vector3f direction = cam.getWorldCoordinates(inputManager.getCursorPosition(), 0.3f);
 
        direction.subtractLocal(origin).normalizeLocal();

        Ray ray = new Ray(origin, direction);
 
        collisionState = new CollisionResults();
 
        targetPool.collideWith(ray, collisionState);

        if (collisionState.size() > 0) {

            CollisionResult closest = collisionState.getClosestCollision();

            mark.setLocalTranslation(closest.getContactPoint());

            mark.setMaterial(closest.getGeometry().getMaterial());

            rootNode.attachChild(mark);

            if(leftMouseButtonPressed){
    
                if(leftMouseButtonDraggable){
                    
                    leftMouseButtonDraggable = false;
                } else {
                    System.out.println("Left Mouse Button Pressed Over: " + closest.getGeometry().getName());
                }

            } else {
                System.out.println("Left Mouse Button Released Over: " + closest.getGeometry().getName());
                leftMouseButtonDraggable = true;
            }
            if(rightMouseButtonPressed){
    
                if(rightMouseButtonDraggable){
                    
                    if(!leftMouseButtonDraggable){


                        leftMouseButtonDraggable = true;
                    }

                    rightMouseButtonDraggable = false;
                } else {
                    //System.out.println("Left Mouse Button Pressed Over: " + closest.getGeometry().getName());
                }

            } else {
                //System.out.println("Left Mouse Button Released Over: " + closest.getGeometry().getName());
                rightMouseButtonDraggable = true;
            }
        } else {

            rootNode.detachChild(mark);
 
        }

    }

    private Geometry mark;

    protected void initMark() {
 
        Sphere sphere = new Sphere(30, 30, 0.2f);
 
        mark = new Geometry("BOOM!", sphere);
 
        Material mark_mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
 
        mark_mat.setColor("Color", ColorRGBA.Red);
 
        mark.setMaterial(mark_mat);
 
    }

    public void chessTableScale(float scale){
        blockSize = blockSize.scaleAdd(scale, blockSize);
    }

    private boolean leftMouseButtonPressed = false;
    private boolean rightMouseButtonPressed = false;

    private ActionListener mouseSelectionEvent = new ActionListener(){

        public void onAction(String e, boolean isPressed, float tpf) {
            if(e.equals("LeftMouseButton")){
                leftMouseButtonPressed = isPressed;
            } else if(e.equals("RightMouseButton")){
                rightMouseButtonPressed = isPressed;
            }
        }
    
    };
}

I can’t run your code because I’m missing the rts cam classes in your project but you still call rootNode.updateGeometricState as well as bulletAppState.update() now which are both wrong.

This is the RtsCam code:

But I figure it out.

I had to place the localTranslation line before making the body rigid.

package mygame.CameraMode;

import com.jme3.app.Application;
import com.jme3.app.state.AbstractAppState;
import com.jme3.app.state.AppStateManager;
import com.jme3.bounding.BoundingVolume;
import com.jme3.input.InputManager;
import com.jme3.input.KeyInput;
import com.jme3.input.MouseInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.AnalogListener;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.input.controls.MouseAxisTrigger;
import com.jme3.input.controls.MouseButtonTrigger;
import com.jme3.math.FastMath;
import com.jme3.math.Vector2f;
import com.jme3.math.Vector3f;
import com.jme3.renderer.Camera;
/**
 * 
 * <pre>
 * getStateManager().detach(getStateManager().getState(FlyCamAppState.class));
 * RtsCam rtsCam = new RtsCam(UpVector.Y_UP);
 * rtsCam.setCenter(new Vector3f(0, 0, 0));
 * rtsCam.setDistance(200);
 * rtsCam.setMaxSpeed(DoF.FWD, 100, 0.5f);
 * rtsCam.setMaxSpeed(DoF.SIDE, 100, 0.5f);
 * rtsCam.setMaxSpeed(DoF.DISTANCE, 100, 0.5f);
 * rtsCam.setHeightProvider(new HeightProvider() {
 *     public float getHeight(Vector2f coord) {
 *         return terrain.getHeight(coord)+10;
 *     }
 * });
 * getStateManager().attach(rtsCam);
 * </pre>
 *
 */
public class RtsCam extends AbstractAppState {

    /**
     * Degree of Freedom
     * 
     */
    public enum DoF {
        SIDE,
        FWD,
        ROTATE,
        TILT,
        DISTANCE
    }

    public enum UpVector {

        Y_UP(Vector3f.UNIT_Y),
        Z_UP(Vector3f.UNIT_Z);

        final Vector3f upVector;

        UpVector(Vector3f upVector) {
            this.upVector = upVector;
        }

    }

    interface HeightProvider {
        public float getHeight(Vector2f coord);
    }

    private InputManager inputManager;
    private Camera cam;
    private BoundingVolume centerBounds;
    private BoundingVolume cameraBounds;

    private final int[] direction = new int[5];
    private final float[] accelTime = new float[5];
    private final float[] offsetMoves = new float[5];

    private final float[] maxSpeedPerSecondOfAccell = new float[5];
    private final float[] maxAccellPeriod = new float[5];
    private final float[] decelerationFactor = new float[5];
    private final float[] minValue = new float[5];
    private final float[] maxValue = new float[5];

    private final Vector3f position = new Vector3f();
    private final Vector3f center = new Vector3f();
    
    private final InternalListener listener = new InternalListener();

    private final UpVector up;

    private final Vector3f oldPosition = new Vector3f();
    private final Vector3f oldCenter = new Vector3f();
    private final Vector2f tempVec2 = new Vector2f();
    private float tilt = FastMath.PI / 4;
    private float rot = -FastMath.PI;
    private float distance = 10;
    
    private HeightProvider heightProvider;


    private boolean wheelEnabled = true;
    private String mouseRotationButton = "BUTTON2";
    private String mouseDragButton = "BUTTON3XXX";

    private boolean mouseRotation;
    private boolean mouseDrag;

    private static final int SIDE = DoF.SIDE.ordinal();
    private static final int FWD = DoF.FWD.ordinal();
    private static final int ROTATE = DoF.ROTATE.ordinal();
    private static final int TILT = DoF.TILT.ordinal();
    private static final int DISTANCE = DoF.DISTANCE.ordinal();

    private static final float WHEEL_SPEED = 1f / 15;

    private static String[] mappings = new String[] {
            "+SIDE", "+FWD", "+ROTATE", "+TILT", "+DISTANCE", "-SIDE", "-FWD", "-ROTATE", "-TILT", "-DISTANCE", "+WHEEL", "-WHEEL", "-MOUSEX", "+MOUSEX", "-MOUSEY", "+MOUSEY",
            "BUTTON1", "BUTTON2", "BUTTON3" };

    public RtsCam(UpVector up) {
        this.up = up;

        setMinMaxValues(DoF.SIDE, Float.NEGATIVE_INFINITY, Float.POSITIVE_INFINITY);
        setMinMaxValues(DoF.FWD, Float.NEGATIVE_INFINITY, Float.POSITIVE_INFINITY);
        setMinMaxValues(DoF.ROTATE, Float.NEGATIVE_INFINITY, Float.POSITIVE_INFINITY);
        setMinMaxValues(DoF.TILT, 0.2f, (float) (Math.PI / 2) - 0.001f);
        setMinMaxValues(DoF.DISTANCE, 2, Float.POSITIVE_INFINITY);

        setMaxSpeed(DoF.SIDE, 10f, 0.4f);
        setMaxSpeed(DoF.FWD, 10f, 0.4f);
        setMaxSpeed(DoF.ROTATE, 2f, 0.4f);
        setMaxSpeed(DoF.TILT, 1f, 0.4f);
        setMaxSpeed(DoF.DISTANCE, 15f, 0.4f);
    }

    @Override
    public void initialize(AppStateManager stateManager, Application app) {
        super.initialize(stateManager, app);
        this.cam = app.getCamera();
        this.inputManager = app.getInputManager();
        registerWithInput(inputManager);
    }

    /**
     * Set the maximum speed for given direction of movement. For SIDE/FWD/DISTANCE it is in units/second, for ROTATE/TILT it is in radians/second. Deceleration time is assumed to be the same
     * as acceleration time.
     * 
     * @param deg
     *            degree of freedom for which to set the maximum speed
     * @param maxSpd
     *            maximum speed of movement in that direction
     * @param accelTime
     *            amount of time which is need to accelerate to full speed in seconds (has to be bigger than zero, values over half second feel very sluggish). Defaults are 0.4
     *            seconds
     */
    public void setMaxSpeed(DoF deg, float maxSpd, float accelTime) {
        setMaxSpeed(deg,maxSpd,accelTime,accelTime);
    }
    
    /**
     * Set the maximum speed for given direction of movement. For SIDE/FWD/DISTANCE it is in units/second, for ROTATE/TILT it is in radians/second. 
     * 
     * @param deg
     *            degree of freedom for which to set the maximum speed
     * @param maxSpd
     *            maximum speed of movement in that direction
     * @param accelTime
     *            amount of time which is need to accelerate to full speed in seconds (has to be bigger than zero, values over half second feel very sluggish). Defaults are 0.4
     *            seconds
     * @param decelerationTime
     *            amount of time in seconds which is needed to automatically decelerate (friction-like stopping) from maxSpd to full stop.
     */
    public void setMaxSpeed(DoF deg, float maxSpd, float accelTime, float decelerationTime) {
        maxSpeedPerSecondOfAccell[deg.ordinal()] = maxSpd / accelTime;
        maxAccellPeriod[deg.ordinal()] = accelTime;
        if ( decelerationTime < 0.00001) {
            decelerationTime = 0.00001f;
        }
        decelerationFactor[deg.ordinal()] = accelTime/decelerationTime; 
    }

    /**
     * Set the terrain following logic for camera. Camera position will not get under the value returned by the heightProvider. Please add some extra buffering here,
     * so camera will not clip the actual terrain - for example
     * 
     * <pre>
     * new HeightProvider() {
     *     &#064;Override
     *     public float getHeight(Vector2f coord) {
     *         return terrain.getHeight(coord) + 10;
     *     }
     * }
     * </pre>
     * 
     * @param heightProvider
     */
    public void setHeightProvider(HeightProvider heightProvider) {
        this.heightProvider = heightProvider;
    }

    /**
     * Enables/disabled wheel-zoom behaviour
     * Default is enabled
     */
    public void setWheelEnabled(boolean wheelEnabled) {
        this.wheelEnabled = wheelEnabled;
    }

    private String mouseButtonName(int button) {
        switch (button) {
            case MouseInput.BUTTON_LEFT:
                return "BUTTON1";

            case MouseInput.BUTTON_MIDDLE:
                return "BUTTON2";

            case MouseInput.BUTTON_RIGHT:
                return "BUTTON3";
            default:
                return null;
        }
    }

    /**
     * Use MouseInput.BUTTON_ constants to indicate which buttons should be used for rotation and dragging with mouse
     * Defaults are BUTTON_MIDDLE for rotation and BUTTON_RIGHT for dragging
     * Use -1 to disable given functionality
     * 
     * @param rotationButton
     *            button to hold to control TILT/ROTATION with mouse movements
     * @param dragButton
     *            button to hold to drag camera position around
     */
    public void setMouseDragging(int rotationButton, int dragButton) {
        mouseDragButton = mouseButtonName(dragButton);
        mouseRotationButton = mouseButtonName(rotationButton);
    }

    public void update(final float tpf) {

        for (int i = 0; i < direction.length; i++) {
            int dir = direction[i];
            switch (dir) {
                case -1:
                    accelTime[i] = clamp(-maxAccellPeriod[i], accelTime[i] - tpf, accelTime[i]);
                    break;
                case 0:
                    if (accelTime[i] != 0) {
                        double oldSpeed = accelTime[i];
                        if (accelTime[i] > 0) {
                            accelTime[i] -= tpf*decelerationFactor[i];
                        } else {
                            accelTime[i] += tpf*decelerationFactor[i];
                        }
                        if (oldSpeed * accelTime[i] < 0) {
                            accelTime[i] = 0;
                        }
                    }
                    break;
                case 1:
                    accelTime[i] = clamp(accelTime[i], accelTime[i] + tpf, maxAccellPeriod[i]);
                    break;
            }

        }

        float distanceChange = maxSpeedPerSecondOfAccell[DISTANCE] * accelTime[DISTANCE] * tpf;
        distance += distanceChange;
        distance += offsetMoves[DISTANCE];

        tilt += maxSpeedPerSecondOfAccell[TILT] * accelTime[TILT] * tpf + offsetMoves[TILT];
        rot += maxSpeedPerSecondOfAccell[ROTATE] * accelTime[ROTATE] * tpf + offsetMoves[ROTATE];

        distance = clamp(minValue[DISTANCE], distance, maxValue[DISTANCE]);
        rot = clamp(minValue[ROTATE], rot%(FastMath.PI*2), maxValue[ROTATE]);
        tilt = clamp(minValue[TILT], tilt, maxValue[TILT]);

        double offX = maxSpeedPerSecondOfAccell[SIDE] * accelTime[SIDE] * tpf + offsetMoves[SIDE];
        double offY = maxSpeedPerSecondOfAccell[FWD] * accelTime[FWD] * tpf + offsetMoves[FWD];

        float sinRot = FastMath.sin(rot);
        float cosRot = FastMath.cos(rot);
        float cosTilt = FastMath.cos(tilt);
        float sinTilt = FastMath.sin(tilt);
        
        
        center.x += offX * cosRot + offY * sinRot;
        if (up == UpVector.Y_UP) {
            center.z += offX * -sinRot + offY * cosRot;
        } else {
            center.y += offX * -sinRot + offY * cosRot;
        }

        if (centerBounds != null) {
            //TODO: clamp center to bounds
        }

        if (up == UpVector.Y_UP) {
            position.x = center.x + (float) (distance * cosTilt * sinRot);
            position.y = center.y + (float) (distance * sinTilt);
            position.z = center.z + (float) (distance * cosTilt * cosRot);
            if (heightProvider != null) {
                float h = heightProvider.getHeight(tempVec2.set(position.x,position.z));
                if (position.y < h) {
                    position.y = h;
                }
            }
        } else {
            position.x = center.x + (float) (distance * cosTilt * sinRot);
            position.y = center.y + (float) (distance * cosTilt * cosRot);
            position.z = center.z + (float) (distance * sinTilt);
            if (heightProvider != null) {
                float h = heightProvider.getHeight(tempVec2.set(position.x,position.y));
                if (position.z < h) {
                    position.z = h;
                }
            }
        }

        for (int i = 0; i < offsetMoves.length; i++) {
            offsetMoves[i] = 0;
        }

        if (oldPosition.equals(position) && oldCenter.equals(center)) {
            return;
        }
        
        if (cameraBounds != null) {
            //TODO: clamp position to bounds
        }

        cam.setLocation(position);
        cam.lookAt(center, up.upVector);

        oldPosition.set(position);
        oldCenter.set(center);
        
    }

    private static float clamp(float min, float value, float max) {
        if (value < min) {
            return min;
        } else if (value > max) {
            return max;
        } else {
            return value;
        }
    }

    public float getMaxSpeed(DoF dg) {
        return maxSpeedPerSecondOfAccell[dg.ordinal()];
    }

    public float getMinValue(DoF dg) {
        return minValue[dg.ordinal()];
    }

    public float getMaxValue(DoF dg) {
        return maxValue[dg.ordinal()];
    }

    /**
     * SIDE and FWD min/max values are ignored
     * 
     * @param dg
     * @param min
     * @param max
     */
    public void setMinMaxValues(DoF dg, float min, float max) {
        minValue[dg.ordinal()] = min;
        maxValue[dg.ordinal()] = max;
    }

    public Vector3f getPosition() {
        return position;
    }

    public void setCenter(Vector3f center) {
        this.center.set(center);
    }

    public Vector3f getCenter() {
        return center;
    }

    public float getDistance() {
        return distance;
    }

    public float getRot() {
        return rot;
    }

    public float getTilt() {
        return tilt;
    }

    public void setDistance(float distance) {
        this.distance = distance;
    }

    public void setRot(float rot) {
        this.rot = rot;
    }

    public void setTilt(float tilt) {
        this.tilt = tilt;
    }

    public Camera getCamera() {
        return cam;
    }

    private void registerWithInput(InputManager inputManager) {
        this.inputManager = inputManager;

        if (up == UpVector.Y_UP) {
            inputManager.addMapping("-SIDE", new KeyTrigger(KeyInput.KEY_A));
            inputManager.addMapping("+SIDE", new KeyTrigger(KeyInput.KEY_D));
            inputManager.addMapping("+ROTATE", new KeyTrigger(KeyInput.KEY_Q));
            inputManager.addMapping("-ROTATE", new KeyTrigger(KeyInput.KEY_E));
        } else {
            inputManager.addMapping("+SIDE", new KeyTrigger(KeyInput.KEY_A));
            inputManager.addMapping("-SIDE", new KeyTrigger(KeyInput.KEY_D));
            inputManager.addMapping("-ROTATE", new KeyTrigger(KeyInput.KEY_Q));
            inputManager.addMapping("+ROTATE", new KeyTrigger(KeyInput.KEY_E));
        }

        inputManager.addMapping("+FWD", new KeyTrigger(KeyInput.KEY_S));
        inputManager.addMapping("-FWD", new KeyTrigger(KeyInput.KEY_W));

        inputManager.addMapping("+TILT", new KeyTrigger(KeyInput.KEY_R));
        inputManager.addMapping("-TILT", new KeyTrigger(KeyInput.KEY_F));
        inputManager.addMapping("-DISTANCE", new KeyTrigger(KeyInput.KEY_Z));
        inputManager.addMapping("+DISTANCE", new KeyTrigger(KeyInput.KEY_X));

        inputManager.addMapping("-WHEEL", new MouseAxisTrigger(MouseInput.AXIS_WHEEL, false));
        inputManager.addMapping("+WHEEL", new MouseAxisTrigger(MouseInput.AXIS_WHEEL, true));

        inputManager.addMapping("-MOUSEX", new MouseAxisTrigger(MouseInput.AXIS_X, false));
        inputManager.addMapping("+MOUSEX", new MouseAxisTrigger(MouseInput.AXIS_X, true));
        inputManager.addMapping("-MOUSEY", new MouseAxisTrigger(MouseInput.AXIS_Y, false));
        inputManager.addMapping("+MOUSEY", new MouseAxisTrigger(MouseInput.AXIS_Y, true));

        inputManager.addMapping("BUTTON1", new MouseButtonTrigger(MouseInput.BUTTON_LEFT));
        inputManager.addMapping("BUTTON2", new MouseButtonTrigger(MouseInput.BUTTON_MIDDLE));
        inputManager.addMapping("BUTTON3", new MouseButtonTrigger(MouseInput.BUTTON_RIGHT));

        inputManager.addListener(listener, mappings);
    }

    @Override
    public void cleanup() {
        super.cleanup();

        for (String mapping : mappings) {
            if (inputManager.hasMapping(mapping)) {
                inputManager.deleteMapping(mapping);
            }
        }
        inputManager.removeListener(listener);
    }

    private class InternalListener implements ActionListener, AnalogListener {

        public void onAction(String name, boolean isPressed, float tpf) {
            if (!isEnabled()) {
                return;
            }

            int press = isPressed ? 1 : 0;

            if (name.contains("WHEEL") || name.contains("MOUSE")) {
                return;
            }

            if (name.equals(mouseRotationButton)) {
                mouseRotation = isPressed;
                inputManager.setCursorVisible(!mouseDrag && !mouseRotation);
                return;
            }

            if (name.equals(mouseDragButton)) {
                mouseDrag = isPressed;
                inputManager.setCursorVisible(!mouseDrag && !mouseRotation);
                return;
            }

            char sign = name.charAt(0);
            if (sign == '-') {
                press = -press;
            } else if (sign != '+') {
                return;
            }

            DoF deg = DoF.valueOf(name.substring(1));
            direction[deg.ordinal()] = press;
        }

        @Override
        public void onAnalog(String name, float value, float tpf) {
            if (!isEnabled()) {
                return;
            }

            if (!name.contains("WHEEL") && !name.contains("MOUSE")) {
                return;
            }

            char sign = name.charAt(0);
            if (sign == '-') {
                value = -value;
            } else if (sign != '+') {
                return;
            }

            if (name.contains("WHEEL")) {
                if (!wheelEnabled) {
                    return;
                }
                float speed = maxSpeedPerSecondOfAccell[DISTANCE] * maxAccellPeriod[DISTANCE] * WHEEL_SPEED;
                offsetMoves[DISTANCE] += value * speed;
            } else if (name.contains("MOUSE")) {
                if (mouseRotation) {
                    int direction;
                    if (name.endsWith("X")) {
                        direction = ROTATE;
                        if ( up == UpVector.Z_UP ) {
                            value = -value;
                        }
                    } else {
                        direction = TILT;
                    }
                    offsetMoves[direction] += value;
                } else if (mouseDrag) {
                    int direction;
                    if (name.endsWith("X")) {
                        direction = SIDE;
                        if ( up == UpVector.Z_UP ) {
                            value = -value;
                        }
                    } else {
                        direction = FWD;
                        value = -value;
                    }
                    offsetMoves[direction] += value * maxSpeedPerSecondOfAccell[direction] * maxAccellPeriod[direction];
                }
            }

        }
    }

}

You should still remove all these lines from simpleUpdate():

rootNode.updateGeometricState();
bulletAppState.update(tpf);
myCam.update(tpf);

I have a new problem:

This is the code for the main class: Nothing changes in the RtsCam.

If you run this code, you can left mouse press button and hold, and drag to another location and the ball will move to the new location, excluding the yellow area or outside the table.

The problem is that while I can see the solid physics body with the physics debug enabled, I noticed that when you move the ball, the physics cube that you can see at the beginning of the scene, does not move with the ball.

Is that something wrong, or do I have to make the rigidbodycontrol of the ball moveable?

package mygame;

import com.jme3.app.SimpleApplication;
import com.jme3.bullet.BulletAppState;
import com.jme3.bullet.collision.shapes.CollisionShape;
import com.jme3.bullet.control.RigidBodyControl;
import com.jme3.bullet.util.CollisionShapeFactory;
import com.jme3.collision.CollisionResult;
import com.jme3.collision.CollisionResults;
import com.jme3.input.MouseInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.MouseButtonTrigger;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Ray;
import com.jme3.math.Vector3f;
import com.jme3.renderer.queue.RenderQueue;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
import com.jme3.scene.shape.Box;
import com.jme3.scene.shape.Sphere;
import com.jme3.util.SkyFactory;
import mygame.CameraMode.RtsCam;

/**
 * test
 * @author normenhansen
 */
public class Main extends SimpleApplication {


    public static void main(String[] args){
        Main app = new Main();
        app.start();
    }

    private RtsCam myCam;

    private Node targetPool = new Node("Targetable");
    
    private Node currentTable = new Node("CurrentTable");

    //Node chessTable = new Node("ChessTable");

    private Vector3f blockSize = new Vector3f(10f, 1f, 10f);
    
    private BulletAppState bulletAppState;

    Geometry solidObject;
    
    private String selectedBoxA = "", selectedBoxB = "";

    @Override
    public void simpleInitApp() {

        bulletAppState = new BulletAppState();

        stateManager.attach(bulletAppState);
        
        bulletAppState.setDebugEnabled(true);
                
        flyCam.setEnabled(false);
        
        setDisplayFps(false);
        setDisplayStatView(false);      

        Spatial mySky = SkyFactory.createSky(assetManager, "Textures/Sky/Bright/BrightSky.dds", false);

        mySky.setName("Sky");

        mySky.setQueueBucket(RenderQueue.Bucket.Sky);

        mySky.setCullHint(Spatial.CullHint.Never);

        Spatial myTerrain = assetManager.loadModel("Scenes/myTerrainScene.j3o");

        Material myTerrainMats = new Material(assetManager, "Common/MatDefs/Misc/ColoredTextured.j3md");

        myTerrainMats.setTexture("ColorMap", assetManager.loadTexture("Textures/dirt.jpg"));

        myTerrain.setMaterial(myTerrainMats);

        myTerrain.setName("Ground");

        RigidBodyControl myTerrain_phy = new RigidBodyControl(0.0f);

        myTerrain.addControl(myTerrain_phy);
        
        bulletAppState.getPhysicsSpace().add(myTerrain_phy);

        myCam = new RtsCam(RtsCam.UpVector.Y_UP);

        myCam.setDistance(265);

        stateManager.attach(myCam);

        currentTable.attachChild(makeTable("Table0", 70, 70, 2, 2, true, bulletAppState));

        ///creating the solid object
        solidObject = new Geometry("Sphere", new Sphere(30, 30, 10f));
        Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
        mat.setColor("Color", ColorRGBA.Blue);
        solidObject.setMaterial(mat);
      
        solidObject.setLocalTranslation(currentTable.getChild("Bx11").getLocalTranslation().x, currentTable.getChild("Bx11").getLocalTranslation().y+10, currentTable.getChild("Bx11").getLocalTranslation().z);

        CollisionShape collisionShape = CollisionShapeFactory.createBoxShape(solidObject);
        RigidBodyControl solid_phy = new RigidBodyControl(collisionShape, 0f);
        solidObject.addControl(solid_phy);

        bulletAppState.getPhysicsSpace().add(solid_phy);


        ///attaching the solidObject to the table node
        currentTable.attachChild(solidObject);
        currentTable.attachChild(myTerrain);
       
        
        targetPool.attachChild(currentTable);
        
        rootNode.attachChild(mySky);
        rootNode.attachChild(myTerrain);
        rootNode.attachChild(targetPool);
        rootNode.attachChild(solidObject);
        
        initMark();
                
        inputManager.addMapping("LeftMouseButton", new MouseButtonTrigger(MouseInput.BUTTON_LEFT));
        inputManager.addMapping("RightMouseButton", new MouseButtonTrigger(MouseInput.BUTTON_RIGHT));

        inputManager.addListener(mouseSelectionEvent, "LeftMouseButton", "RightMouseButton");

    }
   
    CollisionResults collisionState;
    private boolean leftMouseButtonDraggable = true;
    private boolean rightMouseButtonDraggable = true;

    @Override
    public void simpleUpdate(float tpf){

        //rootNode.updateGeometricState();

        //bulletAppState.update(tpf);

        //myCam.update(tpf);

        Vector3f origin    = cam.getWorldCoordinates(inputManager.getCursorPosition(), 0.0f);
 
        Vector3f direction = cam.getWorldCoordinates(inputManager.getCursorPosition(), 0.3f);
 
        direction.subtractLocal(origin).normalizeLocal();

        Ray ray = new Ray(origin, direction);
 
        collisionState = new CollisionResults();
 
        targetPool.collideWith(ray, collisionState);

        if (collisionState.size() > 0) {

            CollisionResult closest = collisionState.getClosestCollision();

            mark.setLocalTranslation(closest.getContactPoint());

            mark.setMaterial(closest.getGeometry().getMaterial());

            rootNode.attachChild(mark);

            if(leftMouseButtonPressed){
    
                if(leftMouseButtonDraggable){
                    selectedBoxA = closest.getGeometry().getName();
                    leftMouseButtonDraggable = false;
                } else {
                    //drawLineFromTo(currentTable, selectedBoxA, closest.getGeometry().getName(), "Bx");
                }

            } else {
                selectedBoxB = closest.getGeometry().getName();
                //System.out.println("Left Mouse Button Released Over: " + closest.getGeometry().getName());
                moveObject(currentTable, solidObject, selectedBoxA, selectedBoxB, "Bx");
                selectedBoxB = "";
                selectedBoxA = "";
                leftMouseButtonDraggable = true;
            }
            if(rightMouseButtonPressed){
    
                if(rightMouseButtonDraggable){
                    
                    if(!leftMouseButtonDraggable){


                        leftMouseButtonDraggable = true;
                    }

                    rightMouseButtonDraggable = false;
                } else {
                    //System.out.println("Left Mouse Button Pressed Over: " + closest.getGeometry().getName());
                }

            } else {
                //System.out.println("Left Mouse Button Released Over: " + closest.getGeometry().getName());
                rightMouseButtonDraggable = true;
            }
        } else {

            rootNode.detachChild(mark);
 
        }

    }

    private Geometry mark;

    protected void initMark() {
 
        Sphere sphere = new Sphere(30, 30, 0.2f);
 
        mark = new Geometry("BOOM!", sphere);
 
        Material mark_mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
 
        mark_mat.setColor("Color", ColorRGBA.Red);
 
        mark.setMaterial(mark_mat);
 
    }

    private boolean leftMouseButtonPressed = false;
    private boolean rightMouseButtonPressed = false;

    private ActionListener mouseSelectionEvent = new ActionListener(){

        public void onAction(String e, boolean isPressed, float tpf) {
            if(e.equals("LeftMouseButton")){
                leftMouseButtonPressed = isPressed;
            } else if(e.equals("RightMouseButton")){
                rightMouseButtonPressed = isPressed;
            }
        }
    
    };

    private boolean moveObject(Node table, Spatial obj, String boxA, String boxB, String boxIdentifier){
        
        if(table!=null){
            if(boxA!=null&&boxB!=null&&boxIdentifier!=null){
                if(!boxA.equals("")&&!boxB.equals("")&&!boxIdentifier.equals("")){
                    if(boxA.substring(0, boxIdentifier.length()).equals(boxIdentifier)&&boxB.substring(0, boxIdentifier.length()).equals(boxIdentifier)){
                        obj.setLocalTranslation(table.getChild(boxB).getLocalTranslation());
                    }
                }
            }
        }
        return false;
    }

    private Node makeTable(String nodeName, float xOffset, float yOffset, float xSeparation, float ySeparation, boolean withBorder, BulletAppState bAppState){
        Node table = new Node(nodeName);
        if(withBorder){
            for(int z = 1; z <= 9; z++){
                for(int x = 1; x <= 9; x++){
                    Geometry block = null;
                    if(x==1&&z==1){
                        block = new Geometry("Bz"+(x)+""+(z), new Box(blockSize.x, blockSize.y, blockSize.z));
                        Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
                        block.setLocalTranslation(xOffset-blockSize.x*(x-1)*xSeparation, 1, yOffset-blockSize.z*(z-1)*ySeparation);
                        mat.setColor("Color", ColorRGBA.Yellow);
                        block.setMaterial(mat);
                    } else if(x>=2&&x<=9&&z==1){
                        block = new Geometry("Bz"+(x)+""+(z), new Box(blockSize.x, blockSize.y, blockSize.z));
                        Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
                        block.setLocalTranslation(xOffset-blockSize.x*(x-1)*xSeparation, 1, yOffset-blockSize.z*(z-1)*ySeparation);
                        mat.setColor("Color", ColorRGBA.Yellow);
                        block.setMaterial(mat);
                    } else if(x==1&&z>=2&&z<=9){
                        block = new Geometry("Bz"+(x)+""+(z), new Box(blockSize.x, blockSize.y, blockSize.z));
                        Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
                        block.setLocalTranslation(xOffset-blockSize.x*(x-1)*xSeparation, 1, yOffset-blockSize.z*(z-1)*ySeparation);
                        mat.setColor("Color", ColorRGBA.Yellow);
                        block.setMaterial(mat);
                    } else if(x>=2&&z>=2&&x<=9&&z<=9){
                        block = new Geometry("Bx"+(x-1)+""+(z-1), new Box(blockSize.x, blockSize.y, blockSize.z));
                        Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
                        block.setLocalTranslation(xOffset-blockSize.x*(x-1)*xSeparation, 1, yOffset-blockSize.z*(z-1)*ySeparation);
                        if(x%2==1&&z%2==1){
                            mat.setColor("Color", ColorRGBA.DarkGray);
                            block.setMaterial(mat);
                        } else if(x%2==0&&z%2==1){
                            mat.setColor("Color", ColorRGBA.White);
                            block.setMaterial(mat);
                        } else if(x%2==1&&z%2==0){
                            mat.setColor("Color", ColorRGBA.White);
                            block.setMaterial(mat);
                        } else if(x%2==0&&z%2==0){
                            mat.setColor("Color", ColorRGBA.DarkGray);
                            block.setMaterial(mat);
                        }
                    }
                    table.attachChild(block);
                }
            }
        } else {
            for(int z = 1; z <= 8; z++){
                for(int x = 1; x <= 8; x++){
                    Geometry block = new Geometry("Bx"+x+""+z, new Box(blockSize.x, blockSize.y, blockSize.z));
                    Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
                    block.setLocalTranslation(xOffset-blockSize.x*(x-1)*xSeparation, 1, yOffset-blockSize.z*(z-1)*ySeparation);
                    if(x%2==1&&z%2==1){
                        mat.setColor("Color", ColorRGBA.DarkGray);
                        block.setMaterial(mat);
                    } else if(x%2==0&&z%2==1){
                        mat.setColor("Color", ColorRGBA.White);
                        block.setMaterial(mat);
                    } else if(x%2==1&&z%2==0){
                        mat.setColor("Color", ColorRGBA.White);
                        block.setMaterial(mat);
                    } else if(x%2==0&&z%2==0){
                        mat.setColor("Color", ColorRGBA.DarkGray);
                        block.setMaterial(mat);
                    }
                    table.attachChild(block);
                }
            }
        }

        //making the table solid
        if(bAppState!=null){
            CollisionShape collisionShape = CollisionShapeFactory.createBoxShape(table);
            RigidBodyControl rbody = new RigidBodyControl(collisionShape, 0.0f);
            table.addControl(rbody);
            bAppState.getPhysicsSpace().add(rbody);
        }

        return table;
    }

}

The rigidbody defines where your geometry is, yes. You could set it to kinematic mode to have it the other way around while you move it.

point me to a tutorial on kinematic mode?

type yourRigidBodyName.setKinem[Ctrl-Space]

I can move the rigid sphere, but when I set it to a y axis height of (N) above the new square location, the sphere still stays in position, it is not falling.

I even applied a mass of (1f), but the sphere does not follow gravity course.

here is code:

package mygame;

import com.jme3.app.SimpleApplication;
import com.jme3.bullet.BulletAppState;
import com.jme3.bullet.collision.shapes.CollisionShape;
import com.jme3.bullet.control.RigidBodyControl;
import com.jme3.bullet.util.CollisionShapeFactory;
import com.jme3.collision.CollisionResult;
import com.jme3.collision.CollisionResults;
import com.jme3.input.MouseInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.MouseButtonTrigger;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Ray;
import com.jme3.math.Vector3f;
import com.jme3.renderer.queue.RenderQueue;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
import com.jme3.scene.shape.Box;
import com.jme3.scene.shape.Sphere;
import com.jme3.util.SkyFactory;
import mygame.CameraMode.RtsCam;

/**
 * test
 * @author normenhansen
 */
public class Main extends SimpleApplication {


    public static void main(String[] args){
        Main app = new Main();
        app.start();
    }

    private RtsCam myCam;

    private Node targetPool = new Node("Targetable");
    
    private Node currentTable = new Node("CurrentTable");

    //Node chessTable = new Node("ChessTable");

    private Vector3f blockSize = new Vector3f(10f, 1f, 10f);
    
    private BulletAppState bulletAppState;

    Geometry solidObject;
    
    private String selectedBoxA = "", selectedBoxB = "";

    @Override
    public void simpleInitApp() {

        bulletAppState = new BulletAppState();

        stateManager.attach(bulletAppState);
        
        bulletAppState.setDebugEnabled(true);
                
        flyCam.setEnabled(false);
        
        setDisplayFps(false);
        setDisplayStatView(false);      

        Spatial mySky = SkyFactory.createSky(assetManager, "Textures/Sky/Bright/BrightSky.dds", false);

        mySky.setName("Sky");

        mySky.setQueueBucket(RenderQueue.Bucket.Sky);

        mySky.setCullHint(Spatial.CullHint.Never);

        Spatial myTerrain = assetManager.loadModel("Scenes/myTerrainScene.j3o");

        Material myTerrainMats = new Material(assetManager, "Common/MatDefs/Misc/ColoredTextured.j3md");

        myTerrainMats.setTexture("ColorMap", assetManager.loadTexture("Textures/dirt.jpg"));

        myTerrain.setMaterial(myTerrainMats);

        myTerrain.setName("Ground");

        RigidBodyControl myTerrain_phy = new RigidBodyControl(0.0f);

        myTerrain.addControl(myTerrain_phy);
        
        bulletAppState.getPhysicsSpace().add(myTerrain_phy);

        myCam = new RtsCam(RtsCam.UpVector.Y_UP);

        myCam.setDistance(265);

        stateManager.attach(myCam);

        currentTable.attachChild(makeTable("Table0", 70, 70, 2, 2, true, bulletAppState));

        ///creating the solid object
        solidObject = new Geometry("Sphere", new Sphere(30, 30, 10f));
        Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
        mat.setColor("Color", ColorRGBA.Blue);
        solidObject.setMaterial(mat);
      
        solidObject.setLocalTranslation(currentTable.getChild("Bx11").getLocalTranslation().x, currentTable.getChild("Bx11").getLocalTranslation().y+10, currentTable.getChild("Bx11").getLocalTranslation().z);

        CollisionShape collisionShape = CollisionShapeFactory.createBoxShape(solidObject);
        RigidBodyControl solid_phy = new RigidBodyControl(collisionShape, 1f);
        solid_phy.setKinematic(true);
        solidObject.addControl(solid_phy);

        bulletAppState.getPhysicsSpace().add(solid_phy);


        ///attaching the solidObject to the table node
        currentTable.attachChild(solidObject);
        currentTable.attachChild(myTerrain);
       
        
        targetPool.attachChild(currentTable);
        
        rootNode.attachChild(mySky);
        rootNode.attachChild(myTerrain);
        rootNode.attachChild(targetPool);
        rootNode.attachChild(solidObject);
        
        initMark();
                
        inputManager.addMapping("LeftMouseButton", new MouseButtonTrigger(MouseInput.BUTTON_LEFT));
        inputManager.addMapping("RightMouseButton", new MouseButtonTrigger(MouseInput.BUTTON_RIGHT));

        inputManager.addListener(mouseSelectionEvent, "LeftMouseButton", "RightMouseButton");

    }
   
    CollisionResults collisionState;
    private boolean leftMouseButtonDraggable = true;
    private boolean rightMouseButtonDraggable = true;

    @Override
    public void simpleUpdate(float tpf){

        //rootNode.updateGeometricState();

        //bulletAppState.update(tpf);

        //myCam.update(tpf);

        Vector3f origin    = cam.getWorldCoordinates(inputManager.getCursorPosition(), 0.0f);
 
        Vector3f direction = cam.getWorldCoordinates(inputManager.getCursorPosition(), 0.3f);
 
        direction.subtractLocal(origin).normalizeLocal();

        Ray ray = new Ray(origin, direction);
 
        collisionState = new CollisionResults();
 
        targetPool.collideWith(ray, collisionState);

        if (collisionState.size() > 0) {

            CollisionResult closest = collisionState.getClosestCollision();

            mark.setLocalTranslation(closest.getContactPoint());

            mark.setMaterial(closest.getGeometry().getMaterial());

            rootNode.attachChild(mark);

            if(leftMouseButtonPressed){
    
                if(leftMouseButtonDraggable){
                    selectedBoxA = closest.getGeometry().getName();
                    leftMouseButtonDraggable = false;
                } else {
                    //drawLineFromTo(currentTable, selectedBoxA, closest.getGeometry().getName(), "Bx");
                }

            } else {
                selectedBoxB = closest.getGeometry().getName();
                //System.out.println("Left Mouse Button Released Over: " + closest.getGeometry().getName());
                moveObject(currentTable, solidObject, selectedBoxA, selectedBoxB, "Bx");
                selectedBoxB = "";
                selectedBoxA = "";
                leftMouseButtonDraggable = true;
            }
            if(rightMouseButtonPressed){
    
                if(rightMouseButtonDraggable){
                    
                    if(!leftMouseButtonDraggable){


                        leftMouseButtonDraggable = true;
                    }

                    rightMouseButtonDraggable = false;
                } else {
                    //System.out.println("Left Mouse Button Pressed Over: " + closest.getGeometry().getName());
                }

            } else {
                //System.out.println("Left Mouse Button Released Over: " + closest.getGeometry().getName());
                rightMouseButtonDraggable = true;
            }
        } else {

            rootNode.detachChild(mark);
 
        }

    }

    private Geometry mark;

    protected void initMark() {
 
        Sphere sphere = new Sphere(30, 30, 0.2f);
 
        mark = new Geometry("BOOM!", sphere);
 
        Material mark_mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
 
        mark_mat.setColor("Color", ColorRGBA.Red);
 
        mark.setMaterial(mark_mat);
 
    }

    private boolean leftMouseButtonPressed = false;
    private boolean rightMouseButtonPressed = false;

    private ActionListener mouseSelectionEvent = new ActionListener(){

        public void onAction(String e, boolean isPressed, float tpf) {
            if(e.equals("LeftMouseButton")){
                leftMouseButtonPressed = isPressed;
            } else if(e.equals("RightMouseButton")){
                rightMouseButtonPressed = isPressed;
            }
        }
    
    };

    private boolean moveObject(Node table, Spatial obj, String boxA, String boxB, String boxIdentifier){
        
        if(table!=null){
            if(boxA!=null&&boxB!=null&&boxIdentifier!=null){
                if(!boxA.equals("")&&!boxB.equals("")&&!boxIdentifier.equals("")){
                    if(boxA.substring(0, boxIdentifier.length()).equals(boxIdentifier)&&boxB.substring(0, boxIdentifier.length()).equals(boxIdentifier)){
                        if(!boxA.equals(boxB)){
                            Vector3f v = table.getChild(boxB).getLocalTranslation();
                            obj.setLocalTranslation(v.x, v.y+30, v.z);
                        }
                    }
                }
            }
        }
        return false;
    }

    private Node makeTable(String nodeName, float xOffset, float yOffset, float xSeparation, float ySeparation, boolean withBorder, BulletAppState bAppState){
        Node table = new Node(nodeName);
        if(withBorder){
            for(int z = 1; z <= 9; z++){
                for(int x = 1; x <= 9; x++){
                    Geometry block = null;
                    if(x==1&&z==1){
                        block = new Geometry("Bz"+(x)+""+(z), new Box(blockSize.x, blockSize.y, blockSize.z));
                        Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
                        block.setLocalTranslation(xOffset-blockSize.x*(x-1)*xSeparation, 1, yOffset-blockSize.z*(z-1)*ySeparation);
                        mat.setColor("Color", ColorRGBA.Yellow);
                        block.setMaterial(mat);
                    } else if(x>=2&&x<=9&&z==1){
                        block = new Geometry("Bz"+(x)+""+(z), new Box(blockSize.x, blockSize.y, blockSize.z));
                        Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
                        block.setLocalTranslation(xOffset-blockSize.x*(x-1)*xSeparation, 1, yOffset-blockSize.z*(z-1)*ySeparation);
                        mat.setColor("Color", ColorRGBA.Yellow);
                        block.setMaterial(mat);
                    } else if(x==1&&z>=2&&z<=9){
                        block = new Geometry("Bz"+(x)+""+(z), new Box(blockSize.x, blockSize.y, blockSize.z));
                        Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
                        block.setLocalTranslation(xOffset-blockSize.x*(x-1)*xSeparation, 1, yOffset-blockSize.z*(z-1)*ySeparation);
                        mat.setColor("Color", ColorRGBA.Yellow);
                        block.setMaterial(mat);
                    } else if(x>=2&&z>=2&&x<=9&&z<=9){
                        block = new Geometry("Bx"+(x-1)+""+(z-1), new Box(blockSize.x, blockSize.y, blockSize.z));
                        Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
                        block.setLocalTranslation(xOffset-blockSize.x*(x-1)*xSeparation, 1, yOffset-blockSize.z*(z-1)*ySeparation);
                        if(x%2==1&&z%2==1){
                            mat.setColor("Color", ColorRGBA.DarkGray);
                            block.setMaterial(mat);
                        } else if(x%2==0&&z%2==1){
                            mat.setColor("Color", ColorRGBA.White);
                            block.setMaterial(mat);
                        } else if(x%2==1&&z%2==0){
                            mat.setColor("Color", ColorRGBA.White);
                            block.setMaterial(mat);
                        } else if(x%2==0&&z%2==0){
                            mat.setColor("Color", ColorRGBA.DarkGray);
                            block.setMaterial(mat);
                        }
                    }
                    table.attachChild(block);
                }
            }
        } else {
            for(int z = 1; z <= 8; z++){
                for(int x = 1; x <= 8; x++){
                    Geometry block = new Geometry("Bx"+x+""+z, new Box(blockSize.x, blockSize.y, blockSize.z));
                    Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
                    block.setLocalTranslation(xOffset-blockSize.x*(x-1)*xSeparation, 1, yOffset-blockSize.z*(z-1)*ySeparation);
                    if(x%2==1&&z%2==1){
                        mat.setColor("Color", ColorRGBA.DarkGray);
                        block.setMaterial(mat);
                    } else if(x%2==0&&z%2==1){
                        mat.setColor("Color", ColorRGBA.White);
                        block.setMaterial(mat);
                    } else if(x%2==1&&z%2==0){
                        mat.setColor("Color", ColorRGBA.White);
                        block.setMaterial(mat);
                    } else if(x%2==0&&z%2==0){
                        mat.setColor("Color", ColorRGBA.DarkGray);
                        block.setMaterial(mat);
                    }
                    table.attachChild(block);
                }
            }
        }

        //making the table solid
        if(bAppState!=null){
            CollisionShape collisionShape = CollisionShapeFactory.createBoxShape(table);
            RigidBodyControl rbody = new RigidBodyControl(collisionShape, 0.0f);
            table.addControl(rbody);
            bAppState.getPhysicsSpace().add(rbody);
        }

        return table;
    }

}


Because its still in kinematic mode I suppose. Again, read the javadoc of setKinematicSpatial.

Without changing the last code I posted:

Now there is something wrong with the collision:

I am getting this warning: warning CollisionDispatcher.needsCollision: static-static collision!

Do you have any idea what that means, and could you fix it?

Unfortunately there is no line number where I can place the error to be coming from.

Its a warning, not an error. It basically means that you will be able to move the kinematic object though the static meshes in your scene while you move it.