0

I want to keep the object permanently at a certain distance from the camera. How i can made this? I tried this:

vec3 obj_pos = -cam->Get_CameraPos() ;
obj_pos .z -= 10.0f ;
...
o_modelMatrix = glm::translate(o_modelMatrix, obj_pos);

but it's not working; The object simply stands on the determined position and not moving

Full code of render:

void MasterRenderer::renderPlane() {            
    PlaneShader->useShaderProgram();
    glm::mat4 o_modelMatrix;
    glm::mat4 o_view = cam->Get_ViewMatrix();
    glm::mat4 o_projection = glm::perspective(static_cast<GLfloat>(glm::radians(cam->Get_fov())),
        static_cast<GLfloat>(WIDTH) / static_cast<GLfloat>(HEIGHT), 0.1f, 1000.0f);

    glUniformMatrix4fv(glGetUniformLocation(PlaneShader->ShaderProgramID, "projection"), 1, GL_FALSE, glm::value_ptr(o_projection ));
    glUniformMatrix4fv(glGetUniformLocation(PlaneShader->ShaderProgramID, "view"), 1, GL_FALSE, glm::value_ptr(o_view ));

    vec3 eye_pos =  vec3(o_view [3][0], o_view [3][1], o_view [3][2]); //or cam->getCameraPosition();
    glm::vec3 losDirection = glm::normalize(vec3(0.0f, 0.0f, -1.0f) - eye_pos);

    vec3 obj_pos = eye_pos + losDirection * 1.0f;

    b_modelMatrix = scale(o_modelMatrix, vec3(20.0f));
    b_modelMatrix = glm::translate(b_modelMatrix, obj_pos );

   glUniformMatrix4fv(glGetUniformLocation(PlaneShader->ShaderProgramID, 
   "model"), 1, GL_FALSE, glm::value_ptr(o_modelMatrix));
    ...
    /// draw 
Nublin
  • 59
  • 1
  • 5

3 Answers3

0

Maybe this is a shot from the hip, but I suppose that you set up a lookat matrix and that you the position of your object is defined in world coordinates.

Commonly a camera is defined by a eye position, at target (center) position and an up vector. The direction in which the camera looks is the line of sight, which is the unit vector from the eye position to the target position.

Calcualte the line of sight:

glm::vec3 cameraPosition ...; // the eye position
glm::vec3 cameraTarget ...;   // the traget (center) posiiton 
glm::vec3 losDirection = glm::normalize( cameraTarget - cameraPosition );

Possibly the camera class knows the direction of view (line of sight), then you can skip this calculation.

If the object is always to be placed a certain distance in front of the camera, the position of the object is the position of the camera plus a distance in the direction of the line of sight:

float distance = ...;
float objectPosition = cameraPosition + losDirection * distance;
glm::mat4 modelPosMat = glm::translate( glm::mat4(1.0f) , objectPosition );

glm::mat4 objectModelMat = ...; // initial model matrix of the object
o_modelMatrix = modelPosMat * objectModelMat;

Note the objectModelMat is the identity matrix if the object has no further transformations glm::mat4(1.0f).

Rabbid76
  • 202,892
  • 27
  • 131
  • 174
  • It's not working right. Object is moving faster camera. If you move back, the object catches up and overtakes the camera. – Nublin Jul 23 '17 at 16:02
  • @Nublin `b_modelMatrix = glm::translate( glm::mat4(1.0f), obj_pos ) * b_modelMatrix;` First the positioning, then the model transformation. – Rabbid76 Jul 23 '17 at 17:25
0

so you want to move the object with camera (instead of moving camera with object like camera follow). If this is just for some GUI stuff you can use different static view matrices for it. But if you want to do this in way you suggested then this is the way:

  1. definitions

    First we need few 3D 4x4 homogenuous transform matrices (read the link to see how to disect/construct what you need). So lets define some matrices we need for this:

    • C - inverse camera matrix (no projection)
    • M - direct object matrix
    • R - direct object rotation

    Each matrix has 4 vectors X,Y,Z are the axises of the coordinate system represented by it and O is the origin. Direct matrix means the matrix directly represents the coordinate system and inverse means that it is the inverse of such matrix.

  2. Math

    so we want to construct M so it is placed at some distance d directly in front of C and has rotation R. I assume you are using perspective projection and C viewing direction is -Z axis. So what you need to do is compute position of M. That is easy you just do this:

    iC = inverse(C); // get the direct matrix of camera
    M  = R; // set rotation of object
    M.O = iC.O - d*iC.Z; // set position of object
    

    The M.O = (M[12],M[13],M[14]) and iC.Z = (iC.Z[8],iC.Z[9],iC.Z[10]) so if you got direct access to your matrix you can do this on your own in case GLM does not provide element access.

    Beware that all this is for standard OpenGL matrix convention and multiplication order. If you use DirectX convention instead then M,R are inverse and C is direct matrix so you would need to change the equations accordingly. Sorry I do not use GLM so I am not confident to generate any code for you.

    In case you want to apply camera rotations on object rotations too then you need to change

    M = R to M = R*iC or M = iC*R

    which depends on what effect you want to achieve.

Spektre
  • 49,595
  • 11
  • 110
  • 380
0

It's work fine with not multiplication, but addition

obj_pos = glm::normalize(glm::cross(vec3(0.0f, 0.0f, -1.0f), vec3(0.0f, 1.0f, 0.0f)));
o_modelMatrix[3][0] = camera_pos.x;
o_modelMatrix[3][1] = camera_pos.y;
o_modelMatrix[3][2] = camera_pos.z + distance;
o_modelMatrix = glm::translate(o_modelMatrix, obj_pos);
Nublin
  • 59
  • 1
  • 5