Q: Implementing Zoom on an orbit camera I wish to zoom in on the target of an orbiting camera.
The camera is manipulated using a function like this:
moveCamera(x,y,z);

Depending on angle the values x,y,z should be different to get a correct zoom feature but I cant figure out an way to do it.
I use functions like getCameraposx, getTargetposy etc.. to get the coordinates for my target and camera.
Zoom kinda works now after PigBens help but I've run in to a problem. Zooming in is no problem but after zooming in too close zooming out stops working. And with too close I'm still quite far away.
Here is my zoom function.
void Camera::orbZoom(bool Zoo)
{
    float x;
        float y;
        float z;
        float xc;
        float yc;
        float zc;
    float zoom;

    x=getTargetposx();
    y=getTargetposy();
    z=getTargetposz();
    xc=getCameraposx();
    yc=getCameraposy();
    zc=getCameraposz();

    xc=xc-x;
    yc=yc-y;
    zc=zc-z;

    if ( ivan==true){
        zoom = 1.02;
        if (xc<1){xc=+1.5;}
        else if (yc<1){yc=+1.5;}
        else if (zc<1){zc=+1.5;}
            xc=xc*zoom;
            yc=yc*zoom;
            zc=zc*zoom;
    }
    if(ivan==false) {
        zoom = 0.98;
    xc=xc*zoom;
    yc=yc*zoom;
    zc=zc*zoom;
    }

    xc=xc+x;
    yc=yc+y;
    zc=zc+z;
    camerapos.assign(xc,yc,zc);

}
Ok so the last thing didnt work as I wrote in the last comment. I'm thinking there is something else causing this behavior. The limit for when it stops working is just a bit closer to target than cameras starting position or at starting position, not really sure on that. But if I start with zooming out and dont get any closer than the cameras starting position it's working.
I think the bug is in this part of the code but I could be wrong so if anyone want to see some other part just ask. All my other camera behaviors are working correctly. Two modes, orbit and tumble. Pitch, yaw and roll works for both modes and strafing for tumble mode.
Here are for example two of those functions.
    void Camera::strafeUp(float distance)
{
    camerapos += upvect * distance;
    targetpos += upvect * distance;
}


void Camera::tumbleYaw(float angle)
{
    Quaternionf rotation((angle*PIdiv180), upvect);
    rightvect = rotation.matrix() * rightvect;
    forwardvect = rotation.matrix() * forwardvect;

    forwardvect.normalize();
    rightvect.normalize();

    targetpos = camerapos + forwardvect * cameralength;
}


A: Subtract the target position from the camera position, then scale it, then add the target position in again.
camera_position -= target_position;
camera_position /= zoom_factor;
camera_position += target_position;

Regarding your second problem.  My guess is that it's due to lack of precision in floats.  When you get down to a certain point, multiplying by 1.02 is not enough to change the float's value to the next higher representable value, so it doesn't change at all.  My tests indicate that this doesn't happen until the float is in the 10e-44 range, so you must be using some pretty gigantic units for this to be a problem.  A few possible solutions.


*

*Use doubles instead of floats.  You will still have the same problem.  But it won't come into play until a much much closer zoom.

*Use smaller units.  I usually just go with 1.0 = 1 meter and I've never run in to this problem.

*Enforce a maximum zoom.  You would actually do this in combination with the other 2 above.
