Beispiel #1
0
        /// <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);
        }