/// <summary> /// Returns intensity (incl. color) of the source contribution to the given scene point. /// Internal integration support. /// </summary> /// <param name="intersection">Scene point (only world coordinates and normal vector are needed).</param> /// <param name="rank">Rank of this sample, 0 <= rank < total (for integration).</param> /// <param name="total">Total number of samples (for integration).</param> /// <param name="rnd">Global (per-thread) instance of the random generator.</param> /// <param name="dir">Direction to the source is set here (zero vector for omnidirectional source). Not normalized!</param> /// <returns>Intensity vector in current color space or null if the point is not lit.</returns> public override double[] GetIntensity(Intersection intersection, int rank, int total, RandomJames rnd, out Vector3d dir) { if (rnd == null) { return(GetIntensity(intersection, out dir)); } SamplingState ss; lock ( states ) { if (!states.TryGetValue(rnd.GetHashCode(), out ss)) { ss = new SamplingState(this, rnd); states.Add(rnd.GetHashCode(), ss); } } // generate a [new] sample: ss.generateSample(rank, total); dir = ss.sample - intersection.CoordWorld; if (Vector3d.Dot(dir, intersection.Normal) <= 0.0) { return(null); } if (Dim == null || Dim.Length < 3) { return(intensity); } double dist = dir.Length; double dimCoef = 1.0 / (Dim[0] + dist * (Dim[1] + dist * Dim[2])); int bands = intensity.Length; double[] result = new double[bands]; for (int i = 0; i < bands; i++) { result[i] = intensity[i] * dimCoef; } return(result); }