public bool GetDisplacement(float x, float z, out Vector3F displacement, out Vector3F normal) { if (!EnableCpuQueries) { throw new InvalidOperationException("OceanWaves.GetDisplacement() can only be called if EnableCpuQueries is set to true."); } displacement = new Vector3F(0); normal = new Vector3F(0, 1, 0); if (_h == null) { return(false); } float texCoordX = (x - TileCenter.X) / TileSize + 0.5f; float texCoordY = (z - TileCenter.Z) / TileSize + 0.5f; // Point sampling or bilinear filtering: #if false // Convert to array indices. int xIndex = Wrap((int)(texCoordX * CpuSize)); int yIndex = Wrap((int)(texCoordY * CpuSize)); float h = _h[xIndex, yIndex].X; Vector2F d = _D[xIndex, yIndex]; Vector2F n = _N[xIndex, yIndex]; #else // Sample 4 values. The upper left index is (without wrapping): float xIndex = texCoordX * CpuSize - 0.5f; float yIndex = texCoordY * CpuSize - 0.5f; // Get the 4 indices. int x0 = Wrap((int)xIndex); int x1 = Wrap((int)xIndex + 1); int y0 = Wrap((int)yIndex); int y1 = Wrap((int)yIndex + 1); // Get fractions to use as lerp parameters. float px = MathHelper.Frac(xIndex); float py = MathHelper.Frac(yIndex); float h = InterpolationHelper.Lerp(InterpolationHelper.Lerp(_h[x0, y0].X, _h[x1, y0].X, px), InterpolationHelper.Lerp(_h[x0, y1].X, _h[x1, y1].X, px), py); Vector2F d = InterpolationHelper.Lerp(InterpolationHelper.Lerp(_D[x0, y0], _D[x1, y0], px), InterpolationHelper.Lerp(_D[x0, y1], _D[x1, y1], px), py); Vector2F n = InterpolationHelper.Lerp(InterpolationHelper.Lerp(_N[x0, y0], _N[x1, y0], px), InterpolationHelper.Lerp(_N[x0, y1], _N[x1, y1], px), py); #endif displacement = new Vector3F(-d.X * Choppiness, h, -d.Y * Choppiness); normal = new Vector3F(-n.X, 0, -n.Y); normal.Y = (float)Math.Sqrt(1 - normal.X * normal.X - normal.Y * normal.Y); return(true); }