Exemplo n.º 1
0
        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);
        }
Exemplo n.º 2
0
        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;
        }
Exemplo n.º 3
0
		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;
		}
Exemplo n.º 4
0
        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;
        }
Exemplo n.º 5
0
        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;
        }
Exemplo n.º 6
0
        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);
        }
Exemplo n.º 7
0
Arquivo: ADT.cs Projeto: primax/WCell
		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;
		}