Anyone ever encountered a physics space location problem?

Hi everyone,

Here is my problem, I have two spatial objects, which are undoubtedly at different position ,but when I outputed the locations by getPhysicsLocation() , I got two equivalent Vector3f(0.0,0.0,0.0). The spatial objects are imported from blend files.

By the way , can I post a picture here? how?

With the image tag… ?



Concerning your position problems: How do you set the positions of your entities?

You can use setLocalLocation only BEFORE you add the physics to the spatial if im well informed. Some code?

If you add a RigidBody to the spatial and then move the spatial while you don’t add the RigidBody to the physicsSpace, the RigidBody will keep its location as its neither changed by physics nor by you.

@KuroSei said:
With the image tag... ?

Concerning your position problems: How do you set the positions of your entities?
You can use setLocalLocation only BEFORE you add the physics to the spatial if im well informed. Some code?

sorry for my delay. here is my code:
viewPort.setBackgroundColor(new ColorRGBA(0.7f, 0.8f, 1f, 1f));
bulletAppState= new BulletAppState();

stateManager.attach(bulletAppState);
bulletAppState.getPhysicsSpace().setMaxSubSteps(16);
runway = assetManager.loadModel("Models/Circle.j3o");
CollisionShape runwayShape = CollisionShapeFactory.createMeshShape(runway);
runwayCtrl = new RigidBodyControl(runwayShape,0);

ball = assetManager.loadModel("Models/Sphere.j3o");
SphereCollisionShape ballShape = new SphereCollisionShape(0.5f);
ballCtrl = new RigidBodyControl(ballShape,0.5f);

ball.addControl(ballCtrl);
bulletAppState.getPhysicsSpace().add(runwayCtrl);
bulletAppState.getPhysicsSpace().add(ballCtrl);
rootNode.attachChild(runway);
rootNode.attachChild(ball);
setupKeys();
setupLight();
@normen said:
If you add a RigidBody to the spatial and then move the spatial while you don't add the RigidBody to the physicsSpace, the RigidBody will keep its location as its neither changed by physics nor by you.

I think I added it to the physicsSpace.
edit: The puzzling part is when I run my program I can see the two objects are at different positions but if I output their locations they are both (0.0,0.0,0.0)

You never set any location in the code you posted :roll: As said, you cannot use setLocalTranslation but have to use setPhysicsLocation on the physics control.

I think I didn’t make myself clear. what confuses me is I can see the objects at different places in the running program , but the location are both at origin when I outputed them

Code please… This is definitely working, you are doing something wrong.

important stuff is in simpleInitApp() and simpleUpdate().

package Rolling;



import com.bulletphysics.collision.shapes.SphereShape;

import com.jme3.app.SimpleApplication;

import com.jme3.bullet.BulletAppState;

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

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

import com.jme3.bullet.control.RigidBodyControl;

import com.jme3.bullet.util.CollisionShapeFactory;

import com.jme3.collision.CollisionResults;

import com.jme3.input.ChaseCamera;

import com.jme3.input.KeyInput;

import com.jme3.input.controls.ActionListener;

import com.jme3.input.controls.KeyTrigger;

import com.jme3.input.controls.Trigger;

import com.jme3.light.AmbientLight;

import com.jme3.light.DirectionalLight;

import com.jme3.material.Material;

import com.jme3.math.ColorRGBA;

import com.jme3.math.FastMath;

import com.jme3.math.Ray;

import com.jme3.math.Vector3f;

import com.jme3.renderer.RenderManager;

import com.jme3.scene.Geometry;

import com.jme3.scene.Spatial;

import com.jme3.scene.shape.Box;

import com.jme3.system.AppSettings;



/**

  • test
  • @author normenhansen

    */

    public class Main extends SimpleApplication implements ActionListener{

    Spatial runway;

    Spatial ball;

    RigidBodyControl ballCtrl,runwayCtrl;

    BulletAppState bulletAppState;

    private boolean left = false, right = false, up = false, down = false;

    public static void main(String[] args) {

    Main app = new Main();

    app.setSettings(new AppSettings(true));

    app.start();

    }



    public void setSettings(AppSettings settings)

    {

    settings.setTitle(“3DRolling”);

    settings.setSettingsDialogImage(“Models/nrmls_craneo.png”);

    settings.setRenderer(AppSettings.LWJGL_OPENGL2);

    settings.setFrameRate(2000);

    super.setSettings(settings);

    }

    @Override

    public void simpleInitApp() {



    viewPort.setBackgroundColor(new ColorRGBA(0.7f, 0.8f, 1f, 1f));

    bulletAppState= new BulletAppState();



    stateManager.attach(bulletAppState);

    bulletAppState.getPhysicsSpace().setMaxSubSteps(16);

    runway = assetManager.loadModel(“Models/Circle.j3o”);

    CollisionShape runwayShape = CollisionShapeFactory.createMeshShape(runway);

    runwayCtrl = new RigidBodyControl(runwayShape,0);

    edit: runway.addControl(runwayCtrl);



    ball = assetManager.loadModel(“Models/Sphere.j3o”);

    SphereCollisionShape ballShape = new SphereCollisionShape(0.5f);

    ballCtrl = new RigidBodyControl(ballShape,0.0f);



    ball.addControl(ballCtrl);

    bulletAppState.getPhysicsSpace().add(runwayCtrl);

    bulletAppState.getPhysicsSpace().add(ballCtrl);

    rootNode.attachChild(runway);

    rootNode.attachChild(ball);

    setupKeys();

    setupLight();



    }

    public void setupKeys(){

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

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

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

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

    inputManager.addListener(this, “Left”);

    inputManager.addListener(this, “Right”);

    inputManager.addListener(this, “Up”);

    inputManager.addListener(this, “Down”);





    }

    public void onAction(String binding, boolean value, float tpf){

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

    if (value) { left = true; } else { left = false; }

    } else if (binding.equals(“Right”)) {

    if (value) { right = true; } else { right = false; }

    } else if (binding.equals(“Up”)) {

    if (value) { up = true; } else { up = false; }

    } else if (binding.equals(“Down”)) {

    if (value) { down = true; } else { down = false; }

    }

    }

    public void setupLight(){

    /*AmbientLight al = new AmbientLight();

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

    rootNode.addLight(al);

    DirectionalLight dl = new DirectionalLight();

    dl.setColor(ColorRGBA.White);

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

    rootNode.addLight(dl); */

    }

    private void updateGravity(){

    int NumOfRay=6;

    float gravity =30;

    Ray ray[]=new Ray[6]; // px,nx,py,ny,pz,nz

    double distance= Double.MAX_VALUE;

    Vector3f point=new Vector3f();

    ray[0]=new Ray(ballCtrl.getPhysicsLocation(),new Vector3f(1,0,0));

    ray[1]=new Ray(ballCtrl.getPhysicsLocation(),new Vector3f(-1,0,0));

    ray[2]=new Ray(ballCtrl.getPhysicsLocation(),new Vector3f(0,1,0));

    ray[3]=new Ray(ballCtrl.getPhysicsLocation(),new Vector3f(0,-1,0));

    ray[4]=new Ray(ballCtrl.getPhysicsLocation(),new Vector3f(0,0,1));

    ray[5]=new Ray(ballCtrl.getPhysicsLocation(),new Vector3f(0,0,-1));

    System.out.println(“ballCtrl=”+ballCtrl.getPhysicsLocation()+“runwayCtrl=”+runwayCtrl.getPhysicsLocation());

    System.out.println(“ball=”+ball.getLocalTranslation()+“runway=”+runway.getLocalTranslation());

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

    CollisionResults result = new CollisionResults();

    runway.collideWith(ray, result);

    if(result.size()>0){

    double d=result.getClosestCollision().getDistance();

    if(d<distance){

    distance=d;

    point = result.getClosestCollision().getContactPoint();

    }

    }

    }



    point.subtractLocal(ballCtrl.getPhysicsLocation());

    // point.multLocal(gravity);

    ballCtrl.setPhysicsLocation(ballCtrl.getPhysicsLocation().add(point));

    // ballCtrl.setGravity(point);

    }

    @Override

    public void simpleUpdate(float tpf) {

    // updateGravity();

    // updateBallPosition();

    System.out.println(ballCtrl.getPhysicsLocation());

    System.out.println(runwayCtrl.getPhysicsLocation());

    //ballCtrl.setGravity(0,0,1);

    //TODO: add update code

    }

    public void updateBallPosition(){

    Vector3f walkDirection = new Vector3f();

    Vector3f camDir = cam.getDirection().clone().multLocal(0.11f);

    Vector3f camLeft = cam.getLeft().clone().multLocal(0.1f);

    walkDirection.set(0, 0, 0);

    if (left) { walkDirection.addLocal(camLeft); }

    if (right) { walkDirection.addLocal(camLeft.negate()); }

    if (up) { walkDirection.addLocal(camDir); }

    if (down) { walkDirection.addLocal(camDir.negate()); }

    // ballCtrl.applyCentralForce(walkDirection);

    ballCtrl.setPhysicsLocation(ballCtrl.getPhysicsLocation().add(walkDirection));

    }

    @Override

    public void simpleRender(RenderManager rm) {

    //TODO: add render code

    }

    }

Your physics objects have a mass of 0 meaning they are static hence they don’t move. Please use code tags, its almost unreadable without indents.

I edited the code,and added runway.addControl(runwayControl), but the problem remains the same

but my test program don’t need to move the ball,so I set its mass to 0 to relieve it of the gravity.

the program just import the two models, put them into a physicsSpace without any positioning, display them and output their locations. the result is two objects , a ball and a runway , are displayed at different places,while the outputed locations are both origin. shouldn’t the two objects be displayed in one place if their coordinate are the same? I 'm sorry I don’t know how to post nicely and I would much like to post my running pictures and I don’t know how, the upLoad image is indirected to another web page. forgive my poor english.

[java]



package Rolling;



import com.bulletphysics.collision.shapes.SphereShape;

import com.jme3.app.SimpleApplication;

import com.jme3.bullet.BulletAppState;

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

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

import com.jme3.bullet.control.RigidBodyControl;

import com.jme3.bullet.util.CollisionShapeFactory;

import com.jme3.collision.CollisionResults;

import com.jme3.input.ChaseCamera;

import com.jme3.input.KeyInput;

import com.jme3.input.controls.ActionListener;

import com.jme3.input.controls.KeyTrigger;

import com.jme3.input.controls.Trigger;

import com.jme3.light.AmbientLight;

import com.jme3.light.DirectionalLight;

import com.jme3.material.Material;

import com.jme3.math.ColorRGBA;

import com.jme3.math.FastMath;

import com.jme3.math.Ray;

import com.jme3.math.Vector3f;

import com.jme3.renderer.RenderManager;

import com.jme3.scene.Geometry;

import com.jme3.scene.Spatial;

import com.jme3.scene.shape.Box;

import com.jme3.system.AppSettings;



/**

  • test
  • @author normenhansen

    */

    public class Main extends SimpleApplication implements ActionListener{

    Spatial runway;

    Spatial ball;

    RigidBodyControl ballCtrl,runwayCtrl;

    BulletAppState bulletAppState;

    private boolean left = false, right = false, up = false, down = false;

    public static void main(String[] args) {

    Main app = new Main();

    app.setSettings(new AppSettings(true));

    app.start();

    }



    public void setSettings(AppSettings settings)

    {

    settings.setTitle("3DRolling");

    settings.setSettingsDialogImage("Models/nrmls_craneo.png");

    settings.setRenderer(AppSettings.LWJGL_OPENGL2);

    settings.setFrameRate(2000);

    super.setSettings(settings);

    }

    @Override

    public void simpleInitApp() {



    viewPort.setBackgroundColor(new ColorRGBA(0.7f, 0.8f, 1f, 1f));

    bulletAppState= new BulletAppState();



    stateManager.attach(bulletAppState);

    bulletAppState.getPhysicsSpace().setMaxSubSteps(16);

    runway = assetManager.loadModel("Models/Circle.j3o");

    CollisionShape runwayShape = CollisionShapeFactory.createMeshShape(runway);

    runwayCtrl = new RigidBodyControl(runwayShape,0);

    runway.addControl(runwayCtrl);



    ball = assetManager.loadModel("Models/Sphere.j3o");

    SphereCollisionShape ballShape = new SphereCollisionShape(0.5f);

    ballCtrl = new RigidBodyControl(ballShape,0.0f);

    ball.addControl(ballCtrl);



    bulletAppState.getPhysicsSpace().add(runwayCtrl);

    bulletAppState.getPhysicsSpace().add(ballCtrl);

    rootNode.attachChild(runway);

    rootNode.attachChild(ball);

    setupKeys();

    setupLight();



    }

    public void setupKeys(){

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

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

    inputManager.addMapping("Up", new KeyTrigger(KeyInput.KEY_W));

    inputManager.addMapping("Down", new KeyTrigger(KeyInput.KEY_S));

    inputManager.addListener(this, "Left");

    inputManager.addListener(this, "Right");

    inputManager.addListener(this, "Up");

    inputManager.addListener(this, "Down");





    }

    public void onAction(String binding, boolean value, float tpf){

    if (binding.equals("Left")) {

    if (value) { left = true; } else { left = false; }

    } else if (binding.equals("Right")) {

    if (value) { right = true; } else { right = false; }

    } else if (binding.equals("Up")) {

    if (value) { up = true; } else { up = false; }

    } else if (binding.equals("Down")) {

    if (value) { down = true; } else { down = false; }

    }

    }

    public void setupLight(){

    /*AmbientLight al = new AmbientLight();

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

    rootNode.addLight(al);

    DirectionalLight dl = new DirectionalLight();

    dl.setColor(ColorRGBA.White);

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

    rootNode.addLight(dl); */

    }

    private void updateGravity(){

    int NumOfRay=6;

    float gravity =30;

    Ray ray[]=new Ray[6]; // px,nx,py,ny,pz,nz

    double distance= Double.MAX_VALUE;

    Vector3f point=new Vector3f();

    ray[0]=new Ray(ballCtrl.getPhysicsLocation(),new Vector3f(1,0,0));

    ray[1]=new Ray(ballCtrl.getPhysicsLocation(),new Vector3f(-1,0,0));

    ray[2]=new Ray(ballCtrl.getPhysicsLocation(),new Vector3f(0,1,0));

    ray[3]=new Ray(ballCtrl.getPhysicsLocation(),new Vector3f(0,-1,0));

    ray[4]=new Ray(ballCtrl.getPhysicsLocation(),new Vector3f(0,0,1));

    ray[5]=new Ray(ballCtrl.getPhysicsLocation(),new Vector3f(0,0,-1));

    System.out.println("ballCtrl="+ballCtrl.getPhysicsLocation()+"runwayCtrl="+runwayCtrl.getPhysicsLocation());

    System.out.println("ball="+ball.getLocalTranslation()+"runway="+runway.getLocalTranslation());

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

    CollisionResults result = new CollisionResults();

    runway.collideWith(ray, result);

    if(result.size()>0){

    double d=result.getClosestCollision().getDistance();

    if(d<distance){

    distance=d;

    point = result.getClosestCollision().getContactPoint();

    }

    }

    }



    point.subtractLocal(ballCtrl.getPhysicsLocation());

    // point.multLocal(gravity);

    ballCtrl.setPhysicsLocation(ballCtrl.getPhysicsLocation().add(point));

    // ballCtrl.setGravity(point);

    }

    @Override

    public void simpleUpdate(float tpf) {

    // updateGravity();

    updateBallPosition();

    System.out.println(ballCtrl.getPhysicsLocation());

    System.out.println(runwayCtrl.getPhysicsLocation());

    //ballCtrl.setGravity(0,0,1);

    //TODO: add update code

    }

    public void updateBallPosition(){

    Vector3f walkDirection = new Vector3f();

    Vector3f camDir = cam.getDirection().clone().multLocal(0.11f);

    Vector3f camLeft = cam.getLeft().clone().multLocal(0.1f);

    walkDirection.set(0, 0, 0);

    if (left) { walkDirection.addLocal(camLeft); }

    if (right) { walkDirection.addLocal(camLeft.negate()); }

    if (up) { walkDirection.addLocal(camDir); }

    if (down) { walkDirection.addLocal(camDir.negate()); }

    // ballCtrl.applyCentralForce(walkDirection);

    ballCtrl.setPhysicsLocation(ballCtrl.getPhysicsLocation().add(walkDirection));

    }

    @Override

    public void simpleRender(RenderManager rm) {

    //TODO: add render code

    }

    }

    [/java]

You don’t set the mass to zero but the gravity if you want zero gravity… Either set it on the physics space before adding or on the objects after adding. Please read the manual about physics.

comment out updateBallPosition() in simpleUpdate() doesn’t affect the test.

:brainsout: this is like talking to a wall… What you do is wrong. Either set the physics object to kinematic mode or control the object via forces. The code you copy/pasted is meant for the CharacterControl…

Ok, I ’ m like a wall, a stubborn wall. So the wall’s here again, with much much simpler codes, but no simpler the problem.:)[java]

package FakeGravity;



import com.jme3.app.SimpleApplication;

import com.jme3.bullet.BulletAppState;

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

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

import com.jme3.bullet.control.RigidBodyControl;

import com.jme3.bullet.util.CollisionShapeFactory;

import com.jme3.math.ColorRGBA;

import com.jme3.math.Vector3f;

import com.jme3.renderer.RenderManager;

import com.jme3.scene.Spatial;





/**

  • test
  • @author normenhansen

    */

    public class Test extends SimpleApplication {

    Spatial runway;

    Spatial ball;

    RigidBodyControl ballCtrl,runwayCtrl;

    BulletAppState bulletAppState;

    public static void main(String[] args) {

    Test app = new Test();

    app.start();

    }



    @Override

    public void simpleInitApp() {

    viewPort.setBackgroundColor(new ColorRGBA(0.7f, 0.8f, 1f, 1f));

    bulletAppState= new BulletAppState();

    stateManager.attach(bulletAppState);





    runway = assetManager.loadModel("Models/Circle.j3o");

    CollisionShape runwayShape = CollisionShapeFactory.createMeshShape(runway);

    runwayCtrl = new RigidBodyControl(runwayShape,0.5f);

    runway.addControl(runwayCtrl);



    ball = assetManager.loadModel("Models/Sphere.j3o");

    SphereCollisionShape ballShape = new SphereCollisionShape(0.5f);

    ballCtrl = new RigidBodyControl(ballShape,0.5f);

    ball.addControl(ballCtrl);



    bulletAppState.getPhysicsSpace().add(runwayCtrl);

    bulletAppState.getPhysicsSpace().add(ballCtrl);



    rootNode.attachChild(runway);

    rootNode.attachChild(ball);



    ballCtrl.setGravity(Vector3f.ZERO);

    runwayCtrl.setGravity(Vector3f.ZERO);



    }



    @Override

    public void simpleUpdate(float tpf) {

    System.out.println("ballPos="+ballCtrl.getPhysicsLocation());

    System.out.println("runwayPos="+runwayCtrl.getPhysicsLocation());

    }



    @Override

    public void simpleRender(RenderManager rm) {

    //TODO: add render code

    }

    }



    [/java]

I’ll stop answering now. I don’t even know what you want to show with that code. getPhysicsLocation works as expected. If you get 0/0/0 then your objects are at 0/0/0.

At the risk of sounding simple couldn’t you just position your objects and then create mesh shapes for them?

I corrected the problem somehow, but I don’t know why,

replace[java]

runway = assetManager.loadModel(“Models/Circle.j3o”);

ball = assetManager.loadModel(“Models/Sphere.j3o”);

[/java]

by

[java]

runway = assetManager.loadModel(“Models/Circle.mesh.xml”);

ball = assetManager.loadModel(“Models/Sphere.mesh.xml”);

[/java]

and the two objects are now at the same place.

@normen said:
I'll stop answering now. I don't even know what you want to show with that code. getPhysicsLocation works as expected. If you get 0/0/0 then your objects are at 0/0/0.

" If you get 0/0/0 then your objects are at 0/0/0." That's what I expected. but the weird thing is the two objects are at 0/0/0 by getPhysicsLocation, while I can see clearly with my eyes they are located at different positions.
what's more weird is when I replace [java]
runway = assetManager.loadModel("Models/runway.j3o");
ball = assetManager.loadModel("Models/ball.j3o");
[/java]
by[java]
runway = assetManager.loadModel("Models/runway.mesh.xml");
ball = assetManager.loadModel("Models/ball.mesh.xml");
[/java]

the two objects are now at 0/0/0 by getPhysicsLocation. and I can see them located at the same place.