Skip to content

Instantly share code, notes, and snippets.

@newpolaris
Last active June 18, 2021 06:13
Show Gist options
  • Select an option

  • Save newpolaris/ffcbb8836830c3780266476b0f46bd13 to your computer and use it in GitHub Desktop.

Select an option

Save newpolaris/ffcbb8836830c3780266476b0f46bd13 to your computer and use it in GitHub Desktop.
if (g_bAlignFix) {
glm::vec4 c = glm::vec4(center, 0.f, 1.0);
glm::vec4 o = transform * glm::vec4(objectPoint, 0.0, 1.0);
glm::vec4 t = glm::vec4(lineTo, 0.0, 1.0);
auto t_ = glm::vec3(t - c);
auto o_ = glm::vec3(o - c);
auto a = glm::normalize(o_);
auto b = glm::normalize(t_);
float dot_ = glm::dot(a, b);
glm::quat q(1.f, 0.f, 0.f, 0.f);
if (dot_ < -1 + 0.001f) {
glm::vec3 rotationAxis = glm::cross(glm::vec3(0.0f, 0.0f, 1.0f), t_);
if (glm::dot(rotationAxis, rotationAxis) < 0.1f) // bad luck, they were parallel, try again!
rotationAxis = glm::cross(glm::vec3(1.0f, 0.0f, 0.0f), t_);
rotationAxis = glm::normalize(rotationAxis);
q = glm::angleAxis(glm::pi<float>(), rotationAxis);
} else {
glm::vec3 rotationAxis = glm::cross(a, b);
float s = glm::sqrt((1.0f + dot_) * 2.f);
float invs = 1 / s;
rotationAxis *= glm::vec3(invs);
q = glm::quat(s * 0.5f, rotationAxis);
}
auto rotated = q * o_;
// scale1, s0 can't used;
auto s0 = glm::length(t_) /glm::length(rotated);
auto scale1 = t_ / rotated;
auto scale2 = glm::dot(t_, rotated) / glm::dot(rotated, rotated);
auto t2 = scale2* rotated;
auto rot = glm::mat4_cast(q);
auto scale = glm::scale(glm::mat4(1.0), glm::vec3(scale2));
project2 = project * scale * rot;
// acos and cross product version
glm::mat4 RotationBetweenVectors() {
glm::vec4 c = glm::vec4(center, 0.f, 1.0);
glm::vec4 o = transform * glm::vec4(objectPoint, 0.0, 1.0);
glm::vec4 t = glm::vec4(lineTo, 0.0, 1.0);
auto t_ = glm::vec3(t - c);
auto o_ = glm::vec3(o - c);
auto a = glm::normalize(o_);
auto b = glm::normalize(t_);
float dot_ = glm::dot(a, b);
glm::quat q(1.f, 0.f, 0.f, 0.f);
if (1.f - 0.001f <= dot_) {
q = glm::quat(1.f, 0.f, 0.f, 0.f);
} else if (dot_ < -1 + 0.001f) {
glm::vec3 rotationAxis = glm::cross(glm::vec3(0.0f, 0.0f, 1.0f), t_);
if (glm::dot(rotationAxis, rotationAxis) < 0.1f) // bad luck, they were parallel, try again!
rotationAxis = glm::cross(glm::vec3(1.0f, 0.0f, 0.0f), t_);
rotationAxis = glm::normalize(rotationAxis);
q = glm::angleAxis(glm::pi<float>(), rotationAxis);
} else {
auto axis = glm::cross(a, b);
// normalize needed!!! cross(normalize, normalize) = (0, 0, 0.6); what;
auto axis2 = glm::normalize(axis);
auto cos = glm::dot(a, b);
// needed : 1.000012
cos = glm::clamp(cos, -1.f, 1.f);
// 1.000012 returns nad(inf);
auto angle = glm::acos(cos);
// normalized axis required
q = glm::angleAxis(angle, axis2);
}
auto rotated = q * o_;
auto scale2 = glm::dot(t_, rotated) / glm::dot(rotated, rotated);
auto t2 = scale2* rotated;
auto rot = glm::mat4_cast(q);
auto scale = glm::scale(glm::mat4(1.0), glm::vec3(scale2));
return scale * rot;
}
// Returns a quaternion such that q*start = dest
Quaternion Math::RotationBetweenVectors( Vector3 start, Vector3 dest )
{
start = Normalize( start );
dest = Normalize( dest );
Scalar cosTheta = Dot( start, dest );
Vector3 rotationAxis;
// cosTheta > 1 no needed
if (cosTheta < -1 + 0.001f) {
// special case when vectors in opposite directions :
// there is no "ideal" rotation axis
// So guess one; any will do as long as it's perpendicular to start
// This implementation favors a rotation around the Up axis,
// since it's often what you want to do.
rotationAxis = Cross( Vector3( 0.0f, 0.0f, 1.0f ), start );
if (LengthSquare( rotationAxis ) < 0.1f) // bad luck, they were parallel, try again!
rotationAxis = Cross( Vector3( 1.0f, 0.0f, 0.0f ), start );
rotationAxis = Normalize( rotationAxis );
return Quaternion( rotationAxis, XM_PI );
}
// Implementation from Stan Melax's Game Programming Gems 1 article
rotationAxis = Cross( start, dest );
float s = sqrtf( (1.0f + cosTheta) * 2.f );
float invs = 1 / s;
rotationAxis *= Vector3( invs, invs, invs );
return Quaternion( Vector4( rotationAxis, s * 0.5f ) );
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment