Skip to content

Instantly share code, notes, and snippets.

@h3r
Last active May 23, 2020 12:57
Show Gist options
  • Select an option

  • Save h3r/0a5280dc7266e2409b6e63bc6c03ff98 to your computer and use it in GitHub Desktop.

Select an option

Save h3r/0a5280dc7266e2409b6e63bc6c03ff98 to your computer and use it in GitHub Desktop.

Revisions

  1. h3r revised this gist May 23, 2020. 1 changed file with 1 addition and 0 deletions.
    1 change: 1 addition & 0 deletions angular.h
    Original file line number Diff line number Diff line change
    @@ -2,6 +2,7 @@
    Most of this code hasn't been made by me (maybe partially tweaked to fit) and just collected those snippets from many sources
    across the internet. I haven't saved some of the original author names and all the credits
    should go to them. I'm pretty some of you may find optimizations to them, feel free to leave a comment.
    HPlass ([email protected]) - 2020
    */

  2. h3r revised this gist May 23, 2020. 1 changed file with 25 additions and 0 deletions.
    25 changes: 25 additions & 0 deletions angular.h
    Original file line number Diff line number Diff line change
    @@ -88,6 +88,31 @@ float angle(VEC3 v1, VEC3 v2) const {
    return atan2f(dot_left, dot_front);
    }

    /*
    Get a Quaterion out of vectors
    Source: http://lolengine.net/blog/2013/09/18/beautiful-maths-quaternion-from-vectors
    */
    QUAT fromaxisangle(float angle, VEC3 axis)
    {
    float half_sin = sinf(0.5f * angle);
    float half_cos = cosf(0.5f * angle);
    return QUAT(half_cos,
    half_sin * axis.x,
    half_sin * axis.y,
    half_sin * axis.z);
    }

    QUAT fromtwovectors(VEC3 u, VEC3 v)
    {
    u.Normalize();
    v.Normalize();
    float cos_theta = u.Dot(v);
    float angle = acos(cos_theta);
    VEC3 w = u.Cross(v);
    w.Normalize();
    return fromaxisangle(angle, w);
    }



    /*
  3. h3r revised this gist May 23, 2020. 1 changed file with 62 additions and 0 deletions.
    62 changes: 62 additions & 0 deletions angular.h
    Original file line number Diff line number Diff line change
    @@ -5,6 +5,7 @@
    HPlass ([email protected]) - 2020
    */


    /*
    Yaw Pitch Roll to Vector and viceversa conversions.
    */
    @@ -28,6 +29,67 @@ void vectorToYawPitch(VEC3 front, float* yaw, float* pitch) {
    *pitch = -atan2f(front.y, mod_xz);
    }

    /*
    Rotation matrix, rotation quat, angle between vectors.
    Source:
    //http://number-none.com/product/IK%20with%20Quaternion%20Joint%20Limits/
    //https://math.stackexchange.com/questions/180418/calculate-rotation-matrix-to-align-vector-a-to-vector-b-in-3d
    */
    QUAT rotateToFrom ( VEC3 v1, VEC3 v2 )
    {
    QUAT out = QUAT::Identity;
    VEC3 axis = v1.Cross(v2);// vec3.cross(vec3.create(), v1, v2);
    float dot = v1.Dot(v2);// vec3.dot(v1, v2);

    if (dot < -1.f + 0.01f) {
    out.x = 0.f;
    out.y = 1.f;
    out.z = 0.f;
    out.w = 0.f;
    return out;
    }

    out.x = axis.x * 0.5f;
    out.y = axis.y * 0.5f;
    out.z = axis.z * 0.5f;
    out.w = (1 + dot) * 0.5f;

    out.Normalize();// quat.normalize(out, out);

    return out;
    }


    MAT44 rotateToFrom( VEC3 A, VEC3 B ) {
    A.Normalize();
    B.Normalize();
    float cos_angle = A.Dot(B);
    VEC3 crossProd = A.Cross(B);

    MAT44 skew(
    0, -crossProd.z, crossProd.y, 0,
    crossProd.z, 0, -crossProd.x, 0,
    -crossProd.y, crossProd.x, 0, 0,
    0, 0, 0, 0
    );

    MAT44 skewPow2 = skew * skew;
    float q = 1.f / (1.f + cos_angle);
    MAT44 rotation = MAT44::Identity + skew + skewPow2 * q;
    return rotation;
    }


    float angle(VEC3 v1, VEC3 v2) const {
    VEC3 v3 = v1.Cross( v2 );
    float dot_front = v1.Dot(v2);
    float dot_left = v3.Dot(v2);

    return atan2f(dot_left, dot_front);
    }



    /*
    Usually we use the delta time from frame to frame to make consistent operations framerate-independant,
    but particularly on lerps doesn't work properly. I found this solution that works like a charm.
  4. h3r created this gist May 23, 2020.
    93 changes: 93 additions & 0 deletions angular.h
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,93 @@
    /*
    Most of this code hasn't been made by me (maybe partially tweaked to fit) and just collected those snippets from many sources
    across the internet. I haven't saved some of the original author names and all the credits
    should go to them. I'm pretty some of you may find optimizations to them, feel free to leave a comment.
    HPlass ([email protected]) - 2020
    */

    /*
    Yaw Pitch Roll to Vector and viceversa conversions.
    */
    VEC3 yawToVector(float yaw) {
    return VEC3(sinf(yaw), 0.0f, cosf(yaw));
    }
    float vectorToYaw(VEC3 front) {
    return atan2f(front.x, front.z);
    }
    VEC3 yawPitchToVector(float yaw, float pitch) {
    return VEC3(
    sinf(yaw) * cosf(-pitch)
    , sinf(-pitch)
    , cosf(yaw) * cosf(-pitch)
    );
    }
    void vectorToYawPitch(VEC3 front, float* yaw, float* pitch) {
    *yaw = vectorToYaw(front);
    // Projection of front in the plane XZ
    float mod_xz = sqrtf(front.x*front.x + front.z*front.z);
    *pitch = -atan2f(front.y, mod_xz);
    }

    /*
    Usually we use the delta time from frame to frame to make consistent operations framerate-independant,
    but particularly on lerps doesn't work properly. I found this solution that works like a charm.
    Source: //http://www.rorydriscoll.com/2016/03/07/frame-rate-independent-damping-using-lerp/
    Dependencies: https://github.com/Microsoft/DirectXTK/wiki/SimpleMath
    */
    float damp(float a, float b, float lambda, float dt) {
    return Lerp(a, b, 1.f - exp(-lambda * dt));
    }

    VEC2 damp(VEC2 a, VEC2 b, float lambda, float dt) {
    return VEC2::Lerp(a, b, 1.f - exp(-lambda * dt));
    }

    VEC3 damp(VEC3 a, VEC3 b, float lambda, float dt) {
    return VEC3::Lerp(a, b, 1.f - exp(-lambda * dt));
    }

    VEC4 damp(VEC4 a, VEC4 b, float lambda, float dt) {
    return VEC4::Lerp(a, b, 1.f - exp(-lambda * dt));
    }

    QUAT damp(QUAT a, QUAT b, float lambda, float dt) {
    return QUAT::Lerp(a, b, 1.f - exp(-lambda * dt));
    }

    /*
    Given a position, returns the closest point in the path to that point.
    This one I made it for a partrolling entity to return to the patrolling route
    without having to return to the point where engaged, instead to thec closest
    point in the route.
    Dependencies: https://github.com/Microsoft/DirectXTK/wiki/SimpleMath
    */
    VEC3 closestPoint2Line(VEC3 p, VEC3 a, VEC3 b) {
    VEC3 ab = b - a;
    VEC3 ap = p - a;
    float ab2 = ab.x * ab.x + ab.y * ab.y;
    float APdotAB = ap.Dot(ab);
    float t = APdotAB / ab2;

    if (t > ab.Length()) return b;
    if (t <= 0) return a;
    return a + ab * t;
    }

    VEC3 closestPoint2Path(VEC3 pos, std::vector<VEC3> path){
    VEC3 point,p;
    size_t size = path.size();
    float d,dist = 9999999999999999.9f;

    for (int i = 0; i < size; ++i){
    p = closestPoint2Line(pos, path[i], path[(i + 1) % size]);
    d = VEC3::Distance(pos, p);
    if (d < dist) {
    dist = d;
    point = p;
    }
    }
    return point;
    }