/* * © Copyright 2014 – Urheberrechtshinweis * Alle Rechte vorbehalten / All Rights Reserved * * Programmcode ist urheberrechtlich geschuetzt. * Das Urheberrecht liegt, soweit nicht ausdruecklich anders gekennzeichnet, bei Frank Ebner. * Keine Verwendung ohne explizite Genehmigung. * (vgl. § 106 ff UrhG / § 97 UrhG) */ #ifndef TRIANGLE3_H #define TRIANGLE3_H #include "Point3.h" #include "Ray3.h" struct Triangle3 { Point3 p1; Point3 p2; Point3 p3; public: /** empty ctor */ Triangle3() : p1(), p2(), p3() {;} /** ctor */ Triangle3(Point3 p1, Point3 p2, Point3 p3) : p1(p1), p2(p2), p3(p3) {;} // Point3 cross(Point3 b, Point3 c) const { // return Point3( // b.y*c.z - c.y*b.z, // b.z*c.x - c.z*b.x, // b.x*c.y - c.x*b.y // ); // } // float dot(Point3 b, Point3 c) const { // return b.x*c.x + b.y*c.y + b.z*c.z; // } Triangle3 operator - (const Point3 o) const { return Triangle3(p1-o, p2-o, p3-o); } Triangle3& operator += (const Point3 o) { p1 += o; p2 += o; p3 += o; return *this; } Triangle3& operator -= (const Point3 o) { p1 -= o; p2 -= o; p3 -= o; return *this; } /** scale using 3 individual components */ Triangle3& operator *= (const Point3 o) { p1 *= o; p2 *= o; p3 *= o; return *this; } /** switch between CW<->CCW */ void reverse() { std::swap(p2, p3); } void rotate_deg(const Point3 rot) { p1 = p1.rot(rot.x/180.0f*M_PI, rot.y/180.0f*M_PI, rot.z/180.0f*M_PI); p2 = p2.rot(rot.x/180.0f*M_PI, rot.y/180.0f*M_PI, rot.z/180.0f*M_PI); p3 = p3.rot(rot.x/180.0f*M_PI, rot.y/180.0f*M_PI, rot.z/180.0f*M_PI); } // void ensureCCW() { // Point3 norm = cross(p3-p1, p2-p1); // if (norm.z < 0) { // reverse(); // } // } Point3 getNormal() const { return cross( p2-p1, p3-p1 ).normalized(); } // http://www.lighthouse3d.com/tutorials/maths/ray-triangle-intersection/ bool intersects(const Ray3& ray, Point3& pos) const { const Point3 e1 = p2-p1; const Point3 e2 = p3-p1; const Point3 h = cross(ray.dir, e2); const double a = dot(e1, h); if (a > -0.00001 && a < 0.00001) {return false;} const double f = 1/a; const Point3 s = ray.start - p1; const double u = f * dot(s,h); if (u < 0.0 || u > 1.0) {return false;} const Point3 q = cross(s, e1); const double v = f * dot(ray.dir, q); if (v < 0.0 || u + v > 1.0) {return false;} const double t = f * dot(e2,q); if (t > 0.00001) { pos = ray.start + (ray.dir * t); return true; } return false; } /** add some slight delta to prevent rounding issues */ bool intersectsDelta(const Ray3& ray, const double delta, Point3& pos) const { const Point3 e1 = p2-p1; const Point3 e2 = p3-p1; // make delta an absolute value (independent of the triangle's size) // larger triangle -> smaller delta, as u,v are [0:1] //double deltaU = delta/e2.length(); //double deltaV = delta/e1.length(); const double deltaU = delta; const double deltaV = delta; const Point3 h = cross(ray.dir, e2); const double a = dot(e1, h); if (a > -0.00001 && a < 0.00001) {return false;} const double f = 1/a; const Point3 s = ray.start - p1; const double u = f * dot(s,h); if (u < 0.0-deltaU || u > 1.0+deltaU) {return false;} const Point3 q = cross(s, e1); const double v = f * dot(ray.dir, q); if (v < 0.0-deltaV || u + v > 1.0+deltaV) {return false;} const double t = f * dot(e2,q); if (t > 0.00001) { pos = ray.start + (ray.dir * t); return true; } return true; } /** perform some sanity checks */ bool isValid() const { if (p1 == p2) {return false;} if (p1 == p3) {return false;} if (p2 == p3) {return false;} return true; } /* int rayIntersectsTriangle(float *p, float *d, float *v0, float *v1, float *v2) { float e1[3],e2[3],h[3],s[3],q[3]; float a,f,u,v; //crossProduct(h,d,e2); a = innerProduct(e1,h); if (a > -0.00001 && a < 0.00001) return(false); f = 1/a; vector(s,p,v0); u = f * (innerProduct(s,h)); if (u < 0.0 || u > 1.0) return(false); crossProduct(q,s,e1); v = f * innerProduct(d,q); if (v < 0.0 || u + v > 1.0) return(false); // at this stage we can compute t to find out where // the intersection point is on the line t = f * innerProduct(e2,q); if (t > 0.00001) // ray intersection return(true); else // this means that there is a line intersection // but not a ray intersection return (false); } */ }; #endif // TRIANGLE3_H