Kinematic Ragdoll Position and Function error

I replicated the TestBoneRagdoll demo in hopes that I would be able to make two enemies and shoot them on both two different locations. However, as you can see on my code (below), the ogres stay at the same position. How do I make them placed on a different position? Also, if I hit one of them, both of them dies. How can I make this properly?

Here’s the code:

package jme3test.bullet;



import com.jme3.animation.*;
import com.jme3.app.SimpleApplication;
import com.jme3.asset.TextureKey;
import com.jme3.bullet.BulletAppState;
import com.jme3.bullet.PhysicsSpace;
import com.jme3.bullet.collision.PhysicsCollisionEvent;
import com.jme3.bullet.collision.PhysicsCollisionObject;
import com.jme3.bullet.collision.RagdollCollisionListener;
import com.jme3.bullet.collision.shapes.SphereCollisionShape;
import com.jme3.bullet.control.KinematicRagdollControl;
import com.jme3.bullet.control.RigidBodyControl;
import com.jme3.font.BitmapText;
import com.jme3.input.KeyInput;
import com.jme3.input.MouseInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.input.controls.MouseButtonTrigger;
import com.jme3.light.DirectionalLight;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.FastMath;
import com.jme3.math.Quaternion;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import com.jme3.scene.debug.SkeletonDebugger;
import com.jme3.scene.shape.Sphere;
import com.jme3.scene.shape.Sphere.TextureMode;
import com.jme3.texture.Texture;

public class TestBoneRagdoll extends SimpleApplication implements RagdollCollisionListener, AnimEventListener {

    private BulletAppState bulletAppState;
    Material matBullet;
    Node model;
    Node orc_model;
    KinematicRagdollControl ragdoll;
    KinematicRagdollControl orc;
    float bulletSize = 1f;
    Material mat;
    Material mat3;
    Material orcMat;
    private Sphere bullet;
    private SphereCollisionShape bulletCollisionShape;

    public static void main(String[] args) {
        TestBoneRagdoll app = new TestBoneRagdoll();
        app.start();
    }

    public void simpleInitApp() {
        initCrossHairs();
        initMaterial();

        cam.setLocation(new Vector3f(0.26924422f, 6.646658f, 22.265987f));
        cam.setRotation(new Quaternion(-2.302544E-4f, 0.99302495f, -0.117888905f, -0.0019395084f));


        bulletAppState = new BulletAppState();
        bulletAppState.setEnabled(true);
        stateManager.attach(bulletAppState);
        bullet = new Sphere(32, 32, 1.0f, true, false);
        bullet.setTextureMode(TextureMode.Projected);
        bulletCollisionShape = new SphereCollisionShape(1.0f);

        PhysicsTestHelper.createPhysicsTestWorld(rootNode, assetManager, bulletAppState.getPhysicsSpace());
        setupLight();

        model = (Node) assetManager.loadModel("Models/Sinbad/Sinbad.mesh.xml");
        orc_model = (Node) assetManager.loadModel("Models/Sinbad/Sinbad.mesh.xml");

        //debug view
        AnimControl control = model.getControl(AnimControl.class);
        SkeletonDebugger skeletonDebug = new SkeletonDebugger("skeleton", control.getSkeleton());
        Material mat2 = new Material(getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
        mat2.getAdditionalRenderState().setWireframe(true);
        mat2.setColor("Color", ColorRGBA.Green);
        mat2.getAdditionalRenderState().setDepthTest(false);
        skeletonDebug.setMaterial(mat2);
        skeletonDebug.setLocalTranslation(model.getLocalTranslation());
        
        AnimControl orc_control = orc_model.getControl(AnimControl.class);
        SkeletonDebugger orc_skeletonDebug = new SkeletonDebugger("skeleton", control.getSkeleton());
        Material mater3 = new Material(getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
        mater3.getAdditionalRenderState().setWireframe(true);
        mater3.setColor("Color", ColorRGBA.Blue);
        mater3.getAdditionalRenderState().setDepthTest(false);
        orc_skeletonDebug.setMaterial(mater3);
        orc_skeletonDebug.setLocalTranslation(orc_model.getLocalTranslation());        

        //Note: PhysicsRagdollControl is still TODO, constructor will change
        ragdoll = new KinematicRagdollControl(0.5f);
        setupSinbad(ragdoll);
        
        ragdoll.addCollisionListener(this);
        model.addControl(ragdoll);
        
        orc = new KinematicRagdollControl(0.5f);
        setupOrc(orc);
        
        orc.addCollisionListener(this);
        orc_model.addControl(orc);        

        float eighth_pi = FastMath.PI * 0.125f;
        ragdoll.setJointLimit("Waist", eighth_pi, eighth_pi, eighth_pi, eighth_pi, eighth_pi, eighth_pi);
        ragdoll.setJointLimit("Chest", eighth_pi, eighth_pi, 0, 0, eighth_pi, eighth_pi);
        
        orc.setJointLimit("Waist", eighth_pi, eighth_pi, eighth_pi, eighth_pi, eighth_pi, eighth_pi);
        orc.setJointLimit("Chest", eighth_pi, eighth_pi, 0, 0, eighth_pi, eighth_pi);

        //Oto's head is almost rigid
        //    ragdoll.setJointLimit("head", 0, 0, eighth_pi, -eighth_pi, 0, 0);

        getPhysicsSpace().add(ragdoll);
        getPhysicsSpace().add(orc);        
        speed = 1.3f;

        rootNode.attachChild(model);
        rootNode.attachChild(orc_model);
        // rootNode.attachChild(skeletonDebug);
        flyCam.setMoveSpeed(50);


        animChannel = control.createChannel();
        animChannel.setAnim("Dance");
        animChannelX = orc_control.createChannel();
        animChannelX.setAnim("Dance");        
        control.addListener(this);
        orc_control.addListener(this);
        inputManager.addListener(new ActionListener() {

        public void onAction(String name, boolean isPressed, float tpf) {
            if (name.equals("toggle") && isPressed) {

                Vector3f v = new Vector3f();
                Vector3f u = new Vector3f();
                v.set(model.getLocalTranslation());
                v.set(orc_model.getLocalTranslation());
                v.y = 0;
                u.y = 0;
                
                model.setLocalTranslation(v);
                orc_model.setLocalTranslation(u);
                
                Quaternion q = new Quaternion();
                float[] angles = new float[3];
                Quaternion r = new Quaternion();
                float[] r_angles = new float[3];
                
                model.getLocalRotation().toAngles(angles);
                
                orc_model.getLocalRotation().toAngles(r_angles);
                
                q.fromAngleAxis(angles[1], Vector3f.UNIT_Y);
                r.fromAngleAxis(angles[1], Vector3f.UNIT_Y);
                model.setLocalRotation(q);
                orc_model.setLocalRotation(r);
                
                if (angles[0] < 0) {
                    animChannel.setAnim("StandUpBack");
                    ragdoll.blendToKinematicMode(0.5f);
                    orc.blendToKinematicMode(0.5f);
                } else {
                    animChannel.setAnim("StandUpFront");
                    ragdoll.blendToKinematicMode(0.5f);
                    orc.blendToKinematicMode(0.5f);
                }

            }
            if (name.equals("bullet+") && isPressed) {
                bulletSize += 0.1f;

            }
            if (name.equals("bullet-") && isPressed) {
                bulletSize -= 0.1f;

            }

            if (name.equals("stop") && isPressed) {
                ragdoll.setEnabled(!ragdoll.isEnabled());
                ragdoll.setRagdollMode();
                orc.setEnabled(!orc.isEnabled());
                orc.setRagdollMode(); 
            }

            if (name.equals("shoot") && !isPressed) {
                Geometry bulletg = new Geometry("bullet", bullet);
                bulletg.setMaterial(matBullet);
                bulletg.setLocalTranslation(cam.getLocation());
                bulletg.setLocalScale(bulletSize);
                bulletCollisionShape = new SphereCollisionShape(bulletSize);
                RigidBodyControl bulletNode = new RigidBodyControl(bulletCollisionShape, bulletSize * 10);
                bulletNode.setCcdMotionThreshold(0.001f);
                bulletNode.setLinearVelocity(cam.getDirection().mult(80));
                bulletg.addControl(bulletNode);
                rootNode.attachChild(bulletg);
                getPhysicsSpace().add(bulletNode);
            }
            if (name.equals("boom") && !isPressed) {
                Geometry bulletg = new Geometry("bullet", bullet);
                bulletg.setMaterial(matBullet);
                bulletg.setLocalTranslation(cam.getLocation());
                bulletg.setLocalScale(bulletSize);
                bulletCollisionShape = new SphereCollisionShape(bulletSize);
                BombControl bulletNode = new BombControl(assetManager, bulletCollisionShape, 1);
                bulletNode.setForceFactor(8);
                bulletNode.setExplosionRadius(20);
                bulletNode.setCcdMotionThreshold(0.001f);
                bulletNode.setLinearVelocity(cam.getDirection().mult(180));
                bulletg.addControl(bulletNode);
                rootNode.attachChild(bulletg);
                getPhysicsSpace().add(bulletNode);
            }
        }
    }, "toggle", "shoot", "stop", "bullet+", "bullet-", "boom");
    inputManager.addMapping("toggle", new KeyTrigger(KeyInput.KEY_SPACE));
    inputManager.addMapping("shoot", new MouseButtonTrigger(MouseInput.BUTTON_LEFT));
    inputManager.addMapping("boom", new MouseButtonTrigger(MouseInput.BUTTON_RIGHT));
    inputManager.addMapping("stop", new KeyTrigger(KeyInput.KEY_H));
    inputManager.addMapping("bullet-", new KeyTrigger(KeyInput.KEY_COMMA));
    inputManager.addMapping("bullet+", new KeyTrigger(KeyInput.KEY_PERIOD));


}

private void setupLight() {

    DirectionalLight dl = new DirectionalLight();
    dl.setDirection(new Vector3f(-0.1f, -0.7f, -1).normalizeLocal());
    dl.setColor(new ColorRGBA(1f, 1f, 1f, 1.0f));
    rootNode.addLight(dl);
}

private PhysicsSpace getPhysicsSpace() {
    return bulletAppState.getPhysicsSpace();
}

public void initMaterial() {

    matBullet = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
    TextureKey key2 = new TextureKey("Textures/Terrain/Rock/Rock.PNG");
    key2.setGenerateMips(true);
    Texture tex2 = assetManager.loadTexture(key2);
    matBullet.setTexture("ColorMap", tex2);
}

protected void initCrossHairs() {
    guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt");
    BitmapText ch = new BitmapText(guiFont, false);
    ch.setSize(guiFont.getCharSet().getRenderedSize() * 2);
    ch.setText("+"); // crosshairs
    ch.setLocalTranslation( // center
            settings.getWidth() / 2 - guiFont.getCharSet().getRenderedSize() / 3 * 2,
            settings.getHeight() / 2 + ch.getLineHeight() / 2, 0);
    guiNode.attachChild(ch);
}

public void collide(Bone bone, PhysicsCollisionObject object, PhysicsCollisionEvent event) {

    if (object.getUserObject() != null && object.getUserObject() instanceof Geometry) {
        Geometry geom = (Geometry) object.getUserObject();
        if ("Floor".equals(geom.getName())) {
            return;
        }
    }

    ragdoll.setRagdollMode();
    orc.setRagdollMode();

}

private void setupSinbad(KinematicRagdollControl ragdoll) {
    ragdoll.addBoneName("Ulna.L");
    ragdoll.addBoneName("Ulna.R");
    ragdoll.addBoneName("Chest");
    ragdoll.addBoneName("Foot.L");
    ragdoll.addBoneName("Foot.R");
    ragdoll.addBoneName("Hand.R");
    ragdoll.addBoneName("Hand.L");
    ragdoll.addBoneName("Neck");
    ragdoll.addBoneName("Root");
    ragdoll.addBoneName("Stomach");
    ragdoll.addBoneName("Waist");
    ragdoll.addBoneName("Humerus.L");
    ragdoll.addBoneName("Humerus.R");
    ragdoll.addBoneName("Thigh.L");
    ragdoll.addBoneName("Thigh.R");
    ragdoll.addBoneName("Calf.L");
    ragdoll.addBoneName("Calf.R");
    ragdoll.addBoneName("Clavicle.L");
    ragdoll.addBoneName("Clavicle.R");

}

private void setupOrc(KinematicRagdollControl orc) {
    orc.addBoneName("Ulna.L");
    orc.addBoneName("Ulna.R");
    orc.addBoneName("Chest");
    orc.addBoneName("Foot.L");
    orc.addBoneName("Foot.R");
    orc.addBoneName("Hand.R");
    orc.addBoneName("Hand.L");
    orc.addBoneName("Neck");
    orc.addBoneName("Root");
    orc.addBoneName("Stomach");
    orc.addBoneName("Waist");
    orc.addBoneName("Humerus.L");
    orc.addBoneName("Humerus.R");
    orc.addBoneName("Thigh.L");
    orc.addBoneName("Thigh.R");
    orc.addBoneName("Calf.L");
    orc.addBoneName("Calf.R");
    orc.addBoneName("Clavicle.L");
    orc.addBoneName("Clavicle.R");

}    

float elTime = 0;
boolean forward = true;
AnimControl animControl;
AnimChannel animChannel;
AnimControl animControlX;
AnimChannel animChannelX;    
Vector3f direction = new Vector3f(0, 0, 1);
Quaternion rotate = new Quaternion().fromAngleAxis(FastMath.PI / 8, Vector3f.UNIT_Y);
boolean dance = true;

@Override
public void simpleUpdate(float tpf) {

}

public void onAnimCycleDone(AnimControl control, AnimChannel channel, String animName) {

    if (channel.getAnimationName().equals("StandUpBack") || channel.getAnimationName().equals("StandUpFront")) {
        channel.setLoopMode(LoopMode.DontLoop);
        channel.setAnim("IdleTop", 5);
        channel.setLoopMode(LoopMode.Loop);
    }

}

public void onAnimChange(AnimControl control, AnimChannel channel, String animName) {
}

}

I don’t see where you place the other model in a different position and your collision callback is registered for both models and makes both models enter ragdoll mode (i.e. “die”).

It’s my exact problem sir, I don’t know how. It’s a test I found on the package and I just replicated the values. How can I separate them?

Heres the tutorial about moving stuff (I suggest you do all of the tutorials):
http://wiki.jmonkeyengine.org/doku.php/jme3:beginner:hello_node

The listener issue could either be solved by checking which ragdoll gives the callback or by creating two separate listeners, e.g. using an anonymous inner class or a separate class. This is more of a general Java thing, I suggest you look into learning Java before trying to do game development with it.