How to Make Camera Follow a 3D Object in Opengl

Display a text facing the camera and following a 3D object in OpenGL

I solved my problem :

The idea is to compute a model-View transformation matrix, which is the combinaison between the view matrix and a model matrix which reset the rotation of the view matrix (taking in account the translation).

I built a dedicated shader for my text object :

void main(void)
{
gl_Position = projectionMatrix * modelViewMatrix * vec4(attribute_Position.xy, 0.0, 1.0);

pass_textureCoords = attribute_TextureCoords;
varying_Color = attribute_Color;
}

And I set the modelViewMatrix like this :

Matrix4f viewMatrix = TransformationMatrix.createViewMatrix(renderer.camera); // or how ever you want to do it
Matrix4f modelMatrix = new Matrix4f();
modelMatrix.setIdentity();
// set the translation
modelMatrix.m30 = entityTranslation.x;
modelMatrix.m31 = entityTranslation.y;
modelMatrix.m32 = entityTranslation.z;
// reset the rotation
modelMatrix.m00 = viewMatrix.m00;
modelMatrix.m01 = viewMatrix.m10;
modelMatrix.m02 = viewMatrix.m20;
modelMatrix.m10 = viewMatrix.m01;
modelMatrix.m11 = viewMatrix.m11;
modelMatrix.m12 = viewMatrix.m21;
modelMatrix.m20 = viewMatrix.m02;
modelMatrix.m21 = viewMatrix.m12;
modelMatrix.m22 = viewMatrix.m22;
// compute modelViewMatrix
Matrix4f modelViewMatrix = modelMatrix;
modelViewMatrix.mul(viewMatrix);

shaderProgram.loadModelViewMatrix(modelViewMatrix);

This does the trick for me

Rotating Camera according to 3D Object's position

Give this a shot, it makes sense in my head but it might not in reality :)

Ok, so we can represent your car's position and velocity as 2-element vectors (in the case of position it is a point, and in the case of velocity it is a true vector.)

Now that we have that, to calculate the position of the camera we can just take the negative of your velocity vector (this means just make all elements of the vector negative, yielding a vector of the same magnitude but exactly opposite direction) and add that vector to your car's position.

For example, say your car is at position (1,1) and your speed vector is (1,2). The negative speed vector would be (-1,-2) and the position of your camera would be (1,1) + (-1,-2) to be (0,-1). You will probably want to normalize the negative speed vector so that your camera stays a constant distance from the car, otherwise the faster you go the further the camera will get :)

Now that you have the camera's position, just call gluLookAt:

gluLookAt(camPos.x,camPos.y,camPos.z,carPos.x,carPos.y,carPos.z,0,1,0);

As you can see, we are passing in the camera's position (which we just calculated in the previous step) and telling the camera to look at the car. You may want to tweak some values (for example, have the camera be floating a few units off the ground, instead of directly behind the car, or maybe have the camera look at a point a few units above the car, etc.)

Let me know how this goes! Again, this is just something I thought might work for you, no guarantees that my math is right though :) But this should be faster and easier to understand than messing around with angles and such. One thing to keep in mind: this will not work if the car is completely stationary (no velocity vector)

Camera following player opengl

If you want a simple behavior, using gluLookAt is probably the simplest option! More infos here.

Seeing that you use glm, consider something like

glm::mat4 CameraMatrix = glm::LookAt(
cameraPosition, // the position of your camera, in world space
cameraTarget, // where you want to look at, in world space
upVector // probably glm::vec3(0,1,0), but (0,-1,0) would make you looking upside-down, which can be great too
);

As taken from this site on opengl tutorials.

OpenGL - FPS style Camera move with object fixed on camera

You have two problems.

The first problem is on your coordinates system.

When you apply :

glTranslatef(iX+0.05,iY, iZ-0.05);

You place the object at the camera position, and add an offset to see him. But this is in the world coordinates system. So when you rotate the camera, the object doesn't move cause it doesn't follow the camera's coordinates system.

You need to translate to the camera center, rotate the camera, then add the offset.

The second problem is on the rotation. Your "camAngle" variable is in radian, cause you use it with cos() and sin(). But in OpenGL, glRotate take the angle as a degree value. You need to convert this angle in angle : angle *= 180/PI. (180/PI ~= 57.2957795)

Here the corrected display function :

void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glColor3f(255,0,0);

glPushMatrix();
glTranslatef(iX,iY,iZ); // Translation to the camera center
glRotatef(-camAngle * 57.2957795, 0,1,0); // Rotate to correspond to the camera
glTranslatef(0.05,0,-0.05); // Offset to draw the object

glutWireCone(0.005,0.1,20,20);
glPopMatrix();

drawEarth();
drawWalls();
glutSwapBuffers();
}

Render object in front of camera in OpenGL

add an offset vector to the position in the direction the camera is looking:

sphere->TranslateModel(cameraPositionWorldSpace+camera->LookingDirection().normalized()*5);

OpenGL: Camera and objects

Let me introduce you to something called a “matrix”:

float matrix[16];

A matrix is a simple array, designed to store all four of your vectors in one neat package, in a format OpenGL understands. You can store your vectors in a matrix in the following manner:

matrix[0] = getAxisX().getX();
matrix[1] = getAxisX().getY();
matrix[2] = getAxisX().getZ();
matrix[3] = 0.0;

matrix[4] = getAxisY().getX();
matrix[5] = getAxisY().getY();
matrix[6] = getAxisY().getZ();
matrix[7] = 0.0;

matrix[8] = getAxisZ().getX();
matrix[9] = getAxisZ().getY();
matrix[10] = getAxisZ().getZ();
matrix[11] = 0.0;

matrix[12] = getOrigin().getX();
matrix[13] = getOrigin().getY();
matrix[14] = getOrigin().getZ();
matrix[15] = 1.0;

You can either copy your data into a matrix each time you want to pass it to OpenGL, or you can save yourself a lot of trouble later by adopting the matrix as the standard way of storing the data in your objects now.

(Note that the 0.0 and 1.0 constants are important, for reasons I won’t digress into here.)

Then simply replace:

gl.glTranslatef((float)origin.x, (float)origin.y, (float)origin.z);

With this:

gl.glMultMatrixf(matrix);

If your version of OpenGL works the way I’d expect, that should do the translation and rotation for you.



Related Topics



Leave a reply



Submit