WIP
DirectOutput framework for virtual pinball cabinets WIP
Go to:
Overview 
MatrixPlasmaEffectBase.cs
Go to the documentation of this file.
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.Xml.Serialization;
6 
7 namespace DirectOutput.FX.MatrixFX
8 {
9  public abstract class MatrixPlasmaEffectBase<MatrixElementType> : MatrixEffectBase<MatrixElementType>
10  {
11 
12  private int _PlasmaSpeed = 100;
13 
21  public int PlasmaSpeed
22  {
23  get { return _PlasmaSpeed; }
24  set { _PlasmaSpeed = value.Limit(1, int.MaxValue); }
25  }
26 
27 
28  private int _PlasmaScale = 100;
29 
37  public int PlasmaScale
38  {
39  get { return _PlasmaScale; }
40  set { _PlasmaScale = value; }
41  }
42 
43 
44  private int _PlasmaDensity = 100;
45 
53  public int PlasmaDensity
54  {
55  get { return _PlasmaDensity; }
56  set { _PlasmaDensity = value; }
57  }
58 
59 
60 
61 
62  private const int RefreshIntervalMs = 30;
63 
64  [XmlIgnore]
65  int CurrentTrigerrValue = 0;
66 
67  [XmlIgnore]
68  DateTime PlasmaStartDateTime = DateTime.Now;
69 
70  [XmlIgnore]
71  public bool Active { get; private set; }
72 
73  private void DoPlasma()
74  {
75  int V = CurrentTrigerrValue.Limit(0, 255);
76  if (V > 0)
77  {
78 
79  if (!Active)
80  {
81  PlasmaStartDateTime = DateTime.Now;
82  Table.Pinball.Alarms.RegisterIntervalAlarm(RefreshIntervalMs, DoPlasma);
83  Active = true;
84  }
85  DrawFrame();
86  }
87  else
88  {
89  Table.Pinball.Alarms.UnregisterIntervalAlarm(DoPlasma);
90  Active = false;
91  ClearFrame();
92  }
93  }
94 
95  [XmlIgnore]
96  double Time = 0;
97 
98 
99  private void DrawFrame()
100  {
101  int F = (FadeMode == FadeModeEnum.OnOff ? (CurrentTrigerrValue > 0 ? 255 : 0) : CurrentTrigerrValue.Limit(0, 255));
102 
103  Time += ((double)PlasmaSpeed / 2000);
104  int W = AreaWidth;
105  int H = AreaHeight;
106 
107 
108 
109  double SX;
110  double SY;
111 
112  if (W >= H)
113  {
114  SX = (double)PlasmaScale / 100 / W;
115  SY = (double)SX;
116  }
117  else
118  {
119  SY = (double)PlasmaScale / 100 / H;
120  SX = (double)SY;
121  }
122 
123  PrecalcTimeValues(Time);
124 
125  for (int X = 0; X < W; X++)
126  {
127  double XX = SX * X;
128  PrecalcXValues(XX, Time);
129 
130  for (int Y = 0; Y < H; Y++)
131  {
132  double YY = (double)SY * Y;
133 
134  double V = CalcPositionValue(XX, YY, Time).Limit(0, 1);
135 
136  MatrixLayer[AreaLeft + X, AreaTop + Y] = GetEffectValue(F, Time, V, XX, YY);
137 
138  }
139 
140  }
141 
142  }
143 
144 
145  private void ClearFrame()
146  {
147  int W = AreaWidth;
148  int H = AreaHeight;
149 
150  double KX = (double)W / H;
151  for (int Y = 0; Y < H; Y++)
152  {
153  for (int X = 0; X < W; X++)
154  {
155  MatrixLayer[AreaLeft + X, AreaTop + Y] = GetEffectValue(0, 0, 0, 0, 0);
156  }
157 
158  }
159 
160  }
161 
162  double CosTime = 0;
163  double SinTimeDiv11767Mult05 = 0;
164  double CosTimeDiv1833371Mult05=0;
165  private void PrecalcTimeValues(double Time)
166  {
167  CosTime = Math.Cos(Time);
168  SinTimeDiv11767Mult05 = .5 * Math.Sin(Time / 1.1767);
169  CosTimeDiv1833371Mult05 = .5 * Math.Cos(Time / 1.833371);
170  }
171 
172  double XWaveValue1 = 0;
173  double XWaveValue2 = 0;
174  private void PrecalcXValues(double X, double Time)
175  {
176  XWaveValue1 = Math.Sin(X * Math.PI * (PlasmaDensity / 28) + Time);
177  XWaveValue2 = X * Math.Sin(Time / 2.567);
178  }
179 
180 
181  private double CalcPositionValue(double X, double Y, double Time)
182  {
183  double V = XWaveValue1;
184 
185  V += Math.Sin(Math.PI * (PlasmaDensity / 28) * (XWaveValue2 + Y * CosTime) + Time);
186 
187  double cx = X + SinTimeDiv11767Mult05;
188  double cy = Y + CosTimeDiv1833371Mult05;
189  V += Math.Sin(Math.Sqrt((Math.PI * (PlasmaDensity / 56)) * (Math.PI * (PlasmaDensity / 56)) * (cx * cx + cy * cy) + 1) + Time);
190  V = ((V + 3) / 6.0);
191 
192  return V;
193  }
194 
195  protected abstract MatrixElementType GetEffectValue(int TriggerValue, double Time, double Value, double X, double Y);
196 
197  public override void Trigger(Table.TableElementData TableElementData)
198  {
199 
200  if (MatrixLayer != null)
201  {
202  CurrentTrigerrValue = TableElementData.Value;
203  if (CurrentTrigerrValue > 0 && !Active)
204  {
205  DoPlasma();
206  }
207  }
208 
209  }
210 
211 
212  }
213 }
Base class for effects targeting a matrix of toys (e.g. addressable ledstrip)
FadeModeEnum
Defines the fading behaviour.
Definition: FadeModeEnum.cs:11
override void Trigger(Table.TableElementData TableElementData)