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); }
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 }