Neodroid  0.2.0
Machine Learning Environment Prototyping Tool
ScatterPlotDisplayer.cs
Go to the documentation of this file.
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
6 using UnityEngine;
7 
8 namespace droid.Runtime.Prototyping.Displayers.ScatterPlots {
12  [ExecuteInEditMode]
13  [AddComponentMenu(DisplayerComponentMenuPath._ComponentMenuPath
14  + "ScatterPlot"
15  + DisplayerComponentMenuPath._Postfix)]
16  [RequireComponent(typeof(ParticleSystem))]
18  [SerializeField] Gradient _gradient;
19  ParticleSystem _particle_system;
20 
21  ParticleSystem.MainModule _particle_system_main_module;
22  ParticleSystemRenderer _particle_system_renderer;
23 
24  [SerializeField]
25  ParticleSystemSimulationSpace _particle_system_simulation_space = ParticleSystemSimulationSpace.World;
26 
27  ParticleSystem.Particle[] _particles;
28  [SerializeField] float _default_start_size = 0.6f;
29 
30  List<float> _vs = new List<float>();
31 
35  protected override void Setup() {
36  this._particle_system = this.GetComponent<ParticleSystem>();
37  var em = this._particle_system.emission;
38  em.enabled = false;
39  em.rateOverTime = 0;
40  var sh = this._particle_system.shape;
41  sh.enabled = false;
42 
43  this._particle_system_main_module = this._particle_system.main;
44  this._particle_system_main_module.loop = false;
45  this._particle_system_main_module.playOnAwake = false;
46  this._particle_system_main_module.simulationSpace = this._particle_system_simulation_space;
47  this._particle_system_main_module.simulationSpeed = 0;
48  this._particle_system_main_module.startSize = this._default_start_size;
49 
50  this._particle_system_renderer = this.GetComponent<ParticleSystemRenderer>();
51  //this._particle_system_renderer.renderMode = ParticleSystemRenderMode.Mesh;
52  this._particle_system_renderer.alignment = ParticleSystemRenderSpace.World;
53 
54  if (this._gradient == null) {
55  this._gradient = new Gradient {
56  colorKeys = new[] {
57  new GradientColorKey(new Color(1, 0, 0), 0f),
58  new GradientColorKey(new Color(0, 1, 0), 1f)
59  }
60  };
61  }
62  }
63 
64  public override void Display(Double value) {
65  #if NEODROID_DEBUG
66  if (this.Debugging) {
67  Debug.Log("Applying the double " + value + " To " + this.name);
68  }
69  #endif
70 
71  this._Values = new[] {(float)value};
72  this.PlotSeries(this._Values);
73  }
74 
75  public override void Display(float[] values) {
76  #if NEODROID_DEBUG
77  if (this.Debugging) {
78  var s = "";
79  foreach (var value in values) {
80  s += $"{value},";
81  }
82 
83  Debug.Log("Applying the float array " + s + " To " + this.name);
84  }
85  #endif
86  this._Values = values;
87  this.PlotSeries(values);
88  }
89 
90  public override void Display(String values) {
91  #if NEODROID_DEBUG
92  if (this.Debugging) {
93  Debug.Log("Applying the float array " + values + " To " + this.name);
94  }
95  #endif
96 
97  this._vs.Clear();
98  foreach (var value in values.Split(',')) {
99  this._vs.Add(float.Parse(value));
100  }
101 
102  this._Values = this._vs.ToArray();
103  this.PlotSeries(this._Values);
104  }
105 
106  public override void Display(Vector3 value) { throw new NotImplementedException(); }
107  public override void Display(Vector3[] value) { this.ScatterPlot(value); }
108 
109  public override void Display(Points.ValuePoint points) { this.PlotSeries(new[] {points}); }
110 
111  public override void Display(Points.ValuePoint[] points) {
112  if (this._particles == null || this._particles.Length != points.Length) {
113  this._particles = new ParticleSystem.Particle[points.Length];
114  }
115 
116  #if NEODROID_DEBUG
117  if (this.Debugging) {
118  var points_str = points.Aggregate("",
119  (current, point) =>
120  current
121  + $"({point._Pos.ToString()}, {point._Val},{point._Size})"
122  + ", ");
123  Debug.Log("Applying the points " + points_str + " to " + this.name);
124  }
125  #endif
126 
127  var i = 0;
128  foreach (var point in points) {
129  this._particles[i].remainingLifetime = 100000;
130  this._particles[i].position = point._Pos;
131  var clamped = Math.Min(Math.Max(0.0f, point._Val), 1.0f);
132  this._particles[i].startColor = this._gradient.Evaluate(clamped);
133  this._particles[i].startSize = point._Size;
134  this._particles[i].startSize3D = this._default_start_size.BroadcastVector3();
135  i++;
136  }
137 
138  this._particle_system.SetParticles(this._particles, points.Length);
139  }
140 
141  public override void Display(Points.StringPoint point) { throw new NotImplementedException(); }
142  public override void Display(Points.StringPoint[] points) { throw new NotImplementedException(); }
143 
144  //public override void Display(Object o) { throw new NotImplementedException(); }
145 
150  public override void Display(float values) {
151  #if NEODROID_DEBUG
152  if (this.Debugging) {
153  Debug.Log("Applying the float " + values + " To " + this.name);
154  }
155  #endif
156 
157  this._Values = new[] {values};
158  this.PlotSeries(this._Values);
159  }
160 
164  public void ScatterPlot(Vector3[] points) {
165  if (this._particles == null || this._particles.Length != points.Length) {
166  this._particles = new ParticleSystem.Particle[points.Length];
167  }
168 
169  #if NEODROID_DEBUG
170  if (this.Debugging) {
171  var points_str = points.Aggregate("", (current, point) => current + point.ToString() + ", ");
172  Debug.Log("Applying the points " + points_str + " To " + this.name);
173  }
174  #endif
175 
176  var i = 0;
177  var l = (float)points.Length;
178  foreach (var point in points) {
179  this._particles[i].remainingLifetime = 100000;
180  this._particles[i].position = point;
181  var clamped = Math.Min(Math.Max(0.0f, i / l), 1.0f);
182  this._particles[i].startColor = this._gradient.Evaluate(clamped);
183  this._particles[i].startSize = this._default_start_size;
184  this._particles[i].startSize3D = this._default_start_size.BroadcastVector3();
185  i++;
186  }
187 
188  this._particle_system.SetParticles(this._particles, points.Length);
189  }
190 
191  public void PlotSeries(float[] points) {
192  if (!this._particle_system) {
193  return;
194  }
195 
196  if (this._particles == null || this._particles.Length != points.Length) {
197  this._particles = new ParticleSystem.Particle[points.Length];
198  }
199 
200  #if NEODROID_DEBUG
201  if (this.Debugging) {
202  Debug.Log("Applying the series " + points + " To " + this.name);
203  }
204  #endif
205 
206  var i = 0;
207  foreach (var point in points) {
208  this._particles[i].remainingLifetime = 100000;
209  this._particles[i].position = Vector3.one * i;
210  var clamped = Math.Min(Math.Max(0.0f, point), 1.0f);
211  this._particles[i].startColor = this._gradient.Evaluate(clamped);
212  this._particles[i].startSize = this._default_start_size;
213  this._particles[i].startSize3D = this._default_start_size.BroadcastVector3();
214  i++;
215  }
216 
217  this._particle_system.SetParticles(this._particles, points.Length);
218  }
219 
223  protected override void Clean() {
224  if (!this._RetainLastPlot) {
225  if (this._particle_system) {
226  this._particle_system.Clear(true);
227  }
228  }
229 
230  base.Clean();
231  }
232 
236  public override void PlotSeries(Points.ValuePoint[] points) {
237  if (!this._particle_system) {
238  return;
239  }
240 
241  if (this._particles == null || this._particles.Length != points.Length) {
242  this._particles = new ParticleSystem.Particle[points.Length];
243  }
244  #if NEODROID_DEBUG
245  if (this.Debugging) {
246  Debug.Log("Applying the series " + points + " To " + this.name);
247  }
248  #endif
249 
250  var alive = this._particle_system.GetParticles(this._particles);
251  if (alive < points.Length) {
252  this._particles = new ParticleSystem.Particle[points.Length];
253  }
254 
255  var i = 0;
256  foreach (var point in points) {
257  this._particles[i].remainingLifetime = 100000;
258  this._particles[i].position = point._Pos;
259  this._particles[i].startColor = this._gradient.Evaluate(point._Val);
260  this._particles[i].startSize = point._Size;
261  this._particles[i].startSize3D = point._Size.BroadcastVector3();
262  i++;
263  }
264 
265  this._particle_system.SetParticles(this._particles, points.Length);
266  }
267  }
268 }