Sphere falling through platform

Well I’m having numerous problems, but as the title suggests, my sphere is falling through my platform randomly. The behavior is erratic as in it does something differently if I close the app and re-open it.



Basically the ball will fall on an angled platform (both objects are spatials with RIgidBodyControls) and usually before reaching the edge of the platform will just fall through. Previous to this action I have tilted the platform (analogListener keypress) by

[java] ground.rotate(rotateSpeed,0,0);

ground.getControl(RigidBodyControl.class).setPhysicsRotation(ground.getLocalRotation().toRotationMatrix());[/java]



I set up the spacebar key to set the sphere above the platform to fall onto again (and sets angular and linear velocities to 0), if I don’t move the platform at all but it is set at the angle, the sphere usually still falls through before reaching the edge.



If you are wondering, I have been using setCcdMotionThreshold on the sphere, set to the radius of my sphere (.5f) though I tried numerous numbers. Also tried using it on the platform as well but don’t think it’s currently set (made no difference).



By the way, the platform is a ogre xml export from Blender, basically a plane with walls, though I had used a flat box shape in the past with the same falling-through problems, and I don’t think I tried that since the change to using the controllers…



Also, a separate issue, but sometimes if my sphere comes to a complete stop, it will freeze and will not move, even if I rotate the platform away from below it.



Anyway, hope someone can help me…

By the way, I am using the Jan 22 nightly.



Thanks

Let me make this easier and/or more cluttered. Here’s the whole code I have for the main class, sorry it’s a bit messy still.



[java]public class Main extends SimpleApplication {



private BulletAppState bulletAppState;



protected Spatial ground;

protected Spatial player;

protected Nifty nifty;

static Main app;

Boolean isRunning=true;

protected Vector3f stpt = new Vector3f(0,4,0);

PointLight pl;



public static void main(String[] args) {

app = new Main();

app.start();

}



@Override

public void simpleInitApp() {

bulletAppState = new BulletAppState();

stateManager.attach(bulletAppState);



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

mat.setTexture(“ColorMap”, assetManager.loadTexture(“Textures/bricks.jpg”));



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

mat2.setTexture(“ColorMap”, assetManager.loadTexture(“Textures/x.gif”));



ground = assetManager.loadModel(“Models/Cube.mesh.xml”);

//ground.setMaterial(mat);

ground.addControl(new RigidBodyControl(0));

//ground.getControl(RigidBodyControl.class).setCcdMotionThreshold(0.5f);

ground.getControl(RigidBodyControl.class).setFriction(100);

rootNode.attachChild(ground);





Sphere sph = new Sphere(32,32,.5f);

player = new Geometry(“Sphere”, sph);

player.setMaterial(mat2);



player.setLocalTranslation(stpt);

rootNode.attachChild(player);

player.addControl(new RigidBodyControl(new SphereCollisionShape(.5f),2));

player.getControl(RigidBodyControl.class).setCcdMotionThreshold(0.5f);

player.getControl(RigidBodyControl.class).setEnabled(true);







bulletAppState.getPhysicsSpace().add(ground);

bulletAppState.getPhysicsSpace().add(player);







cam.setLocation(new Vector3f(0,20,20));

cam.setDirection(new Vector3f(0,-2f,-1));

//flyCam.setDragToRotate(true);

flyCam.setEnabled(false);



initKeys();



NiftyJmeDisplay niftyDisplay = new NiftyJmeDisplay(

assetManager, inputManager, audioRenderer, guiViewPort);

nifty = niftyDisplay.getNifty();

nifty.fromXml(“Interface/rotateControl.xml”, “start”);



// attach the nifty display to the gui view port as a processor

guiViewPort.addProcessor(niftyDisplay);



DirectionalLight dl = new DirectionalLight();

dl.setColor(ColorRGBA.White.clone().multLocal(2)); // bright white light

dl.setDirection(new Vector3f(12.8f, -40.8f, -3.8f));

rootNode.addLight(dl);



pl = new PointLight();

pl.setColor(new ColorRGBA(1, 0.9f, 0.9f, 0));

pl.setPosition(new Vector3f(0f, 0f, 4f));

rootNode.addLight(pl);



}



@Override

public void simpleUpdate(float tpf) {

//TODO: add update code

//ground.getControl(RigidBodyControl.class).applyForce(new Vector3f(0,20,0), stpt);

pl.setPosition(player.getLocalTranslation());

}



@Override

public void simpleRender(RenderManager rm) {

//TODO: add render code

}





/** Custom Keybinding: Map named actions to inputs. */

private void initKeys() {

// You can map one or several inputs to one named action

inputManager.addMapping(“Pause”, new KeyTrigger(KeyInput.KEY_P));

inputManager.addMapping(“Left”, new KeyTrigger(KeyInput.KEY_A));

inputManager.addMapping(“Right”, new KeyTrigger(KeyInput.KEY_D));

inputManager.addMapping(“Backward”, new KeyTrigger(KeyInput.KEY_S));

inputManager.addMapping(“Forward”, new KeyTrigger(KeyInput.KEY_W));

inputManager.addMapping(“Space”, new KeyTrigger(KeyInput.KEY_SPACE));

// Add the names to the action listener.

inputManager.addListener(actionListener, new String[]{“Pause”, “Space”});

inputManager.addListener(analogListener, new String[]{“Left”, “Right”, “Forward”, “Backward”});



}





private ActionListener actionListener = new ActionListener() {

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

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

isRunning = !isRunning;



}

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

player.getControl(RigidBodyControl.class).setPhysicsLocation(stpt);

player.getControl(RigidBodyControl.class).setAngularVelocity(Vector3f.ZERO);

player.getControl(RigidBodyControl.class).setLinearVelocity(Vector3f.ZERO);



}

}

};



private AnalogListener analogListener = new AnalogListener() {

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

if (isRunning) {

Float rotateSpeed = 1f * tpf;



if (name.equals(“Forward”)) {

ground.rotate(-rotateSpeed,0,0);



}

if (name.equals(“Right”)) {

ground.rotate(0,0,-rotateSpeed);



}

if (name.equals(“Left”)) {

ground.rotate(0,0,rotateSpeed);



}

if (name.equals(“Backward”)) {

ground.rotate(rotateSpeed,0,0);



}

ground.getControl(RigidBodyControl.class).setPhysicsRotation(ground.getLocalRotation().toRotationMatrix());

} else {

System.out.println(“Press P to unpause.”);

}

}

};



public void controllerClick(){

Vector2f cursorPos = inputManager.getCursorPosition();

//Vector3f location = cam.getWorldCoordinates(cursorPos, 0);

System.out.println(cursorPos);

//cam.getw

}



}

[/java]

I have also observed my shapes falling through the geometry randomly - in my case it happens if they hit the obstacle with some speed (not extreme speed by any means). I have not noticed CCD giving noticeable benefit - maybe it decreases the occurence statistically, but it still happens often enough to require a workaround.



So far, I had flat floor, so I just implemented extra step of checking if object is under floor and if yes, bumping it up manually bit over floor and letting it fall again - generally, problem is not common enough to happen two or more times in the row. As I’m moving to slightly more complicated collision geometry for ground, I’m starting to have problem with it again…

You should not move immovable/mass zero physics objects (ground), it will inevitably yield wrong results as without mass theres no physics. If you need to move the ground it can not be a mesh shape and has to be a kinematic RigidBody with mass.

1 Like

It is falling through immobile ground for me, but it might be a different problem then Rivensky’s one…

Ok when adding the RigidBodyControl to the ground I set mass to 1, which I didn’t do before because it just fell into oblivion. This time I created a box with size v3f.zero and rigidbody with 0 mass, attached to a ConeJoint, attached to my ground at the center. The ball tipped the ground over with its weight until I set ground’s kinematic to true. It seems to be working and not falling through now.



However, now it seems that my mesh ground shape is only a simple box shape. Normen you mention no mesh for movable ground, does this mean I need to create a crap-ton of individual kinematic RigidBodies moving in unison to create varied terrain, instead of a single ogre-xml ground shape?



thanks for the help

Its only true for terrain that you want to move, I don’t exactly know what you want to do, but what about not rotating the ground but rotating the gravity and the camera? Apart from that, the collision might fail when the triangle size of the mesh is large in relation to the colliding object and the object has considerable speed, thats why the ccd remedies the problems in most cases.

Heh apparently that joint I created to keep the platform from falling was pointless as all I had to do was set the ground to kinematic.



Thanks for the tip about rotating gravity/camera. I really do want to use a single mesh shape created in blender for terrain, so I am looking at it… but it is a much more complicated solution than just rotating the platform and letting the default physics do the work. I’ve been trying to work it out, and I can move the ball based on gravity, but it doesn’t act quite the same as a tilting platform it seems.



Since I stopped moving the ground I went back to using it as a mesh with mass=0 control, and haven’t fallen through yet… but the other issue with the ball freezing in place after coming to a stop still exists, even if the ground has never been moved… I don’t recall this problem happening with the kinematic ground, only the mesh, but haven’t tested that thoroughly. Might be a bug?

When a sphere falls straight down to a flat ground it just stands still, is that what you mean? Its the expected behavior. Also I dont think a change in gravity activates the rigidbodys (they go to sleep to save resources when they are not colliding), so you might have to activate() them.

1 Like

Falling straight down or stopping in a corner, either way, once it stayed still for a bit it wouldn’t move again. But you had the solution - activate(). Thanks.