Physics Collision Groups not working on android?

Hi folks, I’m not sure if this a bug of if I’m doing something wrong…all I know is the same code appears to work correctly on the Desktop, but on android the collisions never occur. Turning on the Debug flag, I see the Collision objects are being rendered on both android&Desktop.

If I do not add the ‘static’ objects below to the 2nd CollisionGroup, and remove from the default…the collisions occur properly on Android…but…obviously that causes other issues.hence the reason for trying to use a different collisionGroup.



Here is essentially what I’m doing:

// Adding static object to the world.

[java]

Vector3f halfExtents = halfExtents = new Vector3f(1.2f, 1f, 1.2f);

pobj.gc = new GhostControl(new BoxCollisionShape(halfExtents));

pobj.gc.removeCollideWithGroup(PhysicsCollisionObject.COLLISION_GROUP_01); // remove from default

pobj.gc.setCollisionGroup(PhysicsCollisionObject.COLLISION_GROUP_02); // place into group 2.

pobj.spatial.addControl(pobj.gc);

bulletAppState.getPhysicsSpace().add(pobj.gc);

[/java]

// Adding moving object to world

[java]

ball_phy = new BallPhysicsControl(500f, ball_geo);

/** Add physical ball to physics space. */

ball_geo.addControl(ball_phy);

ball_phy.addCollideWithGroup(PhysicsCollisionObject.COLLISION_GROUP_02);

bulletAppState.getPhysicsSpace().add(ball_phy);

[/java]



any thoughts? has anyone been able to confirm they do not have issues with Collision Groups on Android?

So you say its inconsistent between jbullet and bullet? Can you make a test case for this? The native bullet implementation is not finished and the collision code was contributed and hasn’t been checked fully yet. It might be the bit masks are not handled correctly.

The example below is based off the Physics Test ‘wall’.

On the desktop, everything is normal.

Loaded onto the Android, the bricks will fall right through the floor at start up.



Here is an example:



[java]

package mygame;

import com.jme3.bullet.BulletAppState;

import com.jme3.app.SimpleApplication;

import com.jme3.bullet.PhysicsSpace;

import com.jme3.bullet.collision.PhysicsCollisionObject;

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

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

import com.jme3.bullet.control.RigidBodyControl;

import com.jme3.font.BitmapText;

import com.jme3.input.KeyInput;

import com.jme3.input.MouseInput;

import com.jme3.input.controls.ActionListener;

import com.jme3.input.controls.KeyTrigger;

import com.jme3.input.controls.MouseButtonTrigger;

import com.jme3.material.Material;

import com.jme3.math.ColorRGBA;

import com.jme3.math.Vector2f;

import com.jme3.math.Vector3f;

import com.jme3.renderer.queue.RenderQueue.ShadowMode;

import com.jme3.scene.Geometry;

import com.jme3.scene.shape.Box;

import com.jme3.scene.shape.Sphere;

import com.jme3.scene.shape.Sphere.TextureMode;



/**

*

  • @author double1984

    */

    public class TestMain extends SimpleApplication {



    static float bLength = 0.48f;

    static float bWidth = 0.24f;

    static float bHeight = 0.12f;

    Material mat;

    Material mat2;

    Material mat3;

    private static Sphere bullet;

    private static Box brick;



    private BulletAppState bulletAppState;



    public static void main(String args[]) {

    TestMain f = new TestMain();

    f.start();

    }



    @Override

    public void simpleInitApp() {



    bulletAppState = new BulletAppState();

    bulletAppState.setThreadingType(BulletAppState.ThreadingType.PARALLEL);

    stateManager.attach(bulletAppState);

    bullet = new Sphere(32, 32, 0.4f, true, false);

    bullet.setTextureMode(TextureMode.Projected);

    brick = new Box(Vector3f.ZERO, bLength, bHeight, bWidth);



    initMaterial();

    initWall();

    initFloor();

    initCrossHairs();

    this.cam.setLocation(new Vector3f(0, 6f, 6f));

    cam.lookAt(Vector3f.ZERO, new Vector3f(0, 1, 0));

    cam.setFrustumFar(15);

    inputManager.addMapping(“shoot”, new MouseButtonTrigger(MouseInput.BUTTON_LEFT));

    inputManager.addListener(actionListener, “shoot”);

    inputManager.addMapping(“gc”, new KeyTrigger(KeyInput.KEY_X));

    inputManager.addListener(actionListener, “gc”);

    }



    private PhysicsSpace getPhysicsSpace() {

    return bulletAppState.getPhysicsSpace();

    }

    private ActionListener actionListener = new ActionListener() {



    public void onAction(String name, boolean keyPressed, float tpf) {

    if (name.equals(“shoot”) && !keyPressed) {

    Geometry bulletg = new Geometry(“bullet”, bullet);

    bulletg.setMaterial(mat2);

    bulletg.setLocalTranslation(cam.getLocation());

    SphereCollisionShape bulletCollisionShape = new SphereCollisionShape(0.4f);

    RigidBodyControl bulletNode = new RigidBodyControl(bulletCollisionShape, 1);



    bulletNode.addCollideWithGroup(PhysicsCollisionObject.COLLISION_GROUP_02);



    bulletNode.setLinearVelocity(cam.getDirection().mult(25));

    bulletg.addControl(bulletNode);

    rootNode.attachChild(bulletg);

    getPhysicsSpace().add(bulletNode);

    }

    if (name.equals(“gc”) && !keyPressed) {

    System.gc();

    }

    }

    };



    public void initWall() {

    float startpt = bLength / 4;

    float height = 0;

    for (int j = 0; j < 15; j++) {

    for (int i = 0; i < 4; i++) {

    Vector3f vt = new Vector3f(i * bLength * 2 + startpt, bHeight + height, 0);

    addBrick(vt);

    }

    startpt = -startpt;

    height += 2 * bHeight;

    }

    }



    public void initFloor() {

    Box floorBox = new Box(Vector3f.ZERO, 10f, 0.1f, 5f);

    floorBox.scaleTextureCoordinates(new Vector2f(3, 6));

    Geometry floor = new Geometry(“floor”, floorBox);

    floor.setMaterial(mat3);

    floor.setShadowMode(ShadowMode.Receive);

    floor.setLocalTranslation(0, -0.1f, 0);

    RigidBodyControl ctrl = new RigidBodyControl(new BoxCollisionShape(new Vector3f(10f, 0.1f, 5f)), 0);

    floor.addControl(ctrl);



    // Remove floor from group 1, and put in group 2

    //ctrl.removeCollideWithGroup(PhysicsCollisionObject.COLLISION_GROUP_01);

    //ctrl.setCollideWithGroups(PhysicsCollisionObject.COLLISION_GROUP_02);

    //ctrl.setCollisionGroup(PhysicsCollisionObject.COLLISION_GROUP_02);



    this.rootNode.attachChild(floor);

    this.getPhysicsSpace().add(floor);

    }



    public void initMaterial() {

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

    mat.setColor(“Color”, ColorRGBA.Blue);

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

    mat2.setColor(“Color”, ColorRGBA.Green);

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

    mat3.setColor(“Color”, ColorRGBA.White);

    }



    public void addBrick(Vector3f ori) {

    Geometry reBoxg = new Geometry(“brick”, brick);

    reBoxg.setMaterial(mat);

    reBoxg.setLocalTranslation(ori);

    // For geometry with sphere mesh the physics system automatically uses a sphere collision shape

    RigidBodyControl ctrl = new RigidBodyControl(0.005f);

    reBoxg.addControl(ctrl);





    ctrl.removeCollideWithGroup(PhysicsCollisionObject.COLLISION_GROUP_01);

    // put bricks into collision group 1 & 2 (brinks should now collide with floor and ‘themselves’

    // observe On android, the bricks fall through floor.

    ctrl.setCollideWithGroups(PhysicsCollisionObject.COLLISION_GROUP_01|PhysicsCollisionObject.COLLISION_GROUP_02);

    ctrl.setCollisionGroup(PhysicsCollisionObject.COLLISION_GROUP_02);



    reBoxg.getControl(RigidBodyControl.class).setFriction(0.6f);

    this.rootNode.attachChild(reBoxg);

    this.getPhysicsSpace().add(reBoxg);

    }



    protected void initCrossHairs() {

    guiFont = assetManager.loadFont(“Interface/Fonts/Default.fnt”);

    BitmapText ch = new BitmapText(guiFont, false);

    ch.setSize(guiFont.getCharSet().getRenderedSize() * 2);

    ch.setText("+"); // crosshairs

    ch.setLocalTranslation( // center

    settings.getWidth() / 2 - guiFont.getCharSet().getRenderedSize() / 3 * 2,

    settings.getHeight() / 2 + ch.getLineHeight() / 2, 0);

    guiNode.attachChild(ch);

    }

    }



    [/java]
1 Like

I also have had the same problem (I did not investigate much) on the desktop, the collision groups work ok, but on android seems to be ignored.

@danomano said:
The example below is based off the Physics Test 'wall'.
On the desktop, everything is normal.
Loaded onto the Android, the bricks will fall right through the floor at start up.

A simpler, literal test case would help more.

Yeah, sorry that was the quickest thing I could through together, this example is cleaned up more, and has all the extra stuff removed, (its still not identical to my particular case, but it show that the ctrl.setCollideWithGroups, is not behaving the same as on the desktop).



The example creates 1 floor (in group 1), and another box which in group 2 which is set to collide with groups 1 & 2.

On android it falls through the floor, on the desktop it stops when it hits the floor.



[java][/java]

package mygame;

import com.jme3.bullet.BulletAppState;

import com.jme3.app.SimpleApplication;

import com.jme3.bullet.PhysicsSpace;

import com.jme3.bullet.collision.PhysicsCollisionObject;

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

import com.jme3.bullet.control.RigidBodyControl;

import com.jme3.material.Material;

import com.jme3.math.ColorRGBA;

import com.jme3.math.Vector3f;

import com.jme3.scene.Geometry;

import com.jme3.scene.shape.Box;



public class TestMain extends SimpleApplication {



Material matBrick;

Material matFloor;



private BulletAppState bulletAppState;



public static void main(String args[]) {

TestMain f = new TestMain();

f.start();

}



@Override

public void simpleInitApp() {

bulletAppState = new BulletAppState();

stateManager.attach(bulletAppState);



initFloor(); // create box default Collision Group



addBrick(); // create 2nd box in collision group 2, set to collide with groups 1 & 2



this.cam.setLocation(new Vector3f(0, 6f, 6f));

cam.lookAt(Vector3f.ZERO, new Vector3f(0, 1, 0));

cam.setFrustumFar(15);

}



private PhysicsSpace getPhysicsSpace() {

return bulletAppState.getPhysicsSpace();

}



public void initFloor() {

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

matFloor.setColor(“Color”, ColorRGBA.White);



Box floorBox = new Box(Vector3f.ZERO, 10f, 0.1f, 5f);

Geometry floor = new Geometry(“floor”, floorBox);

floor.setMaterial(matFloor);

floor.setLocalTranslation(0, -0.1f, 0);

RigidBodyControl ctrl = new RigidBodyControl(new BoxCollisionShape(new Vector3f(10f, 0.1f, 5f)), 0);

floor.addControl(ctrl);



this.rootNode.attachChild(floor);

this.getPhysicsSpace().add(floor);

}





public void addBrick() {

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

matBrick.setColor(“Color”, ColorRGBA.Blue);



Box brick = new Box(Vector3f.ZERO, 0.5f, 0.5f, 0.5f);

Geometry geo = new Geometry(“brick”, brick);

geo.setMaterial(matBrick);

geo.setLocalTranslation(new Vector3f(0f,3,0f));

RigidBodyControl ctrl = new RigidBodyControl(0.005f);

geo.addControl(ctrl);



/////////////// CODE OF INTEREST ///////////////

/// PUT BOX IN GROUP 2, AND SET TO COLLIDE WITH GROUPS 1 & 2

ctrl.removeCollideWithGroup(PhysicsCollisionObject.COLLISION_GROUP_01);

ctrl.setCollisionGroup(PhysicsCollisionObject.COLLISION_GROUP_02);



ctrl.setCollideWithGroups(PhysicsCollisionObject.COLLISION_GROUP_01|

PhysicsCollisionObject.COLLISION_GROUP_02);

//////////////////////////////////////////////////////////////



this.rootNode.attachChild(geo);

this.getPhysicsSpace().add(geo);

}

}

[java][/java]

3 Likes

Thanks very much.

I just stumbled over this problem as well, so since this doesn’t seem to be fixed yet here’s a workaround that works for me. While on the desktop it is sufficient to say that object A should collide with the group of object B, on Android you additionally have to say that object B should collide with the group of object A.
The strange thing is that I’m using jBullet, so I’d expect it to work identical on desktop and Android…

jbullet is never used for android

Oh. Could you go into more detail?
Do you mean it should not be used?

It isn’t. Unless you have butt-slow 1 fps physics on android you don’t use it. The android build replaces the jbullet libs with the native ones automatically.

1 Like

Ah great, thanks - was already wondering how that is handled since there are seperate jme3-libraries-physics and a jme3-libraries-physics-native libraries. I currently don’t use those and included the jars manually: jME3-jbullet.jar, jbullet/jbullet.jar, jbullet/stac-alloc.jar and jbullet/vecmath.jar. Everything correct?