jMonkeyEngine / jMonkeyEngine/jmonkeyengine

physics joints don't work unless both bodies are dynamic

Open
#877 14 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug Contribution welcome Physics
Dominant language
Java
Stars
4.3k
Forks
1.2k
Avg merge
4d 7h
Merged PRs (30d)
14

Description

Hi!

I was following this tutorial https://wiki.jmonkeyengine.org/jme3/advanced/hinges_and_joints.html and I'm doing a cradle with 6 joints and 6 balls.

The problem is that if I have more than 1 joint, the other joints is going to fall down.

Here is the code. Try to run it and add some hinge joints by removing the comments down there.

Right now the code
bulletAppState.getPhysicsSpace().add(Wire1Joint1);

Is activaded and you should see a pendelum with a square.

Try to activate

bulletAppState.getPhysicsSpace().add(Wire1Joint2);

package mygame;


import com.jme3.app.SimpleApplication;
import com.jme3.asset.AssetManager;
import com.jme3.bullet.BulletAppState;
import static com.jme3.bullet.PhysicsSpace.getPhysicsSpace;
import com.jme3.bullet.collision.shapes.BoxCollisionShape;
import com.jme3.bullet.collision.shapes.CollisionShape;
import com.jme3.bullet.control.RigidBodyControl;
import com.jme3.bullet.joints.HingeJoint;
import com.jme3.math.Vector3f;
import com.jme3.renderer.RenderManager;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;


/**
 * This is the Main Class of your Game. You should only do initialization here.
 * Move your Logic into AppStates or Controls
 * @author normenhansen
 */
public class Main extends SimpleApplication {

    private BulletAppState bulletAppState;
    
    public static void main(String[] args) {
        Main app = new Main();
        app.start();
    }

    @Override
    public void simpleInitApp() {
        flyCam.setMoveSpeed(20);
        
        bulletAppState = new BulletAppState();
        stateManager.attach(bulletAppState);
        bulletAppState.setDebugEnabled(true);
        
        // Load Cradle
        //Spatial Frame = assetManager.loadModel("Scenes/CradleScene.j3o");
        // Create node for that Cradle
        Node FrameNode = new Node();
        // Attach the cradle at the node
        //FrameNode.attachChild(Frame);
        rootNode.attachChild(FrameNode);
        
        // Create the static nodes for left wire
        //Node LeftWire1StaticNode = PhysicsTestHelper.createPhysicsTestNode(assetManager, new BoxCollisionShape(new Vector3f( .1f, .1f, .1f)),0);
        //Node LeftWire2StaticNode = PhysicsTestHelper.createPhysicsTestNode(assetManager, new BoxCollisionShape(new Vector3f( .1f, .1f, .1f)),0);
        //Node LeftWire3StaticNode = PhysicsTestHelper.createPhysicsTestNode(assetManager, new BoxCollisionShape(new Vector3f( .1f, .1f, .1f)),0);
        //Node LeftWire4StaticNode = PhysicsTestHelper.createPhysicsTestNode(assetManager, new BoxCollisionShape(new Vector3f( .1f, .1f, .1f)),0);
        //Node LeftWire5StaticNode = PhysicsTestHelper.createPhysicsTestNode(assetManager, new BoxCollisionShape(new Vector3f( .1f, .1f, .1f)),0);
        //Node LeftWire6StaticNode = PhysicsTestHelper.createPhysicsTestNode(assetManager, new BoxCollisionShape(new Vector3f( .1f, .1f, .1f)),0);
        
        Node Wire1StaticNode = createPhysicsTestNode(assetManager, new BoxCollisionShape(new Vector3f( .1f, .1f, .1f)),0);
        Node Wire2StaticNode = createPhysicsTestNode(assetManager, new BoxCollisionShape(new Vector3f( .1f, .1f, .1f)),0);
        Node Wire3StaticNode = createPhysicsTestNode(assetManager, new BoxCollisionShape(new Vector3f( .1f, .1f, .1f)),0);
        Node Wire4StaticNode = createPhysicsTestNode(assetManager, new BoxCollisionShape(new Vector3f( .1f, .1f, .1f)),0);
        Node Wire5StaticNode = createPhysicsTestNode(assetManager, new BoxCollisionShape(new Vector3f( .1f, .1f, .1f)),0);
        Node Wire6StaticNode = createPhysicsTestNode(assetManager, new BoxCollisionShape(new Vector3f( .1f, .1f, .1f)),0);
        
        // Create the static nodes for rigth wire
        //Node RigthWire1StaticNode = PhysicsTestHelper.createPhysicsTestNode(assetManager, new BoxCollisionShape(new Vector3f( .1f, .1f, .1f)),0);
        //Node RigthWire2StaticNode = PhysicsTestHelper.createPhysicsTestNode(assetManager, new BoxCollisionShape(new Vector3f( .1f, .1f, .1f)),0);
        //Node RigthWire3StaticNode = PhysicsTestHelper.createPhysicsTestNode(assetManager, new BoxCollisionShape(new Vector3f( .1f, .1f, .1f)),0);
        //Node RigthWire4StaticNode = PhysicsTestHelper.createPhysicsTestNode(assetManager, new BoxCollisionShape(new Vector3f( .1f, .1f, .1f)),0);
        //Node RigthWire5StaticNode = PhysicsTestHelper.createPhysicsTestNode(assetManager, new BoxCollisionShape(new Vector3f( .1f, .1f, .1f)),0);
        //Node RigthWire6StaticNode = PhysicsTestHelper.createPhysicsTestNode(assetManager, new BoxCollisionShape(new Vector3f( .1f, .1f, .1f)),0);
        
        // Create the dyncamical nodes for the balls
        Node Ball1Node = createPhysicsTestNode(assetManager, new BoxCollisionShape(new Vector3f( .1f, .1f, .1f)),1f);
        Node Ball2Node = createPhysicsTestNode(assetManager, new BoxCollisionShape(new Vector3f( .1f, .1f, .1f)),1);
        Node Ball3Node = createPhysicsTestNode(assetManager, new BoxCollisionShape(new Vector3f( .1f, .1f, .1f)),1);
        Node Ball4Node = createPhysicsTestNode(assetManager, new BoxCollisionShape(new Vector3f( .1f, .1f, .1f)),1);
        Node Ball5Node = createPhysicsTestNode(assetManager, new BoxCollisionShape(new Vector3f( .1f, .1f, .1f)),1);
        Node Ball6Node = createPhysicsTestNode(assetManager, new BoxCollisionShape(new Vector3f( .1f, .1f, .1f)),1);
        
        // Place out the static nodes for left wire
        //LeftWire1StaticNode.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(6f, 14.6214f,-7.56346f));
        //LeftWire2StaticNode.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(3.5f, 14.6214f,-7.56346f));
        //LeftWire3StaticNode.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(1f, 14.6214f,-7.56346f));
        //LeftWire4StaticNode.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(-1.5f, 14.6214f,-7.56346f));
        //LeftWire5StaticNode.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(-4f, 14.6214f,-7.56346f));
        //LeftWire6StaticNode.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(-6.5f, 14.6214f,-7.56346f));
        
        Wire1StaticNode.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(6f, 14.6214f,0f));
        Wire2StaticNode.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(3.5f, 14.6214f,0f));
        Wire3StaticNode.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(1f, 14.6214f,0f));
        Wire4StaticNode.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(-1.5f, 14.6214f,0f));
        Wire5StaticNode.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(-4f, 14.6214f,0f));
        Wire6StaticNode.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(-6.5f, 14.6214f,0f));
        
        // Place out the static nodes for the rigth wire
        //RigthWire1StaticNode.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(6f, 14.6214f,7.56346f));
        //RigthWire2StaticNode.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(3.5f, 14.6214f,7.56346f));
        //RigthWire3StaticNode.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(1f, 14.6214f,7.56346f));
        //RigthWire4StaticNode.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(-1.5f, 14.6214f,7.56346f));
        //RigthWire5StaticNode.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(-4f, 14.6214f,7.56346f));
        //RigthWire6StaticNode.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(-6.5f, 14.6214f,7.56346f));
        
        // Place out the dynamical nodes for the balls
        /*
        Ball1Node.getControl(RigidBodyControl.class).setPhysicsLocation(FrameNode.getChild("Ball1").getLocalTranslation());
        Ball2Node.getControl(RigidBodyControl.class).setPhysicsLocation(FrameNode.getChild("Ball2").getLocalTranslation());
        Ball3Node.getControl(RigidBodyControl.class).setPhysicsLocation(FrameNode.getChild("Ball3").getLocalTranslation());
        Ball4Node.getControl(RigidBodyControl.class).setPhysicsLocation(FrameNode.getChild("Ball4").getLocalTranslation());
        Ball5Node.getControl(RigidBodyControl.class).setPhysicsLocation(FrameNode.getChild("Ball5").getLocalTranslation());
        Ball6Node.getControl(RigidBodyControl.class).setPhysicsLocation(FrameNode.getChild("Ball6").getLocalTranslation());
        */
        
        Ball1Node.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(6, 3, 0));
        Ball2Node.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(3.5f, 3, 0));
        Ball3Node.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(1, 3, 0));
        Ball4Node.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(-1.5f, 3, 0));
        Ball5Node.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(-4, 3, 0));
        Ball6Node.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(-6.5f, 3, 0));
        
        
        // Attach the nodes
        /*
        FrameNode.attachChild(LeftWire1StaticNode);
        FrameNode.attachChild(LeftWire2StaticNode);
        FrameNode.attachChild(LeftWire3StaticNode);
        FrameNode.attachChild(LeftWire4StaticNode);
        FrameNode.attachChild(LeftWire5StaticNode);
        FrameNode.attachChild(LeftWire6StaticNode);
        */
        
        FrameNode.attachChild(Wire1StaticNode);
        FrameNode.attachChild(Wire2StaticNode);
        FrameNode.attachChild(Wire3StaticNode);
        FrameNode.attachChild(Wire4StaticNode);
        FrameNode.attachChild(Wire5StaticNode);
        FrameNode.attachChild(Wire6StaticNode);
        
        /*
        FrameNode.attachChild(RigthWire1StaticNode);
        FrameNode.attachChild(RigthWire2StaticNode);
        FrameNode.attachChild(RigthWire3StaticNode);
        FrameNode.attachChild(RigthWire4StaticNode);
        FrameNode.attachChild(RigthWire5StaticNode);
        FrameNode.attachChild(RigthWire6StaticNode);
        */
        
        // Sett the physics at the nodes
        /*
        getPhysicsSpace().add(LeftWire1StaticNode);
        getPhysicsSpace().add(LeftWire2StaticNode);
        getPhysicsSpace().add(LeftWire3StaticNode);
        getPhysicsSpace().add(LeftWire4StaticNode);
        getPhysicsSpace().add(LeftWire5StaticNode);
        getPhysicsSpace().add(LeftWire6StaticNode);
        */
        
        getPhysicsSpace().add(Wire1StaticNode);
        getPhysicsSpace().add(Wire2StaticNode);
        getPhysicsSpace().add(Wire3StaticNode);
        getPhysicsSpace().add(Wire4StaticNode);
        getPhysicsSpace().add(Wire5StaticNode);
        getPhysicsSpace().add(Wire6StaticNode);
        
        /*
        getPhysicsSpace().add(RigthWire1StaticNode);
        getPhysicsSpace().add(RigthWire2StaticNode);
        getPhysicsSpace().add(RigthWire3StaticNode);
        getPhysicsSpace().add(RigthWire4StaticNode);
        getPhysicsSpace().add(RigthWire5StaticNode);
        getPhysicsSpace().add(RigthWire6StaticNode);
        */
        
        // Sett the nodes for the balls
        FrameNode.attachChild(Ball1Node);
        FrameNode.attachChild(Ball2Node);
        FrameNode.attachChild(Ball3Node);
        FrameNode.attachChild(Ball4Node);
        FrameNode.attachChild(Ball5Node);
        FrameNode.attachChild(Ball6Node);
        
        // Sett the physics for the balls
        getPhysicsSpace().add(Ball1Node);
        getPhysicsSpace().add(Ball2Node);
        getPhysicsSpace().add(Ball3Node);
        getPhysicsSpace().add(Ball4Node);
        getPhysicsSpace().add(Ball5Node);
        getPhysicsSpace().add(Ball6Node);
        
        
        
        // 14.6214f = The static node Y-heigth 
        // 3f = The balls Y-heigth
        // So the rod will be 14.6214 - 3
        
        HingeJoint Wire1Joint1 = new HingeJoint(Wire1StaticNode.getControl(RigidBodyControl.class),
                                                    Ball1Node.getControl(RigidBodyControl.class),
                                                    Wire1StaticNode.getLocalTranslation(),
                                                    new Vector3f(14.6214f - 3f, 0f, 0f),
                                                    Vector3f.UNIT_Z,
                                                    Vector3f.UNIT_Z);
       
        /*
        HingeJoint Wire1Joint2 = new HingeJoint(Wire2StaticNode.getControl(RigidBodyControl.class),
                                                    Ball2Node.getControl(RigidBodyControl.class),
                                                    Wire2StaticNode.getLocalTranslation(),
                                                    new Vector3f(14.6214f - 3f, 0f, 0f),
                                                    Vector3f.UNIT_Z,
                                                    Vector3f.UNIT_Z);
        
        
        HingeJoint Wire1Joint3 = new HingeJoint(Wire3StaticNode.getControl(RigidBodyControl.class),
                                                    Ball3Node.getControl(RigidBodyControl.class),
                                                    Wire3StaticNode.getLocalTranslation(),
                                                    new Vector3f(14.6214f - 3f, 0f, 0f),
                                                    Vector3f.UNIT_Z,
                                                    Vector3f.UNIT_Z);
        
        HingeJoint Wire1Joint4 = new HingeJoint(Wire4StaticNode.getControl(RigidBodyControl.class),
                                                    Ball4Node.getControl(RigidBodyControl.class),
                                                    Wire4StaticNode.getLocalTranslation(),
                                                    new Vector3f(14.6214f - 3f, 0f, 0f),
                                                    Vector3f.UNIT_Z,
                                                    Vector3f.UNIT_Z);
        
        HingeJoint Wire1Joint5 = new HingeJoint(Wire5StaticNode.getControl(RigidBodyControl.class),
                                                    Ball5Node.getControl(RigidBodyControl.class),
                                                    Wire5StaticNode.getLocalTranslation(),
                                                    new Vector3f(14.6214f - 3f, 0f, 0f),
                                                    Vector3f.UNIT_Z,
                                                    Vector3f.UNIT_Z);
        
        HingeJoint Wire1Joint6 = new HingeJoint(Wire6StaticNode.getControl(RigidBodyControl.class),
                                                    Ball6Node.getControl(RigidBodyControl.class),
                                                    Wire6StaticNode.getLocalTranslation(),
                                                    new Vector3f(14.6214f - 3f, 0f, 0f),
                                                    Vector3f.UNIT_Z,
                                                    Vector3f.UNIT_Z);
       */
       // Add joint
       
        // Activate the physics for every joints
        
        bulletAppState.getPhysicsSpace().add(Wire1Joint1);
        //bulletAppState.getPhysicsSpace().add(Wire1Joint2);
        //bulletAppState.getPhysicsSpace().add(Wire1Joint3);
        //bulletAppState.getPhysicsSpace().add(Wire1Joint4);
        //bulletAppState.getPhysicsSpace().add(Wire1Joint5);
        //bulletAppState.getPhysicsSpace().add(Wire1Joint6);
        
        
    }

    @Override
    public void simpleUpdate(float tpf) {
        //TODO: add update code
    }

    @Override
    public void simpleRender(RenderManager rm) {
        //TODO: add render code
    }
    
    private Node createPhysicsTestNode(AssetManager manager, CollisionShape shape, float mass) {
        Node node = new Node("PhysicsNode");
        RigidBodyControl control = new RigidBodyControl(shape, mass);
        node.addControl(control);
        return node;
    }
}

Information

openjdk 10.0.1 2018-04-17
OpenJDK Runtime Environment (build 10.0.1+10-Ubuntu-3ubuntu1)
OpenJDK 64-Bit Server VM (build 10.0.1+10-Ubuntu-3ubuntu1, mixed mode)

jMonkeyEngine V3.2.1-Stable SDK 3 with JDK 1.8 as default

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the supplied Main.simpleInitApp reproduction and the linked hinges-and-joints tutorial. Enable Wire1Joint2 after Wire1Joint1 and inspect the HingeJoint and BulletAppState physics-space setup around the Wire nodes. Done means multiple joints remain attached instead of the other joints falling.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
game-dev
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.