Пример #1
0
        public bool SetResolveMode(bool resolveByFFT, int resolution)
        {
            if (this.resolveByFFT != resolveByFFT || (this.resolveByFFT && this.resolutionFFT != resolution))
            {
                if (resolveByFFT)
                {
                    lock (this)
                    {
                        this.resolutionFFT = resolution;
                        this.mipIndexFFT   = WaterWavesSpectrumData.GetMipIndex(resolution);
                        int resolutionSquared = resolution * resolution;
                        directionalSpectrum      = new Vector2[resolutionSquared];
                        displacements            = new Vector2[4][];
                        forceAndHeight           = new vector4[4][];
                        resultsTiming            = new float[4];
                        directionalSpectrumDirty = 2;
                        cachedTime = float.NegativeInfinity;

                        for (int i = 0; i < 4; ++i)
                        {
                            displacements[i]  = new Vector2[resolutionSquared];
                            forceAndHeight[i] = new vector4[resolutionSquared];
                        }

                        if (this.resolveByFFT == false)
                        {
                            WaterAsynchronousTasks.Instance.AddFFTComputations(this);
                            this.resolveByFFT = true;
                        }
                    }
                }
                else
                {
                    WaterAsynchronousTasks.Instance.RemoveFFTComputations(this);
                    this.resolveByFFT = false;
                }

                return(true);
            }

            return(false);
        }
Пример #2
0
        public Vector4 GetForceAndHeightAt(float x, float z, float spectrumStart, float spectrumEnd, float time)
        {
            vector4 result = new vector4();

            x = -(x + surfaceOffset.x);
            z = -(z + surfaceOffset.y);

            // sample FFT results
            if (spectrumStart == 0.0f)
            {
                for (int scaleIndex = numTiles - 1; scaleIndex >= 0; --scaleIndex)
                {
                    if (tileSpectra[scaleIndex].resolveByFFT)
                    {
                        float     fx, invFx, fy, invFy, t; int index0, index1, index2, index3;
                        Vector2[] da, db; vector4[] fa, fb;

                        lock (tileSpectra[scaleIndex])
                        {
                            InterpolationParams(x, z, scaleIndex, windWaves.TileSizes[scaleIndex], out fx, out invFx, out fy, out invFy, out index0, out index1, out index2, out index3);
                            tileSpectra[scaleIndex].GetResults(time, out da, out db, out fa, out fb, out t);
                        }

                        result += FastMath.Interpolate(
                            fa[index0], fa[index1], fa[index2], fa[index3],
                            fb[index0], fb[index1], fb[index2], fb[index3],
                            fx, invFx, fy, invFy, t
                            );
                    }
                }
            }

            // sample waves directly
            if (filteredCpuWavesCount != 0)
            {
                SampleWavesDirectly(spectrumStart, spectrumEnd, (cpuWaves, startIndex, endIndex) =>
                {
                    Vector4 subResult = new Vector4();

                    for (int i = startIndex; i < endIndex; ++i)
                    {
                        cpuWaves[i].GetForceAndHeightAt(x, z, time, ref subResult);
                    }

#if WATER_SIMD
                    result += new vector4(subResult.x, subResult.y, subResult.z, subResult.w);
#else
                    result += subResult;
#endif
                });
            }

            float horizontalScale = water.HorizontalDisplacementScale * uniformWaterScale;

#if WATER_SIMD
            return(new Vector4(result.X * horizontalScale, result.Y * 0.5f, result.Z * horizontalScale, result.W));
#else
            result.x  = result.x * horizontalScale;
            result.z  = result.z * horizontalScale;
            result.y *= 0.5f * uniformWaterScale;
            result.w *= uniformWaterScale;                          // not 100% sure about this

            return(result);
#endif
        }