//if (ratio < 0.0) bp();
pdf[s + 1] = pdf[s] * Math.max(ratio, 0.0);
}
}
PathNode zjp2 = lightNode;
PathNode zjp1 = eyeNode; // z_{j+1}, j == k - i
for (int i = s + 1; i <= k; i++) {
if (i + 1 > maxLightDepth) {
break;
}
PathNode zj = zjp1.getParent();
double rpdf = 0.0;
if (zjp2 != null) {
Vector3 v = PathUtil.getDirection(zjp2, zjp1);
rpdf = zjp2.isSpecular() ? zjp2.getPDF() : zjp1.getReversePDF(v);
} else if (zjp1 instanceof ScatteringNode) {
ScatteringNode scatNode = (ScatteringNode) zjp1;
Vector3 v = PathUtil.getDirection(zjp1, zj);
rpdf = scatNode.getSourcePDF(v);
}
double ratio = (rpdf * zjp1.getGeometricFactor())
/ (zj.getPDF() * zj.getGeometricFactor());
if (ratio < 0.0) bp();
pdf[i + 1] = pdf[i] * Math.max(ratio, 0.0);
zjp2 = zjp1;
zjp1 = zj;
}
PathNode zj = eyeNode;
boolean specular = false;
for (int i = s; i <= k; i++) {
if (specular) {
pdf[i + 1] = 0.0;
}
specular = zj.isSpecular();
if (specular) {
pdf[i + 1] = 0.0;
}
zj = zj.getParent();
}
}
// Shorter light path, longer eye path
if (lightNode != null) {
if (t < maxEyeDepth) {
if (eyeNode != null) {
Vector3 v = PathUtil.getDirection(eyeNode, lightNode);
double ratio = (eyeNode.getPDF(v) * gle)
/ (lightNode.getPDF() * lightNode.getGeometricFactor());
//if (ratio < 0.0) bp();
pdf[s - 1] = pdf[s] * Math.max(ratio, 0.0);
} else {
/* Here the ratio has in the numerator the probability density
* of selecting the node at the end of the light path (i.e.,
* lightNode) as the starting point for an eye path. Since we
* do not currently support intersections with the aperture,
* this probability is zero. Therefore pdf[s - 1] == 0.0, so
* we have nothing to do here.
*/
}
}
PathNode yip1 = eyeNode;
PathNode yi = lightNode;
for (int i = s - 1; i > 0; i--) {
if (k + 2 - i > maxEyeDepth) {
break;
}
PathNode yim1 = yi.getParent();
double rpdf = yip1 != null
? (yip1.isSpecular() ? yip1.getPDF() : yi.getReversePDF(PathUtil.getDirection(yip1, yi)))
: 0.0;
double ratio = (rpdf * yi.getGeometricFactor())
/ (yim1.getPDF() * yim1.getGeometricFactor());
//if (ratio < 0) bp();
pdf[i - 1] = pdf[i] * Math.max(ratio, 0.0);
yip1 = yi;
yi = yim1;
}
PathNode yim1 = lightNode;
boolean specular = false;
for (int i = s; i > 0; i--) {
if (specular) {
pdf[i - 1] = 0.0;
}
specular = yim1.isSpecular();
if (specular) {
pdf[i - 1] = 0.0;
}
yim1 = yim1.getParent();
}
}
pdf[k + 1] = 0.0; // Aperture not modeled as part of the scene
//pdf[k] = 0.0;