Cube.cpp
Go to the documentation of this file.00001 /**<!--------------------------------------------------------------------> 00002 @file Cube.cpp 00003 @author Travis Fischer (fisch0920@gmail.com) 00004 @author Matthew Jacobs (jacobs.mh@gmail.com) 00005 @date Fall 2008 00006 00007 @brief 00008 Representation of a unit cube in 3-space from (-.5,-.5,-.5) to (.5,.5,.5) 00009 <!-------------------------------------------------------------------->**/ 00010 00011 #include "Cube.h" 00012 #include "SurfacePoint.h" 00013 #include <Random.h> 00014 00015 #include <GL/glut.h> 00016 00017 real_t Cube::getIntersection(const Ray &ray, SurfacePoint &pt) { 00018 Point3 P; 00019 Vector3 D; 00020 _transformRayWorldToObj(ray, P, D); 00021 00022 real_t minT = INFINITY; 00023 00024 // Check for intersection with Sides of Cube 00025 // ----------------------------------------- 00026 for(int u = 3, v = 0, w = 1; u--; w = v, v = u) { 00027 const real_t invD = 1 / D[u]; 00028 const real_t t1 = (0.5 - P[u]) * invD; 00029 00030 if (isValidT(t1, minT)) { 00031 const Point3 &p = P + t1 * D; 00032 00033 if (fabs(p[v]) <= 0.5 && fabs(p[w]) <= 0.5) { 00034 pt.normalCase = u; 00035 minT = t1; 00036 } 00037 } 00038 00039 const real_t t2 = (-0.5 - P[u]) * invD; 00040 if (isValidT(t2, minT)) { 00041 const Point3 &p = P + t2 * D; 00042 00043 if (fabs(p[v]) <= 0.5 && fabs(p[w]) <= 0.5) { 00044 pt.normalCase = 4 + u; 00045 minT = t2; 00046 } 00047 } 00048 } 00049 00050 return minT; 00051 } 00052 00053 bool Cube::intersects(const Ray &ray, real_t tMax) { 00054 Point3 P; 00055 Vector3 D; 00056 _transformRayWorldToObj(ray, P, D); 00057 00058 // Check for intersection with Sides of Cube 00059 // ----------------------------------------- 00060 for(int u = 3, v = 0, w = 1; u--; w = v, v = u) { 00061 const real_t invD = 1 / D[u]; 00062 real_t t = (0.5 - P[u]) * invD; 00063 00064 if (isValidT(t, tMax)) { 00065 const Point3 &p = P + t * D; 00066 00067 if (p[v] > -0.5 && p[v] < 0.5 && p[w] > -0.5 && p[w] < 0.5) 00068 return true; 00069 } 00070 00071 t = (-0.5 - P[u]) * invD; 00072 if (isValidT(t, tMax)) { 00073 const Point3 &p = P + t * D; 00074 00075 if (p[v] > -0.5 && p[v] < 0.5 && p[w] > -0.5 && p[w] < 0.5) 00076 return true; 00077 } 00078 } 00079 00080 return false; 00081 } 00082 00083 void Cube::_getUV(SurfacePoint &pt) const { 00084 const Point3 &P = pt.position; 00085 real_t &u = pt.uv.u, &v = pt.uv.v; 00086 00087 // 0 <= normalCase <= 6 (excluding 3) 00088 const char side = (pt.normalCase & 3); 00089 v = P[side + 1 - 3 * (side == 2)] + 0.5; 00090 u = P[side + 2 - 3 * (side >= 1)] + 0.5; 00091 00092 if (side == 2) { 00093 const real_t c = v; 00094 v = u; 00095 u = 1 - c; 00096 } 00097 00098 if (pt.normalCase & 4) 00099 v = 1 - v; 00100 00101 if (!(pt.normalCase & 5)) { 00102 u = 1 - u; 00103 v = 1 - v; 00104 } 00105 } 00106 00107 void Cube::_getGeometricNormal(SurfacePoint &pt) const { 00108 Vector3 nObj; 00109 nObj[pt.normalCase & 3] = 1 - ((pt.normalCase & 4) >> 1); 00110 00111 _transformVector3ObjToWorld(nObj, pt.normalG); 00112 } 00113 00114 void Cube::preview() { 00115 Transformable::preview(); 00116 00117 glutSolidCube(1.0); 00118 } 00119 00120 real_t Cube::_getSurfaceArea() { 00121 // Transform e1, e2, e3 to world space and get 00122 // basis vectors b1, b2, b3 00123 const Point3 &p0 = m_transToWorld * Point3(0, 0, 0); 00124 const Point3 &p1 = m_transToWorld * Point3(1, 0, 0); 00125 const Point3 &p2 = m_transToWorld * Point3(0, 1, 0); 00126 const Point3 &p3 = m_transToWorld * Point3(0, 0, 1); 00127 00128 const Vector3 &b1 = (p1 - p0); 00129 const Vector3 &b2 = (p2 - p0); 00130 const Vector3 &b3 = (p3 - p0); 00131 00132 real_t area = 0; 00133 area += _parallelogramArea(b1, b2); 00134 area += _parallelogramArea(b1, b3); 00135 area += _parallelogramArea(b2, b3); 00136 area += _parallelogramArea(b2, b1); 00137 area += _parallelogramArea(b3, b2); 00138 area += _parallelogramArea(b3, b1); 00139 00140 return area; 00141 } 00142 00143 #if 0 00144 Vector3 Cube::getNormal(const Point3 &pt) const { 00145 const Point3 &ptObj = m_transToWorldInv * pt; 00146 Vector3 nObj, nWorld; 00147 00148 for(int i = 3; i--;) { 00149 const real_t &val = ptObj[i]; 00150 00151 if (EQ(ABS(val), 0.5)) { 00152 nObj[i] = 1 - 2 * (val < 0); 00153 _transformVector3ObjToWorld(nObj, nWorld); 00154 00155 return nWorld; 00156 } 00157 } 00158 00159 ASSERT(0 && "invalid Cube::getNormal"); 00160 00161 nObj[0] = 1; 00162 _transformVector3ObjToWorld(nObj, nWorld); 00163 00164 return nWorld; 00165 } 00166 #endif 00167
Generated on 28 Feb 2009 for Milton by
1.5.6