private void DrawCurtainVerticalLocation(bool topEdge, int ylimit, List <int> swagArray, PixelLocationFrameBuffer frameBuffer, double level, int width) { var topBufferLimit = BufferHt + BufferHtOffset; var elements = topEdge ? frameBuffer.ElementLocations.Where(e => e.Y > topBufferLimit - ylimit) : frameBuffer.ElementLocations.Where(e => e.Y < ylimit + BufferHtOffset); foreach (var elementLocation in elements) { var hsv = GetVerticalLocationColor(topEdge, width, elementLocation); hsv.V = hsv.V * level; frameBuffer.SetPixel(elementLocation.X, elementLocation.Y, hsv); } //Swag if (swagArray.Count > 0) { var swagElements = topEdge ? frameBuffer.ElementLocations.Where(e => e.Y <= topBufferLimit - ylimit && e.Y >= topBufferLimit - (ylimit + swagArray.Count)).ToLookup(e => e.Y) : frameBuffer.ElementLocations.Where(e => e.Y >= ylimit + BufferHtOffset && e.Y <= ylimit + swagArray.Count + BufferHtOffset).ToLookup(e => e.Y); for (int i = 0; i < swagArray.Count; i++) { int x = topEdge ? topBufferLimit - (ylimit + i) : ylimit + i + BufferHtOffset; var limit = BufferWiOffset + swagArray[i]; foreach (var elementLocation in swagElements[x]) { if (elementLocation.X > limit) { var hsv = GetVerticalLocationColor(topEdge, width, elementLocation); hsv.V = hsv.V * level; frameBuffer.SetPixel(elementLocation.X, elementLocation.Y, hsv); } } } } }
protected override void RenderEffectByLocation(int numFrames, PixelLocationFrameBuffer frameBuffer) { //It kinda stinks so much of this code duplicates the RenderEffect method, but //there are enough differences in the two that it needs to be. Trying to refactor //small parts of it out into reusable chunks is probably not fruitful at this time. double posX = (BufferWi * CenterX / 100.0) + BufferWiOffset; double posY = (BufferHt * CenterY / 100.0) + BufferHtOffset; Point centerPoint = new Point((int)posX, (int)posY); var nodes = frameBuffer.ElementLocations.OrderBy(x => x.X).ThenBy(x => x.Y).GroupBy(x => x.X); Point currentPoint = Point.Empty; for (int effectFrame = 0; effectFrame < numFrames; effectFrame++) { double position = GetEffectTimeIntervalPosition(effectFrame); double effectPositionAdjust = CalculateAcceleration(position, Acceleration); Color c = Color.GetColorAt(position); double centerRadius = StartRadius + (EndRadius - StartRadius) * effectPositionAdjust; double halfWidth = (StartWidth + (EndWidth - StartWidth) * effectPositionAdjust) / 2.0; var radius1 = Math.Max(0.0, centerRadius - halfWidth); var radius2 = centerRadius + halfWidth; foreach (IGrouping <int, ElementLocation> elementLocations in nodes) { foreach (var elementLocation in elementLocations) { currentPoint.X = elementLocation.X; currentPoint.Y = elementLocation.Y; var distance = DistanceFromCenter(centerPoint, currentPoint); if (ContainsPoint(distance, radius1, radius2)) { if (BlendEdges) { double colorPct = 1.0 - Math.Abs(distance - centerRadius) / halfWidth; if (colorPct > 0.0) { HSV hsv = HSV.FromRGB(c); hsv.V = hsv.V * colorPct; frameBuffer.SetPixel(currentPoint.X, currentPoint.Y, hsv); } else { frameBuffer.SetPixel(currentPoint.X, currentPoint.Y, System.Drawing.Color.Transparent); } } else { frameBuffer.SetPixel(currentPoint.X, currentPoint.Y, c); } } else { frameBuffer.SetPixel(currentPoint.X, currentPoint.Y, System.Drawing.Color.Transparent); } } } } }
private void DrawCurtainLocation(bool leftEdge, int xlimit, List <int> swagArray, PixelLocationFrameBuffer frameBuffer, double level, int width) { var rightBufferLimit = BufferWi + BufferWiOffset; var elements = leftEdge ? frameBuffer.ElementLocations.Where(e => e.X >= (rightBufferLimit) - xlimit) : frameBuffer.ElementLocations.Where(e => e.X <= xlimit + BufferWiOffset); foreach (var elementLocation in elements) { var col = GetLocationColor(leftEdge, width, elementLocation); if (level < 1) { HSV hsv = HSV.FromRGB(col); hsv.V *= level; col = hsv.ToRGB(); } frameBuffer.SetPixel(elementLocation.X, elementLocation.Y, col); } // swag if (swagArray.Count > 0) { var swagElements = leftEdge ? frameBuffer.ElementLocations.Where(e => e.X <= (BufferWi + BufferWiOffset) - xlimit && e.X >= (BufferWi + BufferWiOffset) - (xlimit + swagArray.Count)).ToLookup(e => e.X) : frameBuffer.ElementLocations.Where(e => e.X >= xlimit + BufferWiOffset && e.X <= xlimit + swagArray.Count + BufferWiOffset).ToLookup(e => e.X); for (int i = 0; i < swagArray.Count; i++) { int x = leftEdge? rightBufferLimit - (xlimit + i):xlimit + i + BufferWiOffset; var limit = BufferHt - swagArray[i] + BufferHtOffset; foreach (var elementLocation in swagElements[x]) { if (elementLocation.Y < limit) { var col = GetLocationColor(leftEdge, width, elementLocation); if (level < 1) { HSV hsv = HSV.FromRGB(col); hsv.V *= level; col = hsv.ToRGB(); } frameBuffer.SetPixel(elementLocation.X, elementLocation.Y, col); } } } } }
protected override void RenderEffectByLocation(int numFrames, PixelLocationFrameBuffer frameBuffer) { var nodes = frameBuffer.ElementLocations.OrderBy(x => x.X).ThenBy(x => x.Y).GroupBy(x => x.X); for (int frame = 0; frame < numFrames; frame++) { frameBuffer.CurrentFrame = frame; double level = LevelCurve.GetValue(GetEffectTimeIntervalPosition(frame) * 100) / 100; var iterationFrame = frame * Iterations % (numFrames); double position = GetEffectTimeIntervalPosition(iterationFrame); HSV hsv = HSV.FromRGB(Color.GetColorAt(position)); if (Shimmer && frame % 2 != 0) { hsv.V = 0; } foreach (IGrouping <int, ElementLocation> elementLocations in nodes) { foreach (var elementLocation in elementLocations) { var v = hsv.V; //Here we offset our x, y values to get us to zero based coordinates for our math to work out //Our effect is symetrical so we don't need to waste time flipping the coordinates around v = CalculateAdjustedV(v, elementLocation.X - BufferWiOffset, elementLocation.Y - BufferHtOffset); v *= level; HSV hsv2 = hsv; hsv2.V = v; frameBuffer.SetPixel(elementLocation.X, elementLocation.Y, hsv2); } } } }
protected override void RenderEffectByLocation(int numFrames, PixelLocationFrameBuffer frameBuffer) { int colorcnt = Colors.Count(); int barCount = Repeat * colorcnt; if (barCount < 1) { barCount = 1; } int barHt = BufferHt / barCount + 1; if (barHt < 1) { barHt = 1; } int blockHt = colorcnt * barHt; if (blockHt < 1) { blockHt = 1; } int barWi = BufferWi / barCount + 1; if (barWi < 1) { barWi = 1; } int blockWi = colorcnt * barWi; if (blockWi < 1) { blockWi = 1; } var bufferHt = BufferHt; var bufferWi = BufferWi; var bufferHtOffset = BufferHtOffset; var bufferWiOffset = BufferWiOffset; IEnumerable <IGrouping <int, ElementLocation> > nodes; List <IGrouping <int, ElementLocation> > reversedNodes = new List <IGrouping <int, ElementLocation> >(); switch (Direction) { case BarDirection.AlternateUp: case BarDirection.Up: nodes = frameBuffer.ElementLocations.OrderBy(x => x.Y).ThenBy(x => x.X).GroupBy(x => x.Y); break; case BarDirection.Left: case BarDirection.AlternateLeft: nodes = frameBuffer.ElementLocations.OrderByDescending(x => x.X).ThenBy(x => x.Y).GroupBy(x => x.X); break; case BarDirection.Right: case BarDirection.AlternateRight: nodes = frameBuffer.ElementLocations.OrderBy(x => x.X).ThenBy(x => x.Y).GroupBy(x => x.X); break; case BarDirection.Compress: case BarDirection.Expand: nodes = frameBuffer.ElementLocations.OrderByDescending(x => x.Y).ThenBy(x => x.X).GroupBy(x => x.Y); reversedNodes = nodes.Reverse().ToList(); break; case BarDirection.HCompress: case BarDirection.HExpand: nodes = frameBuffer.ElementLocations.OrderBy(x => x.X).ThenBy(x => x.Y).GroupBy(x => x.X); reversedNodes = nodes.Reverse().ToList(); break; default: nodes = frameBuffer.ElementLocations.OrderByDescending(x => x.Y).ThenBy(x => x.X).GroupBy(x => x.Y); break; } var nodeCount = nodes.Count(); var halfNodeCount = (nodeCount - 1) / 2; var evenHalfCount = nodeCount % 2 != 0; for (int frame = 0; frame < numFrames; frame++) { frameBuffer.CurrentFrame = frame; double intervalPosFactor = GetEffectTimeIntervalPosition(frame) * 100; double level = LevelCurve.GetValue(intervalPosFactor) / 100; if (MovementType == MovementType.Iterations) { _position = (GetEffectTimeIntervalPosition(frame) * Speed) % 1; } else { var s = CalculateSpeed(intervalPosFactor); if (frame == 0) { _position = s; } _position += s / 100 * FrameTime / 50d; //Adjust the speed setting for different frame rates with FrameTime / 50d } int n; int colorIdx; if (Direction < BarDirection.Left || Direction == BarDirection.AlternateUp || Direction == BarDirection.AlternateDown) { int fOffset = (int)(_position * blockHt * Repeat); // : Speed * frame / 4 % blockHt); if (Direction == BarDirection.AlternateUp || Direction == BarDirection.AlternateDown) { fOffset = (int)(Math.Floor(_position * barCount) * barHt); } int indexAdjust = 1; int i = 0; bool exitLoop = false; foreach (IGrouping <int, ElementLocation> elementLocations in nodes) { int y = elementLocations.Key; switch (Direction) { case BarDirection.Down: case BarDirection.AlternateDown: case BarDirection.Expand: n = (bufferHt + bufferHtOffset) - y + fOffset; break; default: n = y - bufferHtOffset + fOffset; break; } colorIdx = ((n + indexAdjust) % blockHt) / barHt; //we need the integer division here to make things work var colorPosition = (n + indexAdjust) % barHt / (double)barHt; Color c = Colors[colorIdx].GetColorAt(colorPosition); if (Highlight || Show3D) { var hsv = HSV.FromRGB(c); if (Highlight && (n + indexAdjust) % barHt == 0 || colorPosition > .95) { hsv.S = 0.0f; } if (Show3D) { hsv.V *= (float)(barHt - (n + indexAdjust) % barHt - 1) / barHt; } hsv.V *= level; c = hsv.ToRGB(); } else { if (level < 1) { HSV hsv = HSV.FromRGB(c); hsv.V *= level; c = hsv.ToRGB(); } } switch (Direction) { case BarDirection.Expand: case BarDirection.Compress: // expand / compress if (i <= halfNodeCount) { foreach (var elementLocation in elementLocations) { frameBuffer.SetPixel(elementLocation.X, y, c); } if (i == halfNodeCount & evenHalfCount) { i++; continue; } foreach (var elementLocation in reversedNodes[i]) { frameBuffer.SetPixel(elementLocation.X, elementLocation.Y, c); } i++; } else { exitLoop = true; } break; default: foreach (var elementLocation in elementLocations) { frameBuffer.SetPixel(elementLocation.X, y, c); } break; } if (exitLoop) { break; } } } else { int fOffset = (int)(_position * blockWi * Repeat); if (Direction > BarDirection.AlternateDown) { fOffset = (int)(Math.Floor(_position * barCount) * barWi); } int i = 0; foreach (IGrouping <int, ElementLocation> elementLocations in nodes) { int x = elementLocations.Key; switch (Direction) { case BarDirection.Right: case BarDirection.AlternateRight: case BarDirection.HCompress: n = (bufferWi + bufferWiOffset) - x + fOffset; break; default: n = x - bufferWiOffset + fOffset; break; } //we need the integer division here to make things work colorIdx = (n + 1) % blockWi / barWi; double colorPosition = (n + 1) % barWi / (double)barWi; Color c = Colors[colorIdx].GetColorAt(colorPosition); if (Highlight || Show3D) { var hsv = HSV.FromRGB(c); if (Highlight && (n + 1) % barWi == 0 || colorPosition > .95) { hsv.S = 0.0f; } if (Show3D) { hsv.V *= (float)(barWi - n % barWi - 1) / barWi; } hsv.V *= level; c = hsv.ToRGB(); } else { if (level < 1) { HSV hsv = HSV.FromRGB(c); hsv.V *= level; c = hsv.ToRGB(); } } switch (Direction) { case BarDirection.HExpand: case BarDirection.HCompress: if (i <= halfNodeCount) { foreach (var elementLocation in elementLocations) { frameBuffer.SetPixel(x, elementLocation.Y, c); } if (i == halfNodeCount & evenHalfCount) { i++; continue; } foreach (var elementLocation in reversedNodes[i]) { frameBuffer.SetPixel(elementLocation.X, elementLocation.Y, c); } i++; } break; default: foreach (var elementLocation in elementLocations) { frameBuffer.SetPixel(x, elementLocation.Y, c); } break; } } } } }
protected override void RenderEffectByLocation(int numFrames, PixelLocationFrameBuffer frameBuffer) { int colorcnt = Colors.Count(); int barCount = Repeat * colorcnt; if (barCount < 1) { barCount = 1; } int barHt = BufferHt / barCount + 1; if (barHt < 1) { barHt = 1; } int blockHt = colorcnt * barHt; if (blockHt < 1) { blockHt = 1; } int barWi = BufferWi / barCount + 1; if (barWi < 1) { barWi = 1; } int blockWi = colorcnt * barWi; if (blockWi < 1) { blockWi = 1; } IEnumerable <IGrouping <int, ElementLocation> > nodes; List <IGrouping <int, ElementLocation> > reversedNodes = new List <IGrouping <int, ElementLocation> >(); switch (Direction) { case BarDirection.AlternateUp: case BarDirection.Up: nodes = frameBuffer.ElementLocations.OrderBy(x => x.Y).ThenBy(x => x.X).GroupBy(x => x.Y); break; case BarDirection.Left: case BarDirection.AlternateLeft: nodes = frameBuffer.ElementLocations.OrderByDescending(x => x.X).ThenBy(x => x.Y).GroupBy(x => x.X); break; case BarDirection.Right: case BarDirection.AlternateRight: nodes = frameBuffer.ElementLocations.OrderBy(x => x.X).ThenBy(x => x.Y).GroupBy(x => x.X); break; case BarDirection.Compress: case BarDirection.Expand: nodes = frameBuffer.ElementLocations.OrderByDescending(x => x.Y).ThenBy(x => x.X).GroupBy(x => x.Y); reversedNodes = nodes.Reverse().ToList(); break; case BarDirection.HCompress: case BarDirection.HExpand: nodes = frameBuffer.ElementLocations.OrderBy(x => x.X).ThenBy(x => x.Y).GroupBy(x => x.X); reversedNodes = nodes.Reverse().ToList(); break; default: nodes = frameBuffer.ElementLocations.OrderByDescending(x => x.Y).ThenBy(x => x.X).GroupBy(x => x.Y); break; } var nodeCount = nodes.Count(); var halfNodeCount = (nodeCount - 1) / 2; var evenHalfCount = nodeCount % 2 != 0; for (int frame = 0; frame < numFrames; frame++) { frameBuffer.CurrentFrame = frame; double level = LevelCurve.GetValue(GetEffectTimeIntervalPosition(frame) * 100) / 100; double position = (GetEffectTimeIntervalPosition(frame) * Speed) % 1; int n; int colorIdx; if (Direction < BarDirection.Left || Direction == BarDirection.AlternateUp || Direction == BarDirection.AlternateDown) { int fOffset = (int)(position * blockHt * Repeat); // : Speed * frame / 4 % blockHt); if (Direction == BarDirection.AlternateUp || Direction == BarDirection.AlternateDown) { fOffset = (int)(Math.Floor(position * barCount) * barHt); } if (Direction == BarDirection.Down || Direction == BarDirection.AlternateDown || Direction == BarDirection.Expand) { fOffset = -fOffset; } int indexAdjust = 1; int i = 0; bool exitLoop = false; foreach (IGrouping <int, ElementLocation> elementLocations in nodes) { int y = elementLocations.Key; n = y + fOffset; colorIdx = Math.Abs(((n + indexAdjust) % blockHt) / barHt); //we need the integer division here to make things work double colorPosition = Math.Abs((double)(n + indexAdjust) / barHt - (n + indexAdjust) / barHt); Color c = Colors[colorIdx].GetColorAt(colorPosition); var hsv = HSV.FromRGB(c); if (Highlight && (n + indexAdjust) % barHt == 0) { hsv.S = 0.0f; } if (Show3D) { hsv.V *= (float)(barHt - (n + indexAdjust) % barHt - 1) / barHt; } hsv.V = hsv.V * level; switch (Direction) { case BarDirection.Expand: case BarDirection.Compress: // expand / compress if (i <= halfNodeCount) { foreach (var elementLocation in elementLocations) { frameBuffer.SetPixel(elementLocation.X, y, hsv); } if (i == halfNodeCount & evenHalfCount) { i++; continue; } foreach (var elementLocation in reversedNodes[i]) { frameBuffer.SetPixel(elementLocation.X, elementLocation.Y, hsv); } i++; } else { exitLoop = true; } break; default: foreach (var elementLocation in elementLocations) { frameBuffer.SetPixel(elementLocation.X, y, hsv); } break; } if (exitLoop) { break; } } } else { int fOffset = (int)(position * blockWi * Repeat); if (Direction > BarDirection.AlternateDown) { fOffset = (int)(Math.Floor(position * barCount) * barWi); } if (Direction == BarDirection.Right || Direction == BarDirection.AlternateRight || Direction == BarDirection.HCompress) { fOffset = -fOffset; } int i = 0; foreach (IGrouping <int, ElementLocation> elementLocations in nodes) { int x = elementLocations.Key; n = x + fOffset; colorIdx = Math.Abs(((n + 1) % blockWi) / barWi); //we need the integer division here to make things work double colorPosition = Math.Abs((double)(n + 1) / barWi - (n + 1) / barWi); Color c = Colors[colorIdx].GetColorAt(colorPosition); var hsv = HSV.FromRGB(c); if (Highlight && n % barWi == 0) { hsv.S = 0.0f; } if (Show3D) { hsv.V *= (float)(barWi - n % barWi - 1) / barWi; } hsv.V = hsv.V * level; switch (Direction) { case BarDirection.HExpand: case BarDirection.HCompress: if (i <= halfNodeCount) { foreach (var elementLocation in elementLocations) { frameBuffer.SetPixel(x, elementLocation.Y, hsv); } if (i == halfNodeCount & evenHalfCount) { i++; continue; } foreach (var elementLocation in reversedNodes[i]) { frameBuffer.SetPixel(elementLocation.X, elementLocation.Y, hsv); } i++; } break; default: foreach (var elementLocation in elementLocations) { frameBuffer.SetPixel(x, elementLocation.Y, hsv); } break; } } } } }