I have tried using glm::rotate and such. glm::translate works fine, but rotate doesn't work (if I rotate before/after a translation).
Here is my current setup:
glm::vec4 Off = glm::vec4(0, 0, 0, 1);
glm::vec4 result = Util::createTransform(offset) * Off;
for (int i = 0; i < Tvertex.size(); i++) {
Tvertex[i] += glm::vec3(result.x, result.y, result.z);
Tcolors[i] = currentColor;
}
And here is my Util::createTransform:
glm::mat4 Util::createTransform(glm::vec3 pos) {
glm::mat4 trans = glm::mat4(1.0);
trans = glm::translate(trans, pos);
return trans;
}
glm::mat4 Util::createTransform(glm::vec3 pos, glm::vec3 rot) {
glm::mat4 trans = glm::mat4(1.0);
trans = glm::rotate(trans, glm::radians(rot.x), glm::vec3(1, 0, 0));
trans = glm::rotate(trans, glm::radians(rot.y), glm::vec3(0, 1, 0));
trans = glm::rotate(trans, glm::radians(rot.z), glm::vec3(0, 0, 1));
trans = glm::translate(trans, pos);
return trans;
}
Answer
It's unclear where your issue lies.
To rotate a vector about the origin, you create a rotation matrix, and then you multiply the vertex by the matrix. In order to create the rotation matrix, you need a rotation axis and an angle.
With glm, you can do it this way:
glm::vec3 v3RotAxis( 0.0f, 0.0f, 1.0f ); // Rotate about z+
float angleRad = glm::half_pi(); // Rotate of a quarter of a turn
glm::mat4x4 matRot = glm::rotate( angleRad, v3RotAxis );
Alternatively, you can use a quaternion:
glm::quat quatRot = glm::angleAxis( angleRad, v3RotAxis );
glm::mat4x4 matRot = glm::mat4_cast( quatRot );
To apply this to a vertex (a point in space), you would then do:
glm::vec4 out = matRot * v4In;
If you need to rotate about a point that is not the origin, you have to
- translate the pointToRotate to the origin
- perform the rotation
- translate back the point to the original location
To achieve that, you create a translation matrix, and an inverse of that translation. You then 'sandwich' the rotation matrix in-between these other two:
glm::vec4
rotateAround(
glm::vec4 aPointToRotate,
glm::vec4 aRotationCenter,
glm::mat4x4 aRotationMatrix )
{
glm::mat4x4 translate =
glm::translate(
glm::mat4(),
glm::vec3( aRotationCenter.x, aRotationCenter.y, aRotationCenter.z ) );
glm::mat4x4 invTranslate = glm::inverse( translate );
// The idea:
// 1) Translate the object to the center
// 2) Make the rotation
// 3) Translate the object back to its original location
glm::mat4x4 transform = translate * aRotationMatrix * invTranslate;
return transform * aPointToRotate;
}
Keep in mind that with all the operations done with matrices, the order is important.
I join the whole test program if you want to play with stuff.
#include
#include
#include
#include
#include
#include
glm::vec4
rotateAround(
const glm::vec4& aPointToRotate,
const glm::vec4& aRotationCenter,
const glm::mat4x4& aRotationMatrix )
{
glm::mat4x4 translate =
glm::translate(
glm::mat4(),
glm::vec3( aRotationCenter.x, aRotationCenter.y, aRotationCenter.z ) );
glm::mat4x4 invTranslate = glm::inverse( translate );
// The idea:
// 1) Translate the object to the center
// 2) Make the rotation
// 3) Translate the object back to its original location
glm::mat4x4 transform = translate * aRotationMatrix * invTranslate;
return transform * aPointToRotate;
}
int main( void )
{
{
glm::vec4 v4In( 2.0f, 0.0f, 0.0f, 1.0f );
glm::vec4 v4RotCenter( 1.0f, 0.0f, 0.0f, 1.0f );
glm::vec3 v3RotAxis( 0.0f, 0.0f, 1.0f );
float angleRad = glm::half_pi();
glm::mat4x4 matRot = glm::rotate( angleRad, v3RotAxis );
glm::vec4 out = rotateAround( v4In, v4RotCenter, matRot );
std::cout << out.x << " " << out.y << " " << out.z << " " << out.w << " " < }
{
glm::vec4 v4In( 2.0f, 0.0f, 0.0f, 1.0f );
glm::vec3 v3RotAxis( 0.0f, 0.0f, 1.0f );
float angleRad = glm::half_pi();
glm::mat4x4 matRot = glm::rotate( angleRad, v3RotAxis );
glm::vec4 out = matRot * v4In;
std::cout << out.x << " " << out.y << " " << out.z << " " << out.w << " " < }
return 0;
}
No comments:
Post a Comment