2 using System.Collections;
3 using System.Collections.Generic;
20 [RequireComponent(typeof(ParticleSystem))]
21 [RequireComponent(typeof(ParticleSystemRenderer))]
24 private ParticleSystem particalSystem;
27 private Vector3 initialPosition;
42 private ParticleSystem chaosParticles;
43 private ParticleSystem.Particle[] particles;
44 private int particleCount;
57 private bool[] inactive;
60 private bool oneTimeBurst;
63 private Dictionary<uint,int> particleBySeed;
64 private int lastParticleCount;
66 private const float OUT_OF_VIEW = 10000f;
69 private const bool debugLogs =
false;
70 private int debugCnt = 0;
74 chaosParticles = GetComponent<ParticleSystem>();
76 ParticleSystemRenderer psr = GetComponent<ParticleSystemRenderer>();
77 if (psr.renderMode == ParticleSystemRenderMode.Stretch) {
78 Debug.LogError(
"Stretch render mode does not work for ChaoticParticles");
93 ParticleSystem.Burst[] bursts =
new ParticleSystem.Burst[chaosParticles.emission.burstCount];
94 chaosParticles.emission.GetBursts(bursts);
95 foreach (ParticleSystem.Burst burst in bursts) {
96 burstCount += burst.maxCount;
98 if (burstCount == chaosParticles.main.maxParticles) {
99 Debug.Log(
"One time burst");
102 particleBySeed =
new Dictionary<uint,int>();
106 public override void Init() {
108 initialPosition = transform.position;
112 private void InitParticleData() {
113 if (chaosParticles == null) {
114 Debug.LogError(
"Must be attached to a particle system object");
118 particles =
new ParticleSystem.Particle[chaosParticles.main.maxParticles];
120 chaosParticles.GetParticles(particles);
121 int maxParticles = chaosParticles.main.maxParticles;
122 #pragma warning disable 162 // disable unreachable code warning
124 Debug.Log(
"Init numParticles=" + maxParticles);
126 #pragma warning restore 162
127 x =
new float[maxParticles,3];
128 seed =
new uint[maxParticles];
129 inactive =
new bool[maxParticles];
139 private void InitParticles(
int fromP,
int toP) {
140 for (
int i=fromP; i < toP; i++) {
145 particles[i].velocity = Vector3.zero;
147 #pragma warning disable 162 // disable unreachable code warning
149 Debug.Log(
string.Format(
"InitParticles from={0} to={1} pp_pos={2} phy_pos=({3},{4},{5})",
150 fromP, toP, particles[fromP].position, x[fromP,0], x[fromP,1], x[fromP,2] ));
152 #pragma warning restore 162
160 void ParticleLifeCycleHandler()
165 particleCount = chaosParticles.GetParticles (particles);
166 if (lastParticleCount < particleCount) {
168 InitParticles(lastParticleCount, chaosParticles.particleCount);
169 for (
int i = lastParticleCount; i < chaosParticles.particleCount; i++) {
171 seed[i] = particles[i].randomSeed;
172 particleBySeed[particles[i].randomSeed] = i;
174 lastParticleCount = chaosParticles.particleCount;
184 for (
int i = 0; i < chaosParticles.particleCount; i++) {
185 if (seed[i] != particles[i].randomSeed) {
186 #pragma warning disable 162 // disable unreachable code warning
188 Debug.Log(
"Seed changed was:" + seed[i] +
" now:" + particles[i].randomSeed);
189 #pragma warning restore 162
191 particleBySeed.Remove (seed [i]);
193 if (particleBySeed.ContainsKey (particles[i].randomSeed)) {
195 int oldIndex = particleBySeed[particles[i].randomSeed];
196 x[i, 0] = x[oldIndex, 0];
197 x[i, 1] = x[oldIndex, 1];
198 x[i, 2] = x[oldIndex, 2];
199 particleBySeed [particles[i].randomSeed] = i;
200 #pragma warning disable 162 // disable unreachable code warning
202 Debug.Log(
"Shuffling particle from " + oldIndex +
" to " + i);
203 #pragma warning restore 162
206 #pragma warning disable 162 // disable unreachable code warning
208 Debug.Log(
"Reusing particle " + i +
" vel=" + particles[i].velocity);
209 #pragma warning restore 162
210 InitParticles(i, i+1);
211 particleBySeed[particles[i].randomSeed] = i;
212 #pragma warning disable 162 // disable unreachable code warning
214 Debug.Log(
"Post-Setup Reusing particle " + i);
215 #pragma warning restore 162
217 seed[i] = particles[i].randomSeed;
224 private void Evolve(
float h) {
226 if (inactive == null) {
231 chaosParticles.Play();
235 for (
int j=0; j < particleCount; j++) {
238 Vector3 xout = Vector3.zero;
242 chaosEqn.
Function(ref x_in, ref a_n);
245 arg[0] = x[j,0] + h_frac * a_n[0];
246 arg[1] = x[j,1] + h_frac * a_n[1];
247 arg[2] = x[j,2] + h_frac * a_n[2];
248 chaosEqn.
Function(ref arg, ref b_n);
249 arg[0] = x[j,0] + h_frac * b_n[0];
250 arg[1] = x[j,1] + h_frac * b_n[1];
251 arg[2] = x[j,2] + h_frac * b_n[2];
252 chaosEqn.
Function(ref arg, ref c_n);
254 arg[0] = x[j,0] + h_frac * c_n[0];
255 arg[1] = x[j,1] + h_frac * c_n[1];
256 arg[2] = x[j,2] + h_frac * c_n[2];
257 chaosEqn.
Function(ref arg, ref d_n);
259 x[j,0] = x[j,0] + h_frac*(a_n[0] + 2f * b_n[0] + 2f * c_n[0] + d_n[0]);
260 x[j,1] = x[j,1] + h_frac*(a_n[1] + 2f * b_n[1] + 2f * c_n[1] + d_n[1]);
261 x[j,2] = x[j,2] + h_frac*(a_n[2] + 2f * b_n[2] + 2f * c_n[2] + d_n[2]);
262 if (
double.IsNaN(x[j,0]) ||
double.IsNaN(x[j,1]) ||
double.IsNaN(x[j,2])) {
272 particles =
new ParticleSystem.Particle[chaosParticles.main.maxParticles];
273 ParticleLifeCycleHandler();
275 int numSteps = CalcNumSteps();
277 for (
int i=0; i < numSteps; i++) {
293 for (
int i=0; i < lastParticleCount; i++) {
296 phy_pos =
new Vector3((
float) x[i,0], (
float) x[i,1],(
float) x[i,2]);
298 particles[i].position = Vector3.Scale(phy_pos,
evolveScale) + initialPosition;
299 particles[i].position = transform.rotation * particles[i].position;
302 chaosParticles.SetParticles(particles, particleCount);
303 #pragma warning disable 162, 429 // disable unreachable code warning
304 if (debugLogs && debugCnt++ > 30) {
306 string log =
"time = " + Time.time +
" remaining=" + particleCount ;
307 log +=
" is Stopped " + chaosParticles.isStopped +
" num=" + chaosParticles.particleCount +
" pcount=" + particleCount +
"\n";
309 for (
int i=0; i < logTo; i++) {
310 log +=
string.Format(
"{0} rand={1} life={2} inactive={3} ", i, particles[i].randomSeed, particles[i].remainingLifetime, inactive[i]);
311 log +=
" pos=" + particles[i].position ;
312 log +=
" phyPos= " + x[i,0] +
" " + x[i,1] +
" " + x[i,2];
317 #pragma warning restore 162, 429
ParamBundle paramBundle
The parameter bundle that is used to evolve the system.
ParamBundle customParams
Custom parameter values for evolution (valid only if selectedParams exceeds number of params listed i...
static ChaosEqn Create(int index, int paramIndex, ParamBundle customParams)
Create the ChaosEqn implementation for the specified index in the eqnList, with the selected param bu...
Chaotic system. Base class for chaotic scripts. Holds the type of system selected, the parameter set or the custom parameters to be used.
float scale
scale to ensure that attractor fits in box of size 10
int selectedEqn
Number of chaos system to evolve (w.r.t. ChaosFactory list)
void UpdateParticles()
Updates the particles positions in world space.
abstract void Function(ref float[] x_in, ref float[] x_dot)
Evaluate the first order evolution of the attractor, given the current position.
Vector3 evolveScale
Scale to apply to phyics evolution when mapping back to world space.
Vector3 initialPosition
Initial position for evolution in physics space.
Chaos eqn. Base class for all equations that define a 3D chaotic system.
Vector3 offset
offset to center attractor at local origin
int selectedParams
Number of parameter bundle selected for evolution (per chaotic equation)