// Copyright (c) 2014 Robert Rouhani and other contributors (see CONTRIBUTORS file). // Licensed under the MIT License - https://raw.github.com/Robmaister/SharpNav/master/LICENSE using System; namespace SharpNav { /// /// Stores height data in a grid. /// public class HeightPatch { /// /// The value used when a height value has not yet been set. /// public const int UnsetHeight = -1; private int xmin, ymin, width, length; private int[] data; /// /// Initializes a new instance of the class. /// /// The initial X coordinate of the patch. /// The initial Y coordinate of the patch. /// The width of the patch. /// The length of the patch. public HeightPatch(int x, int y, int width, int length) { if (x < 0 || y < 0 || width <= 0 || length <= 0) throw new ArgumentOutOfRangeException("Invalid bounds."); this.xmin = x; this.ymin = y; this.width = width; this.length = length; this.data = new int[width * length]; Clear(); } /// /// Gets the X coordinate of the patch. /// public int X { get { return xmin; } } /// /// Gets the Y coordinate of the patch. /// public int Y { get { return ymin; } } /// /// Gets the width of the patch. /// public int Width { get { return width; } } /// /// Gets the length of the patch. /// public int Length { get { return length; } } /// /// Gets or sets the height at a specified index. /// /// The index inside the patch. /// The height at the specified index. public int this[int index] { get { return data[index]; } set { data[index] = value; } } /// /// Gets or sets the height at a specified coordinate (x, y). /// /// The X coordinate. /// The Y coordinate. /// The height at the specified index. public int this[int x, int y] { get { return data[y * width + x]; } set { data[y * width + x] = value; } } /// /// Checks an index to see whether or not it's height value has been set. /// /// The index to check. /// A value indicating whether or not the height value at the index is set. public bool IsSet(int index) { return data[index] != UnsetHeight; } /// /// Gets the height value at a specified index. A return value indicates whether the height value is set. /// /// The index to use. /// Contains the height at the value. /// A value indicating whether the value at the specified index is set. public bool TryGetHeight(int index, out int value) { value = this[index]; return value != UnsetHeight; } /// /// Gets the height value at a specified index. A return value indicates whether the height value is set. /// /// The X coordinate. /// The Y coordinate. /// Contains the height at the value. /// A value indicating whether the value at the specified index is set. public bool TryGetHeight(int x, int y, out int value) { value = this[x, y]; return value != UnsetHeight; } /// /// Resizes the patch. Only works if the new size is smaller than or equal to the initial size. /// /// The new X coordinate. /// The new Y coordinate. /// The new width. /// The new length. public void Resize(int x, int y, int width, int length) { if (data.Length < width * length) throw new ArgumentException("Only resizing down is allowed right now."); this.xmin = x; this.ymin = y; this.width = width; this.length = length; } /// /// Clears the by unsetting every value. /// public void Clear() { for (int i = 0; i < data.Length; i++) data[i] = UnsetHeight; } /// /// Sets all of the height values to the same value. /// /// The height to apply to all values. public void SetAll(int h) { for (int i = 0; i < data.Length; i++) data[i] = h; } } }