Exemplo n.º 1
0
        private void DoRendering(CancellationTokenSource tokenSource = null)
        {
            //TODO: get a better increment time. doing it every X ms is..... shitty at best.
            TimeSpan increment = TimeSpan.FromMilliseconds(2);

            List <ElementNode> renderNodes = GetNodesToRenderOn();

            int targetNodeCount = renderNodes.Count;

            Pulse.Pulse   pulse;
            EffectIntents pulseData;

            // apply the 'background' values to all targets if the level is supposed to be nonzero
            if (DefaultLevel > 0)
            {
                int i = 0;
                foreach (ElementNode target in renderNodes)
                {
                    if (tokenSource != null && tokenSource.IsCancellationRequested)
                    {
                        return;
                    }

                    if (target != null && target.Element != null)
                    {
                        bool discreteColors = ColorModule.isElementNodeDiscreteColored(target);

                        pulse             = new Pulse.Pulse();
                        pulse.TargetNodes = new ElementNode[] { target };
                        pulse.TimeSpan    = TimeSpan;
                        double level = DefaultLevel * 100.0;

                        // figure out what color gradient to use for the pulse
                        switch (ColorHandling)
                        {
                        case ChaseColorHandling.GradientForEachPulse:
                            pulse.ColorGradient = StaticColorGradient;
                            pulse.LevelCurve    = new Curve(new PointPairList(new double[] { 0, 100 }, new double[] { level, level }));
                            pulseData           = pulse.Render();
                            _elementData.Add(pulseData);
                            break;

                        case ChaseColorHandling.GradientThroughWholeEffect:
                            pulse.ColorGradient = ColorGradient;
                            pulse.LevelCurve    = new Curve(new PointPairList(new double[] { 0, 100 }, new double[] { level, level }));
                            pulseData           = pulse.Render();
                            _elementData.Add(pulseData);
                            break;

                        case ChaseColorHandling.StaticColor:
                            pulse.ColorGradient = StaticColorGradient;
                            pulse.LevelCurve    = new Curve(new PointPairList(new double[] { 0, 100 }, new double[] { level, level }));
                            pulseData           = pulse.Render();
                            _elementData.Add(pulseData);
                            break;

                        case ChaseColorHandling.ColorAcrossItems:
                            double positionWithinGroup = i / (double)targetNodeCount;
                            if (discreteColors)
                            {
                                List <Tuple <Color, float> > colorsAtPosition =
                                    ColorGradient.GetDiscreteColorsAndProportionsAt(positionWithinGroup);
                                foreach (Tuple <Color, float> colorProportion in colorsAtPosition)
                                {
                                    if (tokenSource != null && tokenSource.IsCancellationRequested)
                                    {
                                        return;
                                    }
                                    double value = level * colorProportion.Item2;
                                    pulse.LevelCurve    = new Curve(new PointPairList(new double[] { 0, 100 }, new double[] { value, value }));
                                    pulse.ColorGradient = new ColorGradient(colorProportion.Item1);
                                    pulseData           = pulse.Render();
                                    _elementData.Add(pulseData);
                                }
                            }
                            else
                            {
                                pulse.ColorGradient = new ColorGradient(ColorGradient.GetColorAt(positionWithinGroup));
                                pulse.LevelCurve    = new Curve(new PointPairList(new double[] { 0, 100 }, new double[] { level, level }));
                                pulseData           = pulse.Render();
                                _elementData.Add(pulseData);
                            }
                            break;
                        }

                        i++;
                    }
                }
            }


            // the total chase time
            TimeSpan chaseTime = TimeSpan.FromMilliseconds(TimeSpan.TotalMilliseconds - PulseOverlap);

            if (chaseTime.TotalMilliseconds <= 0)
            {
                chaseTime = TimeSpan.FromMilliseconds(1);
            }

            // we need to keep track of the element that is 'under' the curve at a given time, to see if it changes,
            // and when it does, we make the effect for it then (since it's a variable time pulse).
            ElementNode lastTargetedNode  = null;
            TimeSpan    lastNodeStartTime = TimeSpan.Zero;

            // iterate up to and including the last pulse generated
            for (TimeSpan current = TimeSpan.Zero; current <= TimeSpan; current += increment)
            {
                if (tokenSource != null && tokenSource.IsCancellationRequested)
                {
                    return;
                }
                double currentPercentageIntoChase = ((double)current.Ticks / (double)chaseTime.Ticks) * 100.0;

                double currentMovementPosition = ChaseMovement.GetValue(currentPercentageIntoChase);
                int    currentNodeIndex        = (int)((currentMovementPosition / 100.0) * targetNodeCount);

                // on the off chance we hit the 100% mark *exactly*...
                if (currentNodeIndex == targetNodeCount && currentNodeIndex > 0)
                {
                    currentNodeIndex--;
                }

                if (currentNodeIndex >= targetNodeCount)
                {
                    Logging.Warn(
                        "Chase effect: rendering, but the current node index is higher or equal to the total target nodes.");
                    continue;
                }

                if (currentNodeIndex < 0)
                {
                    continue;
                }

                ElementNode currentNode = renderNodes[currentNodeIndex];
                if (currentNode == lastTargetedNode)
                {
                    continue;
                }

                // if the last node targeted wasn't null, we need to make a pulse for it
                if (lastTargetedNode != null)
                {
                    TimeSpan duration = current - lastNodeStartTime + TimeSpan.FromMilliseconds(PulseOverlap);
                    GeneratePulse(lastTargetedNode, lastNodeStartTime, duration
                                  , currentMovementPosition);
                }

                lastTargetedNode  = currentNode;
                lastNodeStartTime = current;

                // if we've hit the 100% mark of the chase curve, bail (the last one gets generated after)
                if (currentPercentageIntoChase >= 100.0)
                {
                    break;
                }
            }

            // generate the last pulse
            if (lastTargetedNode != null)
            {
                GeneratePulse(lastTargetedNode, lastNodeStartTime, TimeSpan - lastNodeStartTime, 1.0);
            }

            _elementData = EffectIntents.Restrict(_elementData, TimeSpan.Zero, TimeSpan);
        }
Exemplo n.º 2
0
        private void DoRendering()
        {
            //TODO: get a better increment time. doing it every X ms is..... shitty at best.
            TimeSpan increment = TimeSpan.FromMilliseconds(2);

            List <ElementNode> renderNodes = GetNodesToRenderOn();

            int targetNodeCount = renderNodes.Count;

            Pulse.Pulse   pulse;
            EffectIntents pulseData;

            // apply the 'background' values to all targets
            int i = 0;

            foreach (ElementNode target in renderNodes)
            {
                pulse             = new Pulse.Pulse();
                pulse.TargetNodes = new ElementNode[] { target };
                pulse.TimeSpan    = TimeSpan;
                pulse.LevelCurve  = new Curve(new PointPairList(new double[] { 0, 100 }, new double[] { DefaultLevel * 100, DefaultLevel * 100 }));

                // figure out what color gradient to use for the pulse
                switch (ColorHandling)
                {
                case ChaseColorHandling.GradientForEachPulse:
                    pulse.ColorGradient = new ColorGradient(StaticColor);
                    break;

                case ChaseColorHandling.GradientThroughWholeEffect:
                    pulse.ColorGradient = ColorGradient;
                    break;

                case ChaseColorHandling.StaticColor:
                    pulse.ColorGradient = new ColorGradient(StaticColor);
                    break;

                case ChaseColorHandling.ColorAcrossItems:
                    pulse.ColorGradient = new ColorGradient(ColorGradient.GetColorAt((double)i / (double)targetNodeCount));
                    break;
                }

                pulseData = pulse.Render();
                _elementData.Add(pulseData);
                i++;
            }


            // the total chase time
            TimeSpan chaseTime = TimeSpan.FromMilliseconds(TimeSpan.TotalMilliseconds - PulseOverlap);

            if (chaseTime.TotalMilliseconds <= 0)
            {
                chaseTime = TimeSpan.FromMilliseconds(1);
            }

            // we need to keep track of the element that is 'under' the curve at a given time, to see if it changes,
            // and when it does, we make the effect for it then (since it's a variable time pulse).
            ElementNode lastTargetedNode  = null;
            TimeSpan    lastNodeStartTime = TimeSpan.Zero;

            // iterate up to and including the last pulse generated
            for (TimeSpan current = TimeSpan.Zero; current <= TimeSpan; current += increment)
            {
                double currentPercentageIntoChase = ((double)current.Ticks / (double)chaseTime.Ticks) * 100.0;

                double currentMovementPosition = ChaseMovement.GetValue(currentPercentageIntoChase);
                int    currentNodeIndex        = (int)((currentMovementPosition / 100.0) * targetNodeCount);

                // on the off chance we hit the 100% mark *exactly*...
                if (currentNodeIndex == targetNodeCount)
                {
                    currentNodeIndex--;
                }

                if (currentNodeIndex >= targetNodeCount)
                {
                    VixenSystem.Logging.Warning("Chase effect: rendering, but the current node index is higher or equal to the total target nodes.");
                    continue;
                }

                ElementNode currentNode = renderNodes[currentNodeIndex];
                if (currentNode == lastTargetedNode)
                {
                    continue;
                }

                // if the last node targeted wasn't null, we need to make a pulse for it
                if (lastTargetedNode != null)
                {
                    GeneratePulse(lastTargetedNode, lastNodeStartTime, current - lastNodeStartTime + TimeSpan.FromMilliseconds(PulseOverlap), currentMovementPosition);
                }

                lastTargetedNode  = currentNode;
                lastNodeStartTime = current;

                // if we've hit the 100% mark of the chase curve, bail (the last one gets generated after)
                if (currentPercentageIntoChase >= 100.0)
                {
                    break;
                }
            }

            // generate the last pulse
            if (lastTargetedNode != null)
            {
                GeneratePulse(lastTargetedNode, lastNodeStartTime, TimeSpan - lastNodeStartTime, 1.0);
            }

            _elementData = EffectIntents.Restrict(_elementData, TimeSpan.Zero, TimeSpan);
        }