Reputation: 1313
I've been trying to get my generated geometry to align with a direction vector. To illustrate what my current problem is:
My current solution in code for this triangle example (This code is run for all the nodes you see on screen starting at the split, I am using the GLM math library):
glm::vec3 v1, v2, v3;
v1.x = -0.25f;
v1.z = -0.25f;
v2.x = 0.25f;
v2.z = -0.25f;
v3.x = 0.0f;
v3.z = 0.25f;
v1.y = 0.0f;
v2.y = 0.0f;
v3.y = 0.0f;
glm::mat4x4 translate = glm::translate(glm::mat4x4(1.0f), sp.position);
glm::mat4x4 rotate = glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), sp.direction, glm::vec3(0.0f, 1.0f, 0.0f));
v1 = glm::vec4(translate * rotate * glm::vec4(v1, 1.0f)).swizzle(glm::comp::X, glm::comp::Y, glm::comp::Z);
v2 = glm::vec4(translate * rotate * glm::vec4(v2, 1.0f)).swizzle(glm::comp::X, glm::comp::Y, glm::comp::Z);
v3 = glm::vec4(translate * rotate * glm::vec4(v3, 1.0f)).swizzle(glm::comp::X, glm::comp::Y, glm::comp::Z);
The direction vector values for point A:
The direction vector values for point B:
Edit 1 (24/11/2013 @ 20:36): A and B do not have any relation, both are generated separately. When generating A or B only a position and direction is known.
I've been looking at solutions posted here:
But I haven't been able to successfully rotate my geometry to align with my direction vector. I feel like I'm doing something rather basic wrong.
Any help would be greatly appreciated!
Upvotes: 1
Views: 3273
Reputation: 46960
If A
and B
are unit vectors and you want a rotation matrix R
that transforms B
so that it aligns with A
, then start by computing C = B x A
(the cross-product of B
and A
). C
is the axis of rotation, and arcsin(|C|)
is the necessary rotation angle.
From these you can build the required rotation matrix. It looks like glm
has support for this, so I won't explain further.
NB if you are doing many, many of these in performance-critical code, you can gain a bit of speed by noting |C| = sin(theta), sqrt(1 - |C|^2) = cos(theta)
and computing the matrix yourself with these known values of sin(theta)
and cos(theta)
. For this see for example this discussion. The glm
routine will take your angle arcsin(|C|)
and proceed immediately to compute its sin
and cos
, a small waste since you already knew these and the operations are relatively expensive.
If the rotation is about some point p
other than the origin, then let T
be a translation that takes p
to the origin, and find X = T^-1 R T
. This X
will be the transformation you want.
Upvotes: 2