Exemplo n.º 1
0
        public void Destroy()
        {
            baseAmplitude = amplitude = 0.0f;
            isAlive       = false;

            if (leftNeighbour != null)
            {
                leftNeighbour.rightNeighbour      = rightNeighbour;
                leftNeighbour.disallowSubdivision = true;
            }

            if (rightNeighbour != null)
            {
                rightNeighbour.leftNeighbour       = leftNeighbour;
                rightNeighbour.disallowSubdivision = true;

                if (leftNeighbour == null)
                {
                    group.leftParticle = rightNeighbour;
                }
            }

            leftNeighbour  = null;
            rightNeighbour = null;
        }
Exemplo n.º 2
0
        private void UpdateSpawnPoints(float deltaTime)
        {
            deltaTime *= emissionFrequencyScale;

            for (int i = 0; i < spawnPoints.Length; ++i)
            {
                var spawnPoint = spawnPoints[i];
                spawnPoint.timeLeft -= deltaTime;

                if (spawnPoint.timeLeft < 0)
                {
                    float waveLength             = 2.0f * Mathf.PI / spawnPoint.frequency;
                    float preferredParticleCount = (span * 0.3f) / waveLength;
                    int   minParticles           = Mathf.Max(2, Mathf.RoundToInt(preferredParticleCount * 0.7f));
                    int   maxParticles           = Mathf.Max(2, Mathf.RoundToInt(preferredParticleCount * 1.429f));

                    spawnPoint.timeLeft += spawnPoint.timeInterval;
                    Vector2 position = spawnPoint.position + new Vector2(spawnPoint.direction.y, -spawnPoint.direction.x) * Random.Range(-span * 0.35f, span * 0.35f);

                    var particle = WaveParticle.Create(position, spawnPoint.direction, spawnPoint.frequency, spawnPoint.amplitude, lifetime, shoreWaves);

                    if (particle != null)
                    {
                        wavesParticleSystem.Spawn(particle, Random.Range(minParticles, maxParticles), waveShapeIrregularity);
                        particle.Destroy();
                        particle.AddToCache();
                    }
                }
            }
        }
Exemplo n.º 3
0
        /// <summary>
        /// Ensures that whole wave is either expanding or contracting.
        /// </summary>
        /// <param name="left"></param>
        /// <param name="right"></param>
        /// <param name="waveLength"></param>
        private void FilterRefractedDirections(WaveParticle left, WaveParticle right, int waveLength)
        {
            WaveParticle p          = left;
            int          halfLength = waveLength / 2;

            Vector2 leftDirection = new Vector2();

            for (int i = 0; i < halfLength; ++i)
            {
                leftDirection += p.direction;
                p              = p.rightNeighbour;
            }

            Vector2 rightDirection = new Vector2();

            for (int i = halfLength; i < waveLength; ++i)
            {
                rightDirection += p.direction;
                p = p.rightNeighbour;
            }

            leftDirection.Normalize();
            rightDirection.Normalize();

            p = left;

            for (int i = 0; i < waveLength; ++i)
            {
                p.direction = Vector2.Lerp(leftDirection, rightDirection, i / (waveLength - 1));
                p           = p.rightNeighbour;
            }
        }
Exemplo n.º 4
0
        public bool Spawn(WaveParticle particle, int clones, float waveShapeIrregularity)
        {
            if (particle == null || particles.FreeSpace < clones * 2 + 1)
            {
                return(false);
            }

            particle.group          = new WaveParticlesGroup(simulationTime);
            particle.baseAmplitude *= water.UniformWaterScale;
            particle.baseFrequency /= water.UniformWaterScale;

            WaveParticle previousParticle = null;

            float minAmplitude = 1.0f / waveShapeIrregularity;

            for (int i = -clones; i <= clones; ++i)
            {
                var p = particle.Clone(particle.position + new Vector2(particle.direction.y, -particle.direction.x) * (i * 1.48f / particle.baseFrequency));

                if (p == null)
                {
                    continue;
                }

                p.baseAmplitude *= Random.Range(minAmplitude, 1.0f);
                p.leftNeighbour  = previousParticle;

                if (previousParticle != null)
                {
                    previousParticle.rightNeighbour = p;

                    if (i == clones)
                    {
                        p.disallowSubdivision = true;                                   // it's a last particle of the group
                    }
                }
                else
                {
                    p.group.leftParticle  = p;                                  // it's a first particle of the group
                    p.disallowSubdivision = true;
                }

                if (!particles.AddElement(p))
                {
                    return(previousParticle != null);
                }

                previousParticle = p;
            }

            return(true);
        }
Exemplo n.º 5
0
 public bool Spawn(WaveParticle particle)
 {
     if (particle != null)
     {
         particle.group = new WaveParticlesGroup(simulationTime);
         particle.group.leftParticle = particle;
         return(particles.AddElement(particle));
     }
     else
     {
         return(false);
     }
 }
Exemplo n.º 6
0
        public void Update(float time)
        {
            WaveParticle particle  = leftParticle;
            float        deltaTime = time - lastUpdateTime;

            lastUpdateTime = time;

            float step    = deltaTime < 1.0f ? deltaTime : 1.0f;
            float invStep = 1.0f - step;

            do
            {
                var p = particle;
                particle = particle.rightNeighbour;
                p.Update(deltaTime, step, invStep);
            }while(particle != null);
        }
Exemplo n.º 7
0
        static public WaveParticle Create(Vector2 position, Vector2 direction, float baseFrequency, float baseAmplitude, float lifetime, bool isShoreWave)
        {
            WaveParticle particle;

            if (waveParticlesCache.Count != 0)
            {
                particle                     = waveParticlesCache.Pop();
                particle.position            = position;
                particle.direction           = direction;
                particle.baseFrequency       = baseFrequency;
                particle.baseAmplitude       = baseAmplitude;
                particle.fadeFactor          = 0.0f;
                particle.isShoreWave         = isShoreWave;
                particle.baseSpeed           = 3.2f * Mathf.Sqrt(9.81f / baseFrequency);
                particle.amplitude           = baseAmplitude;
                particle.frequency           = baseFrequency;
                particle.targetSpeed         = 1.0f;
                particle.invkh               = 1.0f;
                particle.targetInvKh         = 1.0f;
                particle.energyBalance       = 0.0f;
                particle.shoaling            = 0.0f;
                particle.speed               = 0.0f;
                particle.lifetime            = lifetime;
                particle.amplitudeModifiers  = 0.0f;
                particle.expansionEnergyLoss = 0.0f;
                particle.isAlive             = true;
                particle.disallowSubdivision = false;
                if (particle.leftNeighbour != null || particle.rightNeighbour != null)
                {
                    particle.leftNeighbour  = null;                             // WYWALIC
                    particle.rightNeighbour = null;
                }
                particle.CostlyUpdate(null, 0.1f);
            }
            else
            {
                particle = new WaveParticle(position, direction, baseFrequency, baseAmplitude, lifetime, isShoreWave);
            }

            return(particle.baseAmplitude != 0.0f ? particle : null);
        }
Exemplo n.º 8
0
        private void Subdivide(WaveParticlesQuadtree quadtree, WaveParticle left, WaveParticle right, ref int numSubdivisions)
        {
            Vector2 diff     = left.position - right.position;
            float   distance = diff.magnitude;

            if (distance * frequency > 1.0f && distance > 1.0f && quadtree.FreeSpace != 0)                     // don't subdivide below 1m on CPU
            {
                var newParticle = Create(right.position + diff * 0.5f, (left.direction + right.direction) * 0.5f, (left.baseFrequency + right.baseFrequency) * 0.5f, (left.baseAmplitude + right.baseAmplitude) * 0.5f, (left.lifetime + right.lifetime) * 0.5f, left.isShoreWave);

                if (newParticle != null)
                {
                    newParticle.group         = left.group;
                    newParticle.amplitude     = (left.amplitude + right.amplitude) * 0.5f;
                    newParticle.frequency     = (left.frequency + right.frequency) * 0.5f;
                    newParticle.speed         = (left.speed + right.speed) * 0.5f;
                    newParticle.targetSpeed   = (left.targetSpeed + right.targetSpeed) * 0.5f;
                    newParticle.energyBalance = (left.energyBalance + right.energyBalance) * 0.5f;
                    newParticle.shoaling      = (left.shoaling + right.shoaling) * 0.5f;

                    if (quadtree.AddElement(newParticle))
                    {
                        /*const float subdivideEnergyLoss = 0.94f;
                         *
                         * left.baseAmplitude *= subdivideEnergyLoss;
                         * left.amplitude *= subdivideEnergyLoss;
                         * right.baseAmplitude *= subdivideEnergyLoss;
                         * right.amplitude *= subdivideEnergyLoss;
                         * newParticle.baseAmplitude *= subdivideEnergyLoss;
                         * newParticle.amplitude *= subdivideEnergyLoss;*/

                        newParticle.leftNeighbour  = left;
                        newParticle.rightNeighbour = right;
                        left.rightNeighbour        = newParticle;
                        right.leftNeighbour        = newParticle;
                    }

                    ++numSubdivisions;
                }
            }
        }
Exemplo n.º 9
0
        public void CostlyUpdate(WaveParticlesQuadtree quadtree, float time)
        {
            WaveParticle particle  = leftParticle;
            float        deltaTime = time - lastCostlyUpdateTime;

            lastCostlyUpdateTime = time;
            int numSubdivisions = 0;

            do
            {
                var p = particle;
                particle         = particle.rightNeighbour;
                numSubdivisions += p.CostlyUpdate(numSubdivisions < 30 ? quadtree : null, deltaTime);
            }while(particle != null);

            particle = leftParticle;
            WaveParticle firstParticleInWave = particle;
            int          waveLength          = 0;

            do
            {
                var p = particle;
                particle = particle.rightNeighbour;

                ++waveLength;

                if (p != firstParticleInWave && (p.disallowSubdivision || particle == null))
                {
                    if (waveLength > 3)
                    {
                        FilterRefractedDirections(firstParticleInWave, p, waveLength);
                    }

                    firstParticleInWave = particle;
                    waveLength          = 0;
                }
            }while(particle != null);
        }
Exemplo n.º 10
0
        public void UpdateParticles(float time, float deltaTime)
        {
            if (!isActiveAndEnabled)
            {
                return;
            }

            switch (wavesSource)
            {
            case WavesSource.CustomWaveFrequency:
            {
                if (time > nextSpawnTime)
                {
                    Vector3 position  = transform.position;
                    Vector3 direction = transform.forward;

                    var particle = WaveParticle.Create(
                        new Vector2(position.x, position.z),
                        new Vector2(direction.x, direction.z).normalized,
                        2.0f * Mathf.PI / wavelength, amplitude, lifetime, shoreWaves
                        );

                    if (particle != null)
                    {
                        wavesParticleSystem.Spawn(particle, width, waveShapeIrregularity);

                        particle.Destroy();
                        particle.AddToCache();
                    }

                    nextSpawnTime += timeStep;
                }

                break;
            }
            }
        }