예제 #1
0
        [Test] public void RemoveResetsReferenceTypesToDefault()
        {
            RawList <string> list = new RawList <string>(
                Enumerable.Range(0, 10)
                .Select(i => i.ToString())
                .ToArray());

            // Is the internal array empty if not assigned otherwise?
            if (list.Capacity > list.Count)
            {
                Assert.AreSame(null, list.Data[list.Count]);
            }

            // Adjusting the count shouldn't affect the internal array, just as documented
            list.Count = 0;
            for (int i = 0; i < 10; i++)
            {
                Assert.AreNotSame(null, list.Data[i]);
            }
            list.Count = 10;

            // Check various types of removal and make sure the internal array is reset properly
            {
                // Remove an element
                list.Remove("1");
                Assert.AreSame(null, list.Data[list.Count]);
                list.RemoveAt(5);
                Assert.AreSame(null, list.Data[list.Count]);

                // Remove the last element specifically to tap into a different code path
                list.RemoveAt(list.Count - 1);
                Assert.AreSame(null, list.Data[list.Count]);

                // Remove a range
                list.RemoveRange(0, 5);
                for (int i = list.Count; i < list.Data.Length; i++)
                {
                    Assert.AreSame(null, list.Data[i]);
                }

                // Clear the list
                list.Clear();
                for (int i = list.Count; i < list.Data.Length; i++)
                {
                    Assert.AreSame(null, list.Data[i]);
                }
            }
        }
        ///<summary>
        /// Removes an entity from the manager.
        ///</summary>
        ///<param name="e">Entity to remove.</param>
        ///<exception cref="InvalidOperationException">Thrown if the entity does not belong to this manager.</exception>
        public void Remove(Entity e)
        {
            lock (InterpolatedStates.FlipLocker)
            {
                lock (ReadBuffers.FlipLocker)
                {
                    if (e.BufferedStates.BufferedStatesManager == this)
                    {
                        int index = entities.IndexOf(e);

                        int endIndex = entities.Count - 1;
                        entities[index] = entities[endIndex];
                        entities.RemoveAt(endIndex);
                        if (index < entities.Count)
                        {
                            entities[index].BufferedStates.motionStateIndex = index;
                        }
                        if (ReadBuffers.Enabled)
                        {
                            ReadBuffers.Remove(index, endIndex);
                        }
                        if (InterpolatedStates.Enabled)
                        {
                            InterpolatedStates.Remove(index, endIndex);
                        }

                        e.BufferedStates.BufferedStatesManager = null;
                    }
                    else
                    {
                        throw new InvalidOperationException("Entity does not belong to this BufferedStatesManager; cannot remove.");
                    }
                }
            }
        }
예제 #3
0
        internal void Remove(ref Int2 index, Grid2DEntry entry)
        {
            int cellIndex;
            int sortingHash;

            if (TryGetIndex(ref index, out cellIndex, out sortingHash))
            {
                cells.Elements[cellIndex].Remove(entry);
                if (cells.Elements[cellIndex].entries.count == 0)
                {
                    //The cell is now empty.  Give it back to the pool.
                    var toRemove = cells.Elements[cellIndex];
                    //There's no cleanup to do on the grid cell.
                    //Its list is empty, and the rest is just value types.
                    cells.RemoveAt(cellIndex);
                    cellPool.GiveBack(toRemove);
                    count--;
                }
            }


            //int sortingHash = index.GetSortingHash();
            //int minIndex = 0; //inclusive
            //int maxIndex = count; //exclusive
            //int i = 0;
            //while (maxIndex - minIndex > 0) //If the testing interval has a length of zero, we've done as much as we can.
            //{
            //    i = (maxIndex + minIndex) / 2;
            //    if (cells.Elements[i].sortingHash > sortingHash)
            //        maxIndex = i;
            //    else if (cells.Elements[i].sortingHash < sortingHash)
            //        minIndex = ++i;
            //    else
            //    {
            //        //Found an equal sorting hash!
            //        //The hash can collide, and we cannot add an entry to
            //        //an incorrect index.  It would break the 'cell responsibility'
            //        //used by the cell update process to avoid duplicate overlaps.
            //        //So, check if the index we found is ACTUALLY correct.
            //        if (cells.Elements[i].cellIndex.Y == index.Y && cells.Elements[i].cellIndex.Z == index.Z)
            //        {
            //            cells.Elements[i].Remove(entry);
            //            if (cells.Elements[i].entries.count == 0)
            //            {
            //                //The cell is now empty.  Give it back to the pool.
            //                var toRemove = cells.Elements[i];
            //                //There's no cleanup to do on the grid cell.
            //                //Its list is empty, and the rest is just value types.
            //                cells.RemoveAt(i);
            //                cellPool.GiveBack(toRemove);
            //                count--;
            //            }
            //            return;
            //        }
            //        //If it was not the correct index, let it continue searching.
            //    }

            //}
            ////Getting here should be impossible.
        }
예제 #4
0
 ///<summary>
 /// Cleans up the constraint.
 ///</summary>
 public override void CleanUp()
 {
     //Deactivate any remaining constraints.
     for (int i = penetrationConstraints.count - 1; i >= 0; i--)
     {
         var penetrationConstraint = penetrationConstraints.Elements[i];
         penetrationConstraint.CleanUp();
         penetrationConstraints.RemoveAt(i);
         penetrationConstraintPool.Push(penetrationConstraint);
     }
     if (twistFriction.isActive)
     {
         twistFriction.CleanUp();
         slidingFriction.CleanUp();
     }
 }
예제 #5
0
 /// <summary>
 /// Removes an entry from the broad phase.
 /// </summary>
 /// <param name="entry">Entry to remove.</param>
 public override void Remove(BroadPhaseEntry entry)
 {
     base.Remove(entry);
     for (int i = 0; i < entries.Count; i++)
     {
         if (entries.Elements[i].item == entry)
         {
             var gridEntry = entries.Elements[i];
             entries.RemoveAt(i);
             //Remove the object from any cells that it is held by.
             for (int j = gridEntry.previousMin.Y; j <= gridEntry.previousMax.Y; j++)
             {
                 for (int k = gridEntry.previousMin.Z; k <= gridEntry.previousMax.Z; k++)
                 {
                     var index = new Int2 {
                         Y = j, Z = k
                     };
                     cellSet.Remove(ref index, gridEntry);
                 }
             }
             gridEntry.item = null;
             entryPool.GiveBack(gridEntry);
             return;
         }
     }
 }
예제 #6
0
        internal void Destroy(Contact contact, int index)
        {
            Fixture fixtureA = contact.FixtureA;
            Fixture fixtureB = contact.FixtureB;
            Body    bodyA    = fixtureA.Body;
            Body    bodyB    = fixtureB.Body;

            if (EndContact != null && contact.IsTouching())
            {
                EndContact(contact);
            }

            // Remove from the world.
            if (index == -1)
            {
                ContactList.Remove(contact);
            }
            else
            {
                ContactList.RemoveAt(index);
            }

            // Remove from body 1
            if (contact.NodeA.Prev != null)
            {
                contact.NodeA.Prev.Next = contact.NodeA.Next;
            }

            if (contact.NodeA.Next != null)
            {
                contact.NodeA.Next.Prev = contact.NodeA.Prev;
            }

            if (contact.NodeA == bodyA.ContactList)
            {
                bodyA.ContactList = contact.NodeA.Next;
            }

            // Remove from body 2
            if (contact.NodeB.Prev != null)
            {
                contact.NodeB.Prev.Next = contact.NodeB.Next;
            }

            if (contact.NodeB.Next != null)
            {
                contact.NodeB.Next.Prev = contact.NodeB.Prev;
            }

            if (contact.NodeB == bodyB.ContactList)
            {
                bodyB.ContactList = contact.NodeB.Next;
            }

            contact.Destroy();
        }
예제 #7
0
        ///<summary>
        /// Cleans up the constraint.
        ///</summary>
        public override void CleanUp()
        {
            //Deactivate any remaining constraints.
            for (int i = penetrationConstraints.count - 1; i >= 0; i--)
            {
                var penetrationConstraint = penetrationConstraints.Elements[i];
                penetrationConstraint.CleanUp();
                penetrationConstraints.RemoveAt(i);
                penetrationConstraintPool.Push(penetrationConstraint);
            }

            for (int i = frictionConstraints.count - 1; i >= 0; i--)
            {
                var frictionConstraint = frictionConstraints.Elements[i];
                frictionConstraint.CleanUp();
                frictionConstraints.RemoveAt(i);
                frictionConstraintPool.Push(frictionConstraint);
            }
        }
예제 #8
0
        [Test] public void Basics()
        {
            RawList <int> intList = new RawList <int>();

            intList.Add(10);
            intList.AddRange(new int[] { 17, 42, 94 });

            Assert.AreEqual(4, intList.Count);
            Assert.IsTrue(intList.Contains(42));
            Assert.AreEqual(2, intList.IndexOf(42));
            CollectionAssert.AreEqual(new int[] { 10, 17, 42, 94 }, intList);
            CollectionAssert.AreEqual(new int[] { 10, 17, 42, 94 }, intList.Data.Take(intList.Count));

            intList.ShrinkToFit();
            Assert.AreEqual(intList.Count, intList.Capacity);

            intList.Remove(42);
            Assert.AreEqual(3, intList.Count);
            Assert.IsTrue(!intList.Contains(42));
            Assert.AreEqual(-1, intList.IndexOf(42));
            CollectionAssert.AreEqual(new int[] { 10, 17, 94 }, intList);
            CollectionAssert.AreEqual(new int[] { 10, 17, 94 }, intList.Data.Take(intList.Count));

            intList.Insert(1, 100);
            CollectionAssert.AreEqual(new int[] { 10, 100, 17, 94 }, intList);
            CollectionAssert.AreEqual(new int[] { 10, 100, 17, 94 }, intList.Data.Take(intList.Count));

            intList.InsertRange(2, new int[] { 150, 200, 250, 300 });
            CollectionAssert.AreEqual(new int[] { 10, 100, 150, 200, 250, 300, 17, 94 }, intList);
            CollectionAssert.AreEqual(new int[] { 10, 100, 150, 200, 250, 300, 17, 94 }, intList.Data.Take(intList.Count));

            intList.RemoveAt(1);
            CollectionAssert.AreEqual(new int[] { 10, 150, 200, 250, 300, 17, 94 }, intList);
            CollectionAssert.AreEqual(new int[] { 10, 150, 200, 250, 300, 17, 94 }, intList.Data.Take(intList.Count));

            intList.RemoveLast();
            CollectionAssert.AreEqual(new int[] { 10, 150, 200, 250, 300, 17 }, intList);
            CollectionAssert.AreEqual(new int[] { 10, 150, 200, 250, 300, 17 }, intList.Data.Take(intList.Count));

            intList.RemoveLast(4);
            CollectionAssert.AreEqual(new int[] { 10, 150 }, intList);
            CollectionAssert.AreEqual(new int[] { 10, 150 }, intList.Data.Take(intList.Count));

            intList.Clear();
            Assert.AreEqual(0, intList.Count);
            Assert.IsTrue(!intList.Contains(10));
        }
예제 #9
0
        internal void Remove(ref Int2 index, Grid2DEntry entry)
        {
            int cellIndex;
            int sortingHash;

            if (TryGetIndex(ref index, out cellIndex, out sortingHash))
            {
                cells.Elements[cellIndex].Remove(entry);
                if (cells.Elements[cellIndex].entries.Count == 0)
                {
                    //The cell is now empty.  Give it back to the pool.
                    GridCell2D toRemove = cells.Elements[cellIndex];
                    //There's no cleanup to do on the grid cell.
                    //Its list is empty, and the rest is just value types.
                    cells.RemoveAt(cellIndex);
                    cellPool.GiveBack(toRemove);
                    count--;
                }
            }
        }
예제 #10
0
        public static void Unmount(string prefix)
        {
            //if (prefix[prefix.Length - 1] != DirectorySeparatorChar) {
            //    prefix = prefix + DirectorySeparatorChar;
            //}

            for (int i = 0; i < virtualFileSystems.Count; i++)
            {
                if (virtualFileSystems[i].Prefix == prefix)
                {
                    IDisposable disposable = virtualFileSystems[i].FileSystem as IDisposable;
                    if (disposable != null)
                    {
                        disposable.Dispose();
                    }

                    virtualFileSystems.RemoveAt(i);
                    break;
                }
            }
        }
예제 #11
0
		[Test] public void Basics()
		{
			RawList<int> intList = new RawList<int>();
			intList.Add(10);
			intList.AddRange(new int[] { 17, 42, 94 });

			Assert.AreEqual(4, intList.Count);
			Assert.IsTrue(intList.Contains(42));
			Assert.AreEqual(2, intList.IndexOf(42));
			CollectionAssert.AreEqual(new int[] { 10, 17, 42, 94 }, intList);
			CollectionAssert.AreEqual(new int[] { 10, 17, 42, 94 }, intList.Data.Take(intList.Count));

			intList.ShrinkToFit();
			Assert.AreEqual(intList.Count, intList.Capacity);

			intList.Remove(42);
			Assert.AreEqual(3, intList.Count);
			Assert.IsTrue(!intList.Contains(42));
			Assert.AreEqual(-1, intList.IndexOf(42));
			CollectionAssert.AreEqual(new int[] { 10, 17, 94 }, intList);
			CollectionAssert.AreEqual(new int[] { 10, 17, 94 }, intList.Data.Take(intList.Count));

			intList.Insert(1, 100);
			CollectionAssert.AreEqual(new int[] { 10, 100, 17, 94 }, intList);
			CollectionAssert.AreEqual(new int[] { 10, 100, 17, 94 }, intList.Data.Take(intList.Count));

			intList.InsertRange(2, new int[] { 150, 200, 250, 300 });
			CollectionAssert.AreEqual(new int[] { 10, 100, 150, 200, 250, 300, 17, 94 }, intList);
			CollectionAssert.AreEqual(new int[] { 10, 100, 150, 200, 250, 300, 17, 94 }, intList.Data.Take(intList.Count));

			intList.RemoveAt(1);
			CollectionAssert.AreEqual(new int[] { 10, 150, 200, 250, 300, 17, 94 }, intList);
			CollectionAssert.AreEqual(new int[] { 10, 150, 200, 250, 300, 17, 94 }, intList.Data.Take(intList.Count));

			intList.Clear();
			Assert.AreEqual(0, intList.Count);
			Assert.IsTrue(!intList.Contains(94));
		}
예제 #12
0
        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));
            }
        }
예제 #13
0
        protected RawList<ImportInputAssignment> SelectImporter(AssetImportEnvironment env)
        {
            if (!env.IsPrepareStep) throw new ArgumentException(
                "The specified import environment must be configured as a preparation environment.",
                "env");

            // Find an importer to handle some or all of the unhandled input files
            RawList<ImportInputAssignment> candidateMapping = new RawList<ImportInputAssignment>();
            foreach (IAssetImporter importer in AssetManager.Importers)
            {
                env.ResetAcquiredData();

                try
                {
                    importer.PrepareImport(env);
                }
                catch (Exception ex)
                {
                    Log.Editor.WriteError("An error occurred in the preparation step of '{1}': {0}",
                        Log.Exception(ex),
                        Log.Type(importer.GetType()));
                    continue;
                }

                if (env.HandledInput.Any())
                {
                    candidateMapping.Add(new ImportInputAssignment
                    {
                        Importer = importer,
                        HandledInput = env.HandledInput.ToArray(),
                        ExpectedOutput = env.Output.ToArray()
                    });
                }
            }

            // Sort candidate mapping from most files to least files, so we can solve the biggest conflicts first
            candidateMapping.Sort((a, b) => b.HandledInput.Length - a.HandledInput.Length);

            // Determine if multiple importers intend to handle the same files and resolve conflicts
            List<int> conflictingIndices = new List<int>();
            List<string> conflictingFiles = new List<string>();
            for (int mainIndex = 0; mainIndex < candidateMapping.Count; mainIndex++)
            {
                ImportInputAssignment assignment = candidateMapping[mainIndex];

                // Find all conflicts related to this assignment
                conflictingIndices.Clear();
                conflictingFiles.Clear();
                for (int secondIndex = 0; secondIndex < candidateMapping.Count; secondIndex++)
                {
                    if (secondIndex == mainIndex) continue;

                    ImportInputAssignment conflictAssignment = candidateMapping[secondIndex];
                    IEnumerable<string> mainFiles = assignment.HandledInput.Select(item => item.Path);
                    IEnumerable<string> secondFiles = conflictAssignment.HandledInput.Select(item => item.Path);
                    string[] conflicts = mainFiles.Intersect(secondFiles).ToArray();
                    if (conflicts.Length > 0)
                    {
                        if (conflictingIndices.Count == 0) conflictingIndices.Add(mainIndex);
                        conflictingIndices.Add(secondIndex);
                        conflictingFiles.AddRange(conflicts);
                    }
                }

                // Resolve conflicts with this assignment
                if (conflictingIndices.Count > 0)
                {
                    // Determine which importer to prefer for this conflict
                    ImportInputAssignment[] conflictingAssignments = conflictingIndices.Select(i => candidateMapping[i]).ToArray();
                    int keepIndex = this.ResolveMappingConflict(conflictingAssignments);

                    // If we somehow decided that none of the options is viable, abort the operation
                    if (keepIndex == -1)
                    {
                        candidateMapping.Clear();
                        return candidateMapping;
                    }

                    // Sort indices to remove in declining order and remove their mappings
                    conflictingIndices.Remove(keepIndex);
                    conflictingIndices.Sort((a, b) => b - a);
                    foreach (int index in conflictingIndices)
                    {
                        candidateMapping.RemoveAt(index);
                    }

                    // Start over with the conflict search
                    mainIndex = -1;
                    continue;
                }
            }

            return candidateMapping;
        }
예제 #14
0
 private static void MaintainEdge(int a, int b, RawList<int> edges)
 {
     bool contained = false;
     int index = 0;
     for (int k = 0; k < edges.Count; k += 2)
     {
         if ((edges[k] == a && edges[k + 1] == b) || (edges[k] == b && edges[k + 1] == a))
         {
             contained = true;
             index = k;
         }
     }
     //If it isn't present, add it to the edge list.
     if (!contained)
     {
         edges.Add(a);
         edges.Add(b);
     }
     else
     {
         //If it is present, that means both edge-connected triangles were deleted now, so get rid of it.
         edges.RemoveAt(index);
         edges.RemoveAt(index);
     }
 }
예제 #15
0
        /// <summary>
        /// Identifies the indices of points in a set which are on the outer convex hull of the set.
        /// </summary>
        /// <param name="points">List of points in the set.</param>
        /// <param name="indices">List of indices composing the triangulated surface of the convex hull.
        /// Each group of 3 indices represents a triangle on the surface of the hull.</param>
        public static void GetConvexHull(RawList<Vector3> points, RawList<int> indices)
        {
            //Points is what will be used as a vertex buffer.
            var outsidePoints = Resources.GetIntList();
            var edges = Resources.GetIntList();

            var toRemove = Resources.GetIntList();
            //Populate the outside points
            for (int k = 0; k < points.Count; k++)
            {
                outsidePoints.Add(k);
            }
            //Find an initial tetrahedron
            var initialTetrahedron = Resources.GetIntList();
            /*float volume = 0;
            Random random = new Random();
            Vector3 dir;
            int count = 0;


            while (initialTetrahedron.Count != 4 && count < 100)
            {
                dir = new Vector3((float)random.NextDouble() - .5f, (float)random.NextDouble() - .5f, (float)random.NextDouble() - .5f);
                getExtremePointOfSet(dir, outsidePoints, points, out maxIndex);
                if(!initialTetrahedron.Contains(maxIndex))
                    initialTetrahedron.Add(maxIndex);
                if (initialTetrahedron.Count == 4)
                {
                    //(a-d) * ((b-d)x(c-d)
                    volume = Vector3.Dot(Vector3.Cross(points[initialTetrahedron[1]] - points[initialTetrahedron[3]], points[initialTetrahedron[2]] - points[initialTetrahedron[3]]), points[initialTetrahedron[0]] - points[initialTetrahedron[3]]);
                    if (Math.Abs(volume) < epsilon)
                        initialTetrahedron.RemoveAt(3);
                }
                count++;

            }*/
            int min, max;
            GetExtremePointsOfSet(Vector3.Up, points, out min, out max);
            if (min == max)
                throw new ArgumentException("Point set is degenerate.");
            initialTetrahedron.Add(min);
            initialTetrahedron.Add(max);
            Vector3 direction = NoVector;
            for (int i = 0; i < points.Count; i++)
            {
                if (i != min && i != max)
                {
                    direction = Vector3.Cross(points[min] - points[i], points[max] - points[i]);
                    if (direction.LengthSquared() > BigEpsilon)
                    {
                        break;
                    }
                }
            }
            float minDistance, maxDistance;
            float lineMin = Vector3.Dot(direction, points[min]);
            GetExtremePointsOfSet(direction, points, out min, out max, out minDistance, out maxDistance);

            if (Math.Abs(minDistance - lineMin) < BigEpsilon)
            {
                if (Math.Abs(maxDistance - lineMin) < BigEpsilon)
                {
                    throw new ArgumentException("Point set is degenerate.");
                }
                initialTetrahedron.Add(max);
            }
            else
            {
                initialTetrahedron.Add(min);
            }

            direction = Vector3.Cross(points[initialTetrahedron[1]] - points[initialTetrahedron[0]], points[initialTetrahedron[2]] - points[initialTetrahedron[0]]);

            lineMin = Vector3.Dot(direction, points[initialTetrahedron[0]]);
            GetExtremePointsOfSet(direction, points, out min, out max, out minDistance, out maxDistance);

            if (Math.Abs(minDistance - lineMin) < BigEpsilon)
            {
                if (Math.Abs(maxDistance - lineMin) < BigEpsilon)
                {
                    throw new ArgumentException("Point set is degenerate.");
                }
                initialTetrahedron.Add(max);
            }
            else
            {
                initialTetrahedron.Add(min);
            }


            //Add initial tetrahedron triangles to indices list, remove from outside points, and remove all interior points from outside points.
            if (initialTetrahedron.Count == 4)
            {
                indices.Add(initialTetrahedron[0]);
                indices.Add(initialTetrahedron[1]);
                indices.Add(initialTetrahedron[2]);

                indices.Add(initialTetrahedron[1]);
                indices.Add(initialTetrahedron[2]);
                indices.Add(initialTetrahedron[3]);

                indices.Add(initialTetrahedron[2]);
                indices.Add(initialTetrahedron[3]);
                indices.Add(initialTetrahedron[0]);

                indices.Add(initialTetrahedron[3]);
                indices.Add(initialTetrahedron[0]);
                indices.Add(initialTetrahedron[1]);

                for (int k = 0; k < 4; k++)
                {
                    outsidePoints.Remove(initialTetrahedron[k]);
                }
                VerifyWindings(indices, points);
                RemovePointsInPolyhedronIfInside(outsidePoints, points, indices);
            }
            else
                throw new ArgumentException("Could not form an initial tetrahedron from the input points; ensure that the input point set has volume.");
            Resources.GiveBack(initialTetrahedron);

            while (outsidePoints.Count > 0)
            {
                //While the convex hull is incomplete
                for (int k = 0; k < indices.Count; k += 3)
                {
                    //Find the normal of the triangle
                    Vector3 normal;
                    FindNormal(indices, points, k, out normal);

                    //Get the furthest point in the direction of the normal.
                    int maxIndex;
                    Vector3 maximum = GetExtremePointOfSet(normal, outsidePoints, points, out maxIndex);

                 


                    
                    //If the point is visible by the triangle, continue.
                    Vector3 offset;
                    Vector3.Subtract(ref maximum, ref points.Elements[indices.Elements[k]], out offset);
                    float dot;
                    Vector3.Dot(ref normal, ref offset, out dot);
                    if (dot >= 0)
                    {
                        //It's been picked! Remove the maximum point from the outside.
                        outsidePoints.Remove(maxIndex);
                        //Remove any triangles that can see the point, including itself!
                        edges.Clear();
                        toRemove.Clear();
                        for (int n = 0; n < indices.Count; n += 3)
                        {
                            //Go through each triangle, if it can be seen, delete it and use maintainEdge on its edges.
                            if (IsTriangleVisibleFromPoint(indices, points, n, ref maximum))
                            {
                                //This triangle can see it!
                                MaintainEdge(indices[n], indices[n + 1], edges);
                                MaintainEdge(indices[n], indices[n + 2], edges);
                                MaintainEdge(indices[n + 1], indices[n + 2], edges);
                                indices.RemoveAt(n);
                                indices.RemoveAt(n);
                                indices.RemoveAt(n);
                                n -= 3;
                            }
                        }
                        //Create new triangles
                        for (int n = 0; n < edges.Count; n += 2)
                        {
                            //For each edge, create a triangle with the extreme point.
                            indices.Add(edges[n]);
                            indices.Add(edges[n + 1]);
                            indices.Add(maxIndex);
                        }
                        VerifyWindings(indices, points);
                        //Remove all points from the outsidePoints if they are inside the polyhedron
                        RemovePointsInPolyhedronIfInside(outsidePoints, points, indices);

                        //The list has been significantly messed with, so restart the loop.
                        break;
                    }
                }
            }
            //"Hullify" the points.

            Resources.GiveBack(outsidePoints);
            Resources.GiveBack(edges);
            Resources.GiveBack(toRemove);
        }
예제 #16
0
 private void RemoveParticle(int index)
 {
     particles.RemoveAt(index);
 }
예제 #17
0
        protected RawList <ImportInputAssignment> SelectImporter(AssetImportEnvironment env)
        {
            if (!env.IsPrepareStep)
            {
                throw new ArgumentException(
                          "The specified import environment must be configured as a preparation environment.",
                          "env");
            }

            // Find an importer to handle some or all of the unhandled input files
            RawList <ImportInputAssignment> candidateMapping = new RawList <ImportInputAssignment>();

            foreach (IAssetImporter importer in AssetManager.Importers)
            {
                env.ResetAcquiredData();

                try
                {
                    importer.PrepareImport(env);
                }
                catch (Exception ex)
                {
                    Log.Editor.WriteError("An error occurred in the preparation step of '{1}': {0}",
                                          Log.Exception(ex),
                                          Log.Type(importer.GetType()));
                    continue;
                }

                if (env.HandledInput.Any())
                {
                    candidateMapping.Add(new ImportInputAssignment
                    {
                        Importer       = importer,
                        HandledInput   = env.HandledInput.ToArray(),
                        ExpectedOutput = env.Output.ToArray()
                    });
                }
            }

            // Sort candidate mapping from most files to least files, so we can solve the biggest conflicts first
            candidateMapping.Sort((a, b) => b.HandledInput.Length - a.HandledInput.Length);

            // Determine if multiple importers intend to handle the same files and resolve conflicts
            List <int>    conflictingIndices = new List <int>();
            List <string> conflictingFiles   = new List <string>();

            for (int mainIndex = 0; mainIndex < candidateMapping.Count; mainIndex++)
            {
                ImportInputAssignment assignment = candidateMapping[mainIndex];

                // Find all conflicts related to this assignment
                conflictingIndices.Clear();
                conflictingFiles.Clear();
                for (int secondIndex = 0; secondIndex < candidateMapping.Count; secondIndex++)
                {
                    if (secondIndex == mainIndex)
                    {
                        continue;
                    }

                    ImportInputAssignment conflictAssignment = candidateMapping[secondIndex];
                    IEnumerable <string>  mainFiles          = assignment.HandledInput.Select(item => item.Path);
                    IEnumerable <string>  secondFiles        = conflictAssignment.HandledInput.Select(item => item.Path);
                    string[] conflicts = mainFiles.Intersect(secondFiles).ToArray();
                    if (conflicts.Length > 0)
                    {
                        if (conflictingIndices.Count == 0)
                        {
                            conflictingIndices.Add(mainIndex);
                        }
                        conflictingIndices.Add(secondIndex);
                        conflictingFiles.AddRange(conflicts);
                    }
                }

                // Resolve conflicts with this assignment
                if (conflictingIndices.Count > 0)
                {
                    // Determine which importer to prefer for this conflict
                    ImportInputAssignment[] conflictingAssignments = conflictingIndices.Select(i => candidateMapping[i]).ToArray();
                    int keepIndex = this.ResolveMappingConflict(conflictingAssignments);

                    // If we somehow decided that none of the options is viable, abort the operation
                    if (keepIndex == -1)
                    {
                        candidateMapping.Clear();
                        return(candidateMapping);
                    }

                    // Sort indices to remove in declining order and remove their mappings
                    conflictingIndices.Remove(keepIndex);
                    conflictingIndices.Sort((a, b) => b - a);
                    foreach (int index in conflictingIndices)
                    {
                        candidateMapping.RemoveAt(index);
                    }

                    // Start over with the conflict search
                    mainIndex = -1;
                    continue;
                }
            }

            return(candidateMapping);
        }
예제 #18
0
		[Test] public void RemoveResetsReferenceTypesToDefault()
		{
			RawList<string> list = new RawList<string>(Enumerable.Range(0, 10).Select(i => i.ToString()));

			// Is the internal array empty if not assigned otherwise?
			if (list.Capacity > list.Count)
				Assert.AreSame(null, list.Data[list.Count]);

			// Adjusting the count shouldn't affect the internal array, just as documented
			list.Count = 0;
			for (int i = 0; i < 10; i++)
			{
				Assert.AreNotSame(null, list.Data[i]);
			}
			list.Count = 10;

			// Check various types of removal and make sure the internal array is reset properly
			{
				// Remove an element
				list.Remove("1");
				Assert.AreSame(null, list.Data[list.Count]);
				list.RemoveAt(5);
				Assert.AreSame(null, list.Data[list.Count]);

				// Remove a range
				list.RemoveRange(0, 5);
				for (int i = list.Count; i < list.Data.Length; i++)
				{
					Assert.AreSame(null, list.Data[i]);
				}

				// Clear the list
				list.Clear();
				for (int i = list.Count; i < list.Data.Length; i++)
				{
					Assert.AreSame(null, list.Data[i]);
				}
			}
		}
예제 #19
0
        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);
                    }
                }
                shapeList.Add(isLoop ?
                    (ShapeInfo)new LoopShapeInfo(vertexBuffer) :
                    (ShapeInfo)new ChainShapeInfo(vertexBuffer));
            }
        }