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
    }
Esempio n. 2
0
    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
    }