public FoundWave(WaterWavesSpectrumData spectrum, WaterWave wave) { this.spectrum = spectrum; this.wave = wave; importance = wave.cpuPriority * spectrum.Weight; }
private void FindCpuWaves() { if (cpuWaves == null) { cpuWaves = new WaterWave[4][][]; } for (int i = 0; i < 4; ++i) { if (cpuWaves[i] == null) { cpuWaves[i] = new WaterWave[displayResolutionIndex + 1][]; } } int resolution = windWaves.FinalResolution; int halfResolution = resolution >> 1; int cpuMaxWaves = windWaves.CpuMaxWaves; float cpuWaveThreshold = windWaves.CpuWaveThreshold; Vector4 tileSizeScales = windWaves.TileSizeScales; var shorelineCandidatesHeap = new Heap <WaterWave>(); var importantWaves = new List <WaterWave> [displayResolutionIndex + 1]; for (int i = 0; i <= displayResolutionIndex; ++i) { importantWaves[i] = new List <WaterWave>(); } for (byte scaleIndex = 0; scaleIndex < 4; ++scaleIndex) { float tileSize = spectrum.TileSize * tileSizeScales[scaleIndex]; Vector3[,] localValues = spectrumValues[displayResolutionIndex][scaleIndex]; float frequencyScale = 2.0f * Mathf.PI / tileSize; float gravity = spectrum.Gravity; float offsetX = tileSize + (0.5f / resolution) * tileSize; float offsetZ = -tileSize + (0.5f / resolution) * tileSize; for (int x = 0; x < resolution; ++x) { float kx = frequencyScale * (x - halfResolution); ushort u = (ushort)((x + halfResolution) % resolution); for (int y = 0; y < resolution; ++y) { float ky = frequencyScale * (y - halfResolution); ushort v = (ushort)((y + halfResolution) % resolution); Vector3 s = localValues[u, v]; float amplitude = Mathf.Sqrt(s.x * s.x + s.y * s.y); float k = Mathf.Sqrt(kx * kx + ky * ky); float w = Mathf.Sqrt(gravity * k); float cpuPriority = amplitude; if (cpuPriority < 0) { cpuPriority = -cpuPriority; } totalAmplitude += amplitude; if (amplitude >= cpuWaveThreshold) { int mipIndex = GetMipIndex(Mathf.Max(Mathf.Min(u, resolution - u - 1), Mathf.Min(v, resolution - v - 1))); importantWaves[mipIndex].Add(new WaterWave(scaleIndex, offsetX, offsetZ, u, v, kx, ky, k, w, amplitude, cpuPriority)); } if (amplitude > 0.025f) { float shorelinePriority = k / amplitude; // it's used in a max-heap, so this is an inverse of a real priority shorelineCandidatesHeap.Insert(new WaterWave(scaleIndex, offsetX, offsetZ, u, v, kx, ky, k, w, amplitude, shorelinePriority)); if (shorelineCandidatesHeap.Count > 200) { shorelineCandidatesHeap.ExtractMax(); } } } } lock (cpuWaves) { for (int mipIndex = 0; mipIndex <= displayResolutionIndex; ++mipIndex) { cpuWaves[scaleIndex][mipIndex] = importantWaves[mipIndex].ToArray(); importantWaves[mipIndex].Clear(); SortCpuWaves(cpuWaves[scaleIndex][mipIndex], false); if (cpuWaves[scaleIndex][mipIndex].Length > windWaves.CpuMaxWaves) { System.Array.Resize(ref cpuWaves[scaleIndex][mipIndex], cpuMaxWaves); } } } } shorelineCandidates = shorelineCandidatesHeap.ToArray(); System.Array.Sort(shorelineCandidates); }