00001 #include <esg/geometry/Triangle.h> 00002 00003 using namespace esg; 00004 00005 // ---- public --- 00006 00007 Geometry* Triangle::clone(const Matrix4* pTrMat) const 00008 { 00009 Triangle* pRet = new Triangle; 00010 pRet->_duplicate_attributes(*this); 00011 if (pTrMat) pRet->_transform(*pTrMat); 00012 return pRet; 00013 } 00014 00015 void Triangle::randomSample(int mask, PointEnv& pe, double* pdf) 00016 { 00017 00018 /* 00019 * Reference: 00020 * Arvo J. et al., State of the Art in Monte Carlo Ray Tracing 00021 * for Relistic Image Sythesis, 00022 * SIGGRAPH2001 Course 29, Aug 13, 2001. Page 25. 00023 */ 00024 00025 pe.mask = ENV_HAVE_NOTHING; 00026 if (!(mask & ENV_WANT_SURFACE_POINT|ENV_WANT_UV_COORD|ENV_WANT_NORMAL)) 00027 return; 00028 00029 Vector3 u(_get_vertex(1)); 00030 Vector3 v(_get_vertex(2)); 00031 pe.intersection.set(_get_vertex(0)); 00032 u.sub(pe.intersection); 00033 v.sub(pe.intersection); 00034 double s = 1 - sqrt(1 - ESG_DBL_RAND); 00035 u.scale(s); 00036 v.scale((1 - s) * ESG_DBL_RAND); 00037 pe.intersection.add(u); 00038 pe.intersection.add(v); 00039 00040 // get UV coord or interpolate normal - unefficient ! 00041 Vector3* n =(((mask&ENV_WANT_NORMAL) &&_normals) ? &(pe.normal) : NULL); 00042 Vector2* uv=(((mask&ENV_WANT_UV_COORD)&&_uvCoords) ? &(pe.uvCoord) : NULL); 00043 if (n || uv) { 00044 (void) _point_inside_polygon(pe.intersection, n, uv); 00045 if (n) { 00046 pe.normalOrientation = PointEnv::OUTWARDS_NORMAL; 00047 pe.mask |= ENV_HAVE_NORMAL; 00048 } else { 00049 if (mask & ENV_WANT_NORMAL) { 00050 // intersection is found but the normal vector 00051 // cannot be interpolated => set it to the facet normal 00052 pe.normal.set(_normal); 00053 if (_normalFixed) pe.normalOrientation = PointEnv::OUTWARDS_NORMAL; 00054 else pe.normalOrientation = PointEnv::RANDOM_NORMAL; 00055 pe.mask |= ENV_HAVE_NORMAL; 00056 } 00057 } 00058 00059 pe.mask |= ((uv) ? 00060 ENV_HAVE_INTERFERENCE|ENV_HAVE_INTERSECTION|ENV_HAVE_UV_COORD : 00061 ENV_HAVE_INTERFERENCE|ENV_HAVE_INTERSECTION); 00062 } 00063 00064 if (pdf) *pdf = 1./_area; 00065 }