SharedNode and physics

Hi everybody,



I once again need a pointer… I got a lot of asteroids and I want to use the physics to detect collisions with the player. Currently I create a staticPhysicsNode for every asteroid and just attach the sharedNode. Then I call generatePhysicsGeometry, but it won't work. The physicsDebugger shows nothing at all. After that I created a DynamicNode with a simple Box attached and it works just perfectly… So the question is, how to use SharedNodes with physics? I tried another way, but got stuck because the modelloader only gives me Nodes to play with, not TriMeshes…



Thanks in advance!

SharedNodes should work if they've got boundings. At least for SharedMeshes there's a test with using boundings: TestDomino



I'm not sure about using shared stuff and triangle accuracy. If it works, the current ODE implementation certainly would copy the trimesh data many times, so it will require lots of memory.

Thanks irrisor, that helped.



Next step is to figure out how to keep all the physics stuff happening in the x-y-plane. I just want to make a 2D game with 3D gfx…

see e.g. this topic

I tried to keep all the stuff in x-y-plane, but I am having some difficulties…


node.getLocalTranslation().z = 0f;


This works pretty well, I call it every update() and the playerobject stays where it should. But I can't figure out how to restrict rotations to the z-axis.
I tried this:


        float f[] = new float[3];
        node.getLocalRotation().toAngles(f);
        node.getLocalRotation().loadIdentity();
        node.getLocalRotation().fromAngleNormalAxis(f[2], new Vector3f(0f, 0f, 1f));



But then the player object just turns 180 degrees and suddenly stops..

Do you got any hints?
irrisor said:

SharedNodes should work if they've got boundings. At least for SharedMeshes there's a test with using boundings: TestDomino


Hee, I hadn't seen TestDomino yet. It's nice, and a useful resource :).

I solved the second problem. See also this thread.

I wrote a small test application I want to share:


package de;

import com.jme.animation.SpatialTransformer;
import com.jme.bounding.BoundingBox;
import com.jme.input.KeyBindingManager;
import com.jme.input.KeyInput;
import com.jme.math.FastMath;
import com.jme.math.Quaternion;
import com.jme.math.Vector3f;
import com.jme.scene.shape.Box;
import com.jme.scene.shape.Sphere;
import com.jmex.physics.DynamicPhysicsNode;
import com.jmex.physics.StaticPhysicsNode;
import com.jmex.physics.util.SimplePhysicsGame;
import java.util.Random;


public class Test extends SimplePhysicsGame{
    DynamicPhysicsNode dyna;
    Vector3f front;
    Vector3f right;
    Vector3f tmp;
    Vector3f tmpArr [];
    float angles [];
   
    public Test() {
        front = new Vector3f(0f, 1f, 0f);
        right = new Vector3f(1f, 0f, 0f);
        tmp = new Vector3f();
        tmpArr = new Vector3f[3];
        tmpArr[0] = new Vector3f();
        tmpArr[1] = new Vector3f();
        tmpArr[2] = new Vector3f();
        angles = new float[3];
    }
   
    protected void simpleUpdate(){
        Vector3f v = new Vector3f(dyna.getLocalTranslation());
        v.z = 50f;
        cam.setLocation(v);
       
        if(dyna.getLocalTranslation().y <= -100f){
            dyna.getLocalTranslation().set(0f, 10f, 0f);
            dyna.clearDynamics();
        }
       
        if(KeyBindingManager.getKeyBindingManager().isValidCommand("thrust")){
            tmp = dyna.getLocalRotation().mult(front);
            tmp.normalize();
            dyna.addForce(tmp.mult(10f));
        }
        if(KeyBindingManager.getKeyBindingManager().isValidCommand("turnright")){
            tmp = dyna.getLocalRotation().mult(right);
            tmp.normalize();
            dyna.addForce(tmp.mult(1f), new Vector3f(0f, 4f, 0f));
        }
        if(KeyBindingManager.getKeyBindingManager().isValidCommand("turnleft")){
            tmp = dyna.getLocalRotation().mult(right);
            tmp.normalize();
            dyna.addForce(tmp.mult(-1f), new Vector3f(0f, 4f, 0f));
        }
        if(KeyBindingManager.getKeyBindingManager().isValidCommand("turn1")){
            dyna.addForce(new Vector3f(1.2f, 0.7f, 2.9f), new Vector3f(1f, 4f, 0.2f));
        }
        if(KeyBindingManager.getKeyBindingManager().isValidCommand("turn2")){
            dyna.addForce(new Vector3f(1.2f, -0.7f, -2.9f), new Vector3f(0.2f, 4f, -1f));
        }
       
        if(KeyBindingManager.getKeyBindingManager().isValidCommand("reset")){
            reset();
        }
       
        reset();
    }
   
    /**
     * resets the rotations and keeps the rotation around the z-axis
     */
    public void reset(){
        dyna.getLocalTranslation().z = 0f;
        tmp = dyna.getLocalRotation().mult(front);
        tmp.z = 0f;
        dyna.getLocalRotation().lookAt(new Vector3f(0f, 0f, 1f), tmp);
    }
   
    protected void simpleInitGame() {
        KeyBindingManager.getKeyBindingManager().set("thrust", KeyInput.KEY_W);
        KeyBindingManager.getKeyBindingManager().set("turnright", KeyInput.KEY_D);
        KeyBindingManager.getKeyBindingManager().set("turnleft", KeyInput.KEY_A);
        KeyBindingManager.getKeyBindingManager().set("reset", KeyInput.KEY_O);
        KeyBindingManager.getKeyBindingManager().set("turn1", KeyInput.KEY_Q);
        KeyBindingManager.getKeyBindingManager().set("turn2", KeyInput.KEY_E);
       
       
        Random r = FastMath.rand;
        for(int i = 0; i < 90; i++){
            StaticPhysicsNode stat = getPhysicsSpace().createStaticNode();
            stat.setLocalTranslation((r.nextFloat()-0.5f)*50f, -r.nextFloat()*100f, 0f);
            Box b = new Box("test"+i, new Vector3f(), 1f, 1f, 1f);
            b.setModelBound(new BoundingBox());
            b.updateModelBound();
           
            SpatialTransformer trans = new SpatialTransformer(1);
            trans.setObject(stat, 0, -1);
            float startAngle = 0f;//r.nextFloat();
            Vector3f vec = new Vector3f(r.nextFloat()-0.5f, r.nextFloat()-0.5f, r.nextFloat()-0.5f);
            Quaternion q1 = new Quaternion();
            q1.fromAngleAxis(startAngle, vec);
            Quaternion q2 = new Quaternion();
            q2.fromAngleAxis(startAngle+FastMath.PI, vec);
            Quaternion q3 = new Quaternion();
            q3.fromAngleAxis(startAngle + FastMath.TWO_PI, vec);
            float time = 10f + 3*r.nextFloat();
            trans.setRotation(0, 0f, q1);
            trans.setRotation(0, time, q2);
            trans.setRotation(0, 2*time, q3);
            trans.setRepeatType(SpatialTransformer.RT_WRAP);
            trans.interpolateMissing();
            stat.addController(trans);
           
            stat.attachChild(b);
           
            stat.generatePhysicsGeometry();
            rootNode.attachChild(stat);
        }
       
        getPhysicsSpace().setDirectionalGravity(new Vector3f(0f, -3.25f, 0f));
       
        dyna = getPhysicsSpace().createDynamicNode();
        dyna.attachChild(new Box("box", new Vector3f(), 0.2f, 2f, 1f));
        dyna.attachChild(new Sphere("sphere", new Vector3f(0f, 1.8f, 0f), 3, 5, 1.0f));
        dyna.setLocalTranslation(0f, 10f, 0f);
        dyna.generatePhysicsGeometry();
        rootNode.attachChild(dyna);
    }
   
    public static void main(String [] args){
        new Test().start();
    }
}