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 doxygen 1.5.6