00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 #include "stdafx.h"
00027 #include "diffgeom.h"
00028 #include "transform.h"
00029 #include "shape.h"
00030 
00031 
00032 DifferentialGeometry::DifferentialGeometry(const Point &P,
00033         const Vector &DPDU, const Vector &DPDV,
00034         const Normal &DNDU, const Normal &DNDV,
00035         float uu, float vv, const Shape *sh)
00036     : p(P), dpdu(DPDU), dpdv(DPDV), dndu(DNDU), dndv(DNDV) {
00037     
00038     nn = Normal(Normalize(Cross(dpdu, dpdv)));
00039     u = uu;
00040     v = vv;
00041     shape = sh;
00042     dudx = dvdx = dudy = dvdy = 0;
00043 
00044     
00045     if (shape && (shape->ReverseOrientation ^ shape->TransformSwapsHandedness))
00046         nn *= -1.f;
00047 }
00048 
00049 
00050 void DifferentialGeometry::ComputeDifferentials(
00051         const RayDifferential &ray) const {
00052     if (ray.hasDifferentials) {
00053         
00054 
00055         
00056         float d = -Dot(nn, Vector(p.x, p.y, p.z));
00057         Vector rxv(ray.rxOrigin.x, ray.rxOrigin.y, ray.rxOrigin.z);
00058         float tx = -(Dot(nn, rxv) + d) / Dot(nn, ray.rxDirection);
00059         if (isnan(tx)) goto fail;
00060         Point px = ray.rxOrigin + tx * ray.rxDirection;
00061         Vector ryv(ray.ryOrigin.x, ray.ryOrigin.y, ray.ryOrigin.z);
00062         float ty = -(Dot(nn, ryv) + d) / Dot(nn, ray.ryDirection);
00063         if (isnan(ty)) goto fail;
00064         Point py = ray.ryOrigin + ty * ray.ryDirection;
00065         dpdx = px - p;
00066         dpdy = py - p;
00067 
00068         
00069 
00070         
00071         float A[2][2], Bx[2], By[2];
00072         int axes[2];
00073         if (fabsf(nn.x) > fabsf(nn.y) && fabsf(nn.x) > fabsf(nn.z)) {
00074             axes[0] = 1; axes[1] = 2;
00075         }
00076         else if (fabsf(nn.y) > fabsf(nn.z)) {
00077             axes[0] = 0; axes[1] = 2;
00078         }
00079         else {
00080             axes[0] = 0; axes[1] = 1;
00081         }
00082 
00083         
00084         A[0][0] = dpdu[axes[0]];
00085         A[0][1] = dpdv[axes[0]];
00086         A[1][0] = dpdu[axes[1]];
00087         A[1][1] = dpdv[axes[1]];
00088         Bx[0] = px[axes[0]] - p[axes[0]];
00089         Bx[1] = px[axes[1]] - p[axes[1]];
00090         By[0] = py[axes[0]] - p[axes[0]];
00091         By[1] = py[axes[1]] - p[axes[1]];
00092         if (!SolveLinearSystem2x2(A, Bx, &dudx, &dvdx)) {
00093             dudx = 0.; dvdx = 0.;
00094         }
00095         if (!SolveLinearSystem2x2(A, By, &dudy, &dvdy)) {
00096             dudy = 0.; dvdy = 0.;
00097         }
00098     }
00099     else {
00100 fail:
00101         dudx = dvdx = 0.;
00102         dudy = dvdy = 0.;
00103         dpdx = dpdy = Vector(0,0,0);
00104     }
00105 }
00106 
00107