Physics gone crazy

I was playing with Hello Physics code and making it objective, but bricks fall and move very fast and when they drop on the floor, they bounce like crazy.

Main class:
[java]
package bin;

import com.jme3.app.SimpleApplication;
import com.jme3.bullet.BulletAppState;
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.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.Spatial;
import com.jme3.scene.shape.Box;
import objects.Ball;
import objects.Block;
import objects.Material;

public class MC extends SimpleApplication {

public static final MC APP = new MC();
private BulletAppState bulletAppState;
private Material brickMat;
private Material ballMat;
private Material floorMat;

public void addInGame(Spatial spatial) {
    rootNode.attachChild(spatial);
    bulletAppState.getPhysicsSpace().addAll(spatial);
}

protected void initCrossHairs() {
    guiNode.detachAllChildren();
    guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt");
    BitmapText ch = new BitmapText(guiFont, false);
    ch.setSize(guiFont.getCharSet().getRenderedSize() * 2);
    ch.setText("+");
    ch.setLocalTranslation(
            settings.getWidth() / 2 - guiFont.getCharSet().getRenderedSize() / 3 * 2,
            settings.getHeight() / 2 + ch.getLineHeight() / 2, 0);
    guiNode.attachChild(ch);
}

public void initFloor() {
    Geometry floor = new Geometry("Floor", new Box(50f, 1f, 50f));
    floor.setMaterial(floorMat);
    floor.setLocalTranslation(0, -1f, 0);
    floor.addControl(new RigidBodyControl(0.0f));
    addInGame(floor);
}

private void initInput() {
    inputManager.addMapping("shoot",
            new MouseButtonTrigger(MouseInput.BUTTON_LEFT));
    inputManager.addMapping("reset", new KeyTrigger(KeyInput.KEY_BACK));
    inputManager.addListener(new ActionListener() {
        @Override
        public void onAction(String name, boolean keyPressed, float tpf) {
            switch (name) {
                case "shoot":
                    if (!keyPressed) {
                        makeCannonBall();
                    }
                    break;
                case "reset":
                    if (!keyPressed) {
                        resetGame();
                    }
            }
        }
    }, "shoot", "reset");
}

private void initMaterials() {
    brickMat = new Material("Common/MatDefs/Misc/Unshaded.j3md", "Textures/ArteryBlast/Bricks.png");
    ballMat = new Material("Common/MatDefs/Misc/ShowNormals.j3md");
    floorMat = new Material("Common/MatDefs/Misc/Unshaded.j3md", "Textures/ArteryBlast/StoneCobble.png");
    floorMat.setRepeat(true);
}

public void initWall() {
    float startpt = Block.MESH.xExtent / 4;
    float height = 0;
    for (int j = 0; j < 15; j++) {
        for (int i = 0; i < 6; i++) {
            Vector3f vt = new Vector3f(i * Block.MESH.xExtent * 2 + startpt, Block.MESH.yExtent + height, 0);
            makeBrick(vt);
        }
        startpt = -startpt;
        height += 2 * Block.MESH.yExtent;
    }
}

public void makeBrick(Vector3f loc) {
    Block brick = new Block(brickMat, 1f);
    addInGame(brick);
    brick.setLocalTranslation(loc);
}

public void makeCannonBall() {
    Ball ball = new Ball(ballMat, 0.5f);
    addInGame(ball);
    ball.setLocalTranslation(cam.getLocation());
    ball.getRigidControl().setLinearVelocity(cam.getDirection());
}

public void resetGame() {
    bulletAppState.getPhysicsSpace().removeAll(rootNode);
    rootNode.detachAllChildren();
    initWall();
    initFloor();
}

@Override
public void simpleInitApp() {
    bulletAppState = new BulletAppState();
    stateManager.attach(bulletAppState);
    cam.setLocation(new Vector3f(2.25f, 1.25f, 6f));
    cam.lookAt(new Vector3f(2.25f, 1.25f, 0f), Vector3f.UNIT_Y);
    initInput();
    initMaterials();
    initCrossHairs();
    resetGame();
}

public static void main(String args[]) {
    APP.start();
}

}
[/java]

Material:
[java]

package objects;

import bin.MC;
import com.jme3.asset.TextureKey;
import com.jme3.material.MatParamTexture;
import com.jme3.material.MaterialDef;
import com.jme3.texture.Texture;

public class Material extends com.jme3.material.Material {

public static final String MAIN_TEXTURE = "ColorMap";

public Material(String definition) {
    super(MC.APP.getAssetManager(), definition);
}

public Material(String definition, String texture) {
    super((MaterialDef) MC.APP.getAssetManager().loadAsset(definition));
    TextureKey key = new TextureKey(texture);
    key.setGenerateMips(true);
    Texture tex = MC.APP.getAssetManager().loadTexture(key);
    this.setTexture(MAIN_TEXTURE, tex);
}

public Texture getTexture(String name) {
    MatParamTexture mpt = this.getTextureParam(name);
    if (mpt != null) {
        return mpt.getTextureValue();
    }
    return null;
}

public void setRepeat(boolean b) {
    getTexture(MAIN_TEXTURE).setWrap(b ? Texture.WrapMode.Repeat : Texture.WrapMode.Clamp);
}

}
[/java]

Ball:
[java]

package objects;

import com.jme3.material.Material;
import com.jme3.scene.shape.Sphere;

public class Ball extends RigidObject {

public static final Sphere MESH = new Sphere(32, 32, 0.4f, true, false);

static {
    MESH.setTextureMode(Sphere.TextureMode.Projected);
}

public Ball(Material material, float mass) {
    super("Ball", MESH, material);
    this.getRigidControl().setMass(mass);
}

}
[/java]

Block:
[java]

package objects;

import com.jme3.material.Material;
import com.jme3.scene.shape.Box;

public class Block extends RigidObject {

public static final Box MESH = new Box(0.5f, 0.5f, 0.5f);

public Block(Material material, float mass) {
    super("Block", MESH, material);
    this.getRigidControl().setMass(mass);
}

}
[/java]

RigidObject:
[java]

package objects;

import com.jme3.bullet.control.RigidBodyControl;
import com.jme3.material.Material;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.Mesh;

public class RigidObject extends Geometry {

private RigidBodyControl control = new RigidBodyControl();

public RigidObject(String name, Mesh mesh, Material material) {
    super(name, mesh);
    this.setMaterial(material);
    this.addControl(control);
}

public RigidBodyControl getRigidControl() {
    return control;
}

@Override
public void setLocalTranslation(Vector3f localTranslation) {
    super.setLocalTranslation(localTranslation);
    control.setPhysicsLocation(localTranslation);
}

@Override
public void setLocalTranslation(float x, float y, float z) {
    this.setLocalTranslation(new Vector3f(x, y, z));
}

}
[/java]

Do you know where is the problem?

Well, I don’t know if it’s the problem but your bricks are big chunks of foam. (1 meter on a side and only weigh 1 kg) I guess that could be pretty bouncy in real life too.

It is not that problem. I’m using these values all the time and before I started making it objective, it had worked correctly.

And now I found out that problem is with gravity because when a ball rolls on the floor and get slow, it is not getting slower but it stops.

Ok, I tried to set smaller gravity but then some bricks stopped in the air or on an edge

Got it!!

Problem was in RigidObject in:
[java]
@Override
public void setLocalTranslation(Vector3f localTranslation) {
super.setLocalTranslation(localTranslation);
control.setPhysicsLocation(localTranslation);
}
[/java]

Because when you call setPhysicsLocation then setLocalTranslation is called internally so it was cycling.