I have been trying to make a simple camera class that lets me rotate and position the camera wherever and whenever I want to. For some reason when I try to rotate the camera on the Z axis (kind of like a barrel roll) it causes the camera to zoom in when turning right and zoom out when turning left. I’ve been stumped on this for a few days and I cant seem to figure it out, any help would be greatly appreciated.
[java]package net.medsouz.liberation.engine;
import net.medsouz.liberation.ProjectLiberation;
import com.jme3.math.Quaternion;
import com.jme3.math.Vector3f;
import com.jme3.scene.CameraNode;
public class Camera {
private static CameraNode cameraNode;
public static void initCamera(){
if(cameraNode != null){
System.err.println(“You cannot have two cameras! Make sure you destory the previous camera before creating a new one!”);
}else{
cameraNode = new CameraNode(“cameraNode”, ProjectLiberation.instance.getCamera());
ProjectLiberation.instance.getRootNode().attachChild(cameraNode);
}
}
public static void destroyCamera(){
setPosition(Vector3f.ZERO);//make sure the camera is at the origin
setRotation(Quaternion.ZERO);
ProjectLiberation.instance.getRootNode().detachChild(cameraNode);
cameraNode = null;
}
public static void setRotation(Quaternion q){
if(cameraNode != null){
cameraNode.getWorldTransform().setRotation(q);
}
}
public static Quaternion getRotation(){
if(cameraNode != null){
return cameraNode.getWorldTransform().getRotation();
}else{
return Quaternion.ZERO;
}
}
public static void setPosition(Vector3f v){
if(cameraNode != null){
cameraNode.getWorldTransform().setTranslation(v);
}
}
public static Vector3f getPosition(){
if(cameraNode != null){
return cameraNode.getWorldTransform().getTranslation();
}else{
return Vector3f.ZERO;
}
}
}
[/java]
To rotate the camera I am using this in the game’s update loop:
[java] if(Keyboard.isKeyDown(Keyboard.KEY_SPACE)){
Camera.setRotation((Camera.getRotation().add(new Quaternion().fromAngles(0,0,0.1f * delta))));
System.out.println(Camera.getRotation().toString() + " | " + Camera.getPosition().toString() + " || "+ t.getRotation().toString() + " | " + t.getPosition().toString());
}
if(Keyboard.isKeyDown(Keyboard.KEY_B)){
Camera.setRotation((Camera.getRotation().add(new Quaternion().fromAngles(0,0,-0.1f * delta))));
System.out.println(Camera.getRotation().toString() + " | " + Camera.getPosition().toString() + " || "+ t.getRotation().toString() + " | " + t.getPosition().toString());
}[/java]
[java]
public static void setRotation(Quaternion q){
if(cameraNode != null){
cameraNode.getWorldTransform().setRotation(q);
}
}
[/java]
Yikes! Setting things on the world transform directly will do pretty nasty things, I think. This is an accumulated transform of the node and its parent transforms.
Try cameraNode.setLocalRotation() instead.
@pspeed said:
[java]
public static void setRotation(Quaternion q){
if(cameraNode != null){
cameraNode.getWorldTransform().setRotation(q);
}
}
[/java]
Yikes! Setting things on the world transform directly will do pretty nasty things, I think. This is an accumulated transform of the node and its parent transforms.
Try cameraNode.setLocalRotation() instead.
When I do local rotation it snaps the cam to 0,0,0 and still zooms.
Maybe it’s something to do with the camera node setup. I honestly didn’t notice that you were using it at first.
Given that you are trying to set the world rotation/location/etc. of the camera, why bother using a camera node at all? Why not just change the Camera directly?
@pspeed said:
Maybe it's something to do with the camera node setup. I honestly didn't notice that you were using it at first.
Given that you are trying to set the world rotation/location/etc. of the camera, why bother using a camera node at all? Why not just change the Camera directly?
I tried that and for some reason when I rotate it snaps my camera to the 3 oclock position on the x axis even though I'm rotating on the Z axis.
[java]package net.medsouz.liberation.engine;
import net.medsouz.liberation.ProjectLiberation;
import com.jme3.math.Quaternion;
import com.jme3.math.Vector3f;
public class Camera {
public static void setRotation(Quaternion q){
ProjectLiberation.instance.getCamera().setRotation(q);
}
public static Quaternion getRotation(){
return ProjectLiberation.instance.getCamera().getRotation();
}
public static void setPosition(Vector3f v){
ProjectLiberation.instance.getCamera().setLocation(v);
}
public static Vector3f getPosition(){
return ProjectLiberation.instance.getCamera().getLocation();
}
}
[/java]
You should be multiplying quaternions together not adding them. Also remember that quaternion multiplication is not commutative I.e A * B != B * A so try multiplying the other way round if results are not as expected
Yeah, I didn’t know if he was trying to accumulate multiple transforms or not.
Writing 3D games requires a certain amount of 3D math knowledge. Your life will be a constant struggle until you get a basic grasp on this, I think.
@pspeed said:
Yeah, I didn't know if he was trying to accumulate multiple transforms or not.
Writing 3D games requires a certain amount of 3D math knowledge. Your life will be a constant struggle until you get a basic grasp on this, I think.
Trust me, I know that. This project is purely for learning. :)