private void FixedUpdate()
        {
            if (!Emit)
            {
                return;
            }

            var velocity = Part?.GetComponent <Rigidbody>().velocity ?? Rb.velocity;
            var originalLocalPosition = gameObject.transform.localPosition;
            var originalPosition      = gameObject.transform.position;
            var startPosition         = gameObject.transform.position + velocity * Time.fixedDeltaTime;
            var originalGapDistance   = Vector3.Distance(originalPosition, startPosition);
            var intermediateSteps     = originalGapDistance / MaxDistance;

            PEmitter.EmitParticle();
            gameObject.transform.position = Vector3.MoveTowards(
                gameObject.transform.position,
                startPosition,
                MaxDistance);
            for (var i = 1; i < intermediateSteps; i++)
            {
                PEmitter.EmitParticle();
                gameObject.transform.position = Vector3.MoveTowards(
                    gameObject.transform.position,
                    startPosition,
                    MaxDistance);
            }
            gameObject.transform.localPosition = originalLocalPosition;
        }
        void FixedUpdate()
        {
            if (!part && !rb)
            {
                internalVelocity = (transform.position - lastPos) / Time.fixedDeltaTime;
                lastPos          = transform.position;
                if (emit && internalVelocity.sqrMagnitude > 562500)
                {
                    return; //dont bridge gap if floating origin shifted
                }
            }

            if (emit)
            {
                maxDistance = Mathf.Clamp((pEmitter.minSize / 3), 0.3f, 5f) +
                              (Mathf.Clamp((BDArmorySetup.numberOfParticleEmitters - 1), 0, 20) * 0.07f);

                Vector3 originalLocalPosition = gameObject.transform.localPosition;
                Vector3 originalPosition      = gameObject.transform.position;

                Vector3 startPosition = gameObject.transform.position;
                if (useInternalV)
                {
                    startPosition -= (velocity * Time.fixedDeltaTime);
                }
                else
                {
                    startPosition += (velocity * Time.fixedDeltaTime);
                }
                float originalGapDistance = Vector3.Distance(originalPosition, startPosition);
                float intermediateSteps   = originalGapDistance / maxDistance;

                pEmitter.EmitParticle();
                gameObject.transform.position = Vector3.MoveTowards(gameObject.transform.position, startPosition,
                                                                    maxDistance);
                for (int i = 1; i < intermediateSteps; i++)
                {
                    pEmitter.EmitParticle();
                    gameObject.transform.position = Vector3.MoveTowards(gameObject.transform.position, startPosition,
                                                                        maxDistance);
                }
                gameObject.transform.localPosition = originalLocalPosition;
            }
        }
        void FixedUpdate()
        {
            if (emit)
            {
                Vector3 velocity = (part == null) ? rb.velocity : part.rigidbody.velocity;
                Vector3 originalLocalPosition = gameObject.transform.localPosition;
                Vector3 originalPosition      = gameObject.transform.position;
                Vector3 startPosition         = gameObject.transform.position + (velocity * Time.fixedDeltaTime);
                float   originalGapDistance   = Vector3.Distance(originalPosition, startPosition);
                float   intermediateSteps     = originalGapDistance / maxDistance;

                pEmitter.EmitParticle();
                gameObject.transform.position = Vector3.MoveTowards(gameObject.transform.position, startPosition, maxDistance);
                for (int i = 1; i < intermediateSteps; i++)
                {
                    pEmitter.EmitParticle();
                    gameObject.transform.position = Vector3.MoveTowards(gameObject.transform.position, startPosition, maxDistance);
                }
                gameObject.transform.localPosition = originalLocalPosition;
            }
        }
Exemplo n.º 4
0
        private void FixedUpdate()
        {
            if (!part && !rb)
            {
                internalVelocity = (transform.position - lastPos) / Time.fixedDeltaTime;
                lastPos          = transform.position;
                if (PEmitter.emit && internalVelocity.sqrMagnitude > 562500)
                {
                    return; //dont bridge gap if floating origin shifted
                }
            }

            if (!Emit)
            {
                return;
            }

            //var velocity = part?.GetComponent<Rigidbody>().velocity ?? rb.velocity;
            var originalLocalPosition = gameObject.transform.localPosition;
            var originalPosition      = gameObject.transform.position;
            var startPosition         = gameObject.transform.position + velocity * Time.fixedDeltaTime;
            var originalGapDistance   = Vector3.Distance(originalPosition, startPosition);
            var intermediateSteps     = originalGapDistance / MaxDistance;

            PEmitter.EmitParticle();
            gameObject.transform.position = Vector3.MoveTowards(
                gameObject.transform.position,
                startPosition,
                MaxDistance);
            for (var i = 1; i < intermediateSteps; i++)
            {
                PEmitter.EmitParticle();
                gameObject.transform.position = Vector3.MoveTowards(
                    gameObject.transform.position,
                    startPosition,
                    MaxDistance);
            }
            gameObject.transform.localPosition = originalLocalPosition;
        }
Exemplo n.º 5
0
        IEnumerator LifeRoutine()
        {
            geoPos = VectorUtils.WorldPositionToGeoCoords(transform.position, body);

            pe.EmitParticle();

            float startTime = Time.time;

            while (Time.time - startTime < pe.maxEnergy)
            {
                transform.position = body.GetWorldSurfacePosition(geoPos.x, geoPos.y, geoPos.z);
                velocity          += FlightGlobals.getGeeForceAtPosition(transform.position) * Time.fixedDeltaTime;
                Vector3 dragForce = (0.008f) * drag * 0.5f * velocity.sqrMagnitude * (float)FlightGlobals.getAtmDensity(FlightGlobals.getStaticPressure(transform.position), FlightGlobals.getExternalTemperature(), body) * velocity.normalized;
                velocity           -= (dragForce) * Time.fixedDeltaTime;
                transform.position += velocity * Time.fixedDeltaTime;
                geoPos              = VectorUtils.WorldPositionToGeoCoords(transform.position, body);
                yield return(new WaitForFixedUpdate());
            }

            gameObject.SetActive(false);
        }
    // Update the particles of the Emitter : Emit, resize, collision and physic
    public void EmitterOnUpdate(Vector3 emitterWorldVelocity)
    {
        // "Default", "TransparentFX", "Local Scenery", "Ignore Raycast"
        int mask = (1 << LayerMask.NameToLayer("Default")) | (1 << LayerMask.NameToLayer("Local Scenery"));

        // Emit particles on fixedUpdate rather than Update so that we know which particles
        // were just created and should be nudged, should not be collided, etc.
        if (fixedEmit)
        {
            // Number of particles to emit:
            double averageEmittedParticles = Random.Range(pe.minEmission, pe.maxEmission)
                                             * TimeWarp.fixedDeltaTime;
            double compensatedEmittedParticles = averageEmittedParticles + particleFraction;
            double emittedParticles            = Math.Truncate(compensatedEmittedParticles);
            particleFraction = compensatedEmittedParticles - emittedParticles;

            int emissionCount = (int)emittedParticles;
            for (int k = 0; k < emissionCount; ++k)
            {
                pe.EmitParticle();
            }
        }

        // This line (and the one that does the oposite at the end) is actally the slowest part of the whole function
        Particle[] particles = pe.pe.particles;

        double averageSize = 0.5 * (pe.minSize + pe.maxSize);

        //For randConeEmit:
        //Only generate a random vector on every other particle, for the in-between particles, negate the disk.
        bool    toggle = true;
        Vector2 disk   = new Vector2(0, 0);
        //For startSpread

        double logGrowConst = TimeWarp.fixedDeltaTime * logarithmicGrow * logarithmicGrowScale;
        float  linGrowConst = (float)(TimeWarp.fixedDeltaTime * linearGrow * averageSize);

        Transform peTransform = pe.transform;

        Vector3d frameVel = Krakensbane.GetFrameVelocity();

        //Step through all the particles:
        for (int j = 0; j < particles.Length; j++)
        {
            Particle particle = particles[j];

            // Check if we need to cull the number of particles
            if (SmokeScreenConfig.particleDecimate != 0 && particles.Length > SmokeScreenConfig.decimateFloor)
            {
                SmokeScreenConfig.particleCounter++;
                if ((SmokeScreenConfig.particleDecimate > 0 &&
                     (SmokeScreenConfig.particleCounter % SmokeScreenConfig.particleDecimate) == 0) ||
                    (SmokeScreenConfig.particleDecimate < 0 &&
                     (SmokeScreenConfig.particleCounter % SmokeScreenConfig.particleDecimate) != 0))
                {
                    particle.energy = 0; // energy set to 0 remove the particle, as per Unity doc
                }
            }


            if (particle.energy > 0)
            {
                //Slight methodology change to avoid duplicating if statements:
                Vector3d pVel;
                Vector3d pPos;
                if (pe.useWorldSpace)
                {
                    pVel = particle.velocity + frameVel;
                    pPos = particle.position;
                }
                else if (!pe.useWorldSpace && particle.energy == particle.startEnergy)
                {
                    Vector3 lVel = new Vector3(0, 0, 1);
                    Vector3 lPos = particle.position;

                    // Adjust initial velocity to make a cone.  Only perform if pe.useWorldSpace
                    // is true, and we have a randConeEmit set.
                    //Produce a random vector within "angle" of the original vector.
                    //The maximum producible cone is 90 degrees when randConeEmit is very large.
                    //Could open up more if we used trig, but it'd be less efficient.

                    if (toggle)
                    {
                        disk   = Random.insideUnitCircle * randConeEmit;
                        toggle = false;
                    }
                    else
                    {
                        disk  *= -1;
                        toggle = true;
                    }
                    lVel.x = disk.x;
                    lVel.y = disk.y;
                    lVel   = Vector3.Normalize(lVel);
                    lVel  *= Vector3.Magnitude(particle.velocity);

                    //Adjust initial position back along its position, if required.
                    //Apply a random offset if vRandOffset != 0, else apply zero.
                    float randoff = (vRandPosOffset != 0)? Random.Range(0, vRandPosOffset) : 0;
                    lPos += Vector3.Normalize(lVel) * (randoff + vPosOffset);

                    //Finalize position and velocity
                    pPos = peTransform.TransformPoint(lPos);
                    pVel = peTransform.TransformDirection(lVel)
                           + frameVel;
                }
                else if (!pe.useWorldSpace && particle.energy != particle.startEnergy)
                {
                    pPos = peTransform.TransformPoint(particle.position);
                    pVel = peTransform.TransformDirection(particle.velocity.x * xyForce,
                                                          particle.velocity.y * xyForce,
                                                          particle.velocity.z * zForce)
                           + frameVel;
                }
                else
                {
                    pPos = peTransform.TransformPoint(particle.position);
                    pVel = peTransform.TransformDirection(particle.velocity) + frameVel;
                }

                // try-finally block to ensure we set the particle velocities correctly in the end.
                try
                {
                    // Fixed update is not the best place to update the size but the particles array copy is
                    // slow so doing each frame would be worse

                    // No need to waste time doing a division if the result is 0.
                    if (logarithmicGrow != 0.0)
                    {
                        // Euler integration of the derivative of Log(logarithmicGrowth * t + 1) + 1.
                        // This might look weird.

                        particle.size += (float)((logGrowConst / (1 + (particle.startEnergy - particle.energy) * logarithmicGrow)) * averageSize);
                    }
                    if (linearGrow != 0.0)
                    {
                        particle.size += linGrowConst;
                    }

                    particle.size = Mathf.Min(particle.size, sizeClamp);

                    if (particle.energy == particle.startEnergy)
                    {
                        if (pe.useWorldSpace)
                        {
                            // Uniformly scatter newly emitted particles along the emitter's trajectory in order to
                            // remove the dotted smoke effect.
                            // use variableDeltaTime since the particle are emited on Update anyway.
                            pPos -= emitterWorldVelocity * Random.value * Time.deltaTime;
                        }

                        if (randomInitalVelocityOffsetMaxRadius != 0.0)
                        {
                            Vector2  diskPoint = Random.insideUnitCircle * randomInitalVelocityOffsetMaxRadius;
                            Vector3d offset;
                            if (pVel.x == 0.0 && pVel.y == 0.0)
                            {
                                offset = new Vector3d(diskPoint.x, diskPoint.y, 0.0);
                            }
                            else
                            {
                                // Convoluted calculations to save some operations (especially divisions).
                                // Not that it really matters, but this achieves 2 divisions and 1 square root.
                                double x                   = pVel.x;
                                double y                   = pVel.y;
                                double z                   = pVel.z;
                                double xSquared            = x * x;
                                double ySquared            = y * y;
                                double xySquareNorm        = xSquared + ySquared;
                                double inverseXYSquareNorm = 1 / xySquareNorm;
                                double inverseNorm         = 1 / Math.Sqrt(xySquareNorm + z * z);
                                double zOverNorm           = z * inverseNorm;

                                // TODO(robin): find an identifier for that...
                                double mixedTerm = x * y * (zOverNorm - 1);
                                offset =
                                    new Vector3d(
                                        ((ySquared + xSquared * zOverNorm) * diskPoint.x + mixedTerm * diskPoint.y)
                                        * inverseXYSquareNorm,
                                        ((xSquared + ySquared * zOverNorm) * diskPoint.y + mixedTerm * diskPoint.x)
                                        * inverseXYSquareNorm,
                                        -(x * diskPoint.x + y * diskPoint.y) * inverseNorm);
                            }
                            pVel += offset;
                        }
                    }

                    if (physical && (j % physicsPass == activePhysicsPass))
                    {
                        // There must be a way to keep the actual initial volume,
                        // but I'm lazy.
                        pVel = ParticlePhysics(particle.size, averageSize, pPos, pVel);
                    }

                    if (collide && particle.energy != particle.startEnergy

                        // Do not collide newly created particles (they collide with the emitter and things look bad).
                        && (j % physicsPass == activePhysicsPass))
                    {
                        pVel = ParticleCollision(pPos, pVel, mask);
                    }
                }
                finally
                {
                    particle.velocity = (pe.useWorldSpace
                        ? (Vector3)(pVel - frameVel)
                        : peTransform.InverseTransformDirection(pVel - frameVel));
                    particle.position = pe.useWorldSpace
                        ? (Vector3)pPos
                        : peTransform.InverseTransformPoint(pPos);
                }
            }
            particles[j] = particle;
        }
        activePhysicsPass = ++activePhysicsPass % physicsPass;
        pe.pe.particles   = particles;
        SmokeScreenConfig.activeParticles += pe.pe.particleCount;
    }