00001
00002 #ifndef _GK_TRIANGLE_H
00003 #define _GK_TRIANGLE_H
00004
00005 #include "Geometry.h"
00006 #include "Transform.h"
00007
00008 namespace gk {
00009
00010
00011 struct Triangle
00012 {
00013 Point a, b, c;
00014
00015
00016 Triangle( ) {}
00017
00018
00019 Triangle( const Point& a, const Point& b, const Point& c )
00020 :
00021 a(a), b(b), c(c)
00022 {}
00023
00024
00025 ~Triangle( ) {}
00026
00027
00028 float getArea( ) const
00029 {
00030 Vector ab(a, b);
00031 Vector ac(a, c);
00032
00033 return .5f * Cross(ab, ac).Length();
00034 }
00035
00036
00037 Normal getNormal( ) const
00038 {
00039 Vector ab(a, b);
00040 Vector ac(a, c);
00041
00042 return Normal( Normalize(Cross(ab, ac)) );
00043 }
00044
00045
00046 BBox getBBox( ) const
00047 {
00048 BBox bbox;
00049 bbox.Union(a);
00050 bbox.Union(b);
00051 bbox.Union(c);
00052
00053 return bbox;
00054 }
00055
00056
00057 Triangle transform( const Transform& t )
00058 {
00059 return Triangle( t(a), t(b), t(c) );
00060 }
00061
00062
00063
00064
00065
00066
00067
00068 bool Intersect( const Ray &ray, const float htmin, const float htmax,
00069 float &rt, float &ru, float&rv ) const
00070 {
00071
00072 Vector ac(a, c);
00073 const Vector pvec= Cross(ray.d, ac);
00074
00075
00076 Vector ab(a, b);
00077 const float det= Dot(ab, pvec);
00078 if (det > -EPSILON && det < EPSILON)
00079 return false;
00080
00081 const float inv_det= 1.0f / det;
00082
00083
00084 const Vector tvec(a, ray.o);
00085
00086
00087 const float u= Dot(tvec, pvec) * inv_det;
00088 if(u < 0.0f || u > 1.0f)
00089 return false;
00090
00091
00092 const Vector qvec= Cross(tvec, ab);
00093
00094
00095 const float v= Dot(ray.d, qvec) * inv_det;
00096 if(v < 0.0f || u + v > 1.0f)
00097 return false;
00098
00099
00100 rt= Dot(ac, qvec) * inv_det;
00101 ru= u;
00102 rv= v;
00103
00104
00105 return (rt < htmax && rt > htmin);
00106 }
00107
00108
00109
00110
00111 bool Intersect( const float * origin, const float *direction,
00112 const float tmin, const float tmax,
00113 float *rt, float *ru, float *rv ) const
00114 {
00115 assert(rt != NULL);
00116 assert(ru != NULL);
00117 assert(rv != NULL);
00118
00119 Ray ray(
00120 Point(origin[0], origin[1], origin[2]),
00121 Vector(direction[0], direction[1], direction[2]),
00122 tmin, tmax);
00123
00124 return Intersect(ray, tmin, tmax, *rt, *ru, *rv);
00125 }
00126 };
00127
00128 }
00129 #endif