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 #include "sampling.h"
00026 #include "paramset.h"
00027 #include "film.h"
00028
00029 #define SQRT_SAMPLE_TABLE_SIZE 64
00030 #define SAMPLE_TABLE_SIZE (SQRT_SAMPLE_TABLE_SIZE * \
00031 SQRT_SAMPLE_TABLE_SIZE)
00032
00033 class BestCandidateSampler : public Sampler {
00034 public:
00035
00036 BestCandidateSampler(int xstart, int xend,
00037 int ystart, int yend,
00038 int pixelsamples);
00039 ~BestCandidateSampler() {
00040 delete[] strat2D;
00041
00042 delete[] oneDSamples;
00043 delete[] twoDSamples;
00044 }
00045 int RoundSize(int size) const {
00046 int root = Ceil2Int(sqrtf((float)size - .5f));
00047 return root*root;
00048 }
00049 bool GetNextSample(Sample *sample);
00050 private:
00051
00052 int tableOffset;
00053 float xTableCorner, yTableCorner, tableWidth;
00054 static const float sampleTable[SAMPLE_TABLE_SIZE][5];
00055 float **oneDSamples, **twoDSamples;
00056 int *strat2D;
00057 float sampleOffsets[3];
00058 };
00059
00060 BestCandidateSampler::
00061 BestCandidateSampler(int xstart, int xend,
00062 int ystart, int yend,
00063 int pixelSamples)
00064 : Sampler(xstart, xend, ystart, yend, pixelSamples) {
00065 tableWidth =
00066 (float)SQRT_SAMPLE_TABLE_SIZE / sqrtf(pixelSamples);
00067 xTableCorner = float(xPixelStart) - tableWidth;
00068 yTableCorner = float(yPixelStart);
00069 tableOffset = SAMPLE_TABLE_SIZE;
00070
00071 oneDSamples = twoDSamples = NULL;
00072 strat2D = NULL;
00073 }
00074 #include "samplers/sampledata.cpp"
00075 bool BestCandidateSampler::GetNextSample(Sample *sample) {
00076 again:
00077 if (tableOffset == SAMPLE_TABLE_SIZE) {
00078
00079 tableOffset = 0;
00080 xTableCorner += tableWidth;
00081 if (xTableCorner >= xPixelEnd) {
00082 xTableCorner = float(xPixelStart);
00083 yTableCorner += tableWidth;
00084 if (yTableCorner >= yPixelEnd)
00085 return false;
00086 }
00087 if (!oneDSamples) {
00088
00089 oneDSamples = new float *[sample->n1D.size()];
00090 for (u_int i = 0; i < sample->n1D.size(); ++i) {
00091 oneDSamples[i] = (sample->n1D[i] == 1) ?
00092 new float[SAMPLE_TABLE_SIZE] : NULL;
00093 }
00094 twoDSamples = new float *[sample->n2D.size()];
00095 strat2D = new int[sample->n2D.size()];
00096 for (u_int i = 0; i < sample->n2D.size(); ++i) {
00097 twoDSamples[i] = (sample->n2D[i] == 1) ?
00098 new float[2 * SAMPLE_TABLE_SIZE] : NULL;
00099 strat2D[i] =
00100 Ceil2Int(sqrtf((float)sample->n2D[i] - .5f));
00101 }
00102 }
00103
00104 for (int i = 0; i < 3; ++i)
00105 sampleOffsets[i] = RandomFloat();
00106
00107 for (u_int i = 0; i < sample->n1D.size(); ++i)
00108 if (sample->n1D[i] == 1)
00109 LDShuffleScrambled1D(SAMPLE_TABLE_SIZE, 1,
00110 oneDSamples[i]);
00111 for (u_int i = 0; i < sample->n2D.size(); ++i)
00112 if (sample->n2D[i] == 1)
00113 LDShuffleScrambled2D(SAMPLE_TABLE_SIZE, 1,
00114 twoDSamples[i]);
00115 }
00116
00117 #define WRAP(x) ((x) > 1 ? ((x)-1) : (x))
00118 sample->imageX = xTableCorner + tableWidth *
00119 sampleTable[tableOffset][0];
00120 sample->imageY = yTableCorner + tableWidth *
00121 sampleTable[tableOffset][1];
00122 sample->time = WRAP(sampleOffsets[0] +
00123 sampleTable[tableOffset][2]);
00124 sample->lensU = WRAP(sampleOffsets[1] +
00125 sampleTable[tableOffset][3]);
00126 sample->lensV = WRAP(sampleOffsets[2] +
00127 sampleTable[tableOffset][4]);
00128
00129 if (sample->imageX < xPixelStart ||
00130 sample->imageX >= xPixelEnd ||
00131 sample->imageY < yPixelStart ||
00132 sample->imageY >= yPixelEnd) {
00133 ++tableOffset;
00134 goto again;
00135 }
00136
00137 for (u_int i = 0; i < sample->n1D.size(); ++i) {
00138 if (sample->n1D[i] == 1)
00139 sample->oneD[i][0] = oneDSamples[i][tableOffset];
00140 else
00141 StratifiedSample1D(sample->oneD[i], sample->n1D[i]);
00142 }
00143 for (u_int i = 0; i < sample->n2D.size(); ++i) {
00144 if (sample->n2D[i] == 1) {
00145 sample->twoD[i][0] = twoDSamples[i][2*tableOffset];
00146 sample->twoD[i][1] = twoDSamples[i][2*tableOffset+1];
00147 }
00148 else {
00149 StratifiedSample2D(sample->twoD[i],
00150 strat2D[i],
00151 strat2D[i]);
00152 }
00153 }
00154 ++tableOffset;
00155 return true;
00156 }
00157 extern "C" DLLEXPORT Sampler *CreateSampler(const ParamSet ¶ms, const Film *film) {
00158
00159 int xstart, xend, ystart, yend;
00160 film->GetSampleExtent(&xstart, &xend, &ystart, ¥d);
00161 int nsamp = params.FindOneInt("pixelsamples", 4);
00162 return new BestCandidateSampler(xstart, xend, ystart, yend, nsamp);
00163 }