Пример #1
0
        private void MixLayers(ILayerMixingFilter filter)
        {
            //Check to see if the layer had any mixing type colors that were combined down to one to process
            if (_tempMixingColor != null)
            {
                //If there are then mix that with the previous layer with the layer mixing logic
                //If we have not seen a previous layer, just assign this color as our color
                //Otherwise pass this color and the previous layer color into the mixing logic
                _combinedMixingColor = _combinedMixingColor == null
                                        ? _tempMixingColor
                                        : MixLayerColors(_combinedMixingColor.Value, _tempMixingColor.Value, filter);
            }
            //Check to see if there were any discrete types. These are combined down to one per color
            if (_tempDiscreteColors?.Count > 0)
            {
                LazyInitializer.EnsureInitialized(ref _combinedDiscreteColors, () => new Dictionary <int, DiscreteValue>(4));
                if (_combinedDiscreteColors.Count == 0)
                {
                    foreach (var tempDiscreteColor in _tempDiscreteColors)
                    {
                        _combinedDiscreteColors[tempDiscreteColor.Key] = tempDiscreteColor.Value;
                    }
                }
                else
                {
                    //If there are then mix that with the previous layer with the layer mixing logic
                    //Discrete are special, so we have to handle them a litle different. We need to maintain each indivdual color and manipulate the intensity
                    MixDiscreteLayerColors(ref _combinedDiscreteColors, _tempDiscreteColors, filter);
                }
                _tempDiscreteColors.Clear();
            }

            //reset our temp variables and go back for more layers
            _tempMixingColor = Color.Empty;
        }
Пример #2
0
        //For Command and Position values we can defer to the base implementation in StateCombinator
        //so we don't need handle methods for those


        private static Color MixLayerColors(Color highLayer, Color lowLayer, ILayerMixingFilter filter)
        {
            //Mixing logic for mixing colors between layers
            return(filter.CombineFullColor(highLayer, lowLayer));

            //var hsv = HSV.FromRGB(lowLayer);
            //hsv.V = hsv.V*(1 - HSV.VFromRgb(highLayer));
            //return highLayer.Combine(hsv.ToRGB());
        }
Пример #3
0
        public override List <IIntentState> Combine(List <IIntentState> states)
        {
            //Reset our return type and check to see if we really have anything to combine.
            //If we have one or none we can skip all the complex stuff
            if (states.Count <= 1)
            {
                if (states.Count == 1 && states[0].Layer.RequiresMixingPartner)
                {
                    return(EmptyState);
                }
                return(states);
            }

            if (states.All(x => x.Layer.RequiresMixingPartner))
            {
                return(EmptyState);
            }

            //Reset all our temp variables
            StateCombinatorValue.Clear();
            _tempMixingColor     = null;
            _combinedMixingColor = null;

            //Order all states in decending order by layer
            //We are going to do this without Linq because it is way more memory efficient
            states.Sort(LayerComparer);

            //Establish the top level layer
            var currentLayer          = states[0].Layer;
            ILayerMixingFilter filter = null;

            //Walk through the groups of layers and process them
            foreach (var state in states)
            {
                //Iterate the states in the layer
                if (state.Layer.LayerLevel == currentLayer.LayerLevel)
                {
                    //Dispatch each state to the Handle method for its type to combine down to one state
                    //per layer in a mixing fashion
                    state.Dispatch(this);
                    continue;
                }

                //We have a new layer so we need to wrap up the previous one
                MixLayers(filter);
                filter = currentLayer.LayerMixingFilter;
                state.Dispatch(this);
                currentLayer = state.Layer;
            }

            //Mix the final layer

            MixLayers(filter);

            //Now we should be down to one mixing type and we can put that in our return obejct as a RGBValue.
            //This will convert all mxing types to the simpler more efficient RGBValue
            if (_combinedMixingColor != null)
            {
                _mixedIntentState.SetValue(new RGBValue(_combinedMixingColor.Value));
                StateCombinatorValue.Add(_mixedIntentState);
            }

            //Do the same for the discrete types. Here we should be down to one per color and we return these as Discrete values
            //so we can maintatin the source color and an intensity
            if (_combinedDiscreteColors?.Count > 0)
            {
                foreach (var combinedDiscreteColor in _combinedDiscreteColors)
                {
                    StateCombinatorValue.Add(new StaticIntentState <DiscreteValue>(combinedDiscreteColor.Value));
                }
                _combinedDiscreteColors.Clear();
            }

            return(StateCombinatorValue);
        }
Пример #4
0
        private static void MixDiscreteLayerColors(ref Dictionary <int, DiscreteValue> highLayer, Dictionary <int, DiscreteValue> lowLayer, ILayerMixingFilter filter)
        {
            //Mixing logic for Discrete colors between layers
            //We are going to look at the lower layer and modify any values in the higher layer if the proportioned value is
            //higher than our existing colors intensity
            foreach (var color in lowLayer)
            {
                if (filter.RequiresMixingPartner)
                {
                    foreach (var key in highLayer.Keys.ToList())
                    {
                        if (!lowLayer.ContainsKey(key))
                        {
                            //We have nothing to mix with, so drop the value.
                            highLayer.Remove(key);
                        }
                    }
                }

                DiscreteValue highDiscreteValue;
                if (highLayer.TryGetValue(color.Key, out highDiscreteValue))
                {
                    var value = filter.CombineDiscreteIntensity(highDiscreteValue, color.Value);
                    if (value.Intensity > 0)
                    {
                        highLayer[color.Key] = value;
                    }
                    else
                    {
                        highLayer.Remove(color.Key);
                    }
                    //double intensity = color.Value.Intensity*(1 - highDiscreteValue.Intensity);
                    //highDiscreteValue.Intensity = Math.Max(intensity, highDiscreteValue.Intensity);
                    //highLayer[color.Key] = highDiscreteValue; //this is a struct, so put our modified copy back in the collection.
                }
                else
                {
                    highLayer[color.Key] = color.Value;
                }
            }
        }