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