public void AddFFTComputations(WaterTileSpectrum scale) { lock (fftSpectra) { fftSpectra.Add(scale); } }
private void CreateSpectraLevels() { this.tileSpectra = new WaterTileSpectrum[numTiles]; for (int scaleIndex = 0; scaleIndex < numTiles; ++scaleIndex) { tileSpectra[scaleIndex] = new WaterTileSpectrum(windWaves, scaleIndex); } }
public void RemoveFFTComputations(WaterTileSpectrum scale) { lock (fftSpectra) { int index = fftSpectra.IndexOf(scale); if (index == -1) { return; } if (index < fftSpectrumIndex) { --fftSpectrumIndex; } fftSpectra.RemoveAt(index); } }
public void Compute(WaterTileSpectrum targetSpectrum, float time, int outputBufferIndex) { this.targetSpectrum = targetSpectrum; this.time = time; Vector2[] displacements; vector4[] forceAndHeight; Vector2[] directionalSpectrum; lock (targetSpectrum) { this.resolution = targetSpectrum.ResolutionFFT; directionalSpectrum = targetSpectrum.directionalSpectrum; displacements = targetSpectrum.displacements[outputBufferIndex]; forceAndHeight = targetSpectrum.forceAndHeight[outputBufferIndex]; } FFTBuffers buffers; if (!buffersCache.TryGetValue(resolution, out buffers)) { buffersCache[resolution] = buffers = new FFTBuffers(resolution); } float tileSize = targetSpectrum.windWaves.UnscaledTileSizes[targetSpectrum.tileIndex]; Vector3[] kMap = buffers.GetPrecomputedK(tileSize); if (targetSpectrum.directionalSpectrumDirty > 0) { ComputeDirectionalSpectra(targetSpectrum.tileIndex, directionalSpectrum, kMap); --targetSpectrum.directionalSpectrumDirty; } ComputeTimedSpectra(directionalSpectrum, buffers.timed, kMap); ComputeFFT(buffers.timed, displacements, forceAndHeight, buffers.indices, buffers.weights, buffers.pingPongA, buffers.pingPongB); }
private void RunFFTTask() { try { var fftTask = new CpuFFT(); Stopwatch stopwatch = new Stopwatch(); bool performanceProblems = false; while (run) { WaterTileSpectrum spectrum = null; lock (fftSpectra) { if (fftSpectra.Count != 0) { if (fftSpectrumIndex >= fftSpectra.Count) { fftSpectrumIndex = 0; } if (fftSpectrumIndex == 0) { if (stopwatch.ElapsedMilliseconds > fftTimeStep * 900.0f) { if (performanceProblems) { fftTimeStep += 0.05f; } else { performanceProblems = true; } } else { performanceProblems = false; if (fftTimeStep > 0.2f) { fftTimeStep -= 0.001f; } } stopwatch.Reset(); stopwatch.Start(); } spectrum = fftSpectra[fftSpectrumIndex++]; } } if (spectrum == null) { stopwatch.Reset(); Thread.Sleep(6); continue; } bool didWork = false; //lock (spectrum) { var spectrumResolver = spectrum.windWaves.SpectrumResolver; if (spectrumResolver == null) { continue; } int recentResultIndex = spectrum.recentResultIndex; int slotIndexPlus2 = (recentResultIndex + 2) % spectrum.resultsTiming.Length; int slotIndexPlus1 = (recentResultIndex + 1) % spectrum.resultsTiming.Length; float recentSlotTime = spectrum.resultsTiming[recentResultIndex]; float slotPlus2Time = spectrum.resultsTiming[slotIndexPlus2]; float currentTime = spectrumResolver.LastFrameTime; if (slotPlus2Time <= currentTime) { float computedSnapshotTime = Mathf.Max(recentSlotTime, currentTime) + fftTimeStep; fftTask.Compute(spectrum, computedSnapshotTime, slotIndexPlus1); spectrum.resultsTiming[slotIndexPlus1] = computedSnapshotTime; spectrum.recentResultIndex = slotIndexPlus1; didWork = true; } } if (!didWork) { stopwatch.Reset(); Thread.Sleep(3); } } } catch (System.Exception e) { threadException = e; } }