【问题标题】:object keep his distance around camera c++ opengl物体在相机周围保持距离c ++ opengl
【发布时间】:2017-07-23 14:41:06
【问题描述】:

我想将对象永久保持在距相机一定距离的位置。我怎么能做这个?我试过这个:

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

但它不起作用;物体只是站在确定的位置上而不是移动

完整的渲染代码:

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 

【问题讨论】:

    标签: c++ opengl glm-math


    【解决方案1】:

    也许这是从臀部拍摄的,但我想你设置了一个 lookat 矩阵,并且你的对象的位置是在世界坐标中定义的。

    相机通常由眼睛位置、目标(中心)位置和向上向量定义。 相机看的方向就是视线,是眼睛位置到目标位置的单位向量。

    计算视线:

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

    可能相机类知道视野方向(视线),那么你可以跳过这个计算。

    如果要始终将物体放置在相机前面一定距离,则物体的位置是相机的位置加上视线方向上的距离:

    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;
    

    请注意,如果对象没有进一步的变换glm::mat4(1.0f)objectModelMat 是单位矩阵。

    【讨论】:

    • 它工作不正常。对象移动速度更快的相机。如果你向后移动,物体就会追上并超过相机。
    • @Nublin b_modelMatrix = glm::translate( glm::mat4(1.0f), obj_pos ) * b_modelMatrix;先定位,再模型变换。
    【解决方案2】:

    所以你想用相机移动物体(而不是用像相机跟随这样的物体移动相机)。如果这只是一些 GUI 的东西,你可以为它使用不同的静态视图矩阵。但是,如果您想按照您建议的方式执行此操作,那么就是这样:

    1. 定义

      首先我们需要几个3D 4x4 homogenuous transform matrices(阅读链接以了解如何剖析/构造您需要的东西)。因此,让我们定义一些我们需要的矩阵:

      • C - 逆相机矩阵(无投影)
      • M - 直接对象矩阵
      • R - 直接对象旋转

      每个矩阵有4个向量X,Y,Z是它所代表的坐标系的轴,O是原点。直接矩阵表示该矩阵直接表示坐标系,而逆表示它是该矩阵的逆矩阵。

    2. 数学

      所以我们要构造M,因此它被放置在d 的某个距离处,直接位于C 前面,并且具有旋转R。我假设您正在使用透视投影并且C 的查看方向是-Z 轴。所以你需要做的是计算M 的位置。这很容易,您只需这样做:

      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
      

      M.O = (M[12],M[13],M[14])iC.Z = (iC.Z[8],iC.Z[9],iC.Z[10]) 因此,如果您可以直接访问您的矩阵,您可以自己执行此操作,以防 GLM 不提供元素访问。

      请注意,所有这些都是针对标准 OpenGL 矩阵约定和乘法顺序的。如果您使用 DirectX 约定,则 M,R 是逆矩阵,C 是直接矩阵,因此您需要相应地更改方程式。抱歉,我不使用 GLM,所以我没有信心为您生成任何代码。

      如果您也想在对象旋转上应用相机旋转,那么您需要将

      M = R 更改为 M = R*iCM = iC*R

      这取决于您想要什么效果去实现。

    【讨论】:

      【解决方案3】:

      不用乘法,加法也可以

      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);
      

      【讨论】:

        猜你喜欢
        • 2022-07-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-09-08
        • 2017-09-16
        • 2019-07-22
        • 1970-01-01
        • 2016-01-18
        相关资源
        最近更新 更多