//private void GenerateExtendedStaticPulse(ElementNode target, IIntentNode intentNode, ColorGradient gradient=null) //{ // if (intentNode == null || intentNode.EndTime >= TimeSpan) return; // var lightingIntent = intentNode.Intent as LightingIntent; // if (lightingIntent != null && lightingIntent.EndValue.Intensity > 0) // { // var newCurve = new Curve(lightingIntent.EndValue.Intensity*100); // GenerateExtendedStaticPulse(target, newCurve, gradient ?? new ColorGradient(lightingIntent.EndValue.FullColor), // TimeSpan - intentNode.EndTime, intentNode.EndTime); // } // else // { // var discreteIntent = intentNode.Intent as DiscreteLightingIntent; // if (discreteIntent != null && discreteIntent.EndValue.Intensity > 0) // { // var newCurve = new Curve(discreteIntent.EndValue.Intensity*100); // GenerateExtendedStaticPulse(target, newCurve, gradient ?? new ColorGradient(discreteIntent.EndValue.FullColor), // TimeSpan - intentNode.EndTime, intentNode.EndTime); // } // } //} //private void GenerateExtendedStaticPulse(ElementNode target, Curve newCurve, ColorGradient gradient, TimeSpan duration, TimeSpan offset) //{ // var result = PulseRenderer.RenderNode(target, newCurve, gradient, duration, HasDiscreteColors); // result.OffsetAllCommandsByTime(offset); // _elementData.Add(result); //} //private void GenerateStartingStaticPulse(ElementNode target, IIntentNode intentNode, ColorGradient gradient=null) //{ // if (intentNode == null || intentNode.StartTime <= TimeSpan.Zero) return; // var lightingIntent = intentNode.Intent as LightingIntent; // if (lightingIntent != null && lightingIntent.StartValue.Intensity > 0) // { // var newCurve = new Curve(lightingIntent.StartValue.Intensity*100); // GenerateStartingStaticPulse(target,newCurve, gradient ?? new ColorGradient(lightingIntent.StartValue.FullColor), intentNode.StartTime); // } // else // { // var discreteIntent = intentNode.Intent as DiscreteLightingIntent; // if (discreteIntent != null && discreteIntent.StartValue.Intensity > 0) // { // var newCurve = new Curve(discreteIntent.StartValue.Intensity*100); // GenerateStartingStaticPulse(target, newCurve, gradient ?? new ColorGradient(discreteIntent.StartValue.FullColor), // intentNode.StartTime); // } // } //} //private void GenerateStartingStaticPulse(ElementNode target, Curve newCurve, ColorGradient gradient, TimeSpan time) //{ // var result = PulseRenderer.RenderNode(target, newCurve, gradient, time, HasDiscreteColors); // _elementData.Add(result); //} private void GeneratePulse(ElementNode target, TimeSpan startTime, TimeSpan duration, double currentMovementPosition) { EffectIntents result = null; // figure out what color gradient to use for the pulse switch (ColorHandling) { case ChaseColorHandling.GradientForEachPulse: result = PulseRenderer.RenderNode(target, PulseCurve, ColorGradient, duration, HasDiscreteColors); result.OffsetAllCommandsByTime(startTime); if (ExtendPulseToStart && result.Count > 0) { foreach (var effectIntent in result.FirstOrDefault().Value) { _elementData.Add(PulseRenderer.GenerateStartingStaticPulse(target, effectIntent, HasDiscreteColors)); } } _elementData.Add(result); if (ExtendPulseToEnd && result.Count > 0) { foreach (var effectIntent in result.FirstOrDefault().Value) { _elementData.Add(PulseRenderer.GenerateExtendedStaticPulse(target, effectIntent, TimeSpan, HasDiscreteColors)); } } break; case ChaseColorHandling.GradientThroughWholeEffect: double startPos = (startTime.Ticks / (double)TimeSpan.Ticks); double endPos = ((startTime + duration).Ticks / (double)TimeSpan.Ticks); if (startPos < 0.0) { startPos = 0.0; } if (endPos > 1.0) { endPos = 1.0; } if (HasDiscreteColors) { double range = endPos - startPos; if (range <= 0.0) { Logging.Error("Chase: bad range: " + range + " (SP=" + startPos + ", EP=" + endPos + ")"); break; } ColorGradient cg = ColorGradient.GetSubGradientWithDiscreteColors(startPos, endPos); foreach (Color color in cg.GetColorsInGradient()) { Curve newCurve = new Curve(PulseCurve.Points); foreach (PointPair point in newCurve.Points) { double effectRelativePosition = startPos + ((point.X / 100.0) * range); double proportion = ColorGradient.GetProportionOfColorAt(effectRelativePosition, color); point.Y *= proportion; } result = PulseRenderer.RenderNode(target, newCurve, new ColorGradient(color), duration, HasDiscreteColors); result.OffsetAllCommandsByTime(startTime); if (ExtendPulseToStart && result.Count > 0) { foreach (var effectIntent in result.FirstOrDefault().Value) { _elementData.Add(PulseRenderer.GenerateStartingStaticPulse(target, effectIntent, HasDiscreteColors, new ColorGradient(color))); } } if (result.Count > 0) { _elementData.Add(result); } if (ExtendPulseToEnd && result.Count > 0) { foreach (var effectIntent in result.FirstOrDefault().Value) { _elementData.Add(PulseRenderer.GenerateExtendedStaticPulse(target, effectIntent, TimeSpan, HasDiscreteColors, new ColorGradient(color))); } } } } else { result = PulseRenderer.RenderNode(target, PulseCurve, ColorGradient.GetSubGradient(startPos, endPos), duration, HasDiscreteColors); result.OffsetAllCommandsByTime(startTime); if (ExtendPulseToStart && result.Count > 0) { foreach (var effectIntent in result.FirstOrDefault().Value) { _elementData.Add(PulseRenderer.GenerateStartingStaticPulse(target, effectIntent, HasDiscreteColors, ColorGradient.GetSubGradient(0, startPos))); } } _elementData.Add(result); if (ExtendPulseToEnd && result.Count > 0) { foreach (var effectIntent in result.FirstOrDefault().Value) { _elementData.Add(PulseRenderer.GenerateExtendedStaticPulse(target, effectIntent, TimeSpan, HasDiscreteColors, ColorGradient.GetSubGradient(endPos, 1))); } } } break; case ChaseColorHandling.StaticColor: result = PulseRenderer.RenderNode(target, PulseCurve, StaticColorGradient, duration, HasDiscreteColors); result.OffsetAllCommandsByTime(startTime); if (ExtendPulseToStart && result.Count > 0) { var intent = result.FirstOrDefault().Value.FirstOrDefault(); _elementData.Add(PulseRenderer.GenerateStartingStaticPulse(target, intent, HasDiscreteColors)); } _elementData.Add(result); if (ExtendPulseToEnd && result.Count > 0) { var intent = result.FirstOrDefault().Value.LastOrDefault(); _elementData.Add(PulseRenderer.GenerateExtendedStaticPulse(target, intent, TimeSpan, HasDiscreteColors)); } break; case ChaseColorHandling.ColorAcrossItems: if (HasDiscreteColors) { List <Tuple <Color, float> > colorsAtPosition = ColorGradient.GetDiscreteColorsAndProportionsAt(currentMovementPosition / 100.0); foreach (Tuple <Color, float> colorProportion in colorsAtPosition) { float proportion = colorProportion.Item2; // scale all levels of the pulse curve by the proportion that is applicable to this color Curve newCurve = new Curve(PulseCurve.Points); foreach (PointPair pointPair in newCurve.Points) { pointPair.Y *= proportion; } result = PulseRenderer.RenderNode(target, newCurve, new ColorGradient(colorProportion.Item1), duration, HasDiscreteColors); result.OffsetAllCommandsByTime(startTime); if (ExtendPulseToStart && result.Count > 0) { foreach (var effectIntent in result.FirstOrDefault().Value) { _elementData.Add(PulseRenderer.GenerateStartingStaticPulse(target, effectIntent, HasDiscreteColors, new ColorGradient(colorProportion.Item1))); } } if (result.Count > 0) { _elementData.Add(result); } if (ExtendPulseToEnd && result.Count > 0) { foreach (var effectIntent in result.FirstOrDefault().Value) { _elementData.Add(PulseRenderer.GenerateExtendedStaticPulse(target, effectIntent, TimeSpan, HasDiscreteColors, new ColorGradient(colorProportion.Item1))); } } } } else { result = PulseRenderer.RenderNode(target, PulseCurve, new ColorGradient(ColorGradient.GetColorAt(currentMovementPosition / 100.0)), duration, HasDiscreteColors); result.OffsetAllCommandsByTime(startTime); if (ExtendPulseToStart && result.Count > 0) { foreach (var effectIntent in result.FirstOrDefault().Value) { _elementData.Add(PulseRenderer.GenerateStartingStaticPulse(target, effectIntent, HasDiscreteColors)); } } _elementData.Add(result); if (ExtendPulseToEnd && result.Count > 0) { foreach (var effectIntent in result.FirstOrDefault().Value) { _elementData.Add(PulseRenderer.GenerateExtendedStaticPulse(target, effectIntent, TimeSpan, HasDiscreteColors)); } } } break; } }
private void RenderCount(List <IElementNode[]> renderNodes, CancellationTokenSource tokenSource) { TimeSpan effectTime = TimeSpan.Zero; int count = 0; double pulseSegment = (TimeSpan.Ticks * ((PulsePercent * ((double)_steps / renderNodes.Count())) / 100)) / PassCount; TimeSpan intervalTime = TimeSpan.FromTicks((long)((TimeSpan.Ticks - pulseSegment) / (renderNodes.Count() * PassCount))); TimeSpan segmentPulse = TimeSpan.FromTicks((long)pulseSegment); while (count < PassCount) { foreach (IElementNode[] item in renderNodes) { if (tokenSource != null && tokenSource.IsCancellationRequested) { return; } foreach (IElementNode element in item) { if (tokenSource != null && tokenSource.IsCancellationRequested) { return; } if (element == null) { continue; } EffectIntents result; if (ColorHandling == ColorHandling.GradientThroughWholeEffect) { result = PulseRenderer.RenderNode(element, _data.Curve, _data.ColorGradient, segmentPulse, HasDiscreteColors); result.OffsetAllCommandsByTime(effectTime); if (WipeOff && count == 0 && result.Any()) { foreach (var effectIntent in result.FirstOrDefault().Value) { _elementData.Add(PulseRenderer.GenerateStartingStaticPulse(element, effectIntent, HasDiscreteColors)); } } if (WipeOn && result.Any() && count == PassCount - 1) { foreach (var effectIntent in result.FirstOrDefault().Value) { _elementData.Add(PulseRenderer.GenerateExtendedStaticPulse(element, effectIntent, TimeSpan, HasDiscreteColors)); } } _elementData.Add(result); } else { double positionWithinGroup = (double)(1.0 / (TimeSpan.Ticks - segmentPulse.Ticks)) * (effectTime.Ticks); if (ColorAcrossItemPerCount) { positionWithinGroup = positionWithinGroup * PassCount % 1; } if (HasDiscreteColors) { List <Tuple <Color, float> > colorsAtPosition = ColorGradient.GetDiscreteColorsAndProportionsAt(positionWithinGroup); foreach (Tuple <Color, float> colorProportion in colorsAtPosition) { float proportion = colorProportion.Item2; // scale all levels of the pulse curve by the proportion that is applicable to this color Curve newCurve = new Curve(Curve.Points); foreach (PointPair pointPair in newCurve.Points) { pointPair.Y *= proportion; } result = PulseRenderer.RenderNode(element, newCurve, new ColorGradient(colorProportion.Item1), segmentPulse, HasDiscreteColors); result.OffsetAllCommandsByTime(effectTime); if (WipeOff && count == 0) { foreach (var effectIntent in result.FirstOrDefault().Value) { _elementData.Add(PulseRenderer.GenerateStartingStaticPulse(element, effectIntent, HasDiscreteColors, new ColorGradient(colorProportion.Item1))); } } if (result.Count > 0) { _elementData.Add(result); } if (WipeOn && count == PassCount - 1) { foreach (var effectIntent in result.FirstOrDefault().Value) { _elementData.Add(PulseRenderer.GenerateExtendedStaticPulse(element, effectIntent, TimeSpan, HasDiscreteColors, new ColorGradient(colorProportion.Item1))); } } } } else { result = PulseRenderer.RenderNode(element, _data.Curve, new ColorGradient(_data.ColorGradient.GetColorAt(positionWithinGroup)), segmentPulse, HasDiscreteColors); result.OffsetAllCommandsByTime(effectTime); if (WipeOff && count == 0) { foreach (var effectIntent in result.FirstOrDefault().Value) { _elementData.Add(PulseRenderer.GenerateStartingStaticPulse(element, effectIntent, HasDiscreteColors)); } } if (WipeOn && count == PassCount - 1) { foreach (var effectIntent in result.FirstOrDefault().Value) { _elementData.Add(PulseRenderer.GenerateExtendedStaticPulse(element, effectIntent, TimeSpan, HasDiscreteColors)); } } _elementData.Add(result); } } } effectTime += intervalTime; } count++; } }
private void RenderNonBurst(CancellationTokenSource tokenSource, IEnumerable <IGrouping <int, ElementNode> > renderNodes) { //var pulse = new Pulse.Pulse(); if (renderNodes != null && renderNodes.Any()) { TimeSpan effectTime = TimeSpan.Zero; if (WipeByCount) { int count = 0; double pulseSegment = TimeSpan.Ticks / (double)PassCount * (PulsePercent / 100); var maxKey = renderNodes.Select(x => x.Key).Max(); var minKey = renderNodes.Select(x => x.Key).Min(); double adjustedMax = maxKey - minKey; TimeSpan totalWipeTime = TimeSpan.FromTicks((long)((TimeSpan.Ticks - pulseSegment) / PassCount)); TimeSpan segmentPulse = TimeSpan.FromTicks((long)pulseSegment); while (count < PassCount) { foreach (var item in renderNodes) { if (tokenSource != null && tokenSource.IsCancellationRequested) { return; } switch (Direction) { case WipeDirection.Left: case WipeDirection.Up: effectTime = TimeSpan.FromTicks((long)(totalWipeTime.Ticks * (1 - (item.Key - minKey) / adjustedMax) + count * totalWipeTime.Ticks)); break; default: effectTime = TimeSpan.FromTicks((long)(totalWipeTime.Ticks * (item.Key - minKey) / adjustedMax + count * totalWipeTime.Ticks)); break; } foreach (ElementNode element in item) { if (tokenSource != null && tokenSource.IsCancellationRequested) { return; } if (element != null) { EffectIntents result; if (ColorHandling == ColorHandling.GradientThroughWholeEffect) { result = PulseRenderer.RenderNode(element, _data.Curve, _data.ColorGradient, segmentPulse, HasDiscreteColors); result.OffsetAllCommandsByTime(effectTime); if (WipeOff && count == 0) { foreach (var effectIntent in result.FirstOrDefault().Value) { _elementData.Add(PulseRenderer.GenerateStartingStaticPulse(element, effectIntent, HasDiscreteColors)); } } _elementData.Add(result); if (WipeOn && count == PassCount - 1) { foreach (var effectIntent in result.FirstOrDefault().Value) { _elementData.Add(PulseRenderer.GenerateExtendedStaticPulse(element, effectIntent, TimeSpan, HasDiscreteColors)); } } } else { double positionWithinGroup = effectTime.Ticks / (double)totalWipeTime.Ticks; if (HasDiscreteColors) { List <Tuple <Color, float> > colorsAtPosition = ColorGradient.GetDiscreteColorsAndProportionsAt(positionWithinGroup); foreach (Tuple <Color, float> colorProportion in colorsAtPosition) { float proportion = colorProportion.Item2; // scale all levels of the pulse curve by the proportion that is applicable to this color Curve newCurve = new Curve(Curve.Points); foreach (PointPair pointPair in newCurve.Points) { pointPair.Y *= proportion; } result = PulseRenderer.RenderNode(element, newCurve, new ColorGradient(colorProportion.Item1), segmentPulse, HasDiscreteColors); result.OffsetAllCommandsByTime(effectTime); if (WipeOff && count == 0) { foreach (var effectIntent in result.FirstOrDefault().Value) { _elementData.Add(PulseRenderer.GenerateStartingStaticPulse(element, effectIntent, HasDiscreteColors, new ColorGradient(colorProportion.Item1))); } } if (result.Count > 0) { _elementData.Add(result); } if (WipeOn && count == PassCount - 1) { foreach (var effectIntent in result.FirstOrDefault().Value) { _elementData.Add(PulseRenderer.GenerateExtendedStaticPulse(element, effectIntent, TimeSpan, HasDiscreteColors, new ColorGradient(colorProportion.Item1))); } } } } else { result = PulseRenderer.RenderNode(element, _data.Curve, new ColorGradient(_data.ColorGradient.GetColorAt(positionWithinGroup)), segmentPulse, HasDiscreteColors); result.OffsetAllCommandsByTime(effectTime); if (WipeOff && count == 0) { foreach (var effectIntent in result.FirstOrDefault().Value) { _elementData.Add(PulseRenderer.GenerateStartingStaticPulse(element, effectIntent, HasDiscreteColors)); } } _elementData.Add(result); if (WipeOn && count == PassCount - 1) { foreach (var effectIntent in result.FirstOrDefault().Value) { _elementData.Add(PulseRenderer.GenerateExtendedStaticPulse(element, effectIntent, TimeSpan, HasDiscreteColors)); } } } } } } } count++; } } else { double intervals = (double)PulseTime / (double)renderNodes.Count(); var intervalTime = TimeSpan.FromMilliseconds(intervals); // the calculation above blows up render time/memory as count goes up, try this.. // also fails if intervals is less than half a ms and intervalTime then gets 0 intervalTime = TimeSpan.FromMilliseconds(Math.Max(intervalTime.TotalMilliseconds, 5)); TimeSpan segmentPulse = TimeSpan.FromMilliseconds(PulseTime); while (effectTime < TimeSpan) { foreach (var item in renderNodes) { EffectIntents result; if (tokenSource != null && tokenSource.IsCancellationRequested) { return; } foreach (ElementNode element in item) { if (element != null) { if (tokenSource != null && tokenSource.IsCancellationRequested) { return; } result = PulseRenderer.RenderNode(element, _data.Curve, _data.ColorGradient, segmentPulse, HasDiscreteColors); result.OffsetAllCommandsByTime(effectTime); //bool discreteElement = HasDiscreteColors && ColorModule.isElementNodeDiscreteColored(element); //_elementData.Add(IntentBuilder.ConvertToStaticArrayIntents(result, TimeSpan, discreteElement)); _elementData.Add(result); } } effectTime += intervalTime; if (effectTime >= TimeSpan) { return; } } } } } }