00001 #ifndef TRIANGLE_H
00002 #define TRIANGLE_H
00003
00004
00005 #include "Primitive.h"
00006 #include "Ray.h"
00007 #include "Object.h"
00008
00009
00015 class Triangle : public Primitive
00016 {
00017 public:
00020 Triangle(const Vec3f & a,
00021 const Vec3f & b,
00022 const Vec3f & c)
00023 : Primitive(),
00024 mA(a),
00025 mB(b),
00026 mC(c),
00027 mEdge1(b - a),
00028 mEdge2(c - a)
00029 {
00030 calcBounds();
00031 }
00032
00035 virtual ~Triangle()
00036 {
00037 }
00038
00043 bool intersect(Ray & ray) const
00044 {
00045 const Vec3f pvec = ray.dir().cross( mEdge2 );
00046
00047 const float det = mEdge1.dot(pvec);
00048 if (fabs(det) < EPSILON)
00049 return false;
00050
00051 const float inv_det = 1.0f / det;
00052
00053 const Vec3f tvec = ray.org() - mA;
00054 float lambda = tvec.dot(pvec);
00055 lambda *= inv_det;
00056
00057 if (lambda < 0.0f || lambda > 1.0f)
00058 return false;
00059
00060 const Vec3f qvec = tvec.cross(mEdge1);
00061 float mue = ray.dir().dot(qvec);
00062 mue *= inv_det;
00063
00064 if (mue < 0.0f || mue+lambda > 1.0f)
00065 return false;
00066
00067 float f = mEdge2.dot(qvec);
00068 f = f * inv_det - EPSILON;
00069 if (ray.t() <= f || f < EPSILON)
00070 return false;
00071
00072 ray.setUV(lambda, mue);
00073 ray.setHit(this, f);
00074
00075 return true;
00076 }
00077
00082 virtual Vec3f normal(const Ray & ray) const
00083 {
00084 assert(ray.hit() == this);
00085 assert(ray.obj());
00086
00087 Vec3f e1 = mB - mA;
00088 Vec3f e2 = mC - mA;
00089 Vec3f normal = e1.cross(e2);
00090 ray.obj()->toGlobalCoordinates(normal);
00091 return normal.normal();
00092 }
00093
00098 void axes(const Ray & , Vec3f & x, Vec3f & y) const
00099 {
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113 x = mEdge1.normal();
00114 y = mEdge2.normal();
00115
00116 }
00117
00118
00119 protected:
00121 Vec3f mA, mB, mC;
00122
00124 Vec3f mEdge1, mEdge2;
00125
00126
00129 virtual void calcBounds()
00130 {
00131 mBounds.extend(mA);
00132 mBounds.extend(mB);
00133 mBounds.extend(mC);
00134 }
00135 };
00136
00137 #endif
00138