/// <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); }
/// <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; }