void Start() { gravityEngine = GravityEngine.instance; dt = gravityEngine.GetParticleDt(); // outOfBoundsSquared = gravityEngine.outOfBounds * gravityEngine.outOfBounds; gravityParticles = GetComponent <ParticleSystem>(); InitParticleData(); // Had Play() here - but after Unity 5.3 this broke. Now moved to the update loop. // Get the Init Delegate (if there is one) particlesInit = GetComponent <IGravityParticlesInit>(); if (particlesInit == null && addNBodyVelocity) { // Find the associated NBody // Can either be directly attached (particleSystem is attached directly to object with NBody) OR // can be the parent (if ParticleSystem has its own Game Object and is a child) if (GetComponent <NBody>() != null) { nbodySource = transform.gameObject; } else if (transform.parent != null && transform.parent.gameObject.GetComponent <NBody>() != null) { nbodySource = transform.parent.gameObject; } } particleBySeed = new Dictionary <uint, int>(); // determine if this is a one-time burst scenario int burstCount = 0; ParticleSystem.Burst[] bursts = new ParticleSystem.Burst[gravityParticles.emission.burstCount]; gravityParticles.emission.GetBursts(bursts); foreach (ParticleSystem.Burst burst in bursts) { burstCount += burst.maxCount; } if (burstCount == gravityParticles.main.maxParticles) { oneTimeBurst = true; burstDone = false; } #pragma warning disable 162 // disable unreachable code warning if (debugLogs) { Debug.Log(this.name + " start: oneTimeBurst=" + oneTimeBurst + " burstCount=" + burstCount + " pc=" + gravityParticles.main.maxParticles); } #pragma warning restore 162 // self-register with NBE gravityEngine.RegisterParticles(this); #pragma warning disable 162 // disable unreachable code warning if (debugLogs) { Debug.Log("Registered with GE: self=" + transform.gameObject.name); } #pragma warning restore 162 }
private void EvolveForTimestep(GravityEngine ge, double physicsDt) { // if everything is on rails, can just jump to the end time if (onRails) { time += physicsDt; MoveFixedBodies(time); // Keep these up-to-date so can flip to off-rails if needed physicalTime[(int)Evolvers.MASSIVE] = time; physicalTime[(int)Evolvers.MASSLESS] = time; physicalTime[(int)Evolvers.PARTICLES] = time; return; } // Objective is to keep physical time proportional to game time // Each integrator will run for at least as long as it is told but may overshoot // so correct time on next iteration. // // Keep the current physical time each integrator has reached in physicalTime[integrator_type] // double engineDt = ge.engineDt; if (physicsDt < engineDt) { return; } double timeEvolved = 0; // Need to move the integrators forward concurrently in steps matching the engineDt // - Hermite may be using a different timestep than this // - particles likely use a much longer timestep while (timeEvolved < physicsDt) { //============================== // Massive bodies //============================== // evolve all the massive game objects double massiveDt = 0.0; if (numBodies > fixedBodiesInIntegrator) { // typical path - have massive bodies: use NBody integration massiveDt = integrator.Evolve(engineDt, this, ref info); physicalTime[(int)Evolvers.MASSIVE] += massiveDt; timeEvolved += massiveDt; } else { // all Kepler mode: skip integration physicalTime[(int)Evolvers.MASSIVE] += engineDt; timeEvolved += engineDt; } //============================== // Fixed Bodies //============================== // Update fixed update objects (if any) // Evolution is to a specific time - so use massive object physical time MoveFixedBodies(physicalTime[(int)Evolvers.MASSIVE]); // Debug.Log(string.Format("gameDt={0} integated={1} ptime={2} wtime={3}", gameDt, dt, physicalTime, worldTime)); // LF is built in to particles and massless routines. They have their own DT built in // these run on a fixed timestep (if it is varied energy conservation is wrecked) // Track their evolution vs wall clock time seperately //============================== // Particles (should only be present in worldState) //============================== if (gravityParticles.Count > 0) { double particle_dt = ge.GetParticleDt(); if (physicalTime[(int)GravityState.Evolvers.PARTICLES] < physicalTime[(int)GravityState.Evolvers.MASSIVE]) { double evolvedFor = 0.0; if (forceDelegate != null) { foreach (GravityParticles nbp in gravityParticles) { evolvedFor = nbp.EvolveWithForce(particle_dt, numBodies, this, ref size2, ref info, forceDelegate); } } else { foreach (GravityParticles nbp in gravityParticles) { evolvedFor = nbp.Evolve(particle_dt, numBodies, this, ref size2, ref info); } } physicalTime[(int)Evolvers.PARTICLES] += evolvedFor; } } //============================== // Massless //============================== if (masslessEngine != null && masslessEngine.NumBodies() > 0) { // rockets need the time if (physicalTime[(int)Evolvers.MASSLESS] < physicalTime[(int)Evolvers.MASSIVE]) { if (forceDelegate != null) { physicalTime[(int)Evolvers.MASSLESS] += masslessEngine.EvolveWithForce(engineDt, time, numBodies, this, ref info, forceDelegate); } else { physicalTime[(int)Evolvers.MASSLESS] += masslessEngine.Evolve(engineDt, time, numBodies, this, ref info); } } } // must update time so trajectory times are up to date time = physicalTime[(int)Evolvers.MASSIVE]; if (hasTrajectories) { ge.UpdateTrajectories(); } } // while }