user6842178 - 1 year ago 217
C++ Question

# How to rotate rotation axis in OpenGL C++?

glm::mat4 Model = glm::mat4(1.0f);

``````float dir_x = 0.0f, dir_y = 1.0f, dir_z = 0.0f;

do {

// Clear the screen

glClear(GL_COLOR_BUFFER_BIT);

glUseProgram(programID);

GLuint MatrixID = glGetUniformLocation(programID, "MVP");

glm::mat4 Projection = glm::perspective(glm::radians(45.0f), 4.0f / 3.0f, 0.1f, 100.0f);

//glm::mat4 Projection = glm::ortho(-1.0f,1.0f,-1.0f,1.0f,0.0f,100.0f); // In world coordinates

// Camera matrix

glm::mat4 View = glm::lookAt(

glm::vec3(0.5, 0.5, 3), // Camera is at (4,3,3), in World Space

glm::vec3(0.5, 0.5, 0), // and looks at the origin

glm::vec3(0, 1, 0)  // Head is up (set to 0,-1,0 to look upside-down)

);

float rot_angle = 0.0f;

const float speed = 0.01f;

glm::vec3 dir = glm::vec3(dir_x, dir_y,  dir-z);

if (glfwGetKey(window, GLFW_KEY_LEFT) == GLFW_PRESS)

{

rot_angle = -1.0f;

Model = glm::translate(tri_center)* glm::rotate(glm::mat4(), glm::radians(rot_angle), glm::vec3(0, 0, -1))*glm::translate(-tri_center)*Model;

//dir left
``````

...

If I rotate the object(car), I want to move it to the head of the car. Now, regardless of the head of car, the car only moves upward.
How do codes make dir rotate?

Changing the center of rotation can be achieved with the following:

1. Remember, multiply matrices RIGHT TO LEFT, the first transform on the rightmost side, the last on the left

2. First, create a translation that brings the center of rotation to the origin of the scene (0, 0, 0), this is basically reversing each x,y, and z. So the translation for the example center `vec3(1.0, 2.3, -5.2)` is `glm::mat4 origin = glm::translate(origin, glm::vec3(-1.0, -2.3, 5.2);`

3. Store this vector, we are going to use this for ALL points in the mesh
4. Now apply the desired rotation(s) to this translate matrix and store them in a new mat4, so do: `glm::mat4 final = glm::rotate(..) * origin`
5. Finally, bring the center (and the rest of the model) back to the original position by creating a translation identical to the vector3 with the following: `glm::mat4 relocate = glm::translate(relocate, center)` and then `glm::mat4 final = relocate * glm::rotate(..) * origin`
6. Essentially what we are doing here is bringing the center of the model to the origin, translating all points relative to that, then rotating them around the center (which is now the origin), then bringing them back the same distance they came.
7. Now apply this translation to ALL of the models points, do this in the vertex shader, obviously. If the model is really small, you could do it in your code but that will gobble memory for most meshes. This mat4 could be applied to the model matrix if you don't want to add another matrix. `model = model * final //note, first do transformations, then scale for the model`

Full code looks something like this: (you could also multiply the matricies manually, but GLM lets you pass a matrix into the args of `translate()` function, it then just applies the translation to the matrix in its current form)

``````glm::vec3 center = vec3(1.0, 2.3, -5.2);
glm::mat4 finalTransform = glm::translate(finalTransform, glm::vec3(-1.0, -2.3, 5.2)); //first bring everything to origin, notice this is a mat4
finalTransform = glm::rotate(finalTransform, ...); //rotate how you want
Also, in your current code it appears that you have the right idea, but you are using the translate function incorrectly. It should be called like this: `glm::translate(mat4, vec3)`. At the very least, construct an empty `mat4` to translate with the `glm::mat4()` constructor.