Node position without rendering

Hello,



I experience a misbehavior in the DynamicsPhysicsNode, i guess. It is not possible to query the position of bodies without rendering the physics. Athough it is possible to simulate physics without rendering, the position of the physics nodes is always 0,0,0.

I thought there is a fairly clear separation between the physics simulation stuff and the graphics.



Any ideas how I can acceess the position of a physical body without rendering the scene?



Greetings,

Marcus

Of course it is possible to query the position without any visual geometry attached. Not sure why you fail to do so. Please provide a short test case, if you still can't get it working. E.g. you could put a sysout in some existing physics test which has no vis (like TestBasicRepresentation).

Hmm, I couldn't find any Test without rendering. TestBasicRepresentation is derived from SimplePhysicsGame, and has implicit rendering.

I will try to set up an "InvisiblePhysicsGame" and set up a test code. But basically I'm just calling "getWorldTranslation()" on the physics node.

ah, seems I misunderstood your set up: I thought you would render, but not the specific node. If you do not have a render loop, make sure you have set up the game loop properly. Esp. updateGeometricState must be called frequently.



To create an InvisiblePhysicsGame as test case would be good.

Here comes the "InvisblePhysicsGame":


/**
 * A minimalistic physics 'game' without rendering.
 * @author marcus bl

I got it:

The problem occurs if one additionally attaches the physics node to a scene node: Compare the following code with the working implementation:



public class FailingPositionTest extends InvisiblePhysicsGame{
    private DynamicPhysicsNode node = null;
      
    private Node scene = new Node();
   
    public FailingPositionTest() {
        createContent();
    }
   
    public static void main(String[] args){
        FailingPositionTest p = new FailingPositionTest();
        p.run(100);
    }

    private void createContent() {
        node = physicsSpace.createDynamicNode();
        PhysicsBox b = node.createBox("Box");
        node.setMass(1);
        node.attachChild(b);
        node.setLocalTranslation(new Vector3f(0,10,0));
        scene.attachChild(node);
    }

    protected void processStep() {
//        node.updateGeometricState(getStepSize(), false);
        System.out.println("Position y: "+node.getWorldTranslation().y);
    }

}



Is this expected behavior?

ehem, why is this

node.updateGeometricState(getStepSize(), false);



commented out? You really need that update. And it should go into the InvisblePhysicsGame.update() method.

Oh, its just commented out, because I wanted to see if I can still get a position if it is missing. And somehow the position (at least) is updated without manually calling it. So at least for my problem it it seems to be uncritical if this is called…

What do you think about the problem that the position information disappears if the physic node is added to a scene node?

Should I modify the invisible game in a way that it's update method loops through all nodes in the space and calls their updateGeometricState()? Is this what should happen there, so the deriving class does not need to do it?

Ok, here is a modified version of InvisiblePhysicsGame. Its update method now calls each nodes updateGeometricState(). Would this be better?


import com.jmex.physics.PhysicsNode;
import com.jmex.physics.PhysicsSpace;

/**
 * A minimalistic physics 'game' without rendering.
 * @author marcus bl

Better, yes. But what about adding a root Node and let it handle that for you?

That would be it :wink:

Finally I found out what the problem is: If you add the physics node to another node (for rendering later) the position will not be updated until the scene node has it's updateGeometricState() called.

Compare the following test with the failed test above:


public class PositionTest extends InvisiblePhysicsGame{
    private DynamicPhysicsNode node = null;
      
    private Node scene = new Node();
   
    public PositionTest() {
        createContent();
    }
   
    public static void main(String[] args){
        PositionTest p = new PositionTest();
        p.run(10);
    }

    private void createContent() {
        node = physicsSpace.createDynamicNode();
        PhysicsBox b = node.createBox("Box");
        node.setMass(1);
        node.attachChild(b);
        node.setLocalTranslation(new Vector3f(0,10,0));
       
        scene.attachChild(node);

    }

    protected void processStep() {
        // if 'scene' node is not updated the position output
        // from 'node' will be 0 (even if it's update method is called).
        scene.updateGeometricState(getStepSize(), false);
        System.out.println("Position y: "+node.getWorldTranslation().y);
    }
}



I will update the InvisibleGame with a root node.

InvisiblePhysicsGame with rootNode:

Ok I have added the root node to the code. Now you need to add the physics node to the root (via addToGame() ) in order to get them updated. I'll post both files again, the abstract class and my position test (as an example of how to use InvisiblePhysicsGame).



InvisiblePhysicsGame:


import com.jme.scene.Node;
import com.jmex.physics.PhysicsNode;
import com.jmex.physics.PhysicsSpace;

/**
 * A minimalistic physics 'game' without rendering.
 * @author marcus bl