Problems with collision detection using PhysicsGhostNode

Okey, here is my second attempt for a collision detection. I want to check if one object collide with several others without using the brute force method (loop trough a list and check all objects one on one). The problem is that I don’t understand how the area work, it seem to be bigger than the other nodes. Here is the code:



package bloxjava;



import com.jme3.app.SimpleBulletApplication;

import com.jme3.bullet.collision.shapes.BoxCollisionShape;

import com.jme3.bullet.nodes.PhysicsGhostNode;

import com.jme3.bullet.nodes.PhysicsNode;

import com.jme3.material.Material;

import com.jme3.math.ColorRGBA;

import com.jme3.math.Vector3f;

import com.jme3.scene.shape.Box;

import com.jme3.scene.Geometry;

import com.jme3.input.KeyInput;

import com.jme3.input.controls.AnalogListener;

import com.jme3.input.controls.KeyTrigger;



public class HelloCollision extends SimpleBulletApplication {

PhysicsNode player;

PhysicsGhostNode collisionChecker;



public static void main(String[] args) {

HelloCollision app = new HelloCollision();

app.start();

}



@Override

public void simpleInitApp() {

player = createBox(“Player”, new Vector3f(0, 3, 0), new Vector3f(1, 1, 1), ColorRGBA.Blue);

rootNode.attachChild(player);



PhysicsNode tmp = createBox(“Box ONE”, new Vector3f(2, 0, 0), new Vector3f(1, 1, 1), ColorRGBA.Red);

rootNode.attachChild(tmp);

getPhysicsSpace().add(tmp);



PhysicsNode tmp2 = createBox(“Box TWO”, new Vector3f(-4, 0, 0), new Vector3f(1, 1, 1), ColorRGBA.Yellow);

rootNode.attachChild(tmp2);

getPhysicsSpace().add(tmp2);



collisionChecker = new PhysicsGhostNode(new BoxCollisionShape(new Vector3f(1, 1, 1)));

rootNode.attachChild(collisionChecker);

getPhysicsSpace().add(collisionChecker);



// Create input

inputManager.addMapping(“MoveRight”, new KeyTrigger(KeyInput.KEY_L));

inputManager.addMapping(“MoveLeft”, new KeyTrigger(KeyInput.KEY_J));

inputManager.addMapping(“MoveUp”, new KeyTrigger(KeyInput.KEY_I));

inputManager.addMapping(“MoveDown”, new KeyTrigger(KeyInput.KEY_K));



inputManager.addListener(analogListener, new String[]{

“MoveRight”, “MoveLeft”, “MoveUp”, “MoveDown”

});

}



private AnalogListener analogListener = new AnalogListener() {



public void onAnalog(String name, float value, float tpf) {

if (name.equals(“MoveRight”))

player.move(10 * tpf, 0, 0);



if (name.equals(“MoveLeft”))

player.move(-10 * tpf, 0, 0);



if (name.equals(“MoveUp”))

player.move(0, 10 * tpf, 0);



if (name.equals(“MoveDown”))

player.move(0, -10 * tpf, 0);

}

};



@Override

public void simpleUpdate(float tpf) {

rootNode.updateGeometricState();



collisionChecker.setLocalTranslation(player.getLocalTranslation());

collisionChecker.updateGeometricState();



if (collisionChecker.getOverlappingCount() > 0)

System.out.println(“Hit”);

else

System.out.println(“Dont hit”);



}



//Make a box with a custom size

PhysicsNode createBox(String name, Vector3f pos, Vector3f size, ColorRGBA color)

{

Box b = new Box(Vector3f.ZERO, size);

Geometry geom = new Geometry(name, b);

Material mat = new Material(assetManager, “Common/MatDefs/Misc/SolidColor.j3md”);

mat.setColor(“m_Color”, color);

geom.setMaterial(mat);



//Used for collision

PhysicsNode pn = new PhysicsNode(geom, new BoxCollisionShape(size), 0);

pn.setLocalTranslation(pos);

pn.updateGeometricState();



return pn;

}

}

Line 75 is a no-go! Never call updateGeometricState() on a node with a parent!

But generally your code looks ok, you say the ghost node seems to be bigger than its collision shape from the results? Did you try attaching a debug shape (node.attachDebugShape(assetManager)) to verify that?

Cheers,

Normen

All physics nodes appear to be the double of the size of the geom attached to it. I tried the half the size, it fixed the size issue but the bounds are moved to the wrong place!

Well, I think there is nothing wrong with the physics nodes, it is rather something weired with the collision box.

Code:
package bloxjava;

import com.jme3.app.SimpleBulletApplication;
import com.jme3.bounding.BoundingBox;
import com.jme3.bullet.collision.shapes.BoxCollisionShape;
import com.jme3.bullet.nodes.PhysicsGhostNode;
import com.jme3.bullet.nodes.PhysicsNode;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.scene.shape.Box;
import com.jme3.scene.Geometry;
import com.jme3.input.KeyInput;
import com.jme3.input.controls.AnalogListener;
import com.jme3.input.controls.KeyTrigger;

public class HelloCollision extends SimpleBulletApplication {
//PhysicsNode player;
PhysicsGhostNode collisionChecker;

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

@Override
public void simpleInitApp() {
    //player = createBox("Player", new Vector3f(0, 3, 0), new Vector3f(1, 1, 1), ColorRGBA.Blue);
    //rootNode.attachChild(player);

    PhysicsNode tmp = createBox("Box ONE", new Vector3f(2, 0, 0), new Vector3f(1, 1, 1), ColorRGBA.Red);
    tmp.attachDebugShape(assetManager);
    rootNode.attachChild(tmp);
    getPhysicsSpace().add(tmp);

    PhysicsNode tmp2 = createBox("Box TWO", new Vector3f(-4, 0, 0), new Vector3f(1, 1, 1), ColorRGBA.Yellow);
    rootNode.attachChild(tmp2);
    tmp2.attachDebugShape(assetManager);
    getPhysicsSpace().add(tmp2);

    collisionChecker = new PhysicsGhostNode(new BoxCollisionShape(new Vector3f(0.5f, 0.5f, 0.5f)));
    collisionChecker.attachDebugShape(assetManager);
    rootNode.attachChild(collisionChecker);
    getPhysicsSpace().add(collisionChecker);

    // Create input
    inputManager.addMapping("MoveRight", new KeyTrigger(KeyInput.KEY_L));
    inputManager.addMapping("MoveLeft", new KeyTrigger(KeyInput.KEY_J));
    inputManager.addMapping("MoveUp", new KeyTrigger(KeyInput.KEY_I));
    inputManager.addMapping("MoveDown", new KeyTrigger(KeyInput.KEY_K));

    inputManager.addListener(analogListener, new String[]{
        "MoveRight", "MoveLeft", "MoveUp", "MoveDown"
    });
}

private AnalogListener analogListener = new AnalogListener() {

    public void onAnalog(String name, float value, float tpf) {
        if (name.equals("MoveRight"))
            collisionChecker.move(10 * tpf, 0, 0);

        if (name.equals("MoveLeft"))
            collisionChecker.move(-10 * tpf, 0, 0);

        if (name.equals("MoveUp"))
            collisionChecker.move(0, 10 * tpf, 0);

        if (name.equals("MoveDown"))
            collisionChecker.move(0, -10 * tpf, 0);
    }
};

@Override
public void simpleUpdate(float tpf) {
    rootNode.updateGeometricState();
    
    if (collisionChecker.getOverlappingCount() > 0)
        System.out.println("Hit");
    else
        System.out.println("Dont hit");

}

//Make a box with a custom size
PhysicsNode createBox(String name, Vector3f pos, Vector3f size, ColorRGBA color)
{
    Box b = new Box(Vector3f.ZERO, size);
    Geometry geom = new Geometry(name, b);
    Material mat = new Material(assetManager, "Common/MatDefs/Misc/SolidColor.j3md");
    mat.setColor("m_Color", color);
    geom.setMaterial(mat);
    //Used for collision
    PhysicsNode pn = new PhysicsNode(geom, new BoxCollisionShape(new Vector3f(size.x / 2, size.y / 2, size.z / 2)), 0);
    pn.setLocalTranslation(pos);
    pn.updateGeometricState();

    return pn;
}

}