189 lines
3.6 KiB
C++
189 lines
3.6 KiB
C++
#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;
|
|
}
|
|
|
|
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
|