I have FPS camera attach to a Player Node using CameraNode. that work find.
Now I have a model of Hands with a gun and I want to attach it to player node. But it doesn’t appear in front of the player. the player node has no geometry and just used by the character control and it has one child which is the camernode.
I do the following to attach the gun also to the player node.
[java]
Node gun = (Node) assiss.loadModel(…);
gun.scale (0.02f); // scale it because it to big
gun.translate(0.0f, 2, 5f);
playNode.attachChild(gun);
[/java]
but when I attach the model to the world it appear at the location i set.
[java]
Node gun = (Node) assiss.loadModel(…);
gun.scale (0.02f); // scale it because it to big
gun.translate(0.0f, 2f, 5f);
world.attachChild(gun);
[/java]
I personally used a cameranode for the camera and attached the gun to that. It has the added benefit of following it in all axes, you just set the position and boom.
I didn’t check the frustum and I haven’t change it, thus must be the default values 1…1000.
and as you see the local transformation for gun 0,2,5 which must be outside the frustum.
Sample 3 - how to load an OBJ model, and OgreXML model, a material/texture,
or text.
*/
public class Main extends SimpleApplication {
private static final Logger logger = Logger.getLogger(Main.class.getName());
private String mainCharacterName = “Jaime”;
//camera
boolean left = false, right = false, up = false, down = false;
private BulletAppState bulletAppState;
private RigidBodyControl landscape;
private BetterCharacterControl player;
public static void main(String[] args) {
Main app = new Main();
app.start();
}
private Node playerNode;
private CameraNode camNode;
private DpadCharacterMotion dbCharacterMotion = null;
private InputHandler inputHandler = null;
@Override
public void simpleInitApp() { //cam.setFrustumPerspective(45, (float)cam.getWidth()/(float)cam.getHeight(), .01f, 100);
bulletAppState = new BulletAppState();
stateManager.attach(bulletAppState);
Node world = (Node) assetManager.loadModel("Scenes/Scene.j3o");
player = new BetterCharacterControl(1.5f, 3f, 30f);
player.setJumpForce(new Vector3f(0, 300, 0));
player.setGravity(new Vector3f(0, -10, 0));
Node gun = (Node) assetManager.loadModel("Models/colt45/HUD.mesh.j3o");
gun.scale(0.02f);
Quaternion quat = new Quaternion();
quat.lookAt(new Vector3f(0, 0, -1), Vector3f.UNIT_Y);
gun.setLocalRotation(quat);
gun.setLocalTranslation(new Vector3f(0, -1f, -5));
AnimControl control = gun.getControl(AnimControl.class);
AnimChannel channel = control.createChannel();
channel.setAnim("Idle");
channel.setLoopMode(LoopMode.Loop);
Node gunNode = new Node("the gun");
//gunNode.attachChild(gun);
gun.addControl(new GunControl(gun));
playerNode = new Node("the player");
playerNode.setLocalTranslation(new Vector3f(0, 2, -20));
//playerNode.attachChild(gun);
// 4. Add the player control to the PhysicsSpace
playerNode.addControl(player);
rootNode.attachChild(world);
rootNode.attachChild(playerNode);
//rootNode.attachChild(gunNode);
initCamera();
camNode.attachChild(gun);
dbCharacterMotion = new DpadCharacterMotion(player, playerNode);
dbCharacterMotion.setCamera(cam);
//dbCharacterMotion.setUseCameraRotation(true);
stateManager.attach(dbCharacterMotion);
inputHandler = new InputHandler();
stateManager.attach(inputHandler);
inputHandler.addInputActionListener(dbCharacterMotion);
CameraRotateState cameraRotateState = new CameraRotateState(player, playerNode);
stateManager.attach(cameraRotateState);
inputHandler.addInputActionListener(cameraRotateState);
//bulletAppState.getPhysicsSpace().add(landscape);
createIndivMeshRigidBodies(bulletAppState.getPhysicsSpace(), world, 0, true);
bulletAppState.getPhysicsSpace().add(player);
gun.setCullHint(Spatial.CullHint.Never); // always drawn
}
/**
CameraNode depends on playerNode. The camera follows the player.
*/
private void initCamera() {
camNode = new CameraNode(“CamNode”, cam);
camNode.setControlDir(CameraControl.ControlDirection.SpatialToCamera);
camNode.setLocalTranslation(new Vector3f(0, 2, 0));
Quaternion quat = new Quaternion();
quat.lookAt(Vector3f.UNIT_Z, Vector3f.UNIT_Y);
camNode.setLocalRotation(quat);
playerNode.attachChild(camNode);
camNode.setEnabled(true);
flyCam.setEnabled(false);
}
public synchronized static void createIndivMeshRigidBodies(
final PhysicsSpace physicsSpace, final Spatial spatial, final float mass,
final boolean enableLogging) {
SceneGraphVisitorAdapter v = new SceneGraphVisitorAdapter() {
@Override
public void visit(Node node) {
// Skip creating rigid body of Nodes, only do the Geometries
// Allows bullet to take advantage of broadphase
}
@Override
public void visit(Geometry geometry) {
Boolean bool = geometry.getUserData(UserData.JME_PHYSICSIGNORE);
if (bool != null && bool.booleanValue()) {
logger.log(Level.INFO, "rigid body skipped for {0}", geometry.getName());
return;
}
CollisionShape colShape;
if (mass > 0) {
colShape = CollisionShapeFactory.createDynamicMeshShape(geometry);
} else {
colShape = CollisionShapeFactory.createMeshShape(geometry);
}
RigidBodyControl rigidBodyControl = new RigidBodyControl(colShape, mass);
geometry.addControl(rigidBodyControl);
physicsSpace.add(rigidBodyControl);
logger.log(Level.INFO, "Added rigid body to {0}", geometry.getName());
logger.log(Level.INFO, "Created Physics Control: {0}, in PhysicsSpace: {1}",
new Object[]{rigidBodyControl, physicsSpace});
}
};
You could also add some debug printlns (or set a breakpoint) to dump the current world location of the gun every frame or so. Assuming the box doesn’t show up.