I have a character with a better character control. I switched the chase cam to a camera node. I can rotate the camera node while being stationary and that works. I can move forward without moving the camera and that works. I can move the camera while moving forward and that works. pressing a or s or d makes the model spin at an extreme rate. pressing d for example should make the right side of the model, the world famous lisa, show her right side and move in that direction. I do understand what is going on but do not know how to fix it. the character control rotates to move the model in the direction but that also rotates the camera node target. rotating the camera node target causes the spinning. I have tried to find a way to get and then set the world rotation but that does not seem possible in JME. I have made something similar to this in unity and I had access to the world rotation. I need to be able to change the camera node target rotation back to the angle it was pointing before which would mean the world rotation not the local rotation. I am not sure how to accomplish this. I have edited down a code sample to what I think is the relevant code from the original file. If needed I can zip the whole directory and post it here. here is the code sample.
*** Edit. If I get the camera at just the right angle, nearly 90 the the side of lisa and press a or d then I can get the expected behavior. If the camera is more than a few degrees off the model will rotate way too fast.
public void simpleInitApp() {
BulletAppState bulletAppState = new BulletAppState();
stateManager.attach(bulletAppState);
//landscape
//lisa, has better character controler. camRotate is child node of lisa. camParent is child node of camRotate.
flyCam.setEnabled(false);
camNode = new CameraNode("Camera Node", cam);
camNode.setControlDir(ControlDirection.SpatialToCamera);
camRotate = (Node) lisa.getChild("camRotate");
camParent = (Node) lisa.getChild("camParent");
camParent.attachChild(camNode);
camNode.setLocalTranslation(new Vector3f(0, 0, 0));
inputManager.addMapping("CharLeft", new KeyTrigger(KeyInput.KEY_A));
inputManager.addMapping("CharRight", new KeyTrigger(KeyInput.KEY_D));
inputManager.addMapping("CharForward", new KeyTrigger(KeyInput.KEY_W));
inputManager.addMapping("CharBackward", new KeyTrigger(KeyInput.KEY_S));
inputManager.addMapping("CharJump", new KeyTrigger(KeyInput.KEY_RETURN));
inputManager.addMapping("CharAttack", new KeyTrigger(KeyInput.KEY_SPACE));
inputManager.addMapping("toggleRotate", new MouseButtonTrigger(MouseInput.BUTTON_LEFT));
inputManager.addMapping("rotateRight", new MouseAxisTrigger(MouseInput.AXIS_X, true));
inputManager.addMapping("rotateLeft", new MouseAxisTrigger(MouseInput.AXIS_X, false));
inputManager.addMapping("rotateUp", new MouseAxisTrigger(MouseInput.AXIS_Y, true));
inputManager.addMapping("rotateDown", new MouseAxisTrigger(MouseInput.AXIS_Y, false));
inputManager.addListener(this, "CharLeft", "CharRight", "CharForward", "CharBackward", "CharJump", "CharAttack", "rotateRight", "rotateLeft", "toggleRotate", "rotateUp", "rotateDown");
}
public void simpleUpdate(float tpf) {
Vector3f camDir = cam.getDirection().clone();
Vector3f camLeft = cam.getLeft().clone();
camDir.y = 0;
camLeft.y = 0;
camDir.normalizeLocal();
camLeft.normalizeLocal();
walkDirection.set(0, 0, 0);
float [] angles = camRotate.getLocalRotation().toAngles(null);
float [] anglesW= camRotate.getWorldRotation().toAngles(null);
if (left) {
walkDirection.addLocal(camLeft);
}
if (right) {
walkDirection.addLocal(camLeft.negate());
}
if (up) {
walkDirection.addLocal(camDir);
camRotate.getLocalRotation().fromAngles( angles[0], angles[1], 0 ).nlerp( Quaternion.ZERO.fromAngles( angles[0], 0, 0 ), .4f );
}
if (down) {
walkDirection.addLocal(camDir.negate());
}
walkDirection.multLocal(25f).multLocal(tpf);
character.setWalkDirection(walkDirection);
if ( !up ) camRotate.setLocalRotation( Quaternion.ZERO.fromAngles( angles[0], angles[1], 0 ) );
}
public void onAction(String binding, boolean value, float tpf) {
if (binding.equals("CharLeft")) {
if (value) left = true;
else left = false;
} else if (binding.equals("CharRight")) {
if (value) right = true;
else right = false;
} else if (binding.equals("CharForward")) {
if (value) up = true;
else up = false;
} else if (binding.equals("CharBackward")) {
if (value) down = true;
else down = false;
} else if (binding.equals("CharJump"))
character.jump();
if (binding.equals("toggleRotate") && value) {
rotate = true;
inputManager.setCursorVisible(false);
}
if (binding.equals("toggleRotate") && !value) {
rotate = false;
inputManager.setCursorVisible(true);
}
}
public void onAnalog(String name, float value, float tpf) {
float [] angles = camRotate.getLocalRotation().toAngles(null);
float speed = 1f;
if (name.equals("rotateRight") && rotate) {
camRotate.setLocalRotation( Quaternion.ZERO.fromAngles( angles[0], angles[1] + (speed * tpf), 0 ) );
}
if (name.equals("rotateLeft") && rotate) {
camRotate.setLocalRotation( Quaternion.ZERO.fromAngles( angles[0], angles[1] + (-speed * tpf), 0 ) );
}
if (name.equals("rotateUp") && rotate) {
camRotate.setLocalRotation( Quaternion.ZERO.fromAngles( angles[0] + (speed * tpf), angles[1], 0 ) );
}
if (name.equals("rotateDown") && rotate) {
camRotate.setLocalRotation( Quaternion.ZERO.fromAngles( angles[0] + (-speed * tpf), angles[1], 0 ) );
}
}
I would appreciate any insight. Thank you all in advance.