Rotating the camera on the Z axis is causing it to zoom in...?

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.

1 Like
@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. :)
1 Like