internal float GetInterpolatedHeight(ChunkCoord chunkCoord, PointX2D coord, HeightMapFraction heightMapFraction) { // Height stored as: h5 - its v8 grid, h1-h4 - its v9 grid // +--------------> X // | h1--------h2 Coordinates are: // | | | | h1 0,0 // | | 1 | 2 | h2 0,1 // | |----h5---| h3 1,0 // | | 3 | 4 | h4 1,1 // | | | | h5 1/2,1/2 // | h3--------h4 // V Y if (HeightMaps == null) return float.NaN; var heightMap = HeightMaps[chunkCoord.ChunkX, chunkCoord.ChunkY]; if (heightMap == null) return float.NaN; var medianHeight = HalfUtils.Unpack(heightMap.MedianHeight); if (heightMap.IsFlat) return medianHeight; // Fixme: Indexing is backwards. var heightX = (coord.Y == TerrainConstants.UnitsPerChunkSide) ? (TerrainConstants.UnitsPerChunkSide - 1) : coord.Y; var heightY = (coord.X == TerrainConstants.UnitsPerChunkSide) ? (TerrainConstants.UnitsPerChunkSide - 1) : coord.X; // Determine what quad we're in var xf = heightMapFraction.FractionX; var yf = heightMapFraction.FractionY; float topLeft, topRight, bottomLeft, bottomRight; if (xf < 0.5f) { if (yf < 0.5) { // Calc the #1 quad // +--------------> X // | h1--------h2 Coordinates are: // | | | | h1 0,0 // | | 1 | | h2 0,1 // | |----h5---| h3 1,0 // | | | | h4 1,1 // | | | | h5 1/2,1/2 // | h3--------h4 // V Y var packed1 = heightMap.OuterHeightDiff[heightX, heightY]; var packed2 = heightMap.OuterHeightDiff[heightX, heightY + 1]; var packed3 = heightMap.OuterHeightDiff[heightX + 1, heightY]; var packed5 = heightMap.InnerHeightDiff[heightX, heightY]; var h1 = HalfUtils.Unpack(packed1); var h2 = HalfUtils.Unpack(packed2); var h3 = HalfUtils.Unpack(packed3); var h5 = HalfUtils.Unpack(packed5); topLeft = h1; topRight = (h1 + h2)/2.0f; bottomLeft = (h1 + h3)/2.0f; bottomRight = h5; } else { // Calc the #3 quad // +--------------> X // | h1--------h2 Coordinates are: // | | | | h1 0,0 // | | | | h2 0,1 // | |----h5---| h3 1,0 // | | 3 | | h4 1,1 // | | | | h5 1/2,1/2 // | h3--------h4 // V Y var packed1 = heightMap.OuterHeightDiff[heightX, heightY]; var packed3 = heightMap.OuterHeightDiff[heightX + 1, heightY]; var packed4 = heightMap.OuterHeightDiff[heightX + 1, heightY + 1]; var packed5 = heightMap.InnerHeightDiff[heightX, heightY]; var h1 = HalfUtils.Unpack(packed1); var h3 = HalfUtils.Unpack(packed3); var h4 = HalfUtils.Unpack(packed4); var h5 = HalfUtils.Unpack(packed5); topLeft = (h1 + h3) / 2.0f; topRight = h5; bottomLeft = h3; bottomRight = (h3 + h4) / 2.0f; yf -= 0.5f; } } else { if (yf < 0.5) { // Calc the #2 quad // +--------------> X // | h1--------h2 Coordinates are: // | | | | h1 0,0 // | | | 2 | h2 0,1 // | |----h5---| h3 1,0 // | | | | h4 1,1 // | | | | h5 1/2,1/2 // | h3--------h4 // V Y var packed1 = heightMap.OuterHeightDiff[heightX, heightY]; var packed2 = heightMap.OuterHeightDiff[heightX, heightY + 1]; var packed4 = heightMap.OuterHeightDiff[heightX + 1, heightY + 1]; var packed5 = heightMap.InnerHeightDiff[heightX, heightY]; var h1 = HalfUtils.Unpack(packed1); var h2 = HalfUtils.Unpack(packed2); var h4 = HalfUtils.Unpack(packed4); var h5 = HalfUtils.Unpack(packed5); topLeft = (h1 + h2) / 2.0f; topRight = h2; bottomLeft = h5; bottomRight = (h2 + h4) / 2.0f; xf -= 0.5f; } else { // Calc the #4 quad // +--------------> X // | h1--------h2 Coordinates are: // | | | | h1 0,0 // | | | | h2 0,1 // | |----h5---| h3 1,0 // | | | 4 | h4 1,1 // | | | | h5 1/2,1/2 // | h3--------h4 // V Y var packed2 = heightMap.OuterHeightDiff[heightX, heightY + 1]; var packed3 = heightMap.OuterHeightDiff[heightX + 1, heightY]; var packed4 = heightMap.OuterHeightDiff[heightX + 1, heightY + 1]; var packed5 = heightMap.InnerHeightDiff[heightX, heightY]; var h2 = HalfUtils.Unpack(packed2); var h3 = HalfUtils.Unpack(packed3); var h4 = HalfUtils.Unpack(packed4); var h5 = HalfUtils.Unpack(packed5); topLeft = h5; topRight = (h2 + h4) / 2.0f; bottomLeft = (h3 + h4) / 2.0f; bottomRight = h4; xf -= 0.5f; yf -= 0.5f; } } //var heightDiff = InterpolateTriangle(ref vec1, ref vec2, ref vec3, heightMapFraction); var heightDiff = BilinearInterpolate(ref topLeft, ref topRight, ref bottomLeft, ref bottomRight, ref xf, ref yf); return medianHeight + heightDiff; }
internal float GetLiquidHeight(ChunkCoord chunkCoord, PointX2D pointX2D) { if (!LiquidProfile[chunkCoord.ChunkX, chunkCoord.ChunkY]) return float.MinValue; var heightMap = HeightMaps[chunkCoord.ChunkX, chunkCoord.ChunkY]; var liquidHeights = heightMap.LiquidHeight; return (liquidHeights == null) ? float.MinValue : liquidHeights[pointX2D.X, pointX2D.Y]; }