src/rcrt/primitives/DisplacedTriangle.cpp

Go to the documentation of this file.
00001 #include "DisplacedTriangle.h"
00002 
00003 using namespace std;
00004 
00005 namespace rcrt
00006 {
00007 
00008 DisplacedTriangle::DisplacedTriangle(Vertex* av,Vertex* bv,Vertex* cv, SolidObject* parent) : Triangle(av,bv,cv,parent)
00009 {
00010         da = Point3D(a->pos() + ((a->normal() / (a->normal() * faceNormal)) * parent->getMaxDispl()));
00011         db = Point3D(b->pos() + ((b->normal() / (b->normal() * faceNormal)) * parent->getMaxDispl()));
00012         dc = Point3D(c->pos() + ((c->normal() / (c->normal() * faceNormal)) * parent->getMaxDispl()));
00013                 
00014         box.extend(da);
00015         box.extend(a->pos() + (faceNormal * (parent->getMaxDispl() + 100*numeric_limits<float>::epsilon())));
00016         box.extend(db);
00017         box.extend(b->pos() + (faceNormal * (parent->getMaxDispl() + 100*numeric_limits<float>::epsilon())));
00018         box.extend(dc);
00019         box.extend(c->pos() + (faceNormal * (parent->getMaxDispl() + 100*numeric_limits<float>::epsilon())));
00020         
00021         upper = new Triangle(new Vertex(da,a->normal()),new Vertex(db,b->normal()),new Vertex(dc,c->normal()),parent);
00022         
00023         ab = new ConvexQuad(parent,a->pos(),b->pos(),db,da);
00024         bc = new ConvexQuad(parent,b->pos(),c->pos(),dc,db);
00025         ca = new ConvexQuad(parent,c->pos(),a->pos(),da,dc);
00026         
00027         triangles = new vector<Triangle*>();
00028         
00029         int N = parent->getDisplDens();
00030         
00031         for (int i = 0; i < N; i++) {
00032                 for (int j = 0; j < N; j++) {
00033                         for (int k = 0; k < N; k++) {
00034                                 if (i+j+k == N-1) {
00035                                         std::cout << "lower" << std::endl;
00036                                         Point2D uv1 = Point2D(j/N,k/N);
00037                                         Point2D uv2 = Point2D((j+1)/N,k/N);
00038                                         Point2D uv3 = Point2D(j/N,(k+1)/N);
00039                                         
00040                                         Point3D po1 = getDispPoint(uv1);
00041                                         Point3D po2 = getDispPoint(uv2);
00042                                         Point3D po3 = getDispPoint(uv3);
00043                                         
00044                                         Vec3D sno = (po2 - po1).crossP(po3 - po1).normalize();
00045                                         Triangle* t = new Triangle(po1,po2,po3,sno,parent);
00046 //                                      Triangle* t = new Triangle(new Vertex(po1,sno),new Vertex(po2,sno),new Vertex(po3,sno),parent, true);
00047                                         
00048                                         triangles->push_back(t);
00049                                 }
00050                                 
00051                                 if (i+j+k == N-2) {
00052                                         std::cout << "upper" << std::endl;
00053                                         Point2D uv1 = Point2D(j/N,(k+1)/N);
00054                                         Point2D uv2 = Point2D((j+1)/N,k/N);
00055                                         Point2D uv3 = Point2D((j+1)/N,(k+1)/N);
00056                                         
00057                                         Point3D po1 = getDispPoint(uv1);
00058                                         Point3D po2 = getDispPoint(uv2);
00059                                         Point3D po3 = getDispPoint(uv3);
00060                                         
00061                                         Vec3D sno = (po2 - po1).crossP(po3 - po1).normalize();
00062                                         Triangle* t = new Triangle(po1,po2,po3,sno,parent);
00063 //                                      Triangle* t = new Triangle(new Vertex(po1,sno),new Vertex(po2,sno),new Vertex(po3,sno),parent, true);
00064                                         
00065                                         triangles->push_back(t);
00066                                 }
00067                         }               
00068                 }
00069         }
00070         
00071         tree.setTraceables(triangles);
00072 }
00073 
00074 DisplacedTriangle::~DisplacedTriangle()
00075 {
00076         if (ab) delete ab;
00077         if (bc) delete bc;
00078         if (ca) delete ca;
00079         
00080         if (upper) delete upper;
00081 }
00082 
00083 Intersection DisplacedTriangle::baseIntersect(Ray& ray) const
00084 {
00085         ray.tris++;
00086         const Vec3D edge1 = b->pos()-a->pos();
00087     const Vec3D edge2 = c->pos()-a->pos();
00088 
00089     const Vec3D pvec = ray.dir().crossP(edge2);
00090 
00091     const float det = edge1 * pvec;
00092     if (fabs(det) < numeric_limits<float>::epsilon()) return Intersection();
00093 
00094     const float inv_det = 1.0f / det;
00095 
00096     const Vec3D tvec = ray.org()-a->pos();
00097     float lambda = tvec * pvec;
00098     lambda *= inv_det;
00099 
00100     if (lambda < 0.0f || lambda > 1.0f) return Intersection();
00101 
00102     const Vec3D qvec = tvec.crossP(edge1);
00103     float mue = ray.dir() * qvec;
00104     mue *= inv_det;
00105 
00106     if (mue < 0.0f || mue+lambda > 1.0f) return Intersection();
00107 
00108     float f = edge2 * qvec;
00109     f = f * inv_det - numeric_limits<float>::epsilon();
00110     if (ray.maxDist() <= f || f <  numeric_limits<float>::epsilon()  ) return Intersection();
00111 
00112     //Vec3D normal = lambda * b->normal() + mue * c->normal() + (1-lambda-mue) * a->normal();
00113     //normal.normalize();
00114     bool flip = ray.dir()*faceNormal >= numeric_limits<float>::epsilon();
00115     //std::cout << "[TRI-Intersect] t = " << f << " backside=" << flip << " distToOrg=" << (ray.org()-getCentroid()).norm() << " angle="<<ray.dir()*normal << std::endl;
00116     return Intersection(f, this, ray.atDistance(f), lambda, mue, flip);
00117 }
00118 
00119 Intersection DisplacedTriangle::intersect(Ray& ray) const
00120 {
00121         
00122         //Intersection is = tree.intersect(ray);
00123         
00124         Intersection is;
00125         
00126         for(std::vector<Triangle*>::iterator i = triangles->begin(); i != triangles->end(); ++i) {
00127                 is = (*i)->intersect(ray);
00128                 if (is.isValid()) {
00129                         return is;
00130                 }
00131         }
00132         
00133         if (is.isValid()) {
00134                 is.setPrimitive(this);
00135                 return is;
00136         }
00137         
00138         return Intersection();
00139         
00140         //intersect BBox
00141         if (!box.intersect(ray).isValid())
00142                 return Intersection();
00143         
00144 //      Intersection is = triangles.intersect(ray);
00145 //      if (is.isValid()) {
00146 //              is.setPrimitive(this);
00147 //              return is;
00148 //      }
00149         //std::cout << "intersecting volume" << std::endl;
00150         
00151         //const ImageTexture* const dispMap = parent->getDisplMap();
00152         float N = parent->getDisplDens();
00153         //const float maxDispl = parent->getMaxDispl();
00154         
00155         Intersection topIs, bottomIs, abIs, bcIs, caIs, nearIs, farIs;
00156         topIs = upper->intersect(ray);
00157         bottomIs = baseIntersect(ray);
00158 //      bool nearFound = false;
00159 //      bool farFound = false;
00160         
00161 //      nearIs = topIs;
00162 //      farIs = bottomIs;
00163         
00164         //std::cout << "topIS: " << topIs.isValid() << " bottomIS: " << bottomIs.isValid() << std::endl;
00165         
00166         if (false && (topIs.isValid() || bottomIs.isValid())) {
00167                 //std::cout << "topIS: " << topIs.isValid() << " bottomIS: " << bottomIs.isValid() << std::endl;
00168                 nearIs = topIs.isValid() ? topIs : bottomIs;
00169                 Intersection is = nearIs;
00170                 is.setPrimitive(this);
00171                 is.setSNormalL(Vec3D(1,1,1));
00172                 return is;
00173         }
00174         
00175         if (!(topIs.isValid() && bottomIs.isValid())) {
00176                 if(topIs.isValid() || bottomIs.isValid()) {
00177                         nearIs = topIs.isValid() ? topIs : bottomIs;
00178                 }
00179                 
00180                 abIs = ab->intersect(ray);
00181                 bcIs = bc->intersect(ray);
00182                 caIs = ca->intersect(ray);
00183                 
00184                 //std::cout << "abIS: " << abIs.isValid() << " bcIS: " << bcIs.isValid() << " caIS: " << caIs.isValid() << std::endl;
00185                 
00186                 if (false && (abIs.isValid() || bcIs.isValid() || caIs.isValid())) {
00187                         Intersection is = nearIs;
00188                         is.setPrimitive(this);
00189                         //is.setSNormal(Vec3D(1,1,1));
00190                         return is;
00191                 }
00192                 
00193                 if (abIs.isValid() && abIs.getDistance() < nearIs.getDistance()) {
00194                         //std::cout << "setting ab to near" << std::endl;
00195                         farIs = nearIs;
00196                         nearIs = abIs;
00197                 }
00198                 else if (abIs.isValid() && abIs.getDistance() < farIs.getDistance()) {
00199                         //std::cout << "setting ab to far" << std::endl;
00200                         farIs = abIs;
00201                 }
00202                 if (bcIs.isValid() && bcIs.getDistance() < nearIs.getDistance()) {
00203                         //std::cout << "setting bc to near" << std::endl;
00204                         farIs = nearIs;
00205                         nearIs = bcIs;
00206                 }
00207                 else if (bcIs.isValid() && bcIs.getDistance() < farIs.getDistance()) {
00208                         //std::cout << "setting bc to far" << std::endl;
00209                         farIs = bcIs;
00210                 }
00211                 if (caIs.isValid() && caIs.getDistance() < nearIs.getDistance()) {
00212                         //std::cout << "setting ca to near" << std::endl;
00213                         farIs = nearIs;
00214                         nearIs = caIs;
00215                 }
00216                 else if (caIs.isValid() && caIs.getDistance() < farIs.getDistance()) {
00217                         //std::cout << "setting ca to far" << std::endl;
00218                         farIs = caIs;
00219                 }
00220         }
00221         else {
00222                 if(topIs.getDistance() < bottomIs.getDistance()) {
00223                         nearIs = topIs;
00224                         farIs = bottomIs;
00225                 }
00226                 else {
00227                         nearIs = bottomIs;
00228                         farIs = topIs;
00229                 }
00230         }
00231         
00232         //std::cout << "nearIS: " << nearIs.isValid() << " farIS: " << farIs.isValid() << std::endl;
00233         
00234         if (!(nearIs.isValid() && farIs.isValid())) {
00235 //              std::cout << "not both valid" << std::endl;
00236 //              Intersection is = Intersection(1,this, Point3D(1,1,1),1,1,false);
00237 //              //is.setPrimitive(this);
00238 //              is.setSNormalL(Vec3D(1,1,1));
00239 //              return is;
00240                 return Intersection();
00241         }       
00242         
00243         if (false) {
00244                 Intersection is = nearIs;
00245                 is.setPrimitive(this);
00246                 is.setSNormalL(Vec3D(1,1,1));
00247                 return is;
00248         }
00249         
00250         //std::cout << "near and far valid" << std::endl;
00251         
00252         int i = 0,iStop = N,j = 0,jStop = N,k = 0,kStop = N;
00253         
00254         int lastChange = 0;
00255         
00256         Point3D subPA, subPB, subPC;
00257         Vec3D subNC;
00258         Point2D uva, uvb, uvc;
00259         bool rightOfC = false;
00260         
00261         // {iplus = 0, jminus = 1, kplus = 2, iminus = 3, jplus = 4,kminus = 5}
00262         
00263         // setting up start state
00264         
00265         // first intersection with bottom or top triangle
00266         
00267         //std::cout << "first is with top or bottom" << std::endl;
00268         
00269         if (nearIs.getPrimitive() == this || nearIs.getPrimitive() == upper) {
00270                 
00271 //              nearIs = topIs.isValid() ? topIs : bottomIs;
00272 //              Intersection is = nearIs;
00273 //              is.setPrimitive(this);
00274 //              is.setSNormalL(Vec3D(1,1,1));
00275 //              return is;
00276                 
00277                 const Point2D& bcoord = nearIs.getParams();
00278                 float beta = bcoord[0];
00279                 float gamma = bcoord[1];
00280                 
00281                 // get cell indices
00282                 i = floor((1-beta-gamma) * N);
00283                 j = floor(beta * N);
00284                 k = floor(gamma * N);
00285                 
00286                 //std::cout << "i: " << i << " j: " << j << " k: " << k << std::endl;
00287                 
00288                 //first sub triangle is a lower triangle
00289                 if (i+j+k == N-1) {
00290                         
00291                         //std::cout << "lower tri" << std::endl;
00292                         
00293 //                      nearIs.setSNormalL(Vec3D(1,0,1));
00294 //                      return nearIs;
00295                         
00296                         Point2D tuva = Point2D(j/N,k/N);
00297                         Point2D tuvb = Point2D((j+1)/N,k/N);
00298                         Point2D tuvc = Point2D(j/N,(k+1)/N);
00299                         
00300                         Point3D la = getPoint(tuva);
00301                         Point3D lb = getPoint(tuvb);
00302                         Point3D lc = getPoint(tuvc);
00303                         Point3D ua = upper->getPoint(tuva);
00304                         Point3D ub = upper->getPoint(tuvb);
00305                         Point3D uc = upper->getPoint(tuvc);
00306                         
00307                         //setting up points
00308                         
00309                         Point3D ta = getDispPoint(tuva);
00310                         Point3D tb = getDispPoint(tuvb);
00311                         Point3D tc = getDispPoint(tuvc);
00312                         
00313                         ConvexQuad testAB(parent,la,lb,ub,ua);
00314                         ConvexQuad testBC(parent,lb,lc,uc,ub);
00315                         ConvexQuad testCA(parent,lc,la,ua,uc);
00316                         
00317                         if (testAB.intersect(ray).isValid()) {
00318                                 //std::cout << "testAB intersect" << std::endl;
00319                                 //return nearIs;
00320                                 lastChange = 0;
00321                                 subPA = tb; subPB = tc; subPC = ta; uva = tuvb; uvb = tuvc; uvc = tuva;
00322                         }
00323                         else if (testBC.intersect(ray).isValid()) {
00324                                 //std::cout << "testBC intersect" << std::endl;
00325                                 //return nearIs;
00326                                 lastChange = 4;
00327                                 subPA = tc; subPB = ta; subPC = tb; uva = tuvc; uvb = tuva; uvc = tuvb;
00328                         }
00329                         else if (testCA.intersect(ray).isValid()) {
00330                                 //std::cout << "testCA intersect" << std::endl;
00331                                 //return nearIs;
00332                                 lastChange = 0;
00333                                 subPA = tb; subPB = tc; subPC = ta; uva = tuvb; uvb = tuvc; uvc = tuva;
00334                         }
00335                         else {
00336                                 //std::cout << "no intersect" << std::endl;
00337                                 lastChange = 0;
00338                                 subPA = tb; subPB = tc; subPC = ta; uva = tuvb; uvb = tuvc; uvc = tuva;
00339                                 iStop = i; jStop = j; kStop = k;
00340                         }
00341                 }
00342                 
00343                 //first sub triangle is a upper triangle
00344                 if (i+k+j == N-2) {
00345                         
00346                         //std::cout << "upper tri" << std::endl;
00347                         
00348 //                      nearIs.setSNormalL(Vec3D(0,1,0));
00349 //                      return nearIs;
00350                         
00351                         Point2D tuva = Point2D(j/N,(k+1)/N);
00352                         Point2D tuvb = Point2D((j+1)/N,k/N);
00353                         Point2D tuvc = Point2D((j+1)/N,(k+1)/N);
00354                         
00355                         Point3D la = getPoint(tuva);
00356                         Point3D lb = getPoint(tuvb);
00357                         Point3D lc = getPoint(tuvc);
00358                         Point3D ua = upper->getPoint(tuva);
00359                         Point3D ub = upper->getPoint(tuvb);
00360                         Point3D uc = upper->getPoint(tuvc);
00361                         
00362                         Point3D ta = getDispPoint(tuva);
00363                         Point3D tb = getDispPoint(tuvb);
00364                         Point3D tc = getDispPoint(tuvc);
00365                         
00366                         //setting up points
00367                         
00368                         ConvexQuad testAB(parent,la,lb,ub,ua);
00369                         ConvexQuad testBC(parent,lb,lc,uc,ub);
00370                         ConvexQuad testCA(parent,lc,la,ua,uc);
00371                         
00372                         if (testAB.intersect(ray).isValid()) {
00373                                 //std::cout << "testAB intersect" << std::endl;
00374                                 //return nearIs;
00375                                 lastChange = 1;
00376                                 subPA = tb; subPB = tc; subPC = ta; uva = tuvb; uvb = tuvc; uvc = tuva;
00377                         }
00378                         else if (testBC.intersect(ray).isValid()) {
00379                                 //std::cout << "testBC intersect" << std::endl;
00380                                 //return nearIs;
00381                                 lastChange = 3;
00382                                 subPA = ta; subPB = tb; subPC = tc; uva = tuva; uvb = tuvb; uvc = tuvc;
00383                         }
00384                         else if (testCA.intersect(ray).isValid()) {
00385                                 //std::cout << "testCA intersect" << std::endl;
00386                                 //return nearIs;
00387                                 lastChange = 3;
00388                                 subPA = ta; subPB = tb; subPC = tc; uva = tuva; uvb = tuvb; uvc = tuvc;
00389                         }
00390                         else {
00391                                 //std::cout << "no intersect" << std::endl;
00392                                 lastChange = 0;
00393                                 subPA = tb; subPB = tc; subPC = ta; uva = tuvb; uvb = tuvc; uvc = tuva;
00394                                 iStop = i; jStop = j; kStop = k;
00395                         }
00396                 }
00397         }
00398         // first Intersection with side quads
00399         else {
00400                 
00401                 //std::cout << "first IS with side" << std::endl;
00402                 
00403                 // determining cell to enter
00404                 if(nearIs.getPrimitive() == ab) {
00405                         Point3D p = nearIs.getPosition();
00406                         Vec3D v = p - a->pos();
00407                         Vec3D orthInSide = (da - a->pos()).crossP(b->pos()-a->pos()).crossP(b->pos() - a->pos()).normalize();
00408                         orthInSide = orthInSide * (orthInSide * faceNormal);
00409                         Vec3D vp = orthInSide * (v * orthInSide);
00410                         //Vec3D vp = faceNormal * (v * faceNormal);
00411                         float f = fabs(vp.norm());
00412                         Point3D aAl = a->pos() + (da - a->pos()) * f;
00413                         Point3D bAl = b->pos() + (db - b->pos()) * f;
00414                         float x = (bAl - aAl).norm();
00415                         float y = (p - aAl).norm();
00416                         float ratio = y / x;
00417                         
00418                         //std::cout << "ratio: " << ratio << std::endl;
00419                         
00420                         // calculating indices - gamma=0
00421                         float alpha = 1 - ratio;
00422                         float beta = ratio;
00423                         float gamma = 0;
00424                         
00425                         // get cell indices
00426                         i = floor(alpha * N);
00427                         j = floor(beta * N);
00428                         k = floor(gamma * N);
00429                         
00430                         //setting up points
00431                         Point2D tuva = Point2D(j/N,k/N);
00432                         Point2D tuvb = Point2D((j+1)/N,k/N);
00433                         Point2D tuvc = Point2D(j/N,(k+1)/N);
00434                         
00435                         Point3D ta = getDispPoint(tuva);
00436                         Point3D tb = getDispPoint(tuvb);
00437                         Point3D tc = getDispPoint(tuvc);
00438                         
00439                         lastChange = 2;
00440                         subPA = ta; subPB = tb; subPC = tc; uva = tuva; uvb = tuvb; uvc = tuvc;
00441                 }
00442                 else if(nearIs.getPrimitive() == bc) {
00443                         Point3D p = nearIs.getPosition();
00444                         Vec3D v = p - b->pos();
00445                         Vec3D orthInSide = (db - b->pos()).crossP(c->pos()-b->pos()).crossP(c->pos() - b->pos()).normalize();
00446                         orthInSide = orthInSide * (orthInSide * faceNormal);
00447                         Vec3D vp = orthInSide * (v * orthInSide);
00448                         float f = fabs(vp.norm());
00449                         Point3D bAl = b->pos() + (db - b->pos()) * f;
00450                         Point3D cAl = c->pos() + (dc - c->pos()) * f;
00451                         float x = (cAl - bAl).norm();
00452                         float y = (p - bAl).norm();
00453                         float ratio = y / x;
00454                         
00455                         //std::cout << "ratio: " << ratio << std::endl;
00456                         
00457                         // calculating indices - gamma=0
00458                         float alpha = 0;
00459                         float beta = 1 - ratio;
00460                         float gamma = ratio;
00461                         
00462                         // get cell indices
00463                         i = floor(alpha * N);
00464                         j = floor(beta * N);
00465                         k = floor(gamma * N);
00466                         
00467                         //setting up points and uvs
00468                         Point2D tuva = Point2D(j/N,k/N);
00469                         Point2D tuvb = Point2D((j+1)/N,k/N);
00470                         Point2D tuvc = Point2D(j/N,(k+1)/N);
00471                         
00472                         Point3D ta = getDispPoint(tuva);
00473                         Point3D tb = getDispPoint(tuvb);
00474                         Point3D tc = getDispPoint(tuvc);
00475                         
00476                         lastChange = 0;
00477                         subPA = tb; subPB = tc; subPC = ta; uva = tuvb; uvb = tuvc; uvc = tuva;
00478                 }
00479                 else if(nearIs.getPrimitive() == ca) {
00480                         Point3D p = nearIs.getPosition();
00481                         Vec3D v = p - c->pos();
00482                         Vec3D orthInSide = (dc - c->pos()).crossP(a->pos()-c->pos()).crossP(a->pos() - c->pos()).normalize();
00483                         orthInSide = orthInSide * (orthInSide * faceNormal);
00484                         Vec3D vp = orthInSide * (v * orthInSide);
00485                         float f = fabs(vp.norm());
00486                         Point3D cAl = c->pos() + (dc - c->pos()) * f;
00487                         Point3D aAl = a->pos() + (da - a->pos()) * f;
00488                         float x = (aAl - cAl).norm();
00489                         float y = (p - cAl).norm();
00490                         float ratio = y / x;
00491                         
00492                         //std::cout << "ratio: " << ratio << std::endl;
00493                         
00494                         // calculating indices - gamma=0
00495                         float alpha = ratio;
00496                         float beta = 0;
00497                         float gamma = 1 - ratio;
00498                         
00499                         // get cell indices
00500                         i = floor(alpha * N);
00501                         j = floor(beta * N);
00502                         k = floor(gamma * N);
00503                         
00504                         //setting up points and uvs
00505                         Point2D tuva = Point2D(j/N,k/N);
00506                         Point2D tuvb = Point2D((j+1)/N,k/N);
00507                         Point2D tuvc = Point2D(j/N,(k+1)/N);
00508                         
00509                         Point3D ta = getDispPoint(tuva);
00510                         Point3D tb = getDispPoint(tuvb);
00511                         Point3D tc = getDispPoint(tuvc);
00512                         
00513                         lastChange = 2;
00514                         subPA = tc; subPB = ta; subPC = tb; uva = tuvc; uvb = tuva; uvc = tuvb;
00515                 }
00516         }
00517         
00518         if (!(i+j+k == N-1 || i+j+k == N-2)) {
00519                 std::cout << "omfg!!! i=" << i << " j=" << j << " k=" << k << " N=" << N << std::endl; 
00520         }
00521         
00522         if (false) {
00523                 if (i+j+k == N-1) {
00524                         Intersection is = nearIs;
00525                         is.setPrimitive(this);
00526                         is.setSNormalL(Vec3D(1,0,0));
00527                         return is;
00528                 }
00529                 if (i+j+k == N-2) {
00530                         Intersection is = nearIs;
00531                         is.setPrimitive(this);
00532                         is.setSNormalL(Vec3D(0,1,0));
00533                         return is;
00534                 }
00535         }
00536         
00537 //      //determining end cells
00538 //      
00539 //      if (farIs.getPrimitive() == this || farIs.getPrimitive() == upper) {
00540 //              // end intersection with top or bottom
00541 //              const Point2D& bcoord = nearIs.getParams();
00542 //              float beta = bcoord[0];
00543 //              float gamma = bcoord[1];
00544 //              
00545 //              // get cell indices
00546 //              iStop = floor((1-beta-gamma) * N);
00547 //              jStop = floor(beta * N);
00548 //              kStop = floor(gamma * N);
00549 //      }
00550 //      else {
00551 //              // end intersection with side
00552 //              if(farIs.getPrimitive() == ab) {
00553 //                      Point3D p = farIs.getPosition();
00554 //                      Vec3D v = p - a->pos();
00555 //                      Vec3D orthInSide = (da - a->pos()).crossP(b->pos()-a->pos()).crossP(b->pos() - a->pos()).normalize();
00556 //                      orthInSide = orthInSide * (orthInSide * faceNormal);
00557 //                      Vec3D vp = orthInSide * (v * orthInSide);
00558 //                      //Vec3D vp = faceNormal * (v * faceNormal);
00559 //                      float f = fabs(vp.norm());
00560 //                      Point3D aAl = a->pos() + (da - a->pos()) * f;
00561 //                      Point3D bAl = b->pos() + (db - b->pos()) * f;
00562 //                      float x = (bAl - aAl).norm();
00563 //                      float y = (p - aAl).norm();
00564 //                      float ratio = y / x;
00565 //                      
00566 //                      // calculating indices - gamma=0
00567 //                      float alpha = 1 - ratio;
00568 //                      float beta = ratio;
00569 //                      float gamma = 0;
00570 //                      
00571 //                      // get cell indices
00572 //                      iStop = floor(alpha * N);
00573 //                      jStop = floor(beta * N);
00574 //                      kStop = floor(gamma * N);
00575 //              }
00576 //              else if(farIs.getPrimitive() == bc) {
00577 //                      Point3D p = farIs.getPosition();
00578 //                      Vec3D v = p - b->pos();
00579 //                      Vec3D orthInSide = (db - b->pos()).crossP(c->pos()-b->pos()).crossP(c->pos() - b->pos()).normalize();
00580 //                      orthInSide = orthInSide * (orthInSide * faceNormal);
00581 //                      Vec3D vp = orthInSide * (v * orthInSide);
00582 //                      float f = fabs(vp.norm());
00583 //                      Point3D bAl = b->pos() + (db - b->pos()) * f;
00584 //                      Point3D cAl = c->pos() + (dc - c->pos()) * f;
00585 //                      float x = (cAl - bAl).norm();
00586 //                      float y = (p - bAl).norm();
00587 //                      float ratio = y / x;
00588 //                      
00589 //                      // calculating indices - gamma=0
00590 //                      float alpha = 0;
00591 //                      float beta = 1 - ratio;
00592 //                      float gamma = ratio;
00593 //                      
00594 //                      // get cell indices
00595 //                      iStop = floor(alpha * N);
00596 //                      jStop = floor(beta * N);
00597 //                      kStop = floor(gamma * N);
00598 //              }
00599 //              else if(farIs.getPrimitive() == ca) {
00600 //                      Point3D p = farIs.getPosition();
00601 //                      Vec3D v = p - c->pos();
00602 //                      Vec3D orthInSide = (dc - c->pos()).crossP(a->pos()-c->pos()).crossP(a->pos() - c->pos()).normalize();
00603 //                      orthInSide = orthInSide * (orthInSide * faceNormal);
00604 //                      Vec3D vp = orthInSide * (v * orthInSide);
00605 //                      float f = fabs(vp.norm());
00606 //                      Point3D cAl = c->pos() + (dc - c->pos()) * f;
00607 //                      Point3D aAl = a->pos() + (da - a->pos()) * f;
00608 //                      float x = (aAl - cAl).norm();
00609 //                      float y = (p - cAl).norm();
00610 //                      float ratio = y / x;
00611 //                      
00612 //                      // calculating indices - gamma=0
00613 //                      float alpha = ratio;
00614 //                      float beta = 0;
00615 //                      float gamma = 1 - ratio;
00616 //                      
00617 //                      // get cell indices
00618 //                      iStop = floor(alpha * N);
00619 //                      jStop = floor(beta * N);
00620 //                      kStop = floor(gamma * N);
00621 //              }
00622 //      }
00623         
00624         // brute Force
00625         if(true) {
00626                 for (i = 0; i < N; i++) {
00627                         for (j = 0; j < N; j++) {
00628                                 for (k = 0; k < N; k++) {
00629                                         if (i+j+k == N-1) {
00630                                                 //std::cout << "lower" << std::endl;
00631                                                 Point2D uv1 = Point2D(j/N,k/N);
00632                                                 Point2D uv2 = Point2D((j+1)/N,k/N);
00633                                                 Point2D uv3 = Point2D(j/N,(k+1)/N);
00634                                                 
00635                                                 Point3D po1 = getDispPoint(uv1);
00636                                                 Point3D po2 = getDispPoint(uv2);
00637                                                 Point3D po3 = getDispPoint(uv3);
00638                                                 
00639                                                 Vec3D sno = (po2 - po1).crossP(po3 - po1).normalize();
00640                                                 
00641                                                 Triangle t = Triangle(po1,po2,po3,sno,parent);
00642                                                 
00643                                                 Intersection is = t.intersect(ray);
00644                                                 
00645                                                 if(is.isValid()) {
00646                                                         is.setPrimitive(this);
00647                                                         is.setGNormalL(sno);
00648                                                         is.setSNormalL(sno);
00649                                                         return is;
00650                                                 }
00651                                         }
00652                                         
00653                                         if (i+j+k == N-2) {
00654                                                 //std::cout << "upper" << std::endl;
00655                                                 Point2D uv1 = Point2D(j/N,(k+1)/N);
00656                                                 Point2D uv2 = Point2D((j+1)/N,k/N);
00657                                                 Point2D uv3 = Point2D((j+1)/N,(k+1)/N);
00658                                                 
00659                                                 Point3D po1 = getDispPoint(uv1);
00660                                                 Point3D po2 = getDispPoint(uv2);
00661                                                 Point3D po3 = getDispPoint(uv3);
00662                                                 
00663                                                 Vec3D sno = (po2 - po1).crossP(po3 - po1).normalize();
00664                                                 
00665                                                 Triangle t = Triangle(po1,po2,po3,sno,parent);
00666 
00667                                                 Intersection is = t.intersect(ray);
00668 
00669                                                 if(is.isValid()) {
00670                                                         is.setPrimitive(this);
00671                                                         is.setGNormalL(sno);
00672                                                         is.setSNormalL(sno);
00673                                                         return is;
00674                                                 }
00675                                         }
00676                                 }               
00677                         }
00678                 }
00679                 return Intersection();
00680         }
00681         
00682         //std::cout << "Idices: i=" << i << " j=" << j << " k=" << k << std::endl;
00683         
00684         // calculating C Normal
00685         
00686 //      std::cout << "uvc: beta=" << uvc[0] << " gamma=" << uvc[1] << std::endl;
00687 //      std::cout << "uva: beta=" << uva[0] << " gamma=" << uva[1] << std::endl;
00688 //      std::cout << "uvb: beta=" << uvb[0] << " gamma=" << uvb[1] << std::endl;
00689         
00690         subNC = getDispNormal(uvc);
00691         
00692         // traversal
00693         
00694         float delta = 1 / N;
00695         
00696         //return Intersection();
00697         
00698         while(true) {
00699                 //std::cout << "loop" << std::endl;
00700                 //return Intersection();
00701                 //std::cout << "Volume Traversal: change:" << lastChange << "  Idices: i=" << i << " j=" << j << " k=" << k << std::endl;
00702                 Vec3D subNormal = (subPB - subPA).crossP(subPC - subPA).normalize();
00703                 Triangle subTri(subPA, subPB, subPC, subNormal, parent);
00704                 //std::cout << "Normal: " << subNormal << "  A: " << subPA << "  B: " << subPB << "  C: " << subPC << std::endl;
00705                 Intersection subIs = subTri.intersect(ray);
00706                 if (subIs.isValid()) {
00707 //                      if (i+j+k == N - 1)
00708 //                              subNormal = Vec3D(1,0,1);
00709 //                      if (i+j+k == N - 2)
00710 //                              subNormal = Vec3D(0,1,0);
00711                         //std::cout << "valid subIS" << std::endl;
00712                         subIs.setPrimitive(this);
00713                         subIs.setGNormalL(subNormal);
00714                         //std::cout << "setting sNormal " << subNormal << std::endl;
00715                         subIs.setSNormalL(subNormal);
00716                         //subIs.setUV(getUV(subIs.getParams()));
00717                         //std::cout << "normal set to " << subIs.getSNormal() << " and returning"<< std::endl;
00718                         return subIs;
00719                 }
00720                 //std::cout << "no valid subIS" << std::endl;
00721                 if (i == iStop && j == jStop && k == kStop) {
00722                         //std::cout << "Stop Coordinates reached" << std::endl;
00723                         return Intersection();
00724                 }
00725                 rightOfC = ((subNC.crossP(ray.org() - subPC)) * ray.dir() < 0);
00726                 if(rightOfC) {
00727                         subPA = subPC; uva = uvc;
00728                 }
00729                 else {
00730                         subPB = subPC; uvb = uvc;
00731                 }
00732                 // Take advantage of numbering. 5 = −1 mod 6
00733                 lastChange = (lastChange + (rightOfC ? 1 : 5)) % 6;
00734                 //std::cout << "change: " << lastChange << std::endl;
00735                 if(lastChange == 3 /* change == iminus */) {
00736                         if (--i < 0){
00737                                 //std::cout << "moving out of volume" << std::endl;
00738                                 return Intersection();
00739                         }
00740                         uvc = Point2D((j+1)*delta, (k+1)*delta);
00741                 }
00742                 else if(lastChange == 0 /* change == iplus */) {
00743                         if (++i >= N ) {
00744                                 //std::cout << "moving out of volume" << std::endl;
00745                                 return Intersection();
00746                         }
00747                         uvc = Point2D( j*delta, k*delta);
00748                 }
00749                 else if(lastChange == 1 /* change == jminus */) {
00750                         if (--j < 0) {
00751                                 //std::cout << "moving out of volume" << std::endl;
00752                                 return Intersection();
00753                         }
00754                         uvc = Point2D( j*delta, (k+1)*delta);
00755                 }
00756                 else if(lastChange == 4 /* change == jplus */) {
00757                         if (++j >= N ) {
00758                                 //std::cout << "moving out of volume" << std::endl;
00759                                 return Intersection();
00760                         }
00761                         uvc = Point2D( (j+1)*delta, k*delta);
00762                 }
00763                 else if(lastChange == 5 /* change == kminus */) {
00764                         if (--k < 0) {
00765                                 //std::cout << "moving out of volume" << std::endl;
00766                                 return Intersection();
00767                         }
00768                         uvc = Point2D( (j+1)*delta, k*delta);
00769                 }
00770                 else if(lastChange == 2 /* change == kplus */) {
00771                         if (++k >= N ) {
00772                                 //std::cout << "moving out of volume" << std::endl;
00773                                 return Intersection();
00774                         }
00775                         uvc = Point2D( j*delta, (k+1)*delta);
00776                 }
00777                 subPC = getDispPoint(uvc);
00778                 subNC = getDispNormal(uvc);
00779         }
00780 
00781 }
00782 
00783 Point3D DisplacedTriangle::getDispPoint(float beta, float gamma) const
00784 {
00785         Point3D lp = getPoint(beta,gamma);
00786         return lp + ((upper->getPoint(beta,gamma)-lp).normalize()*parent->getMaxDispl()*parent->getDisplMap()->getColor(getUV(beta,gamma)).getLuminance());
00787 }
00788 
00789 Vec3D DisplacedTriangle::getDispNormal(float beta, float gamma) const
00790 {
00791         Point3D lp = getPoint(beta,gamma);
00792         return (upper->getPoint(beta,gamma)-lp).normalize();
00793 }
00794 
00795 Point3D DisplacedTriangle::getDispPoint(const Point2D& p) const
00796 {
00797         float beta = p[0];
00798         float gamma = p[1];
00799         return getDispPoint(beta,gamma);
00800 }
00801 
00802 Vec3D DisplacedTriangle::getDispNormal(const Point2D& p) const
00803 {
00804         float beta = p[0];
00805         float gamma = p[1];
00806         return getDispNormal(beta,gamma);
00807 }
00808 
00809 }

Generated on Thu Jan 31 19:26:19 2008 for RenderingCompetitionRayTracer by  doxygen 1.5.3