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);
            }
        }
Exemple #4
0
        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;
            }
        }