Physics gone crazy

I’ve been playing around with the Physics engine for a while, and something really odd kept hapening. my physics objects kept hitting non-existent objects. eventually I found out about the physics debugger built into PhysicsSpace and i enabled it to find that my actual physics objects locations did not patch the real ones. in fact, everything was shifted down to the center of each object (see the picture to see what i mean):





Heres the full source code if anyone has any ideas on whats wrong:

[java]

package mygame;



import com.jme3.app.SimpleApplication;

import com.jme3.asset.TextureKey;

import com.jme3.bullet.BulletAppState;

import com.jme3.bullet.control.RigidBodyControl;

import com.jme3.input.controls.ActionListener;

import com.jme3.input.controls.AnalogListener;

import com.jme3.input.controls.MouseAxisTrigger;

import com.jme3.input.controls.MouseButtonTrigger;

import com.jme3.light.AmbientLight;

import com.jme3.light.DirectionalLight;

import com.jme3.material.Material;

import com.jme3.math.ColorRGBA;

import com.jme3.math.Vector3f;

import com.jme3.renderer.RenderManager;

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;

import com.jme3.shadow.BasicShadowRenderer;

import com.jme3.texture.Texture;

import com.jme3.texture.Texture.WrapMode;



/**

  • test
  • @author normenhansen

    /

    public class Main extends SimpleApplication {



    public static final float floorWidth = 5.0f;

    public static final float floorLength = 10.0f;

    public static final float floorDepth = 0.1f;

    public static final float roofHeight = 2.0f;



    public static Geometry paddleGeom;

    public static RigidBodyControl paddlePhysics;



    private RigidBodyControl ball_phy;

    private static final Sphere sphere;



    public static Material wallMat;



    static{

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

    sphere.setTextureMode(TextureMode.Projected);

    }



    private BulletAppState bulletAppState;





    private AnalogListener analogListener = new AnalogListener() {

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

    System.out.println(name + " " + keyPressed
    100);

    if(name.equals("mouseLeft"))

    paddlePhysics.getPhysicsLocation().x += keyPressed100;

    else if(name.equals("mouseRight"))

    {

    paddlePhysics.getPhysicsLocation().x -= keyPressed
    100;

    }





    }

    };



    public static void main(String[] args) {

    Main app = new Main();

    app.start();

    }



    @Override

    public void simpleInitApp() {



    cam.setLocation(new Vector3f(0, floorDepth+1, 0));

    cam.lookAt(new Vector3f(floorWidth, 0, 0), Vector3f.UNIT_Y);

    /Box b = new Box(Vector3f.ZERO, 1, 1, 1);

    Geometry geom = new Geometry("Box", b);

    geom.updateModelBound();



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

    mat.setColor("m_Color", ColorRGBA.Blue);

    geom.setMaterial(mat);



    rootNode.attachChild(geom);*/



    bulletAppState = new BulletAppState();

    stateManager.attach(bulletAppState);



    Box floor = new Box(Vector3f.ZERO, new Vector3f(floorLength, floorDepth, floorWidth));

    Box farWall = new Box(Vector3f.ZERO, new Vector3f(floorDepth, roofHeight, floorWidth));

    Box leftWall = new Box(Vector3f.ZERO, new Vector3f(floorLength, roofHeight, floorDepth));

    Box rightWall = new Box(Vector3f.ZERO, new Vector3f(floorLength, roofHeight, floorDepth));





    Geometry farWallGeom = new Geometry("FarWall", farWall);

    Geometry leftWallGeom = new Geometry("LeftWall", leftWall);

    Geometry rightWallGeom = new Geometry("RightWall", rightWall);



    leftWallGeom.setLocalTranslation(0, floorDepth, -floorWidth/2);

    rightWallGeom.setLocalTranslation(0, floorDepth, floorWidth/2);

    farWallGeom.setLocalTranslation(floorLength, floorDepth, -floorWidth/2);



    wallMat = loadMaterial("Textures/cementTexture.png");



    farWallGeom.setMaterial(wallMat);

    leftWallGeom.setMaterial(wallMat);

    rightWallGeom.setMaterial(wallMat);



    leftWallGeom.updateModelBound();

    rightWallGeom.updateModelBound();

    farWallGeom.updateModelBound();



    leftWallGeom.updateGeometricState();

    rightWallGeom.updateGeometricState();

    farWallGeom.updateGeometricState();



    farWallGeom.setShadowMode(ShadowMode.CastAndReceive);

    leftWallGeom.setShadowMode(ShadowMode.CastAndReceive);

    rightWallGeom.setShadowMode(ShadowMode.CastAndReceive);



    RigidBodyControl farWallPhysics = new RigidBodyControl(0.0f);

    RigidBodyControl leftWallPhysics = new RigidBodyControl(0.0f);

    RigidBodyControl rightWallPhysics = new RigidBodyControl(0.0f);



    farWallGeom.addControl(farWallPhysics);

    leftWallGeom.addControl(leftWallPhysics);

    rightWallGeom.addControl(rightWallPhysics);





    rootNode.attachChild(farWallGeom);

    rootNode.attachChild(leftWallGeom);

    rootNode.attachChild(rightWallGeom);



    bulletAppState.getPhysicsSpace().add(farWallPhysics);

    bulletAppState.getPhysicsSpace().add(leftWallPhysics);

    bulletAppState.getPhysicsSpace().add(rightWallPhysics);





    Geometry floorGeom = new Geometry("Floor", floor);

    floorGeom.setLocalTranslation(0, 0, -floorWidth/2);

    Material floorMat = loadMaterial("Textures/cementTexture.png");

    floorGeom.setMaterial(floorMat);



    floorGeom.setShadowMode(ShadowMode.Receive);

    RigidBodyControl floorPhysics = new RigidBodyControl(0.0f);

    floorGeom.addControl(floorPhysics);

    rootNode.attachChild(floorGeom);

    bulletAppState.getPhysicsSpace().add(floorPhysics);



    AmbientLight al = new AmbientLight();

    al.setColor(ColorRGBA.White.mult(1.3f));

    rootNode.addLight(al);

    rootNode.updateModelBound();

    DirectionalLight dl = new DirectionalLight();

    dl.setColor(ColorRGBA.White);

    dl.setDirection(new Vector3f(2.8f, -2.8f, -2.8f).normalizeLocal());

    rootNode.addLight(dl);

    initShadows();

    //this.getFlyByCamera().setMoveSpeed(0.0f);

    setupPaddle();

    //this.getFlyByCamera().setEnabled(false);

    String[] inputs = {"mouseLeft", "mouseRight"};





    inputManager.setCursorVisible(false);

    inputManager.addMapping("mouseLeft", new MouseAxisTrigger(0, true));

    inputManager.addMapping("mouseRight", new MouseAxisTrigger(0, false));

    inputManager.addMapping("shoot", new MouseButtonTrigger(mouseInput.BUTTON_LEFT));

    inputManager.addListener(analogListener, inputs);

    inputManager.addListener(new ActionListener() {



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

    if(isPressed)

    makeCannonBall();

    }

    }, new String[]{"shoot"});

    bulletAppState.getPhysicsSpace().enableDebug(assetManager);



    }



    /
    This method creates one individual physical cannon ball.
  • By defaul, the ball is accelerated and flies
  • from the camera position in the camera direction.*/

    public void makeCannonBall() {

    /** Create a cannon ball geometry and attach to scene graph. /

    Geometry ball_geo = new Geometry(“cannon ball”, sphere);

    ball_geo.setMaterial(wallMat);

    rootNode.attachChild(ball_geo);

    /
    * Position the cannon ball and activate shadows /

    ball_geo.setLocalTranslation(cam.getLocation());

    ball_geo.setShadowMode(ShadowMode.CastAndReceive);

    /
    * Make the ball physcial with a mass > 0.0f /

    ball_phy = new RigidBodyControl(1f);

    /
    * Add physical ball to physics space. /

    ball_geo.addControl(ball_phy);

    bulletAppState.getPhysicsSpace().add(ball_phy);

    /
    * Accelerate the physcial ball to shoot it. */

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

    }



    public void setupPaddle()

    {

    Box paddleMsh = new Box(Vector3f.ZERO, new Vector3f(floorDepth, 2, 2));

    paddleGeom = new Geometry(“Paddle”, paddleMsh);

    paddleGeom.setLocalTranslation(5.0f, floorDepth+1, 0);

    Material paddleMat = loadMaterial(“Textures/cementTexture.png”);

    paddleGeom.setMaterial(paddleMat);

    paddlePhysics = new RigidBodyControl(0.0f);

    //paddlePhysics.setGravity(Vector3f.UNIT_XYZ);

    paddleGeom.addControl(paddlePhysics);

    rootNode.attachChild(paddleGeom);

    bulletAppState.getPhysicsSpace().add(paddlePhysics);







    }



    @Override

    public void simpleUpdate(float tpf) {

    paddleGeom.updateGeometricState();

    paddleGeom.updateLogicalState(tpf);



    }



    public Material loadMaterial(String location)

    {

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

    TextureKey key = new TextureKey(location);

    key.setGenerateMips(true);

    Texture floorTexture = assetManager.loadTexture(key);

    floorTexture.setWrap(WrapMode.Repeat);

    floorMat.setTexture(“ColorMap”, floorTexture);



    return floorMat;

    }



    @Override

    public void simpleRender(RenderManager rm) {

    //TODO: add render code

    }



    private void initShadows() {

    BasicShadowRenderer bsr = new BasicShadowRenderer(assetManager, 256);

    bsr.setDirection(new Vector3f(-1, -1, -1).normalizeLocal());

    viewPort.addProcessor(bsr);

    // Default mode is Off – Every node declares own shadow mode!

    rootNode.setShadowMode(ShadowMode.Off);

    }

    }

    [/java]



    i have no idea why half the code looks like its commented out, Its not. and it doesn’t look that way in JMP

Dont move the spatial locations before attaching the control / creating the collisionshapes.

Found the problem, and it was partly that, the other thing that was causing a problem, was how i was initializing the walls. this must be some sort of bug, when i inititialized like this:

[java]

Box floor = new Box(Vector3f.ZERO, new Vector3f(floorLength, floorDepth, floorWidth));

Box farWall = new Box(Vector3f.ZERO, new Vector3f(floorDepth, roofHeight, floorWidth));

Box leftWall = new Box(Vector3f.ZERO, new Vector3f(floorLength, roofHeight, floorDepth));

Box rightWall = new Box(Vector3f.ZERO, new Vector3f(floorLength, roofHeight, floorDepth));

[/java]

it set the center of the collision box to the corner of the actual box, however when i initialized them like this:

[java]

Box floor = new Box(Vector3f.ZERO, floorLength/2, floorDepth/2, floorWidth/2);

Box farWall = new Box(Vector3f.ZERO, floorDepth/2, roofHeight/2, floorWidth/2);

Box leftWall = new Box(Vector3f.ZERO, floorLength/2, roofHeight/2, floorDepth/2);

Box rightWall = new Box(Vector3f.ZERO, floorLength/2, roofHeight/2, floorDepth/2);

[/java]

the physics box seemed to be perfectly aligned. not only that, but the actual box seems to be aligned using the center of the box instead of the corner as it was when i used the first initialization system



I also took your advice on moving spacial locations and moved everything after initializing and attaching everything:

[java]

leftWallPhysics.setPhysicsLocation(new Vector3f(floorLength/2, floorDepth+(roofHeight/2), -floorWidth/2));

rightWallPhysics.setPhysicsLocation(new Vector3f(floorLength/2, floorDepth+(roofHeight/2), floorWidth/2));

farWallPhysics.setPhysicsLocation(new Vector3f(floorLength, floorDepth+(roofHeight/2), 0));

[/java]

everything seems to work fine now.

Thanks



—Update—



Ok, thats a bug. i just tried changing the Physics location of my last box (paddle), and left the initialization using the first version. the results are exactly the same, the collisionBox is aligned to the Corner of the Actual Box. I’ll change the initialization, but it certainly is a bug that should be looked into.

No its not a bug, its the world location of the spatial. The collisionshapefactory uses that to create the spatial. I had it crash if the spatial had a parent before, but people complained… I will try to avoid this pitfall by combining the locations just up to the creation spatial as parent…

clwillingham said:
i have no idea why half the code looks like its commented out, Its not. and it doesn't look that way in JMP


Its because of "/*" - start comment , the display gets confused and does not recognize end "*/" correctly.
One way to avoid this is having only "/**" for starting comments (javadoc version)
nego said:
Its because of "/*" - start comment , the display gets confused and does not recognize end "*/" correctly.
One way to avoid this is having only "/**" for starting comments (javadoc version)

that worked, i fixed it for anyone else whos had the same troubles,
thanks normon for clarifying the solution for me.

One more question, i finally got all of the physics boxes and spheres in there right position, and now i’m having trouble making my spheres bounce off of my paddle (i’m making a pong-like game), the spheres are just bouncing right through the paddle. i suspect it has to do with the way i’m moving the paddle, but its moving the way i want it to and i can’t think of a better way to move it, any ideas? heres the code:

[java]

package mygame;



import com.jme3.app.SimpleApplication;

import com.jme3.asset.TextureKey;

import com.jme3.bullet.BulletAppState;

import com.jme3.bullet.control.RigidBodyControl;

import com.jme3.input.controls.ActionListener;

import com.jme3.input.controls.AnalogListener;

import com.jme3.input.controls.MouseAxisTrigger;

import com.jme3.input.controls.MouseButtonTrigger;

import com.jme3.light.AmbientLight;

import com.jme3.light.DirectionalLight;

import com.jme3.material.Material;

import com.jme3.math.ColorRGBA;

import com.jme3.math.Vector3f;

import com.jme3.renderer.RenderManager;

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;

import com.jme3.shadow.BasicShadowRenderer;

import com.jme3.texture.Texture;

import com.jme3.texture.Texture.WrapMode;

import org.omg.PortableInterceptor.SYSTEM_EXCEPTION;



/**

  • test
  • @author clwillingham

    /

    public class Main extends SimpleApplication {



    public static final float floorWidth = 10.0f;

    public static final float floorLength = 20.0f;

    public static final float floorDepth = 0.1f;

    public static final float roofHeight = 10.0f;



    public static Geometry paddleGeom;

    public static RigidBodyControl paddlePhysics;

    public static float paddlePositionX = 0;

    public static float paddlePositionY = 2;



    private RigidBodyControl ball_phy;

    private static final Sphere sphere;



    public static Material wallMat;



    static{

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

    sphere.setTextureMode(TextureMode.Projected);

    }



    private BulletAppState bulletAppState;





    private AnalogListener analogListener = new AnalogListener() {

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



    if(name.equals("mouseLeft")&& paddlePositionX > (-floorWidth/2)+0.6f)

    {



    paddlePositionX -= keyPressed
    10;

    }

    else if(name.equals("mouseRight") && paddlePositionX < (floorWidth/2)-0.6f)

    {

    paddlePositionX += keyPressed10;

    }

    else if(name.equals("mouseUp") && paddlePositionY > 0.5f)

    {

    paddlePositionY -= keyPressed
    10;

    }

    else if(name.equals("mouseDown") && paddlePositionY < roofHeight-0.4f)

    {

    paddlePositionY += keyPressed*10;

    }

    paddlePhysics.setPhysicsLocation(new Vector3f(3.0f, paddlePositionY, paddlePositionX));





    }

    };



    public static void main(String[] args) {

    Main app = new Main();

    app.start();

    }



    @Override

    public void simpleInitApp() {



    cam.setLocation(new Vector3f(0, floorDepth+4, 0));

    cam.lookAt(new Vector3f(floorWidth, 0, 0), Vector3f.UNIT_Y);



    bulletAppState = new BulletAppState();

    stateManager.attach(bulletAppState);



    Box floor = new Box(Vector3f.ZERO, floorLength/2, floorDepth/2, floorWidth/2);

    Box farWall = new Box(Vector3f.ZERO, floorDepth/2, roofHeight/2, floorWidth/2);

    Box leftWall = new Box(Vector3f.ZERO, floorLength/2, roofHeight/2, floorDepth/2);

    Box rightWall = new Box(Vector3f.ZERO, floorLength/2, roofHeight/2, floorDepth/2);





    Geometry farWallGeom = new Geometry("FarWall", farWall);

    Geometry leftWallGeom = new Geometry("LeftWall", leftWall);

    Geometry rightWallGeom = new Geometry("RightWall", rightWall);







    wallMat = loadMaterial("Textures/BrickWall.png");



    farWallGeom.setMaterial(wallMat);

    leftWallGeom.setMaterial(wallMat);

    rightWallGeom.setMaterial(wallMat);



    leftWallGeom.updateModelBound();

    rightWallGeom.updateModelBound();

    farWallGeom.updateModelBound();



    leftWallGeom.updateGeometricState();

    rightWallGeom.updateGeometricState();

    farWallGeom.updateGeometricState();



    farWallGeom.setShadowMode(ShadowMode.CastAndReceive);

    leftWallGeom.setShadowMode(ShadowMode.CastAndReceive);

    rightWallGeom.setShadowMode(ShadowMode.CastAndReceive);



    RigidBodyControl farWallPhysics = new RigidBodyControl(0.0f);

    RigidBodyControl leftWallPhysics = new RigidBodyControl(0.0f);

    RigidBodyControl rightWallPhysics = new RigidBodyControl(0.0f);



    farWallGeom.addControl(farWallPhysics);

    leftWallGeom.addControl(leftWallPhysics);

    rightWallGeom.addControl(rightWallPhysics);





    rootNode.attachChild(farWallGeom);

    rootNode.attachChild(leftWallGeom);

    rootNode.attachChild(rightWallGeom);



    bulletAppState.getPhysicsSpace().add(farWallPhysics);

    bulletAppState.getPhysicsSpace().add(leftWallPhysics);

    bulletAppState.getPhysicsSpace().add(rightWallPhysics);



    leftWallPhysics.setPhysicsLocation(new Vector3f(floorLength/2, floorDepth+(roofHeight/2), -floorWidth/2));

    rightWallPhysics.setPhysicsLocation(new Vector3f(floorLength/2, floorDepth+(roofHeight/2), floorWidth/2));

    farWallPhysics.setPhysicsLocation(new Vector3f(floorLength, floorDepth+(roofHeight/2), 0));







    Geometry floorGeom = new Geometry("Floor", floor);

    floorGeom.setLocalTranslation(floorLength/2, floorDepth/2, 0);

    Material floorMat = loadMaterial("Textures/cementTexture.png");

    //Material wallMat = loadMaterial("Textures/BrickWall.png");

    floorGeom.setMaterial(floorMat);



    floorGeom.setShadowMode(ShadowMode.Receive);

    RigidBodyControl floorPhysics = new RigidBodyControl(0.0f);

    floorGeom.addControl(floorPhysics);

    rootNode.attachChild(floorGeom);

    bulletAppState.getPhysicsSpace().add(floorPhysics);



    AmbientLight al = new AmbientLight();

    al.setColor(ColorRGBA.White.mult(1.3f));

    rootNode.addLight(al);

    rootNode.updateModelBound();

    DirectionalLight dl = new DirectionalLight();

    dl.setColor(ColorRGBA.White);

    dl.setDirection(new Vector3f(2.8f, -2.8f, -2.8f).normalizeLocal());

    rootNode.addLight(dl);

    initShadows();

    //this.getFlyByCamera().setMoveSpeed(0.0f);

    setupPaddle();

    this.getFlyByCamera().setEnabled(false);

    String[] inputs = {"mouseLeft", "mouseRight", "mouseUp", "mouseDown"};





    inputManager.setCursorVisible(false);

    inputManager.addMapping("mouseLeft", new MouseAxisTrigger(0, true));

    inputManager.addMapping("mouseRight", new MouseAxisTrigger(0, false));

    inputManager.addMapping("mouseUp", new MouseAxisTrigger(mouseInput.AXIS_Y, true));

    inputManager.addMapping("mouseDown", new MouseAxisTrigger(mouseInput.AXIS_Y, false));

    inputManager.addMapping("shoot", new MouseButtonTrigger(mouseInput.BUTTON_LEFT));



    inputManager.addListener(analogListener, inputs);

    inputManager.addListener(new ActionListener() {



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

    if(isPressed)

    makeCannonBall(cam.getDirection().mult(25), cam.getLocation());

    }

    }, new String[]{"shoot"});

    bulletAppState.getPhysicsSpace().enableDebug(assetManager);



    bulletAppState.getPhysicsSpace().setAccuracy(0.001f);



    makeCannonBall(new Vector3f(25, 0, 0), new Vector3f(5, 1, 0));



    leftWallPhysics.setRestitution(0.5f);

    rightWallPhysics.setRestitution(0.5f);

    farWallPhysics.setRestitution(0.9f);

    paddlePhysics.setRestitution(0.9f);

    floorPhysics.setRestitution(1f);







    }



    /** This method creates one individual physical cannon ball.
  • By defaul, the ball is accelerated and flies
  • from the camera position in the camera direction.*/

    public void makeCannonBall(Vector3f valocity, Vector3f location) {

    /** Create a cannon ball geometry and attach to scene graph. /

    Geometry ball_geo = new Geometry("cannon ball", sphere);

    ball_geo.setMaterial(loadMaterial("Textures/RustyMetal.png"));

    rootNode.attachChild(ball_geo);

    /
    * Position the cannon ball and activate shadows /

    ball_geo.setLocalTranslation(location);

    ball_geo.setShadowMode(ShadowMode.CastAndReceive);

    /
    * Make the ball physcial with a mass > 0.0f /

    ball_phy = new RigidBodyControl(1000f);

    /
    * Add physical ball to physics space. /

    ball_geo.addControl(ball_phy);

    bulletAppState.getPhysicsSpace().add(ball_phy);

    /
    * Accelerate the physcial ball to shoot it. */

    ball_phy.setLinearVelocity(valocity);

    //ball_phy.setLinearDamping(0.0f);

    ball_phy.setRestitution(0.5f);

    }



    public void setupPaddle()

    {

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

    paddleGeom = new Geometry("Paddle", paddleMsh);



    Material paddleMat = loadMaterial("Textures/cementTexture.png");

    paddleGeom.setMaterial(paddleMat);

    paddlePhysics = new RigidBodyControl(0.0f);

    //paddlePhysics.setGravity(Vector3f.UNIT_XYZ);

    paddleGeom.addControl(paddlePhysics);

    rootNode.attachChild(paddleGeom);

    bulletAppState.getPhysicsSpace().add(paddlePhysics);

    paddlePhysics.setPhysicsLocation(new Vector3f(3.0f, paddlePositionY, paddlePositionX));

    //.setKinematic(true);

    paddlePhysics.setKinematicSpatial(true);



    }



    @Override

    public void simpleUpdate(float tpf) {

    paddleGeom.updateGeometricState();

    paddleGeom.updateLogicalState(tpf);

    cam.lookAt(paddleGeom.getLocalTranslation(), Vector3f.UNIT_Y);



    }



    public Material loadMaterial(String location)

    {

    Material floorMat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");

    TextureKey key = new TextureKey(location);

    key.setGenerateMips(true);

    Texture floorTexture = assetManager.loadTexture(key);

    floorTexture.setWrap(WrapMode.Repeat);

    floorMat.setTexture("ColorMap", floorTexture);



    return floorMat;

    }



    @Override

    public void simpleRender(RenderManager rm) {

    //TODO: add render code

    }



    private void initShadows() {

    BasicShadowRenderer bsr = new BasicShadowRenderer(assetManager, 256);

    bsr.setDirection(new Vector3f(-1, -1, -1).normalizeLocal());

    viewPort.addProcessor(bsr);

    // Default mode is Off – Every node declares own shadow mode!

    rootNode.setShadowMode(ShadowMode.Off);

    }

    }

    [/java]

The paddle has a mass of 0 and is thus a static physics object that cannot be moved (it has no kinematic energy). If you want a physics object you can move and that does not fall down by itself give it a mass and use setKinematic(true); In this mode you move the spatial and the RigidBody will move along with it.