Example #1
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);
     }
 }
Example #2
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;
                }
            }
        }
Example #3
0
        private void UpdateParticles(float time)
        {
            var  enabledWaterCameras    = WaterCamera.EnabledWaterCameras;
            int  numEnabledWaterCameras = enabledWaterCameras.Count;
            bool isVisible = false;

            for (int i = 0; i < numEnabledWaterCameras; ++i)
            {
                if (rect.Overlaps(enabledWaterCameras[i].LocalMapsRect))
                {
                    isVisible = true;
                    break;
                }
            }

            int startIndex, endIndex, vertexIndex;

            if (!isVisible)
            {
                startIndex  = lastUpdateIndex;
                endIndex    = lastUpdateIndex + 8;
                vertexIndex = startIndex << 2;

                if (endIndex >= elements.Length)
                {
                    endIndex        = elements.Length;
                    lastUpdateIndex = 0;
                }
                else
                {
                    lastUpdateIndex = endIndex;
                }
            }
            else
            {
                startIndex  = 0;
                endIndex    = elements.Length;
                vertexIndex = 0;
            }

            WaveParticlesQuadtree rootQuadtree = isVisible ? root : null;
            float updateDelay       = isVisible ? 0.01f : 1.5f;
            float costlyUpdateDelay = isVisible ? 0.4f : 8.0f;
            bool  didCostlyUpdate   = false;

            updateDelay       *= root.stress;
            costlyUpdateDelay *= root.stress;

            for (int i = 0; particleGroups != null && i < particleGroups.Length; ++i)
            {
                var group = particleGroups[i];

                if (group != null)
                {
                    if (!group.leftParticle.isAlive)
                    {
                        --numParticleGroups;
                        particleGroups[i] = null;
                        continue;
                    }

                    if (time >= group.lastUpdateTime + updateDelay)
                    {
                        if (time >= group.lastCostlyUpdateTime + costlyUpdateDelay && !didCostlyUpdate)
                        {
                            if (!RectContainsParticleGroup(group))
                            {
                                --numParticleGroups;
                                particleGroups[i] = null;
                                continue;
                            }

                            group.CostlyUpdate(rootQuadtree, time);
                            didCostlyUpdate = true;
                        }

                        group.Update(time);
                    }
                }
            }

            if (elements != null)
            {
                for (int i = startIndex; i < endIndex; ++i)
                {
                    var particle = elements[i];

                    if (particle != null)
                    {
                        if (particle.isAlive)
                        {
                            if (marginRect.Contains(particle.position))
                            {
                                var vertexData   = particle.VertexData;
                                var particleData = particle.PackedParticleData;
                                vertices[vertexIndex]       = vertexData;
                                tangentsPack[vertexIndex++] = particleData;
                                vertices[vertexIndex]       = vertexData;
                                tangentsPack[vertexIndex++] = particleData;
                                vertices[vertexIndex]       = vertexData;
                                tangentsPack[vertexIndex++] = particleData;
                                vertices[vertexIndex]       = vertexData;
                                tangentsPack[vertexIndex++] = particleData;
                                tangentsPackChanged         = true;
                            }
                            else
                            {
                                // re-add particle
                                base.RemoveElementAt(i);

                                vertices[vertexIndex++].x = float.NaN;
                                vertices[vertexIndex++].x = float.NaN;
                                vertices[vertexIndex++].x = float.NaN;
                                vertices[vertexIndex++].x = float.NaN;
                                root.AddElement(particle);
                            }
                        }
                        else
                        {
                            // remove particle
                            base.RemoveElementAt(i);

                            vertices[vertexIndex++].x = float.NaN;
                            vertices[vertexIndex++].x = float.NaN;
                            vertices[vertexIndex++].x = float.NaN;
                            vertices[vertexIndex++].x = float.NaN;
                            particle.AddToCache();
                        }
                    }
                    else
                    {
                        vertexIndex += 4;
                    }
                }
            }
        }