public bool Spawn(WaveParticle particle) { if (particle != null) { particle.group = new WaveParticlesGroup(simulationTime); particle.group.leftParticle = particle; return(particles.AddElement(particle)); } else { return(false); } }
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; } } }
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; } } } }