Joint problem

I'm creating a ragdoll puppet program which attaches joints to the hands feet and head of a ragdoll and then moves the anchors of the joints to animate it. I've tried to use the code from the physics picker to make a class that would do this but have been unsuccessful. how should i go about doing this?

Animating ragdolls will be hard, I think. You can use powered joints or 'pull' the extremities, I guess. But I don't have experience with ragdolls. The ragdoll test was contributed (search on boards), but it's not animated in that sense…

the class will not be specifically for ragdolls. the goal is to make a class that works like the physics picker but where you can move the pick node using the keyboard or along bezier curves.

OK I've made the class (mostly pulled form physics picker) which can attach a dynamic physics node and move it but if i release and then re-attach the joint pushes the picked object away.


public class LimbJoint {

    private final Node rootNode;
    private final DynamicPhysicsNode myNode;
    private final Joint joint;
    private final Joint worldJoint;
    private DynamicPhysicsNode Limb;
    private Quaternion limbRotation = new Quaternion();
    private boolean attached = false;  
    private LimbJoint.MoveAction moveAction;
    private Node worldNode;
    private boolean allowRotation = true;

  
    public LimbJoint(Node rootNode, DynamicPhysicsNode limbInput, PhysicsSpace physicsSpace) {
      
        this.rootNode = rootNode;
        joint = physicsSpace.createJoint();
        if (allowRotation) {
            joint.createRotationalAxis().setDirection(Vector3f.UNIT_X);
            joint.createRotationalAxis().setDirection(Vector3f.UNIT_Y);
            joint.createRotationalAxis().setDirection(Vector3f.UNIT_Z);
        }
        Limb = limbInput;
        worldNode = new Node("limbLoc");
        rootNode.attachChild(worldNode);
        joint.setSpring(2000, 200);
        myNode = physicsSpace.createDynamicNode();
        myNode.setName("Physics Picker Helper Node");
        myNode.setAffectedByGravity(false);
        worldJoint = physicsSpace.createJoint();
        activatePhysicsPicker();
        attach();
    }
    private DynamicPhysicsNode picked;
    private final Vector2f mousePosition = new Vector2f();

    public boolean isAttached() {
        return attached;
    }

    public void move(Vector3f loc, Quaternion dir) {
        worldNode.setLocalTranslation(loc);
        worldNode.setLocalRotation(dir);
        moveAction.performAction(null);
    }

    private void activatePhysicsPicker() {

        moveAction = new MoveAction();
    }

    public void release() {
        picked = null;
        joint.detach();
        worldJoint.detach();
        myNode.setActive(false);
        attached = false;
    }
    private final Vector3f pickedScreenPos = new Vector3f();
    private final Vector3f pickedWorldOffset = new Vector3f();

    public void attach() {
        worldNode.setLocalTranslation(Limb.getWorldTranslation());
        pickedWorldOffset.set(worldNode.getLocalTranslation());
        picked = Limb;
        Limb.localToWorld(Limb.getCenterOfMass(myNode.getLocalTranslation()), myNode.getLocalTranslation());
        pickedWorldOffset.subtractLocal(myNode.getLocalTranslation());
        myNode.setActive(true);
        worldJoint.setAnchor(myNode.getLocalTranslation());
        worldJoint.attach(myNode);
        joint.attach(myNode, Limb);
        joint.setAnchor(new Vector3f());
        attached = true;
    }

    public void delete() { 
        myNode.setActive(false);
        myNode.removeFromParent();
        joint.detach();
        joint.setActive(false);
        worldJoint.detach();
        worldJoint.setActive(false);
        picked = null;
    }

    public DynamicPhysicsNode getPickedNode() {
        return picked;
    }

    private class MoveAction extends InputAction {

        private final Vector3f anchor = new Vector3f();

        public void performAction(InputActionEvent evt) {



            if (picked != null) {
              
                anchor.set(worldNode.getLocalTranslation());

                myNode.getLocalTranslation().set(anchor.subtractLocal(pickedWorldOffset));
                worldJoint.setAnchor(myNode.getLocalTranslation());
                worldJoint.attach(myNode);
            }
        }
    }
}



if anyone can tell me where I'm going wrong i would be grateful

could you create a little demo app to show the problem?

if people just can copy paste the code and try it out its easier to help :slight_smile:

i finally managed to fix it :smiley:

i just needed to call attach on every cycle, rookie mistake