GhostControl becomes solid in Android

Hello,
we have a problem using GhostControl on android. It might be related to the other topics about collision groups not working properly; however we have the opposite problem from http://hub.jmonkeyengine.org/forum/topic/physics-collision-groups-not-working-on-android/
We have a GhostControl, with a simple BoxCollisionShape, which simply detects when the player (a CharacterControl) crosses a certain point. On the computer this works fine and the character passes through the GhostControl box. On the android (a Samsung Galaxy SII) the GhostControl becomes solid! The character gets stuck since there’s a floating box in the way.

We constructed the basic test case of this behaviour; you can find it in the code below. Running this on the computer the red box passes through the green one; on the Android device it gets stuck.

Any thoughts? It seems unlikely that noone else has ever used GhostControl in this fashion on Android before, so are we missing something obvious? If this is a problem with the native libraries and GhostControl just can’t be pass-through like it’s supposed to, what’s another good way to check if one object is in a certain place? The end goal is to use the GhostControl for a fireball that’s flying across the screen, and have a PhysicsCollisionListener report when it hits the player and dealing damage.

[java]
package mygame;

import com.jme3.app.SimpleApplication;
import com.jme3.bullet.BulletAppState;
import com.jme3.bullet.collision.shapes.BoxCollisionShape;
import com.jme3.bullet.collision.shapes.CapsuleCollisionShape;
import com.jme3.bullet.control.CharacterControl;
import com.jme3.bullet.control.GhostControl;
import com.jme3.bullet.control.RigidBodyControl;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.renderer.RenderManager;
import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Box;

/**

  • test

  • @author jonatankilhamn
    */
    public class Main extends SimpleApplication {
    BulletAppState bulletAppState;

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

    @Override
    public void simpleInitApp() {
    bulletAppState = new BulletAppState();
    stateManager.attach(bulletAppState);
    bulletAppState.getPhysicsSpace().enableDebug(assetManager);

     /* Player */
     Box playerBox = new Box(Vector3f.ZERO, 1, 1, 1);
     Geometry player = new Geometry("Box", playerBox);
     Material mat1 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
     mat1.setColor("Color", ColorRGBA.Red);
     player.setMaterial(mat1);
     
     player.setLocalTranslation(new Vector3f(-2f,1f,0f));
     
     CharacterControl c = new CharacterControl(new CapsuleCollisionShape(2f,0.5f),1);
     c.setWalkDirection(Vector3f.UNIT_X.mult(0.03f));
     player.addControl(c);
     
     /* Floating ghost box */
     Box ghostBox = new Box(Vector3f.ZERO, 1, 1, 1);
     Geometry ghost = new Geometry("Box", ghostBox);
     Material mat2 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
     mat2.setColor("Color", ColorRGBA.Green);
     ghost.setMaterial(mat2);
    
     ghost.setLocalTranslation(new Vector3f(4f,1f,0f));
     
     GhostControl g = new GhostControl(new BoxCollisionShape(new Vector3f(1f,1f,1f)));
     ghost.addControl(g);
     
     /* Floor */
     Box floorBox = new Box(Vector3f.ZERO, 30, 1, 30);
     Geometry floor = new Geometry("Box", floorBox);
     Material mat3 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
     mat3.setColor("Color", ColorRGBA.Blue);
     floor.setMaterial(mat3);
     
     floor.setLocalTranslation(new Vector3f(0f,-4f,0f));
     
     RigidBodyControl r = new RigidBodyControl(0.0f);
     floor.addControl(r);
     
     /* Putting it together */
     rootNode.attachChild(floor);
     rootNode.attachChild(player);
     rootNode.attachChild(ghost);
     
     bulletAppState.getPhysicsSpace().addAll(rootNode);
    

    }

    @Override
    public void simpleUpdate(float tpf) {
    //TODO: add update code
    }

    @Override
    public void simpleRender(RenderManager rm) {
    //TODO: add render code
    }
    }

[/java]

There is a known problem with native bullet character control and ghost objects. I assume that you are using jBullet when you are running on the PC (the default) and native bullet when running on Android (the default).

For jBullet, a patch was applied locally to the jME copy of jBullet to remove the issue, but there has been no local patch applied to the native bullet copy jME is using.

This issue is that character control provided by bullet itself collides physically with other ghost objects which sounds exactly like what you are describing.

One alternative is to use the BetterCharacterControl class instead of the standard CharacterControl. BetterCharacterControl is a new character control class developed by @normen and does not have this issue on jBullet or native Bullet

http://hub.jmonkeyengine.org/forum/topic/bettercharactercontrol-in-the-works/

1 Like