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