00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 #if defined(_MSC_VER)
00025 #pragma once
00026 #endif
00027 
00028 #ifndef PBRT_TEXTURES_CHECKERBOARD_H
00029 #define PBRT_TEXTURES_CHECKERBOARD_H
00030 
00031 
00032 #include "pbrt.h"
00033 #include "texture.h"
00034 #include "paramset.h"
00035 #include "montecarlo.h"
00036 #include "shape.h"
00037 #include "parallel.h"
00038 #include "progressreporter.h"
00039 
00040 
00041 template <typename T> class Checkerboard2DTexture : public Texture<T> {
00042 public:
00043     
00044     Checkerboard2DTexture(TextureMapping2D *m, Reference<Texture<T> > c1,
00045                           Reference<Texture<T> > c2, const string &aa)
00046         : mapping(m), tex1(c1), tex2(c2) {
00047         
00048         if (aa == "none")             aaMethod = NONE;
00049         else if (aa == "closedform")  aaMethod = CLOSEDFORM;
00050         else {
00051             Warning("Antialiasing mode \"%s\" not understood by "
00052                     "Checkerboard2DTexture; using \"closedform\"", aa.c_str());
00053             aaMethod = CLOSEDFORM;
00054         }
00055     }
00056     ~Checkerboard2DTexture() {
00057         delete mapping;
00058     }
00059     T Evaluate(const DifferentialGeometry &dg) const {
00060         float s, t, dsdx, dtdx, dsdy, dtdy;
00061         mapping->Map(dg, &s, &t, &dsdx, &dtdx, &dsdy, &dtdy);
00062         if (aaMethod == NONE) {
00063             
00064             if ((Floor2Int(s) + Floor2Int(t)) % 2 == 0)
00065                 return tex1->Evaluate(dg);
00066             return tex2->Evaluate(dg);
00067         }
00068         else {
00069             
00070 
00071             
00072             float ds = max(fabsf(dsdx), fabsf(dsdy));
00073             float dt = max(fabsf(dtdx), fabsf(dtdy));
00074             float s0 = s - ds, s1 = s + ds;
00075             float t0 = t - dt, t1 = t + dt;
00076             if (Floor2Int(s0) == Floor2Int(s1) && Floor2Int(t0) == Floor2Int(t1)) {
00077                 
00078                 if ((Floor2Int(s) + Floor2Int(t)) % 2 == 0)
00079                     return tex1->Evaluate(dg);
00080                 return tex2->Evaluate(dg);
00081             }
00082 
00083             
00084 #define BUMPINT(x) \
00085                 (Floor2Int((x)/2) + \
00086                  2.f * max((x/2)-Floor2Int(x/2) - .5f, 0.f))
00087             float sint = (BUMPINT(s1) - BUMPINT(s0)) / (2.f * ds);
00088             float tint = (BUMPINT(t1) - BUMPINT(t0)) / (2.f * dt);
00089             float area2 = sint + tint - 2.f * sint * tint;
00090             if (ds > 1.f || dt > 1.f)
00091                 area2 = .5f;
00092             return (1.f - area2) * tex1->Evaluate(dg) +
00093                    area2         * tex2->Evaluate(dg);
00094         }
00095     }
00096 private:
00097     
00098     TextureMapping2D *mapping;
00099     Reference<Texture<T> > tex1, tex2;
00100     enum { NONE, CLOSEDFORM } aaMethod;
00101 };
00102 
00103 
00104 template <typename T> class Checkerboard3DTexture : public Texture<T> {
00105 public:
00106     
00107     Checkerboard3DTexture(TextureMapping3D *m, Reference<Texture<T> > c1,
00108                           Reference<Texture<T> > c2)
00109         : mapping(m), tex1(c1), tex2(c2) {
00110     }
00111     ~Checkerboard3DTexture() {
00112         delete mapping;
00113     }
00114     T Evaluate(const DifferentialGeometry &dg) const {
00115         Vector dpdx, dpdy;
00116         Point p = mapping->Map(dg, &dpdx, &dpdy);
00117         if ((Floor2Int(p.x) + Floor2Int(p.y) + Floor2Int(p.z)) % 2 == 0)
00118             return tex1->Evaluate(dg);
00119         else
00120             return tex2->Evaluate(dg);
00121     }
00122 private:
00123     
00124     TextureMapping3D *mapping;
00125     Reference<Texture<T> > tex1, tex2;
00126 };
00127 
00128 
00129 Texture<float> *CreateCheckerboardFloatTexture(const Transform &tex2world,
00130         const TextureParams &tp);
00131 Texture<Spectrum> *CreateCheckerboardSpectrumTexture(const Transform &tex2world,
00132         const TextureParams &tp);
00133 
00134 #endif // PBRT_TEXTURES_CHECKERBOARD_H