int callbackInterval = Math.min(1000,
Math.max(1, pairsPerSeedTask / 100));
int nextCallback = 0;
DoubleArray weight = new DoubleArray();
short[] lightPathLength = new short[pairsPerSeedTask];
short[] eyePathLength = new short[pairsPerSeedTask];
long randomSeed = initialRandomSeed;
for (int i = 0; i < pairsPerSeedTask; i++) {
if (--nextCallback <= 0) {
if (!monitor.notifyProgress(i, pairsPerSeedTask)) {
monitor.notifyCancelled();
return null;
}
nextCallback = callbackInterval;
}
Path path = generatePath(randomSeed++);
/* store information about the path so we don't have to
* regenerate it during the resampling phase.
*/
if (path.getLightPathLength() > Short.MAX_VALUE) {
throw new UnexpectedException("Light subpath too long.");
}
if (path.getEyePathLength() > Short.MAX_VALUE) {
throw new UnexpectedException("Eye subpath too long.");
}
lightPathLength[i] = (short) path.getLightPathLength();
eyePathLength[i] = (short) path.getEyePathLength();
join(path.getLightTail(), path.getEyeTail(), weight);
}
monitor.notifyStatusChanged("Resampling MLT seeds");
double totalWeight = MathUtil.sum(weight);
double scale = (double) numPathSeeds / totalWeight;
double x = 0.5;
int x0 = (int) Math.floor(x);
int x1;
List<PathSeed> seeds = new ArrayList<PathSeed>();
for (int i = 0, n = 0; i < pairsPerSeedTask; i++) {
int s0 = lightPathLength[i];
int t0 = eyePathLength[i];
for (int s = s0; s >= -1; s--) {
for (int t = t0; t >= -1; t--, n++) {
x += scale * weight.get(n);
x1 = (int) Math.floor(x);
for (int j = x0; j < x1; j++) {
PathSeed seed = new PathSeed();
seed.randomSeed = initialRandomSeed + (long) i;
seed.lightPathLength = s;