Exemplo n.º 1
0
        static private DepthSlice MakeBaseDepthSlice(Heightmap heightmap)
        {
            RawDepthData rawDepthData = GetRawDepthData(heightmap, 0, heightmap.StartX - 1, heightmap.Width + 2); // <- Guarantuee missing ranges on each end (for extrapolation)

            if (rawDepthData.IsBlank)
            {
                return(DepthSlice.CreateBlank(heightmap.StartX, heightmap.StartZ));
            }

            // Fill in missing data and do extrapolation:
            rawDepthData.RepairMissingRanges();
            int dataStart = rawDepthData.missingDataRanges[0].index + rawDepthData.missingDataRanges[0].count;
            int dataEnd   = rawDepthData.missingDataRanges[rawDepthData.missingDataRanges.Count - 1].index;

            // Bring extrapolations into the legitimate data range:
            if (rawDepthData.depthFront[dataStart - 1] == rawDepthData.depthBack[dataStart - 1])
            {
                dataStart--;
            }
            if (rawDepthData.depthFront[dataEnd] == rawDepthData.depthBack[dataEnd])
            {
                dataEnd++;
            }


            return(PackDepthSlice(ref rawDepthData, dataStart, dataEnd));
        }
Exemplo n.º 2
0
        private static DepthSlice PackDepthSlice(ref RawDepthData rawDepthData, int dataStart, int dataEnd)
        {
            DepthSlice depthSlice = new DepthSlice();

            depthSlice.xOffset = rawDepthData.startX + dataStart;

            depthSlice.zOffset = int.MaxValue;
            for (int i = dataStart; i < dataEnd; i++)
            {
                Debug.Assert(rawDepthData.depthFront[i] <= rawDepthData.depthBack[i]);
                Debug.Assert(rawDepthData.depthBack[i] != int.MinValue);

                if (rawDepthData.depthFront[i] < depthSlice.zOffset)
                {
                    depthSlice.zOffset = rawDepthData.depthFront[i];
                }
            }

            depthSlice.depths = new FrontBack[dataEnd - dataStart];
            for (int i = 0; i < depthSlice.depths.Length; i++)
            {
                depthSlice.depths[i].front = (byte)System.Math.Min(byte.MaxValue, rawDepthData.depthFront[i + dataStart] - depthSlice.zOffset);
                depthSlice.depths[i].back  = (byte)System.Math.Min(byte.MaxValue, rawDepthData.depthBack[i + dataStart] - depthSlice.zOffset);
            }

            return(depthSlice);
        }
Exemplo n.º 3
0
        static DepthSlice MakeNonBaseDepthSlice(Heightmap heightmap, int yOffset, DepthSlice previousSlice)
        {
            Debug.Assert(yOffset != 0);
            Debug.Assert(previousSlice != null);

            RawDepthData rawDepthData = GetRawDepthData(heightmap, yOffset, previousSlice.xOffset, previousSlice.Width);

            if (rawDepthData.IsBlank)
            {
                return(DepthSlice.CreateBlank(previousSlice.xOffset, previousSlice.zOffset));
            }

            DepthSlice depthSlice = PackDepthSlice(ref rawDepthData, 0, previousSlice.Width);

            // Pull up missing data from previous layers:
            foreach (var missingRange in rawDepthData.missingDataRanges)
            {
                for (int j = 0; j < missingRange.count; j++)
                {
                    int i           = j + missingRange.index;
                    var belowBounds = previousSlice.depths[i];

                    if (belowBounds.front == belowBounds.back && missingRange.count == 1) // <- Indicates the lower layer is an extrapolation (keep it that way)
                    {
                        depthSlice.depths[i] = belowBounds;
                    }
                    else // Lower bounds is a surface, encode an "above" bounds
                    {
                        depthSlice.depths[i] = new FrontBack {
                            back = belowBounds.back, front = (byte)System.Math.Min(byte.MaxValue, (int)belowBounds.back + 1)
                        }
                    };
                }
            }

            return(depthSlice);
        }

        #endregion
    }
Exemplo n.º 4
0
        static RawDepthData GetRawDepthData(Heightmap heightmap, int yOffset, int startX, int width)
        {
            RawDepthData output = new RawDepthData(startX, width);

            // Now walk left-to-right, finding front and back depth bounds,
            // as well as ranges where the heightmap has no data:
            int endOfLastDataIndex = 0;

            for (int i = 0; i < width; i++)
            {
                int x = i + startX;

                if (x >= heightmap.StartX && x < heightmap.EndX)
                {
                    // Walk back to find front of heightmap for this column, at the given height
                    int front = heightmap.StartZ; // <- front is an inclusive bound
                    while (true)
                    {
                        if (front >= heightmap.EndZ)
                        {
                            goto skipColumn; // no data
                        }
                        if (heightmap[x, front] > yOffset)
                        {
                            break;
                        }
                        front++;
                    }

                    // Walk forward to find the back of the heightmap
                    int back = heightmap.EndZ; // <- back is an exclusive bound
                    while (true)
                    {
                        Debug.Assert(back > front); // <- if this fires, there's a bug in the algorithm (or heightmap misbehaved)
                        if (heightmap[x, back - 1] > yOffset)
                        {
                            break;
                        }
                        back--;
                    }

                    // Note any missing data up to here:
                    Debug.Assert(endOfLastDataIndex <= i);
                    if (endOfLastDataIndex != i)
                    {
                        output.missingDataRanges.Add(new DataRange {
                            index = endOfLastDataIndex, count = (i - endOfLastDataIndex)
                        });
                    }
                    endOfLastDataIndex = i + 1;

                    // Save the bounds:
                    output.depthFront[i] = front;
                    output.depthBack[i]  = back;
                }

skipColumn:
                ;
            }

            if (endOfLastDataIndex != width)
            {
                output.missingDataRanges.Add(new DataRange {
                    index = endOfLastDataIndex, count = (width - endOfLastDataIndex)
                });
            }

            return(output);
        }