public Vector3 GetSurfaceNormal(Point2D chunkCoord, Point2D unitCoord, HeightMapFraction heightMapFraction) { if (Chunks == null) { return(Vector3.Zero); } var chunk = Chunks[chunkCoord.X, chunkCoord.Y]; if (chunk == null) { return(Vector3.Zero); } if (chunk.HolesMap[unitCoord.X / 2, unitCoord.Y / 2]) { return(Vector3.Zero); } if (chunk.IsFlat) { return(Vector3.Up); } var outerHeights = chunk.Heights.GetLowResMapMatrix(); var innerHeights = chunk.Heights.GetHighResMapMatrix(); var v12 = new Vector3(0.5f, 0.5f, innerHeights[unitCoord.X, unitCoord.Y]); var x = heightMapFraction.FractionX; var y = heightMapFraction.FractionY; Vector3 a, b; if (y < x) { if (y < (1.0f - x)) { // Upper triangle <h00, h01, h12> var v00 = new Vector3(0.0f, 0.0f, outerHeights[unitCoord.X, unitCoord.Y]); var v01 = new Vector3(0.0f, 1.0f, outerHeights[unitCoord.X + 1, unitCoord.Y]); a = v00 - v12; b = v01 - v12; } else { // Right triangle <h01, h11, h12> var v01 = new Vector3(0.0f, 1.0f, outerHeights[unitCoord.X + 1, unitCoord.Y]); var v11 = new Vector3(1.0f, 1.0f, outerHeights[unitCoord.X + 1, unitCoord.Y + 1]); a = v01 - v12; b = v11 - v12; } } else { if (y < (1.0f - x)) { // Left triangle <h10, h00, h12> var v10 = new Vector3(1.0f, 0.0f, outerHeights[unitCoord.X + 1, unitCoord.Y]); var v00 = new Vector3(0.0f, 0.0f, outerHeights[unitCoord.Y, unitCoord.Y]); a = v10 - v12; b = v00 - v12; } else { // Bottom triangle <h11, h10, h12> var v11 = new Vector3(1.0f, 1.0f, outerHeights[unitCoord.Y + 1, unitCoord.Y + 1]); var v10 = new Vector3(1.0f, 0.0f, outerHeights[unitCoord.X + 1, unitCoord.Y]); a = v11 - v12; b = v10 - v12; } } var nml = Vector3.Cross(b, a); nml.Normalize(); return(nml); }
public float GetInterpolatedHeight(Point2D chunkCoord, Point2D unitCoord, HeightMapFraction heightMapFraction) { // Height stored as: h5 - its v8 grid, h1-h4 - its v9 grid // h00------h01 Coordinates are: // | \ / | h00 0,0 // | \ 1 / | h01 0,1 // | \ / | // | 4 h12 2 | h10 1,0 // | / \ | h11 1,1 // | / 3 \ | h12 1/2,1/2 // | / \ | // h10------h11 if (Chunks == null) { return(float.NaN); } var chunk = Chunks[chunkCoord.X, chunkCoord.Y]; if (chunk == null) { return(float.NaN); } if (chunk.HolesMap[unitCoord.X / 2, unitCoord.Y / 2]) { return(float.NaN); } var medianHeight = chunk.MedianHeight; if (chunk.IsFlat) { return(medianHeight); } // Using simplified Barycentric Coordinate coordinates, this actually becomes quite simple. var outerHeights = chunk.Heights.GetLowResMapMatrix(); var innerHeights = chunk.Heights.GetHighResMapMatrix(); var h12 = innerHeights[unitCoord.X, unitCoord.Y]; var x = heightMapFraction.FractionX; var y = heightMapFraction.FractionY; float heightOffset; if (y < x) { if (y < (1.0f - x)) { // Upper triangle <h00, h01, h12> var h00 = outerHeights[unitCoord.X, unitCoord.Y]; var h01 = outerHeights[unitCoord.X + 1, unitCoord.Y]; var alpha = 1 - x - y; var beta = (y - x); var gamma = 1.0f - alpha - beta; heightOffset = (alpha * h00 + beta * h01 + gamma * h12); } else { // Right triangle <h01, h11, h12> var h01 = outerHeights[unitCoord.X + 1, unitCoord.Y]; var h11 = outerHeights[unitCoord.X + 1, unitCoord.Y + 1]; var alpha = (y - x); var beta = (x + y - 1.0f); var gamma = 1.0f - alpha - beta; heightOffset = (alpha * h01 + beta * h11 + gamma * h12); } } else { if (y < (1.0f - x)) { // Left triangle <h10, h00, h12> var h10 = outerHeights[unitCoord.X + 1, unitCoord.Y]; var h00 = outerHeights[unitCoord.X, unitCoord.Y]; var alpha = x - y; var beta = 1.0f - x - y; var gamma = 1.0f - alpha - beta; heightOffset = (alpha * h10 + beta * h00 + gamma * h12); } else { // Bottom triangle <h11, h10, h12> var h11 = outerHeights[unitCoord.X + 1, unitCoord.Y + 1]; var h10 = outerHeights[unitCoord.X + 1, unitCoord.Y]; var alpha = (x + y - 1.0f); var beta = x - y; var gamma = 1.0f - alpha - beta; heightOffset = (alpha * h11 + beta * h10 + gamma * h12); } } return(medianHeight + heightOffset); //// Fixme: Indexing is backwards. //var heightX = (unitCoord.Y == TerrainConstants.UnitsPerChunkSide) // ? (TerrainConstants.UnitsPerChunkSide - 1) // : unitCoord.Y; //var heightY = (unitCoord.X == TerrainConstants.UnitsPerChunkSide) // ? (TerrainConstants.UnitsPerChunkSide - 1) // : unitCoord.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 h1 = chunk.OuterHeightDiff[heightX, heightY]; // var h2 = chunk.OuterHeightDiff[heightX, heightY + 1]; // var h3 = chunk.OuterHeightDiff[heightX + 1, heightY]; // var h5 = chunk.InnerHeightDiff[heightX, heightY]; // 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 h1 = chunk.OuterHeightDiff[heightX, heightY]; // var h3 = chunk.OuterHeightDiff[heightX + 1, heightY]; // var h4 = chunk.OuterHeightDiff[heightX + 1, heightY + 1]; // var h5 = chunk.InnerHeightDiff[heightX, heightY]; // 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 h1 = chunk.OuterHeightDiff[heightX, heightY]; // var h2 = chunk.OuterHeightDiff[heightX, heightY + 1]; // var h4 = chunk.OuterHeightDiff[heightX + 1, heightY + 1]; // var h5 = chunk.InnerHeightDiff[heightX, heightY]; // 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 h2 = chunk.OuterHeightDiff[heightX, heightY + 1]; // var h3 = chunk.OuterHeightDiff[heightX + 1, heightY]; // var h4 = chunk.OuterHeightDiff[heightX + 1, heightY + 1]; // var h5 = chunk.InnerHeightDiff[heightX, heightY]; // 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; }
public float GetInterpolatedHeight(Point2D chunkCoord, Point2D unitCoord, HeightMapFraction heightMapFraction) { // Height stored as: h5 - its v8 grid, h1-h4 - its v9 grid // h00------h01 Coordinates are: // | \ / | h00 0,0 // | \ 1 / | h01 0,1 // | \ / | // | 4 h12 2 | h10 1,0 // | / \ | h11 1,1 // | / 3 \ | h12 1/2,1/2 // | / \ | // h10------h11 if (Chunks == null) return float.NaN; var chunk = Chunks[chunkCoord.X, chunkCoord.Y]; if (chunk == null) return float.NaN; if (chunk.HolesMap[unitCoord.X / 2, unitCoord.Y / 2]) return float.NaN; var medianHeight = chunk.MedianHeight; if (chunk.IsFlat) return medianHeight; // Using simplified Barycentric Coordinate coordinates, this actually becomes quite simple. var outerHeights = chunk.Heights.GetLowResMapMatrix(); var innerHeights = chunk.Heights.GetHighResMapMatrix(); var h12 = innerHeights[unitCoord.X, unitCoord.Y]; var x = heightMapFraction.FractionX; var y = heightMapFraction.FractionY; float heightOffset; if (y < x) { if (y < (1.0f - x)) { // Upper triangle <h00, h01, h12> var h00 = outerHeights[unitCoord.X, unitCoord.Y]; var h01 = outerHeights[unitCoord.X + 1, unitCoord.Y]; var alpha = 1 - x - y; var beta = (y - x); var gamma = 1.0f - alpha - beta; heightOffset = (alpha*h00 + beta*h01 + gamma*h12); } else { // Right triangle <h01, h11, h12> var h01 = outerHeights[unitCoord.X + 1, unitCoord.Y]; var h11 = outerHeights[unitCoord.X + 1, unitCoord.Y + 1]; var alpha = (y - x); var beta = (x + y - 1.0f); var gamma = 1.0f - alpha - beta; heightOffset = (alpha*h01 + beta*h11 + gamma*h12); } } else { if (y < (1.0f - x)) { // Left triangle <h10, h00, h12> var h10 = outerHeights[unitCoord.X + 1, unitCoord.Y]; var h00 = outerHeights[unitCoord.X, unitCoord.Y]; var alpha = x - y; var beta = 1.0f - x - y; var gamma = 1.0f - alpha - beta; heightOffset = (alpha*h10 + beta*h00 + gamma*h12); } else { // Bottom triangle <h11, h10, h12> var h11 = outerHeights[unitCoord.X + 1, unitCoord.Y + 1]; var h10 = outerHeights[unitCoord.X + 1, unitCoord.Y]; var alpha = (x + y - 1.0f); var beta = x - y; var gamma = 1.0f - alpha - beta; heightOffset = (alpha*h11 + beta*h10 + gamma*h12); } } return medianHeight + heightOffset; //// Fixme: Indexing is backwards. //var heightX = (unitCoord.Y == TerrainConstants.UnitsPerChunkSide) // ? (TerrainConstants.UnitsPerChunkSide - 1) // : unitCoord.Y; //var heightY = (unitCoord.X == TerrainConstants.UnitsPerChunkSide) // ? (TerrainConstants.UnitsPerChunkSide - 1) // : unitCoord.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 h1 = chunk.OuterHeightDiff[heightX, heightY]; // var h2 = chunk.OuterHeightDiff[heightX, heightY + 1]; // var h3 = chunk.OuterHeightDiff[heightX + 1, heightY]; // var h5 = chunk.InnerHeightDiff[heightX, heightY]; // 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 h1 = chunk.OuterHeightDiff[heightX, heightY]; // var h3 = chunk.OuterHeightDiff[heightX + 1, heightY]; // var h4 = chunk.OuterHeightDiff[heightX + 1, heightY + 1]; // var h5 = chunk.InnerHeightDiff[heightX, heightY]; // 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 h1 = chunk.OuterHeightDiff[heightX, heightY]; // var h2 = chunk.OuterHeightDiff[heightX, heightY + 1]; // var h4 = chunk.OuterHeightDiff[heightX + 1, heightY + 1]; // var h5 = chunk.InnerHeightDiff[heightX, heightY]; // 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 h2 = chunk.OuterHeightDiff[heightX, heightY + 1]; // var h3 = chunk.OuterHeightDiff[heightX + 1, heightY]; // var h4 = chunk.OuterHeightDiff[heightX + 1, heightY + 1]; // var h5 = chunk.InnerHeightDiff[heightX, heightY]; // 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; }
public Vector3 GetSurfaceNormal(Point2D chunkCoord, Point2D unitCoord, HeightMapFraction heightMapFraction) { if (Chunks == null) return Vector3.Zero; var chunk = Chunks[chunkCoord.X, chunkCoord.Y]; if (chunk == null) return Vector3.Zero; if (chunk.HolesMap[unitCoord.X / 2, unitCoord.Y / 2]) return Vector3.Zero; if (chunk.IsFlat) return Vector3.Up; var outerHeights = chunk.Heights.GetLowResMapMatrix(); var innerHeights = chunk.Heights.GetHighResMapMatrix(); var v12 = new Vector3(0.5f, 0.5f, innerHeights[unitCoord.X, unitCoord.Y]); var x = heightMapFraction.FractionX; var y = heightMapFraction.FractionY; Vector3 a,b; if (y < x) { if (y < (1.0f - x)) { // Upper triangle <h00, h01, h12> var v00 = new Vector3(0.0f, 0.0f, outerHeights[unitCoord.X, unitCoord.Y]); var v01 = new Vector3(0.0f, 1.0f, outerHeights[unitCoord.X + 1, unitCoord.Y]); a = v00 - v12; b = v01 - v12; } else { // Right triangle <h01, h11, h12> var v01 = new Vector3(0.0f, 1.0f, outerHeights[unitCoord.X + 1, unitCoord.Y]); var v11 = new Vector3(1.0f, 1.0f, outerHeights[unitCoord.X + 1, unitCoord.Y + 1]); a = v01 - v12; b = v11 - v12; } } else { if (y < (1.0f - x)) { // Left triangle <h10, h00, h12> var v10 = new Vector3(1.0f, 0.0f, outerHeights[unitCoord.X + 1, unitCoord.Y]); var v00 = new Vector3(0.0f, 0.0f, outerHeights[unitCoord.Y, unitCoord.Y]); a = v10 - v12; b = v00 - v12; } else { // Bottom triangle <h11, h10, h12> var v11 = new Vector3(1.0f, 1.0f, outerHeights[unitCoord.Y + 1, unitCoord.Y + 1]); var v10 = new Vector3(1.0f, 0.0f, outerHeights[unitCoord.X + 1, unitCoord.Y]); a = v11 - v12; b = v10 - v12; } } var nml = Vector3.Cross(b, a); nml.Normalize(); return nml; }
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; }
private static float InterpolateTriangle(ref Vector3 point1, ref Vector3 point2, ref Vector3 point3, HeightMapFraction heightMapFraction) { var Ax = point2.X - point1.X; var Ay = point2.Y - point1.Y; var Az = point2.Z - point1.Z; var Bx = point3.X - point1.X; var By = point3.Y - point1.Y; var Bz = point3.Z - point1.Z; var Nnx = (Ay * Bz) - (Az * By); var Nny = (Az * Bx) - (Ax * Bz); var Nnz = (Ax * By) - (Ay * Bx); var Nnsquared = ((Nnx * Nnx) + (Nny * Nny)) + (Nnz * Nnz); var length = 1f / ((float)Math.Sqrt(Nnsquared)); var Nx = Nnx * length; var Ny = Nny * length; var Nz = Nnz * length; var D = (Nx * point1.X) + (Ny * point1.Y) + (Nz * point1.Z); var temp = D - (Nx * heightMapFraction.FractionX) - (Ny * heightMapFraction.FractionY); return (temp / Nz); }
public float GetInterpolatedHeight(Point2D chunkCoord, Point2D unitCoord, 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 (Chunks == null) return float.NaN; var chunk = Chunks[chunkCoord.X, chunkCoord.Y]; if (chunk == null) return float.NaN; var medianHeight = chunk.MedianHeight; if (chunk.IsFlat) return medianHeight; // TODO: Fix interpolated height return medianHeight; //// Fixme: Indexing is backwards. //var heightX = (unitCoord.Y == TerrainConstants.UnitsPerChunkSide) // ? (TerrainConstants.UnitsPerChunkSide - 1) // : unitCoord.Y; //var heightY = (unitCoord.X == TerrainConstants.UnitsPerChunkSide) // ? (TerrainConstants.UnitsPerChunkSide - 1) // : unitCoord.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 h1 = chunk.OuterHeightDiff[heightX, heightY]; // var h2 = chunk.OuterHeightDiff[heightX, heightY + 1]; // var h3 = chunk.OuterHeightDiff[heightX + 1, heightY]; // var h5 = chunk.InnerHeightDiff[heightX, heightY]; // 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 h1 = chunk.OuterHeightDiff[heightX, heightY]; // var h3 = chunk.OuterHeightDiff[heightX + 1, heightY]; // var h4 = chunk.OuterHeightDiff[heightX + 1, heightY + 1]; // var h5 = chunk.InnerHeightDiff[heightX, heightY]; // 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 h1 = chunk.OuterHeightDiff[heightX, heightY]; // var h2 = chunk.OuterHeightDiff[heightX, heightY + 1]; // var h4 = chunk.OuterHeightDiff[heightX + 1, heightY + 1]; // var h5 = chunk.InnerHeightDiff[heightX, heightY]; // 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 h2 = chunk.OuterHeightDiff[heightX, heightY + 1]; // var h3 = chunk.OuterHeightDiff[heightX + 1, heightY]; // var h4 = chunk.OuterHeightDiff[heightX + 1, heightY + 1]; // var h5 = chunk.InnerHeightDiff[heightX, heightY]; // 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; }