Question

I'm currently trying to visualize a building in OpenGL ES 2 in Android. When I swipe to the left, the whole scene should move to the left (same with right, bottom and top). Now when I rotate the model by 90° the axis are swapped. When I swipe to the right, the model is moved to the top instead of the right (same with the other axis).

How can I translate the camera without having the problem with the current rotation of the scene? As I'm working with a phone, I always want to move the object to the direction I'm swiping to. When I call translate first, the translation works fine, but the rotation has some errors.

Update: I created most of the camera-class (suggested in answers):

private Vector3D c = new Vector3D(eye); // copy of eye
private Vector3D l = Vector3D.getNormalized
        (Vector3D.subtract(center, eye)); // normalized center-eye
private Vector3D u = new Vector3D(up); // up (normalized)

public void rotateX(float angle) {
    // Now you can rotate L vector left and
    // right by rotating it around U by any angle. ??
}

public void rotateY(float angle) {
    // If you also need to look up and down
    // (rotate) you need to rotate both L and U around S ??
}

public void rotateZ(float angle) {
    // to tilt left and right you need to rotate U around L. ??
}

// move left and right
// C = C+S * inputfactor
public void translateX(float inputFactor) {
    Vector3D s = Vector3D.cross(l, u);
    Vector3D sTimesInput = mul(s, inputFactor);
    c = new Vector3D(c).add(sTimesInput);
}

// move forward and backward
// C = C+L*inputfactor
public void translateY(float inputFactor) {
    Vector3D lTimesInput = mul(l, inputFactor);
    c = new Vector3D(c).add(lTimesInput);
}

// move up and down
// C = C+U * inputfactor
public void translateZ(float inputFactor) {
    Vector3D uTimesInput = mul(u, inputFactor);
    c = new Vector3D(c).add(uTimesInput);
}

// reconstruct lookAt - eye,center,up

public Vector3D getEye() {
    return new Vector3D(c);
}

public Vector3D getCenter() {
    return new Vector3D(c).add(new Vector3D(l));
}

public Vector3D getUp() {
    return new Vector3D(u);
}

public float[] createLookAt() {
    Vector3D eye = getEye();
    Vector3D center = getCenter();
    Vector3D up = getUp();
    return new float[] { eye.getX(), eye.getY(), eye.getZ(), center.getX(),
            center.getY(), center.getZ(), up.getX(), up.getY(), up.getZ() };
}

// helper-function
public Vector3D mul(Vector3D vec, float factor) {
    return new Vector3D(vec.getX() * factor, vec.getY() * factor,
            vec.getZ() * factor);
}

How can I rotate a vector around another vector by an angle?

Was it helpful?

Solution 2

I think you mix the concept of moving the camera and rotating your object. First you need to separate the action of rotating your object from any interaction with the camera. You should be able to do anything with the object without changing the camera at all. To do this just use the model matrix to describe the translation/rotation/scaling of your object. Then you handle your camera separatly by using Matrix.setLookAtM with an eyeX, eyeY, eyeZ that is independent of your model position. And a point to look at that in your case is dependent of the eyeX, eyeY, eyeZ, as you want to be looking at the same direction all the time.

For example, if you want to rotate your object 90 degrees around the Y axis, use:

Matrix.rotateM(mModelMatrix, 0, 90, 0.0f, 1.0f, 0.0f);

Also remember that all matrix operations after Matrix.setIdentityM will be done in a backwards order, ie if you rotate first and then translate as you do the first thing in your code, you will first translate your object away from its origin position, then rotate around the origin, making your object do a kind of rotation around of the first origin, instead of the center of your object.

Then lets say you have translated your camera 100 units to the left and looking at -Z direction, use:

Matrix.setLookAtM(mViewMatrix, offset, -100.0f+camX, camY, camZ, -100.0f+camX, camY, -1.0f+camZ, upX, upY, upZ);

OTHER TIPS

If you define camera base vectors C-center, L-look at, U-up such that C is the camera center, L is the normalized vector from center towards the point you are looking at and U is up normalized. Now you can rotate the L vector left and right by rotating it around U by any angle.

As for moving left and right you will have to reconstruct side vector S: a cross product between L and U (S=LxU). Now all you have to do is move the center: C = C+S*inputFactor.

To reconstruct the lookAt vectors:

eye = C
center = C+L
up = U

Just as a note: If you also need to look up and down (rotate) you need to rotate both L and U around S, to tilt left and right you need to rotate U around L. To move forward or backwards C = C+L*inputFactor and to move up and down C = C+U*inputFactor.

This should solve all logical camera movement and rotations.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top