Last active
June 18, 2021 06:13
-
-
Save newpolaris/ffcbb8836830c3780266476b0f46bd13 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // 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; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // 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