Reputation: 3789
I was wondering how I can move my camera to a specific point in my scene, even if I already have rotated, translated and scaled in all three dimensions. For a point P (x,y,z) I clearly can't use translate(x,y,z) - if I do so I'm ending on a totally different point.
I've a building with floors and rooms. I would like to have two different camera perspectives. The first one is the Bird-Eye, where I can see a specific position from the top. It should look similar to:
The second one is a 3-dimensional, where I have my camera with a specific value (but constant, like 30°) and I'm looking to the point (and I would like to chose my "x"-rotation here). As you can see in the following picture, this is what the second camera view should look like:
Like I said I'm not aware of how to move the camera to a specific position because after rotation/translating the values are totally different. Besides this, I'm not sure if I'm thinking about the correct way.
My whole translation/rotation/scaling is only about the model. I don't change anything in the look-at method. I'm using the following methods for modifying the model (by on-touch-gestures):
// translate to world position
Matrix.setIdentityM(tmpMatrix, 0);
Matrix.translateM(tmpMatrix, 0, translateX, translateY, translateZ);
Matrix.multiplyMM(resMatrix, 0, tmpMatrix, 0, mModelMatrix, 0);
System.arraycopy(resMatrix, 0, mModelMatrix, 0, 16);
// rotate around center
Matrix.setIdentityM(tmpMatrix, 0);
if (rotationX != 0)
Matrix.rotateM(tmpMatrix, 0, rotationX, 1.0f, 0.0f, 0.0f);
if (rotationY != 0)
Matrix.rotateM(tmpMatrix, 0, rotationY, 0.0f, 1.0f, 0.0f);
if (rotationZ != 0)
Matrix.rotateM(tmpMatrix, 0, rotationZ, 0.0f, 0.0f, 1.0f);
Matrix.multiplyMM(resMatrix, 0, tmpMatrix, 0, mModelMatrix, 0);
System.arraycopy(resMatrix, 0, mModelMatrix, 0, 16);
// scale down
Matrix.setIdentityM(tmpMatrix, 0);
Matrix.scaleM(tmpMatrix, 0, r * s, r * s, r * s);
Matrix.multiplyMM(resMatrix, 0, tmpMatrix, 0, mModelMatrix, 0);
System.arraycopy(resMatrix, 0, mModelMatrix, 0, 16);
*
* Set the camera position (View matrix)
*/
Matrix.setLookAtM(mViewMatrix, offset, eyeX, eyeY, eyeZ,
centerX, centerY, centerZ, upX, upY, upZ);
/*
* combine the model with the view matrix
*/
Matrix.multiplyMM(mMVMatrix, 0, mViewMatrix, 0, mModelMatrix, 0);
/*
* this projection matrix is applied to object coordinates in the
* onDrawFrame() method
*/
Matrix.frustumM(mProjectionMatrix, 0, -ratio, ratio, 1, -1,
nearPlaneDistance, farPlaneDistance);
/*
* Calculate the projection and view transformation
*/
float[] mMVPMatrix = new float[16];
Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mMVMatrix, 0);
/*
* all the drawing stuff inside the model-object (otherwise
* translation/rotation wouldn't affect every object)
*/
model3d.draw(mMVPMatrix);
I'm also taking care of translating in x,y,z while the model is rotated (e.g. the model is rotated by 90° - the object should still move to the left when I swipe left). This is managed by my onTouchEvent-Helper:
position.add(touchManager.moveDelta(0).rotate(-angle));
My whole sourcecode is open-source, you could have a look into github.
How can I translate and rotate the camera to a specific point (with specific distance/angle) no matter how my current rotation/position is? Are there any good literatures available? Any good open-source project I could have a look into? Sources on GitHub are really rare...
Should I work with the "lookAt"-Method or do I have to do some kind of translation/rotation of the model? Or should I change my eye and center?
Edit: Lets assume that I don't translate my model by my own (I'll disable the translating by user). I want to look at a specific point p (x,y,z) - no matter how I rotate and scale my model, I always want to look at this point p! - How do I do this? Do I have to translate my model - do I have to change my eye or center?
Upvotes: 2
Views: 2294
Reputation: 408
If you want the direction of the camera and the distance from the point to be constant, if you know the angles around y and pitch-roll axis, you can set the 3D-distance (the distance in x, y and z axis) from the scalar distance d:
Vector3 dist = Vector3 ( d * sin(yawAngle) * fabs(cos(pitchRollAngle)),
d * sin(pitchRollAngle),
d * cos(yawAngle) * fabs(cos(pitchRollAngle)) );
Where the value of yawAngle can go from -π to π while the value of pitchRollAngle can go from -π / 2.0f to π / 2.0f. So, you can define the eyePt vector as:
Vector3 eyePt = Vector3 ( pnt.x - dist.x,
pnt.y - dist.y,
pnt.z - dist.z );
Where the pnt vector is the position of the point. Then, you set the lookAt vector in this way:
Vector3 lookAt = pnt;
Finally, the up vector is:
Vector3 up = Vector3 ( 0.0f, 1.0f, 0.0f );
I hope this would help you. And sorry for my poor English.
Upvotes: 2