totalSurfaceArea += weight[i];
}
final double scale = totalSurfaceArea / emissive.size();
final double totalWeight = totalSurfaceArea;
final CategoricalRandom rnd = new CategoricalRandom(weight);
return new AbstractLight() {
private static final long serialVersionUID = -4977755592893506132L;
public void illuminate(SurfacePoint x, WavelengthPacket lambda,
Random rng, Illuminable target) {
ShadingContext context = new MinimalShadingContext(rng);
int index = rnd.next(rng);
int primitive = primIndex[index];
generateImportanceSampledSurfacePoint(primitive, x, context, rng.next(), rng.next(), rng.next());
context.getModifier().modify(context);
Point3 p = context.getPosition();
Material mat = context.getMaterial();
Vector3 v = x.getPosition().unitVectorFrom(p);
Vector3 n = context.getShadingNormal();
double d2 = x.getPosition().squaredDistanceTo(p);
double atten = Math.max(n.dot(v), 0.0) * totalWeight
/ (4.0 * Math.PI * d2);
Color ri = mat.emission(context, v, lambda).times(atten);
LightSample sample = new PointLightSample(x, p, ri);
target.addLightSample(sample);
}
public LightNode sample(PathInfo pathInfo, double ru, double rv, double rj) {
ShadingContext context = new MinimalShadingContext(null);
SeedReference ref = new SeedReference(rj);
int index = rnd.next(ref);
int primitive = primIndex[index];
generateRandomSurfacePoint(primitive, context, ru, rv, ref.seed);
context.getModifier().modify(context);