Physics6DofJoint question

Hi again…  Sorry for being a pest.  I have another question.



I setup another test case.  Two (2) PhysicsNodes 'tied together' with a Physics6DofJoint, all angular and linear joint limits set to zero (0.f).  An impluse is applied at the C.G. of one of the Nodes (the larger, more massive of the two, in this case).  This results is, the first (impulse applied to) Node rotate. The second Node also rotates but lags such that it hinged about the common connection point.  I assume (and may have read) that there are springs associated with each DOF to prevent INF and singular matrices.

Assuming I don't have a mistake in my code or assumptions (sorry if I do), then are the associate spring rates adustable?



import com.jme3.app.SimpleBulletApplication;
import com.jme3.asset.TextureKey;
import com.jme3.bullet.collision.CollisionEvent;
import com.jme3.bullet.collision.CollisionListener;
import com.jme3.bullet.collision.shapes.BoxCollisionShape;
import com.jme3.bullet.collision.shapes.SphereCollisionShape;
import com.jme3.bullet.joints.Physics6DofJoint;
import com.jme3.bullet.nodes.PhysicsNode;

import com.jme3.input.KeyInput;
import com.jme3.input.binding.BindingListener;
import com.jme3.light.PointLight;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Matrix3f;
import com.jme3.math.Quaternion;
import com.jme3.math.Vector3f;
import com.jme3.renderer.Camera;
import com.jme3.scene.Geometry;


import com.jme3.scene.shape.Box;
import com.jme3.scene.shape.Sphere;
import com.jme3.texture.Texture;

public class TestBox_2 extends SimpleBulletApplication implements BindingListener, CollisionListener
{
     PhysicsNode player, npn, xpn;
     Quaternion tempQ1;
     Vector3f tempV1, tempV2;
     boolean test = true;
     public static void main(String[] args)
     {
        TestBox_2 app = new TestBox_2();
        app.start();
     }

     private void build()
     {
       
          Vector3f v3F = new Vector3f(0, 0, 0);
          Vector3f v4F = new Vector3f(0, 0, 0);
          PointLight pl = new PointLight();
          pl.setColor(ColorRGBA.White);
          pl.setPosition(v3F);
         
          pl.setRadius(100f);
          rootNode.addLight(pl);
          getPhysicsSpace().setAccuracy(1.f/1000f);
          getPhysicsSpace().setGravity(Vector3f.ZERO);

          Material mat = new Material(assetManager, "Common/MatDefs/Misc/SimpleTextured.j3md");
          TextureKey key = new TextureKey("Interface/Logo/Monkey.jpg", true);
          key.setGenerateMips(true);
          Texture tex = assetManager.loadTexture(key);
          mat.setTexture("m_ColorMap", tex);
         
        Camera cam5C = getCamera();
        cam5C.setLocation(new Vector3f(0f,0f,0f));
        CameraNode cameraNode = new CameraNode("TEST", cam5C);
        cameraNode.updateGeometricState();
        float[] fTemp = { 0.f, (float)Math.PI, 0.f};
        Quaternion qTemp = new Quaternion(fTemp);
        cameraNode.setLocalRotation(qTemp);
        cameraNode.setLocalTranslation(0, 0, 25);

        cameraNode.setEnabled(true);

          Box s1 = new Box(Vector3f.ZERO, 4.f, 3.f, 1.5f);
          Geometry g1 = new Geometry("S1",s1);
          g1.setMaterial(mat);
          player = new PhysicsNode(g1,new BoxCollisionShape(new Vector3f(4.f, 3.f, 1.5f)), 4000.f);
          v3F.set(-4.f , 0.f, .0f);
          player.setLocalTranslation(v3F);
          player.setDamping(0f, 0f);
          player.setSleepingThresholds(0, 0);
          //player.setKinematic(true);
          player.attachChild(cameraNode);
          player.updateGeometricState();
          player.updateModelBound();
          rootNode.attachChild(player);
          getPhysicsSpace().addQueued(player);


          Sphere s2 = new Sphere(10,10,1.5f);
          Geometry g2 = new Geometry("S2",s2);
          g2.setMaterial(mat);
          npn = new PhysicsNode(g2,new SphereCollisionShape(1.5f), 500.f);
          npn.setDamping(.0f, .0f);
          v4F.set(1.5f, .0f, 0.f);
          npn.setLocalTranslation(v4F);
          //npn.pNode.setLocalRotation(m5F);
          npn.setSleepingThresholds(0, 0);
          npn.updateGeometricState();

          npn.updateModelBound();
          rootNode.attachChild(npn);
          rootNode.updateGeometricState();

          getPhysicsSpace().addQueued(npn);

          Matrix3f m7F = new Matrix3f();

          Physics6DofJoint pJoint = new Physics6DofJoint(   player,
                                                            npn,
                                                            new Vector3f(4f,0f,0f),
                                                            new Vector3f(-1.5f,0f,0f),
                                                            m7F,
                                                            m7F,
                                                            true);
          pJoint.setCollisionBetweenLinkedBodys(false);
          pJoint.setAngularLowerLimit(Vector3f.ZERO);
          pJoint.setAngularUpperLimit(Vector3f.ZERO);
          pJoint.setLinearLowerLimit(Vector3f.ZERO);
          pJoint.setLinearUpperLimit(Vector3f.ZERO);
          getPhysicsSpace().add(pJoint);
     }

     @Override
     public void collision(CollisionEvent event)
     {
          if(event.getNodeA().getName() != null)
          {
               if(event.getNodeA().getName().equals("BOX") ||
                  event.getNodeB().getName().equals("BOX") )
               {
                     System.out.println(event.getNodeA().getName());
                     System.out.println(event.getNodeB().getName());
                     System.out.println(event.getIndex0());
                     System.out.println(event.getIndex1());
               }
          }
     }
   
     private void setupKeys()
     {
         
          inputManager.registerKeyBinding("ENTER", KeyInput.KEY_RETURN);
          inputManager.registerMouseButtonBinding("ENTER", 3);
          inputManager.registerMouseButtonBinding("LEFT", 0);
          inputManager.registerMouseButtonBinding("RIGHT", 1);

          inputManager.addBindingListener(this);
    }

    @Override
    public void onBinding(String binding, float value)
    {
        
          if (binding.equals("ENTER"))
          {
               player.setLinearVelocity(Vector3f.ZERO);
               player.setAngularVelocity(Vector3f.ZERO);
               npn.setLinearVelocity(Vector3f.ZERO);
               npn.setAngularVelocity(Vector3f.ZERO);
               if(test)
               {
                    test = false;
               }
               else
               {
                    test = true;
               }
          }
          if(binding == null ? "LEFT" == null : binding.equals("LEFT"))
          {
               tempQ1.set(player.getWorldRotation());
               tempV1 = tempQ1.getRotationColumn(1);
               tempV2 = tempV1.mult(100f);
               player.applyImpulse(tempV2, Vector3f.ZERO);
         }
          if(binding == null ? "RIGHT" == null : binding.equals("RIGHT"))
          {
               tempQ1.set(player.getWorldRotation());
               tempV1 = tempQ1.getRotationColumn(1);
               tempV2 = tempV1.mult(-100f);
               player.applyImpulse(tempV2, Vector3f.ZERO);
         }
    }

    @Override
    public void simpleInitApp()
    {
         setupKeys();
         build();
         getPhysicsSpace().addCollisionListener(this);
         tempQ1 = new Quaternion();
    }

     @Override
    public void simpleUpdate(float tpf)
    {
         tempQ1.set(player.getLocalRotation());
              tempV1 = tempQ1.getRotationColumn(2);
              if(test)
              {
                    tempV2 = tempV1.mult(20000.f);
                  //  player.applyTorque(tempV2);
                    System.out.println(npn.getWorldTranslation().distance(player.getWorldTranslation()));
                    System.out.println(player.getAngularVelocity());
              }
    }

The 6dofJoint has 4 limit motors to modify the axes forces and damping, you can get the translational one with getTranslationalLimitMotor() and the rotational ones with getRotationalLimitMotor(int index).



Cheers,

Normen

As always, many thanks.