I created something like this for a ludum dare competition (it was adapted from the CamNode):
Edit: Created a testcase for you guys
[java]package com.mmm.util.test;
import com.jme3.app.SimpleApplication;
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.Spatial;
import com.jme3.scene.shape.Box;
public class TestFPSGun extends SimpleApplication {
private Spatial weapon;
public static void main(String[] args) {
new TestFPSGun().start();
}
@Override
public void simpleInitApp() {
// Weapon
Box box = new Box(0.5f, 0.5f, 0.5f);
weapon = new Geometry("geometry", box);
Material unshadedMat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
weapon.setMaterial(unshadedMat);
rootNode.attachChild(weapon);
// Random thing
Box box1 = new Box(2, 2, 2);
Spatial box2 = new Geometry("geometry", box1);
Material unshadedMat1 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
unshadedMat1.setColor("Color", ColorRGBA.Blue);
box2.setMaterial(unshadedMat1);
rootNode.attachChild(box2);
}
public void simpleUpdate(float tpf) {
Vector3f vectorDifference = new Vector3f(cam.getLocation().subtract(weapon.getWorldTranslation()));
weapon.setLocalTranslation(vectorDifference.addLocal(weapon.getLocalTranslation()));
Quaternion worldDiff = new Quaternion(cam.getRotation().mult(weapon.getWorldRotation().inverse()));
weapon.setLocalRotation(worldDiff.multLocal(weapon.getLocalRotation()));
// Move it to the bottom right of the screen
weapon.move(cam.getDirection().mult(3));
weapon.move(cam.getUp().mult(-0.8f));
weapon.move(cam.getLeft().mult(-1f));
weapon.rotate(0.3f, FastMath.PI, 0);
}
}[/java]
Edit again: changed color of other box, so you can see easier