Beispiel #1
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);
        }
Beispiel #2
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));
        }
Beispiel #3
0
        public static DepthBounds CreateForFlat(AnimationSet animationSet)
        {
            Debug.Assert(animationSet.Heightmap == null); // <- should be going through other path

            DepthSlice ds = new DepthSlice();

            ds.xOffset = animationSet.physicsStartX;
            ds.zOffset = animationSet.physicsStartZ;

            int width = animationSet.physicsEndX - animationSet.physicsStartX;

            ds.depths = new FrontBack[width];
            if (animationSet.flatDirection != 0)
            {
                for (int i = 0; i < width; i++)
                {
                    int depth = i;
                    if (animationSet.flatDirection == Oblique.Left)
                    {
                        depth = width - 1 - i;
                    }

                    byte d = (byte)System.Math.Min(byte.MaxValue, depth);
                    ds.depths[i].front = d;
                    ds.depths[i].back  = d;
                }
            }

            return(new DepthBounds {
                slices = new[] { ds }
            });                                               // <- single slice
        }
Beispiel #4
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
    }
Beispiel #5
0
        /// <summary>Deserialize.</summary>
        public DepthBounds(AnimationDeserializeContext context)
        {
            int heightCount = context.br.ReadInt32();

            heights = (heightCount == 0) ? null : context.br.ReadBytes(heightCount);

            slices = new DepthSlice[heightCount + 1];
            for (int i = 0; i < slices.Length; i++)
            {
                slices[i] = new DepthSlice()
                {
                    xOffset = context.br.ReadInt32(),
                    zOffset = context.br.ReadInt32(),
                    depths  = new FrontBack[context.br.ReadInt32()],
                };

                for (int j = 0; j < slices[i].depths.Length; j++)
                {
                    slices[i].depths[j].front = context.br.ReadByte();
                    slices[i].depths[j].back  = context.br.ReadByte();
                }
            }
        }
Beispiel #6
0
        public static DepthBounds CreateForHeightmap(Heightmap heightmap)
        {
            if (heightmap.heightmapData.Data == null) // <- Empty heightmap makes me sad
            {
                return(new DepthBounds());
            }
            if (!heightmap.IsObjectHeightmap) // <- Don't generate depth bounds for levels
            {
                return(new DepthBounds());
            }


            // Determine what heights are used in the heightmap, and only generate depth slices for those heights
            bool[] usedHeights = new bool[256];
            for (int i = 0; i < heightmap.heightmapData.Data.Length; i++)
            {
                usedHeights[heightmap.heightmapData.Data[i]] = true;
            }


            List <byte>       heights = new List <byte>();
            List <DepthSlice> slices  = new List <DepthSlice>();

            DepthSlice previousSlice  = null;
            int        previousHeight = 0;

            for (int y = 1; y < usedHeights.Length; y++)
            {
                if (!usedHeights[y])
                {
                    continue;
                }

                Debug.Assert(y - 1 <= byte.MaxValue);

                if (previousSlice == null)
                {
                    // First slice always starts at height = 0, and its starting height is implicit (not stored in heights):
                    Debug.Assert(slices.Count == 0);
                    slices.Add(previousSlice = MakeBaseDepthSlice(heightmap));
                }
                else
                {
                    slices.Add(previousSlice = MakeNonBaseDepthSlice(heightmap, y - 1, previousSlice)); // <- note that the slice is wrapped around height at y-1
                    heights.Add((byte)previousHeight);
                }

                previousHeight = y;
            }

            if (slices.Count == 0)
            {
                return(new DepthBounds()); // <- no physics
            }
            else
            {
                Debug.Assert(heights.Count == slices.Count - 1);
                return(new DepthBounds
                {
                    heights = heights.Count == 0 ? null : heights.ToArray(),
                    slices = slices.ToArray(),
                });
            }
        }