kick
/Users/morten/Programmering/cpp/kick/src/kick/math/ray.cpp
00001 //
00002 //  ray.cpp
00003 //  KickCPP
00004 //
00005 //  Created by Morten Nobel-Jørgensen on 18/12/13.
00006 //  Copyright (c) 2013 Morten Nobel-Joergensen. All rights reserved.
00007 //
00008 
00009 #include "kick/math/ray.h"
00010 
00011 using namespace glm;
00012 
00013 namespace kick {
00014     Ray::Ray()
00015     : mOrigin{vec3(0,0,0)}, mDirection{vec3(0,0,-1)}
00016     {
00017     
00018     }
00019     
00020     Ray::Ray(vec3 origin, vec3 direction)
00021     : mOrigin{origin}, mDirection{glm::normalize(direction)}
00022     {
00023     }
00024     
00025     bool Ray::closestPoints(Ray otherRay, glm::vec3& outPoint1, glm::vec3& outPoint2) const {
00026         vec3 otherRayOrigin = otherRay.mOrigin;
00027         vec3 otherRayDirection = otherRay.mDirection;
00028         float epsilon = 1.401298E-45f;
00029         bool isParallel = fabs(dot(mDirection, otherRayDirection)) >= 1 - epsilon;
00030         if (isParallel){
00031             outPoint1 = vec3{0};
00032             outPoint2 = vec3{0};
00033             return false;
00034         }
00035 
00036         // loosely based on http://www.youtube.com/watch?v=HC5YikQxwZA
00037         // t is distance traveled at ray and s distance traveled at otherRay
00038         // PQ is vector between rays
00039         vec3 PQT = -mDirection;
00040         vec3 PQS = otherRayDirection;
00041         vec3 PQVal = -mOrigin + otherRayOrigin;
00042 
00043         float PQu1S = dot(PQS, mDirection);
00044         float PQu1T = dot(PQT, mDirection);
00045         float PQu1Val = dot(PQVal, mDirection) * -1;
00046 
00047         float PQu2S = dot(PQS, otherRayDirection);
00048         float PQu2T = dot(PQT, otherRayDirection);
00049         float PQu2Val = dot(PQVal, otherRayDirection) * -1;
00050 
00051         // maybe not the most efficient way to solve the system of linear equations
00052         mat2x2 mat;
00053         mat[0][0] = PQu1S;
00054         mat[1][0] = PQu1T;
00055         mat[0][1] = PQu2S;
00056         mat[1][1] = PQu2T;
00057 
00058         mat = inverse(mat);
00059         vec2 res = mat * vec2(PQu1Val, PQu2Val);
00060 
00061         outPoint1 = mOrigin + mDirection * res[1];
00062         outPoint2 = otherRayOrigin + otherRayDirection * res[0];
00063 
00064         return true;
00065     }
00066     
00067     void Ray::setDirection(glm::vec3 const &direction) {
00068         Ray::mDirection = glm::normalize(direction);
00069     }
00070 
00071     glm::vec3 const &Ray::direction() const {
00072         return mDirection;
00073     }
00074 
00075     void Ray::setOrigin(glm::vec3 const &origin) {
00076         Ray::mOrigin = origin;
00077     }
00078 
00079     glm::vec3 const &Ray::origin() const {
00080         return mOrigin;
00081     }
00082 
00083     glm::vec3 Ray::point(float offset) const {
00084         return mOrigin + mDirection * offset;
00085     }
00086 
00087     bool Ray::intersectTriangle(glm::vec3 v0, glm::vec3 v1, glm::vec3 v2, glm::vec3 &intersectionPoint, bool clampBackIntersections) const {
00088         // based on RTR 3ed page 750
00089         vec3 e1 = v1 - v0;
00090         vec3 e2 = v2 - v0;
00091         vec3 q = cross(mDirection, e2);
00092         float a = dot(e1, q);
00093         float eps = 1e-10;
00094         if (a > -eps && a < eps) return false;
00095         float f = 1 / a;
00096         vec3 s = mOrigin - v0;
00097         float u = f * dot(s, q);
00098         if (u < 0.0) return false;
00099         vec3 r = cross(s, e1);
00100         float v = f * dot(mDirection, r);
00101         if (v < 0.0 || u + v > 1.0) return false;
00102         float t = f * dot(e2, r);
00103         if (clampBackIntersections && t < 0){
00104             return false;
00105         }
00106         intersectionPoint = point(t);
00107 
00108         return true;
00109     }
00110 
00111     glm::vec3 Ray::closestPoint(glm::vec3 point) const {
00112         return mOrigin + dot(point - mOrigin, mDirection) / dot(mDirection,mDirection) * mDirection;
00113     }
00114 }
 All Classes Functions Variables