public void CopyTo() { RawList<int> list = new RawList<int>(new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 100, 100, 100 }, 10); RawList<int> listCopy = new RawList<int>(list); Assert.AreNotSame(list.Data, listCopy.Data); Assert.AreEqual(list.Count, listCopy.Count); CollectionAssert.AreEqual(list.Data.Take(list.Count), listCopy.Data.Take(list.Count)); CollectionAssert.AreEqual(list, listCopy); RawList<int> listCopy2 = new RawList<int>(); Assert.Throws<ArgumentNullException>(() => list.CopyTo(null, 0, 1)); Assert.Throws<ArgumentException>(() => list.CopyTo(listCopy2, 0, 17)); Assert.Throws<ArgumentException>(() => list.CopyTo(listCopy2, -1, 1)); CollectionAssert.AreEqual(new int[] { }, listCopy2); list.CopyTo(listCopy2, 1, 2); CollectionAssert.AreEqual(new int[] { 0, 0, 1 }, listCopy2); list.CopyTo(listCopy2, 0, 10); CollectionAssert.AreEqual(list, listCopy2); }
[Test] public void CopyTo() { RawList <int> list = new RawList <int>(new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 100, 100, 100 }, 10); RawList <int> listCopy = new RawList <int>(list); Assert.AreNotSame(list.Data, listCopy.Data); Assert.AreEqual(list.Count, listCopy.Count); CollectionAssert.AreEqual(list.Data.Take(list.Count), listCopy.Data.Take(list.Count)); CollectionAssert.AreEqual(list, listCopy); RawList <int> listCopy2 = new RawList <int>(); Assert.Throws <ArgumentNullException>(() => list.CopyTo(null, 0, 1)); Assert.Throws <ArgumentException>(() => list.CopyTo(listCopy2, 0, 17)); Assert.Throws <ArgumentException>(() => list.CopyTo(listCopy2, -1, 1)); CollectionAssert.AreEqual(new int[] { }, listCopy2); list.CopyTo(listCopy2, 1, 2); CollectionAssert.AreEqual(new int[] { 0, 0, 1 }, listCopy2); list.CopyTo(listCopy2, 0, 10); CollectionAssert.AreEqual(list, listCopy2); }
private static void GenerateCollisionShapes(TileEdgeMap edgeMap, Vector2 origin, Vector2 tileSize, bool roundedCorners, IList <ShapeInfo> shapeList) { // Traverse the edge map and gradually create chain / loop // shapes until all edges have been used. RawList <Point2> currentChain = new RawList <Point2>(); RawList <Vector2> vertexBuffer = new RawList <Vector2>(); while (true) { // Begin a new continuous chain of nodes currentChain.Clear(); // Find a starting node for our current chain. // If there is none, we found and handled all edges. Point2 start = edgeMap.FindNonEmpty(); if (start == new Point2(-1, -1)) { break; } // Traverse the current chain node-by-node from the start we found Point2 current = start; while (true) { // Add the current node to our continuous chain currentChain.Add(current); // Find the next node that connects to the current one. // If there is none, our current chain is done. Point2 next = edgeMap.GetClockwiseNextFrom(current); if (next == new Point2(-1, -1)) { break; } // Remove the edge we used to get to the next node edgeMap.RemoveEdge(current, next); // Use the next node as origin for traversing further current = next; } // Generate a shape from the current chain bool isLoop = (start == currentChain[currentChain.Count - 1]); if (isLoop) { currentChain.RemoveAt(currentChain.Count - 1); } vertexBuffer.Clear(); // Rounded corners if (roundedCorners && currentChain.Count >= 3) { vertexBuffer.Reserve(currentChain.Count * 2); vertexBuffer.Count = 0; for (int i = 0; i < currentChain.Count; i++) { int prevIndex = (i - 1 + currentChain.Count) % currentChain.Count; int nextIndex = (i + 1) % currentChain.Count; Vector2 currentVert = origin + tileSize * (Vector2)currentChain[i]; Vector2 prevVert = origin + tileSize * (Vector2)currentChain[prevIndex]; Vector2 nextVert = origin + tileSize * (Vector2)currentChain[nextIndex]; if (nextVert - currentVert != currentVert - prevVert) { if (!isLoop && (i == 0 || i == currentChain.Count - 1)) { vertexBuffer.Add(currentVert); } else { vertexBuffer.Add(currentVert + (prevVert - currentVert).Normalized * tileSize * 0.2f); vertexBuffer.Add(currentVert + (nextVert - currentVert).Normalized * tileSize * 0.2f); } } } } // Sharp corners else { vertexBuffer.Reserve(currentChain.Count); vertexBuffer.Count = 0; for (int i = 0; i < currentChain.Count; i++) { int prevIndex = (i - 1 + currentChain.Count) % currentChain.Count; int nextIndex = (i + 1) % currentChain.Count; Vector2 currentVert = origin + tileSize * (Vector2)currentChain[i]; Vector2 prevVert = origin + tileSize * (Vector2)currentChain[prevIndex]; Vector2 nextVert = origin + tileSize * (Vector2)currentChain[nextIndex]; if (nextVert - currentVert != currentVert - prevVert) { vertexBuffer.Add(currentVert); } } } Vector2[] vertices = new Vector2[vertexBuffer.Count]; vertexBuffer.CopyTo(vertices, 0); shapeList.Add(isLoop ? (ShapeInfo) new LoopShapeInfo(vertices) : (ShapeInfo) new ChainShapeInfo(vertices)); } }
private static void GetTileAreaOutlines(IReadOnlyGrid<bool> tileArea, Vector2 tileSize, ref List<Vector2[]> outlines) { // Initialize the container we'll put our outlines into if (outlines == null) outlines = new List<Vector2[]>(); else outlines.Clear(); // Generate a data structure containing all visible edges TileEdgeMap edgeMap = new TileEdgeMap(tileArea.Width + 1, tileArea.Height + 1); for (int y = 0; y < edgeMap.Height; y++) { for (int x = 0; x < edgeMap.Width; x++) { // Determine highlight state of the four tiles around this node bool topLeft = x > 0 && y > 0 && tileArea[x - 1, y - 1]; bool topRight = x < tileArea.Width && y > 0 && tileArea[x , y - 1]; bool bottomLeft = x > 0 && y < tileArea.Height && tileArea[x - 1, y ]; bool bottomRight = x < tileArea.Width && y < tileArea.Height && tileArea[x , y ]; // Determine which edges are visible if (topLeft != topRight ) edgeMap.AddEdge(new Point2(x, y), new Point2(x , y - 1)); if (topRight != bottomRight) edgeMap.AddEdge(new Point2(x, y), new Point2(x + 1, y )); if (bottomRight != bottomLeft ) edgeMap.AddEdge(new Point2(x, y), new Point2(x , y + 1)); if (bottomLeft != topLeft ) edgeMap.AddEdge(new Point2(x, y), new Point2(x - 1, y )); } } // Traverse edges to form outlines until no more edges are left RawList<Vector2> outlineBuilder = new RawList<Vector2>(); while (true) { // Find the beginning of an outline Point2 current = edgeMap.FindNonEmpty(); if (current.X == -1 || current.Y == -1) break; // Traverse it until no more edges are left while (true) { Point2 next = edgeMap.GetClockwiseNextFrom(current); if (next.X == -1 || next.Y == -1) break; outlineBuilder.Add(next * tileSize); edgeMap.RemoveEdge(current, next); current = next; } // Close the loop by adding the first element again if (outlineBuilder.Count > 0) outlineBuilder.Add(outlineBuilder[0]); // If we have enough vertices, keep the outline for drawing Vector2[] outline = new Vector2[outlineBuilder.Count]; outlineBuilder.CopyTo(outline, 0); outlines.Add(outline); // Reset the outline builder to an empty state outlineBuilder.Clear(); } }