Camera rotation span

Started by miron123, February 27, 2014, 01:01:45 PM

Previous topic - Next topic

miron123

Hello Im currently working on a project which needs an orbital camera movement. I want to rotate my camera vertically around a point. At the moment I tried it like this:

camera.moveCamera(Camera.CAMERA_MOVEIN, dist); //dist to rotation point
//-delta to invert camera
camera.rotateCameraAxis(new SimpleVector(1, 0, 0), -delta* cameraRotationFactor);
camera.moveCamera(Camera.CAMERA_MOVEOUT, dist);

Now I want to limit the range of the camera rotation. So I want the the camera can rotate between 1 and 90 Degrees.
My question is how can I limit the camera rotation to a specific rotation degree?.
I tried to calc the angle based on the rotation matrix and based on the methods in this forum but I didnt get the correct values.
Please help.

atreyu64

Hi, I've developed this kind of camera behaviour, but I use a different approach.

Basically I manage four things for the orbit control :

  • a vertical angle (on y mouse drag)
  • an horizontal angle (on x mouse drag)
  • a "look at" point to shift the orbit center (on right-click drag)
  • a distance to the "look at" point.

Here are some keys to do it...


protected Camera cam;
protected SimpleVector lookAt = new SimpleVector();
protected SimpleVector camPos;
protected static final float angle2Max = (float) (Math.PI / 2 - 0.001);
protected static final float angle2Min = 0;
protected float angle1 = 0; // angle around y-axis, as measured from positive x-axis
protected float angle2 = angle2Max; // angle up from x-z plane, clamped to [0:Pi/2]
protected static final float dragGain = 0.01f;


Camera Rotation (with min/max angle) :

protected void leftButtonDragged(float dx, float dy) {
angle1 += dx * dragGain;
angle2 = Math.min(angle2 + dy * dragGain, angle2Max);
angle2 = Math.max(angle2, angle2Min);
cameraChange();
}


Camera shift :

protected void rightButtonDragged(float dx, float dy) {
cameraShift(dx * dragGain, dy * dragGain);
cameraChange();
}


Camera shift is a little bit more complicated :

private void cameraShift(float screen_dx, float screen_dy) {
if(screen_dx ==0 && screen_dy == 0) return;

float distRatio = (camDist/camDistMin);
screen_dx *= distRatio;
screen_dy *= distRatio;

camPos = cam.getPosition();
cam.moveCamera(Camera.CAMERA_MOVERIGHT, screen_dx);
cam.moveCamera(Camera.CAMERA_MOVEDOWN, screen_dy);
SimpleVector shift = cam.getPosition().calcSub(camPos);
lookAt.sub(shift);

if(lookAt.y > lookAtYMax) lookAt.y = lookAtYMax;
else if(lookAt.y < lookAtYMin) lookAt.y = lookAtYMin;
}


Update camera position and rotation :
public void cameraChange() {
         camPos = cam.getPosition();
         updateCamPosition(camPos, lookAt, camDist, angle1, angle2, camYMax);
         cam.setPosition(camPos);
         cam.lookAt(lookAt);
}


public void updateCamPosition(SimpleVector camPos, SimpleVector lookAt, float camDist, float angle1, float angle2, float camYMax) {
double t = camDist*Math.cos(angle2);   // distance to y-axis after being rotated up
camPos.x = (float) ((t*Math.sin(angle1)) + lookAt.x);
camPos.y = (float) - (camDist*Math.sin(angle2)) + lookAt.y;
camPos.z = (float) ((t*Math.cos(angle1)) + lookAt.z);
}



Hope it helps, do not hesitate to ask me some more details if you are interested.

miron123

Sounds correct but my problem is that I dont have a specific point to look at. So I get the distance through a while loop which moves my camera in til the z coord. is 0. the it rotates and moves out again.
Based on this I want to rotate my camera based on its postion which works at the moment but I want to implement a limit how far the camera can rotate. Cause if I rotate the camera more than 90 degrees it stands on its head. If i rotate below 0 degrees the camera looks at my world from below.
I want to calc its current rotation and if its between 1 and 90 degrees its correct else rotate back.

atreyu64

Well, this is pretty much what I actually do, if you want to see the result :  http://sangla.axerito.perso.sfr.fr/TopoMapNeouvielle.jar
I use a few more tricks to prevent camera from going where it's not supposed to, but basically this should be all what you need.

miron123

Yesterday I tried you implementation and I ran into a few question. Specificly a few of your variables:

camDist; camYMax; lookAtYMax, lookAtYMin.

I didnt realy understand what these values should represent. Could you explain it?

atreyu64


  • camDist is the distance between the camera position and the camera lookAt point (the orbit radius).
  • camYMax is the maximum Y value of my camera, maybe you don't need it
  • lookAtYMin and lookAtYMax are Y min/max values of the lookAt point, you shouldn't need them neither.
I've set these min/max values to prevent my camera from going below my terrain or too high, but I let the camera shift on x and z axis infinitely.

miron123

Well I tried to implement your approach but it just didn t work. So I implemented a different version which rotates my camera correctly.

private void orbitalRotationVertical(float delta) {
   float dist = getCamDistance();
   camera.moveCamera(Camera.CAMERA_MOVEIN, dist);
   camera.rotateCameraAxis(new SimpleVector(1, 0, 0), -delta);
        camera.moveCamera(Camera.CAMERA_MOVEOUT, dist);
}

But now I want to implement an if which should check the current rotation of the camera. If this rotation is above 90 Degree or below 0 Degree the camera shouldn t rotate at all.
My question now is which angle do I need for this if and how do I calc it?.

Pseudo:
if(camera.getRotation() < Math.pi/2 - 0.001 & camera.getRotation > 0){
        camera.rotate()
}