[SOLVED] Attaching spatial to bone through controls

Hey @domas, I quickly wrote a test app for you. It just shall show you how to place your gun to the players hand. It might be that you have to adjust your gun with an extra node, so that the gun fits perfectly into the hands.

Here the TestApp:

public class Main extends SimpleApplication {

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

	@Override
	public void simpleInitApp() {
		cam.setLocation(Vector3f.UNIT_Z);

		Spatial player = assetManager.loadModel("Models/Player/Player.j3o");
		rootNode.attachChild(player);

		AnimControl animControl = player.getControl(AnimControl.class);
		AnimChannel channel = animControl.createChannel();
		
		Collection<String> anims = animControl.getAnimationNames();
		Iterator i = anims.iterator();
		channel.setAnim((String) i.next());
		
		animControl.addListener(new AnimEventListener() {
			@Override
			public void onAnimCycleDone(AnimControl control, AnimChannel channel, String animName) {
				if (i.hasNext()) {
					channel.setAnim((String) i.next());
				}
			}

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

		SkeletonControl skeletonControl = player.getControl(SkeletonControl.class);
		Bone attachmentBone = skeletonControl.getSkeleton().getBone("YOUR_ATTACHMENT_BONE");

		WeaponAttachmentControl control = new WeaponAttachmentControl(skeletonControl, attachmentBone.getName());

		Spatial gun = assetManager.loadModel("Models/cube.j3o");
		gun.scale(0.1f);
		gun.addControl(control);
		rootNode.attachChild(gun);

	   
		AmbientLight ambient = new AmbientLight();
		ambient.setColor(ColorRGBA.White);
		rootNode.addLight(ambient);
	}

	@Override
	public void simpleUpdate(float tpf) {
	}

	@Override
	public void simpleRender(RenderManager rm) {
	}

}

Here the simple control:

public class WeaponAttachmentControl extends AbstractControl {
	
	private final Node attachmentNode;

	public WeaponAttachmentControl(Node attachmentNode) {
		this.attachmentNode = attachmentNode;
	}
	
	public WeaponAttachmentControl(SkeletonControl skeletonControl, String bone) {
		if (skeletonControl != null && bone != null) {
			attachmentNode = skeletonControl.getAttachmentsNode(bone);
		} else {
			attachmentNode = null;
		}
	}

	@Override
	protected void controlUpdate(float tpf) {
		if (spatial == null || attachmentNode == null) {
			return;
		}
		spatial.setLocalTranslation(attachmentNode.getWorldTranslation());
		spatial.setLocalRotation(attachmentNode.getWorldRotation());
	}
	
	@Override
	protected void controlRender(RenderManager rm, ViewPort vp) {
	}
	
}

If I were you, I would create several controls, one for keeping the gun at the correct position, one to take care of animations, and so on …

It should be no problem to execute animations of the gun anymore.

If you are missing something, feel free to tell us.

Greetings, Domenic