Exemplo n.º 1
0
        /// <summary>
        /// Get a ColorStop on the left of pos, and on the right of pos.
        /// Third tuple member is true when no stop was found that actually
        /// matches pos
        /// </summary>
        /// <param name="pos"></param>
        /// <returns></returns>
        public LeftRightFound GetLeftRight(float pos)
        {
            var needle = new ColorStop {
                Position = pos
            };
            ColorStop l = null;
            ColorStop r = null;

            var idx      = Stops.BinarySearch(needle);
            var notfound = false;

            if (idx < 0)
            {
                idx = ~idx;
            }

            if (idx == Stops.Count)             // there was no item larger than needle
            {
                notfound = true;
                // get the last two stops, or just last one if possible.
                r = new ColorStop(Stops[idx - 1]);
                if ((idx - 2) >= 0)
                {
                    l = new ColorStop(Stops[idx - 2]);
                }
                else
                {
                    // if there was only one stop we copy r to l, then set r to be on position 1.0f
                    // so we can still interpolate
                    l          = new ColorStop(r);
                    r.Position = 1.0f;
                }
            }
            else
            {
                // idx is the either precisely pos or the one right after.
                r = new ColorStop(Stops[idx]);

                // try to get the stop on the left of pos
                if ((idx - 1) >= 0)
                {
                    l = new ColorStop(Stops[idx - 1]);
                }
                else
                {
                    // or copy the one from the right,
                    l = new ColorStop(r);
                    // but set its position to 0.0f so we can
                    // still interpolate
                    l.Position = 0.0f;
                }
            }

            // done, give it back.
            return(new LeftRightFound(l, r, notfound));
        }
Exemplo n.º 2
0
        /// <summary>
        /// Add given ColorStop
        /// </summary>
        /// <param name="cstop"></param>
        public void InsertColorStop(ColorStop cstop)
        {
            if (Stops.Count == 0)
            {
                Stops.Add(cstop);
                return;
            }

            var idx = Stops.BinarySearch(cstop);

            if (idx < 0)
            {
                idx = ~idx;
            }

            if (idx == Stops.Count)
            {
                Stops.Add(cstop);
            }
            else
            {
                Stops.Insert(idx, cstop);
            }
        }
Exemplo n.º 3
0
        /// <summary>
        /// Evaluate pos into a color
        /// </summary>
        /// <param name="pos">Value in range 0.0f-1.0f</param>
        /// <param name="color">Color will be interpolated into this</param>
        /// <returns></returns>
        public void evaluate(float pos, float4 color)
        {
            if (Stops.Count == 0)
            {
                color.x = 0.0f;
                color.y = 0.0f;
                color.z = 0.0f;
                color.w = 0.0f;
                return;
            }

            // stop1 = left of pos
            var left = Stops[0];
            // stop2 = right of pos
            ColorStop right = null;

            // if there is only one stop, or we're on the left of the very first stop
            // just copy the color, we're done.
            if (Stops.Count == 1 || pos <= left.Position)
            {
                color.Copy(left.Color);
            }
            else
            {
                // get left and right items
                var lr = GetLeftRight(pos);
                left  = lr.Item1;
                right = lr.Item2;
                var last_item = lr.Item3;

                // if we're on the right of the right stop, copy
                // color, we're done.
                if (pos >= right.Position)
                {
                    color.Copy(right.Color);
                }
                else
                {
                    // if we're on constant interpolation, lets use
                    // color on left of position.
                    if (Interpolation == Interpolations.Constant)
                    {
                        color.Copy(left.Color);
                    }
                    else
                    {
                        // ok, so we need to interpolate
                        float mfac;
                        float fac;
                        // get factor
                        if (Math.Abs(left.Position - right.Position) > 0.0001)
                        {
                            fac = Math.Abs(pos - right.Position) / Math.Abs(left.Position - right.Position);
                        }
                        else
                        {
                            fac = last_item ? 1.0f : 0.0f;
                        }

                        // extra easing if ease
                        if (Interpolation == Interpolations.Ease)
                        {
                            mfac = fac * fac;
                            fac  = 3.0f * mfac - 2.0f * mfac * fac;
                        }

                        // right color fac
                        mfac = 1.0f - fac;

                        // factor colors
                        left.Color  *= fac;
                        right.Color *= mfac;
                        // add factored colors to get new interpolated color
                        var interpolated_color = left.Color + right.Color;
                        // copy, done
                        color.Copy(interpolated_color);
                    }
                }
            }
        }