3
$\begingroup$

Another code review question.

I am trying to draw an arrow to represent a vector. I have started with an unit arrow with vertices defined as follows:

//vertex data for vector with arrow    
GLfloat vertices[] = {
    //line
    0.0f, 0.0f, 0.0f,
    1.0f, 0.0f, 0.0f,

    //arrow bases
    0.95f, 0.01f, 0.0f,
    0.95f,-0.01f, 0.0f
};

GLuint indices[] = {
    0, 1,       // Line
    1, 2, 3    // Arrow Triangle
};

I have another array that contains the actual vector start and end positions:

GLfloat lineVertices[] = {

    1.0f, 2.0f, 3.0f, //v1 start
    3.0f, 5.0f,-5.0f, //v1 end

   -1.0f,-1.0f,-1.0f, //v2 start
   -3.0f, 5.0f,-10.0f //v2 end
};

I am trying to construct the model matrix to apply the transformation from lineVertices for each vectors on the unit arrow.

//'view', and 'projection' matrix is set out side of the loop
for (GLint i = 0; i < sizeof(lineVertices) / sizeof(GLfloat); i += 6)
{
    glm::mat4 model;

    //apply transformation
    glm::vec3 start(lineVertices[i], lineVertices[i + 1], lineVertices[i + 2]);
    glm::vec3 end(lineVertices[i + 3], lineVertices[i + 4], lineVertices[i + 5]);
    glm::vec3 startToEnd = end - start;
    GLfloat length = glm::length(startToEnd);

    //translate
    model = glm::translate(model, start);

    //rotate
    //GLfloat xyAngle = glm::atan(startToEnd.z, length);
    //GLfloat xzAngle = glm::atan(startToEnd.y, length);
    //GLfloat yzAngle = glm::atan(startToEnd.x, length);

    //model = glm::rotate(model, xyAngle, glm::vec3(1.0f, 1.0f, 0.0f));
    //model = glm::rotate(model, xzAngle, glm::vec3(1.0f, 0.0f, 1.0f));
    //model = glm::rotate(model, yzAngle, glm::vec3(0.0f, 1.0f, 1.0f));

    //rotate
    GLfloat angleWithZ = glm::acos(startToEnd.z/length);
    GLfloat angleWithY = glm::acos(startToEnd.y/length);
    GLfloat angleWithX = glm::acos(startToEnd.x/length);

    model = glm::rotate(model, angleWithX, glm::vec3(0.0f, 0.0f, 1.0f));
    model = glm::rotate(model, angleWithY, glm::vec3(0.0f, 0.0f, 1.0f));
    model = glm::rotate(model, angleWithZ, glm::vec3(1.0f, 0.0f, 0.0f));

    //scale
    model = glm::scale(model, glm::vec3(length));

    glUniformMatrix4fv(glGetUniformLocation(ourShader.Program, "model"), 1, GL_FALSE, glm::value_ptr(model));

    glDrawElements(GL_LINES, 2, GL_UNSIGNED_INT, 0);
    glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, BUFFER_OFFSET(2));
}

Though this seems to work, as I can see all those arrows, however, I am not sure whether this is the right implementation or not. Please let me know, if this is correct and/or there is room for improvement, or there are easier ways to achieve this, and so on.

Edit: updated my code sample (only the rotation part) based on Direction cosine (wikipedia). Old code is still kept commented.

P.S.: this implementation is based on following stack exchange discussions: 1, 2

$\endgroup$
  • 1
    $\begingroup$ Right is not defined, if it works it works $\endgroup$ – joojaa Jun 11 '16 at 10:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.