/// <summary>
 /// Removes redundant points.  Two points are redundant if they occupy the same hash grid cell.
 /// </summary>
 /// <param name="points">List of points to prune.</param>
 /// <param name="cellSize">Size of cells to determine redundancy.</param>
 public static void RemoveRedundantPoints(ref QuickList<Vector3> points, double cellSize)
 {
     var set = new QuickSet<Int3>(BufferPools<Int3>.Locking, BufferPools<int>.Locking, BufferPool.GetPoolIndex(points.Count));
     for (int i = points.Count - 1; i >= 0; --i)
     {
         var element = points.Elements[i];
         var cell = new Int3
         {
             X = (int)Math.Floor(element.X / cellSize),
             Y = (int)Math.Floor(element.Y / cellSize),
             Z = (int)Math.Floor(element.Z / cellSize)
         };
         if (set.Contains(cell))
         {
             points.FastRemoveAt(i);
         }
         else
         {
             set.Add(cell);
             //TODO: Consider adding adjacent cells to guarantee that a point on the border between two cells will still detect the presence
             //of a point on the opposite side of that border.
         }
     }
     set.Dispose();
 }
        /// <summary>
        /// Removes redundant points.  Two points are redundant if they occupy the same hash grid cell.
        /// </summary>
        /// <param name="points">List of points to prune.</param>
        /// <param name="cellSize">Size of cells to determine redundancy.</param>
        public static void RemoveRedundantPoints(ref QuickList <Vector3> points, double cellSize)
        {
            var set = new QuickSet <Int3>(BufferPools <Int3> .Locking, BufferPools <int> .Locking, BufferPool.GetPoolIndex(points.Count));

            for (int i = points.Count - 1; i >= 0; --i)
            {
                var element = points.Elements[i];
                var cell    = new Int3
                {
                    X = (int)Math.Floor(element.X / cellSize),
                    Y = (int)Math.Floor(element.Y / cellSize),
                    Z = (int)Math.Floor(element.Z / cellSize)
                };
                if (set.Contains(cell))
                {
                    points.FastRemoveAt(i);
                }
                else
                {
                    set.Add(cell);
                    //TODO: Consider adding adjacent cells to guarantee that a point on the border between two cells will still detect the presence
                    //of a point on the opposite side of that border.
                }
            }
            set.Dispose();
        }
        internal IEnumerable <TElement> ResolveEnumerable <TElement>(Func <Type, string, ImplicitRegistration, object> resolve, string name)
        {
            TElement value;
            var      set  = new QuickSet <Type>();
            int      hash = typeof(TElement).GetHashCode();

            // Iterate over hierarchy
            for (var container = this; null != container; container = container._parent)
            {
                // Skip to parent if no data
                if (null == container._metadata)
                {
                    continue;
                }

                // Hold on to registries
                var registry = container._registry;

                // Get indexes and iterate over them
                var length = container._metadata.GetEntries <TElement>(hash, out int[] data);
                for (var i = 1; i < length; i++)
                {
                    var index = data[i];

                    if (set.Add(registry.Entries[index].HashCode, registry.Entries[index].Key.Type))
                    {
                        try
                        {
                            var registration = (ExplicitRegistration)registry.Entries[index].Value;
                            value = (TElement)resolve(typeof(TElement), registry.Entries[index].Key.Name, registration);
                        }
                        catch (ArgumentException ex) when(ex.InnerException is TypeLoadException)
                        {
                            continue;
                        }

                        yield return(value);
                    }
                }
            }

            // If nothing registered attempt to resolve the type
            if (0 == set.Count)
            {
                try
                {
                    var registration = GetRegistration(typeof(TElement), name);
                    value = (TElement)resolve(typeof(TElement), name, registration);
                }
                catch
                {
                    yield break;
                }

                yield return(value);
            }
        }
Пример #4
0
        public static void RasterizeTriangle(ref Vector3 a, ref Vector3 b, ref Vector3 c, float cellSize, ref Vector3 gridOrigin, BufferPool pool, ref QuickSet <Cell, Buffer <Cell>, Buffer <int>, CellComparer> cells)
        {
            var gridA = a - gridOrigin;
            var gridB = b - gridOrigin;
            var gridC = c - gridOrigin;

            //Compute the bounding box of the triangle.
            var max = Vector3.Max(Vector3.Max(gridA, gridB), gridC);
            var min = Vector3.Min(Vector3.Min(gridA, gridB), gridC);

            var epsilon = new Vector3(1e-5f);

            min -= epsilon;
            max += epsilon;

            //Discretize the bounding box.
            //All indices are positive, so we can just truncate.
            int   startX, endX, startY, endY, startZ, endZ;
            float inverseCellSize = 1f / cellSize;

            startX = (int)Math.Floor(min.X * inverseCellSize);
            endX   = (int)Math.Floor(max.X * inverseCellSize);
            startY = (int)Math.Floor(min.Y * inverseCellSize);
            endY   = (int)Math.Floor(max.Y * inverseCellSize);
            startZ = (int)Math.Floor(min.Z * inverseCellSize);
            endZ   = (int)Math.Floor(max.Z * inverseCellSize);

            //Test the triangle against each cell.
            var halfExtents = new Vector3(cellSize * 0.5f);
            var cellPool    = pool.SpecializeFor <Cell>();
            var tablePool   = pool.SpecializeFor <int>();

            for (int i = startX; i <= endX; ++i)
            {
                for (int j = startY; j <= endY; ++j)
                {
                    for (int k = startZ; k <= endZ; ++k)
                    {
                        var cellIndex  = new Vector3(i, j, k);
                        var cellOrigin = cellSize * cellIndex + halfExtents;
                        var shiftedA   = gridA - cellOrigin;
                        var shiftedB   = gridB - cellOrigin;
                        var shiftedC   = gridC - cellOrigin;

                        if (BoxTriangleCollider.Intersecting(ref halfExtents, ref shiftedA, ref shiftedB, ref shiftedC))
                        {
                            cells.Add(new Cell {
                                X = i, Y = j, Z = k
                            }, cellPool, tablePool);
                        }
                    }
                }
            }
        }
Пример #5
0
        internal IEnumerable <TElement> ComplexArray <TElement>(Func <Type, IRegistration, object?> resolve, Type type)
        {
            object?value;
            var    set     = new QuickSet();
            var    key     = new HashKey(typeof(TElement));
            var    typeKey = new HashKey(type);

            // Iterate over hierarchy
            for (UnityContainer?container = this; null != container; container = container._parent)
            {
                // Skip to parent if no data
                if (null == container._metadata)
                {
                    continue;
                }

                // Hold on to registries
                Debug.Assert(null != container._registry);
                var registry = container._registry;

                // Get indexes and iterate over them
                var length = container._metadata.GetMeta(ref typeKey, out int[]? data);
                if (null != data)
                {
                    for (var i = 1; i < length; i++)
                    {
                        var index        = data[i];
                        var registration = (ExplicitRegistration)registry.Entries[index].Policies;

                        if (null != registration.Name && set.Add(registration.Name))
                        {
                            try
                            {
                                var itemKey = new HashKey(typeof(TElement), registration.Name);
                                var item    = container.GetOrAdd(ref itemKey, typeof(TElement), registration.Name, registration);
                                value = resolve(typeof(TElement), item);
                            }
                            catch (ArgumentException ex) when(ex.InnerException is TypeLoadException)
                            {
                                continue;
                            }

#pragma warning disable CS8601 // Possible null reference assignment.
                            yield return((TElement)value);

#pragma warning restore CS8601 // Possible null reference assignment.
                        }
                    }
                }
            }
        }
Пример #6
0
        /// <summary>
        /// Identifies the points on the surface of hull.
        /// </summary>
        /// <param name="points">List of points in the set.</param>
        /// <param name="outputTriangleIndices">List of indices into the input point set composing the triangulated surface of the convex hull.
        /// Each group of 3 indices represents a triangle on the surface of the hull.</param>
        /// <param name="outputSurfacePoints">Unique points on the surface of the convex hull.</param>
        public static void GetConvexHull(ref QuickList <Vector3> points, ref QuickList <int> outputTriangleIndices, IList <Vector3> outputSurfacePoints)
        {
            GetConvexHull(ref points, ref outputTriangleIndices);

            var alreadyContainedIndices = new QuickSet <int>(BufferPools <int> .Locking, BufferPools <int> .Locking);

            for (int i = outputTriangleIndices.Count - 1; i >= 0; i--)
            {
                int index = outputTriangleIndices[i];
                if (alreadyContainedIndices.Add(index))
                {
                    outputSurfacePoints.Add(points[index]);
                }
            }
            alreadyContainedIndices.Dispose();
        }
        internal IEnumerable <TElement> ComplexArray <TElement>(Func <Type, string, ImplicitRegistration, object> resolve, Type type)
        {
            TElement value;
            var      set      = new QuickSet <Type>();
            int      hashCode = type.GetHashCode();

            // Iterate over hierarchy
            for (var container = this; null != container; container = container._parent)
            {
                // Skip to parent if no data
                if (null == container._metadata)
                {
                    continue;
                }

                // Hold on to registries
                var registry = container._registry;

                // Get indexes and iterate over them
                var length = container._metadata.GetEntries(hashCode, type, out int[] data);
                for (var i = 1; i < length; i++)
                {
                    var index = data[i];
                    var name  = registry.Entries[index].Key.Name;
                    if (null == name)
                    {
                        continue;
                    }
                    if (set.Add(registry.Entries[index].HashCode, registry.Entries[index].Key.Type))
                    {
                        try
                        {
                            int hash         = NamedType.GetHashCode(typeof(TElement), name);
                            var registration = container.GetOrAdd(hash, typeof(TElement), name, registry.Entries[index].Value);
                            value = (TElement)resolve(typeof(TElement), name, registration);
                        }
                        catch (ArgumentException ex) when(ex.InnerException is TypeLoadException)
                        {
                            continue;
                        }

                        yield return(value);
                    }
                }
            }
        }
        public static void TestSetResizing(IUnmanagedMemoryPool pool)
        {
            Random        random     = new Random(5);
            var           set        = new QuickSet <int, PrimitiveComparer <int> >(4, pool);
            HashSet <int> controlSet = new HashSet <int>();

            for (int iterationIndex = 0; iterationIndex < 100000; ++iterationIndex)
            {
                if (random.NextDouble() < 0.7)
                {
                    set.Add(iterationIndex, pool);
                    controlSet.Add(iterationIndex);
                }
                if (random.NextDouble() < 0.2)
                {
                    var indexToRemove = random.Next(set.Count);
                    var toRemove      = set[indexToRemove];
                    set.FastRemove(toRemove);
                    controlSet.Remove(toRemove);
                }
                if (iterationIndex % 1000 == 0)
                {
                    set.EnsureCapacity(set.Count * 3, pool);
                }
                else if (iterationIndex % 7777 == 0)
                {
                    set.Compact(pool);
                }
            }

            Debug.Assert(set.Count == controlSet.Count);
            for (int i = 0; i < set.Count; ++i)
            {
                Debug.Assert(controlSet.Contains(set[i]));
            }
            foreach (var element in controlSet)
            {
                Debug.Assert(set.Contains(element));
            }

            set.Dispose(pool);
        }
Пример #9
0
        public static void TestSetResizing()
        {
            Random random = new Random(5);
            UnsafeBufferPool <int> pool       = new UnsafeBufferPool <int>();
            QuickSet <int>         set        = new QuickSet <int>(pool, pool);
            HashSet <int>          controlSet = new HashSet <int>();

            for (int iterationIndex = 0; iterationIndex < 100000; ++iterationIndex)
            {
                if (random.NextDouble() < 0.7)
                {
                    set.Add(iterationIndex);
                    controlSet.Add(iterationIndex);
                }
                if (random.NextDouble() < 0.2)
                {
                    var indexToRemove = random.Next(set.Count);
                    var toRemove      = set[indexToRemove];
                    set.FastRemove(toRemove);
                    controlSet.Remove(toRemove);
                }
                if (iterationIndex % 1000 == 0)
                {
                    set.EnsureCapacity(set.Count * 3);
                }
                else if (iterationIndex % 7777 == 0)
                {
                    set.Compact();
                }
            }

            Assert.IsTrue(set.Count == controlSet.Count);
            for (int i = 0; i < set.Count; ++i)
            {
                Assert.IsTrue(controlSet.Contains(set[i]));
            }
            foreach (var element in controlSet)
            {
                Assert.IsTrue(set.Contains(element));
            }
        }
Пример #10
0
        internal IEnumerable <TElement> ResolveEnumerable <TElement>(Func <Type, IRegistration, object?> resolve,
                                                                     Type typeDefinition, string?name)
        {
            object?value;
            var    set        = new QuickSet();
            var    key        = new HashKey(typeof(TElement));
            var    keyGeneric = new HashKey(typeDefinition);

            // Iterate over hierarchy
            for (UnityContainer?container = this; null != container; container = container._parent)
            {
                // Skip to parent if no data
                if (null == container._metadata)
                {
                    continue;
                }

                // Hold on to registries
                Debug.Assert(null != container._registry);
                var registry = container._registry;

                // Get indexes for bound types and iterate over them
                var length = container._metadata.GetMeta(ref key, out int[]? data);
                if (null != data)
                {
                    for (var i = 1; i < length; i++)
                    {
                        var index        = data[i];
                        var registration = (ExplicitRegistration)registry.Entries[index].Policies;

                        if (!set.Add(registration.Name))
                        {
                            continue;
                        }

                        try
                        {
                            value = resolve(typeof(TElement), registration);
                        }
                        catch (ArgumentException ex) when(ex.InnerException is TypeLoadException)
                        {
                            continue;
                        }

#pragma warning disable CS8601 // Possible null reference assignment.
                        yield return((TElement)value);

#pragma warning restore CS8601 // Possible null reference assignment.
                    }
                }

                // Get indexes for unbound types and iterate over them
                length = container._metadata.GetMeta(ref keyGeneric, out data);
                if (null != data)
                {
                    for (var i = 1; i < length; i++)
                    {
                        var index        = data[i];
                        var registration = (ExplicitRegistration)registry.Entries[index].Policies;

                        if (set.Add(registration.Name))
                        {
                            try
                            {
                                var itemKey = new HashKey(typeof(TElement), registration.Name);
                                var item    = container.GetOrAdd(ref itemKey, typeof(TElement), registration.Name, registration);
                                value = resolve(typeof(TElement), item);
                            }
                            catch (MakeGenericTypeFailedException) { continue; }
                            catch (InvalidRegistrationException)   { continue; }

#pragma warning disable CS8601 // Possible null reference assignment.
                            yield return((TElement)value);

#pragma warning restore CS8601 // Possible null reference assignment.
                        }
                    }
                }
            }

            // If nothing registered attempt to resolve the type
            if (0 == set.Count)
            {
                try
                {
                    var registration = GetRegistration(typeof(TElement), name);
                    value = resolve(typeof(TElement), registration);
                }
                catch
                {
                    yield break;
                }

#pragma warning disable CS8601 // Possible null reference assignment.
                yield return((TElement)value);

#pragma warning restore CS8601 // Possible null reference assignment.
            }
        }
        internal IEnumerable <TElement> ResolveEnumerable <TElement>(Func <Type, string, ImplicitRegistration, object> resolve,
                                                                     Type typeDefinition, string name)
        {
            TElement value;
            var      set         = new QuickSet <Type>();
            int      hashCode    = typeof(TElement).GetHashCode();
            int      hashGeneric = typeDefinition.GetHashCode();

            // Iterate over hierarchy
            for (var container = this; null != container; container = container._parent)
            {
                // Skip to parent if no data
                if (null == container._metadata)
                {
                    continue;
                }

                // Hold on to registries
                var registry = container._registry;

                // Get indexes for bound types and iterate over them
                var length = container._metadata.GetEntries <TElement>(hashCode, out int[] data);
                for (var i = 1; i < length; i++)
                {
                    var index = data[i];

                    if (set.Add(registry.Entries[index].HashCode, registry.Entries[index].Key.Type))
                    {
                        try
                        {
                            var registration = (ExplicitRegistration)registry.Entries[index].Value;
                            value = (TElement)resolve(typeof(TElement), registry.Entries[index].Key.Name, registration);
                        }
                        catch (ArgumentException ex) when(ex.InnerException is TypeLoadException)
                        {
                            continue;
                        }

                        yield return(value);
                    }
                }

                // Get indexes for unbound types and iterate over them
                length = container._metadata.GetEntries(hashGeneric, typeDefinition, out data);
                for (var i = 1; i < length; i++)
                {
                    var index = data[i];
                    var key   = registry.Entries[index].Key.Name;

                    if (set.Add(registry.Entries[index].HashCode, registry.Entries[index].Key.Type))
                    {
                        try
                        {
                            int hash         = NamedType.GetHashCode(typeof(TElement), key);
                            var registration = container.GetOrAdd(hash, typeof(TElement), key, registry.Entries[index].Value);
                            value = (TElement)resolve(typeof(TElement), key, registration);
                        }
                        catch (MakeGenericTypeFailedException) { continue; }
                        catch (InvalidOperationException ex) when(ex.InnerException is InvalidRegistrationException)
                        {
                            continue;
                        }
                        // TODO: Verify if required
                        //catch (ArgumentException ex) when (ex.InnerException is TypeLoadException)
                        //{
                        //    continue;
                        //}

                        yield return(value);
                    }
                }
            }

            // If nothing registered attempt to resolve the type
            if (0 == set.Count)
            {
                try
                {
                    var registration = GetRegistration(typeof(TElement), name);
                    value = (TElement)resolve(typeof(TElement), name, registration);
                }
                catch
                {
                    yield break;
                }

                yield return(value);
            }
        }
Пример #12
0
        /// <summary>
        /// Identifies the points on the surface of hull.
        /// </summary>
        /// <param name="points">List of points in the set.</param>
        /// <param name="outputTriangleIndices">List of indices into the input point set composing the triangulated surface of the convex hull.
        /// Each group of 3 indices represents a triangle on the surface of the hull.</param>
        /// <param name="outputSurfacePoints">Unique points on the surface of the convex hull.</param>
        public static void GetConvexHull(ref QuickList<Vector3> points, ref QuickList<int> outputTriangleIndices, IList<Vector3> outputSurfacePoints)
        {
            GetConvexHull(ref points, ref outputTriangleIndices);

            var alreadyContainedIndices = new QuickSet<int>(BufferPools<int>.Locking, BufferPools<int>.Locking);

            for (int i = outputTriangleIndices.Count - 1; i >= 0; i--)
            {
                int index = outputTriangleIndices[i];
                if (alreadyContainedIndices.Add(index))
                {
                    outputSurfacePoints.Add(points[index]);
                }
            }
            alreadyContainedIndices.Dispose();
        }
Пример #13
0
        public static void TestSetResizing()
        {
            Random random = new Random(5);
            UnsafeBufferPool<int> pool = new UnsafeBufferPool<int>();
            QuickSet<int> set = new QuickSet<int>(pool, pool);
            HashSet<int> controlSet = new HashSet<int>();

            for (int iterationIndex = 0; iterationIndex < 100000; ++iterationIndex)
            {
                if (random.NextDouble() < 0.7)
                {
                    set.Add(iterationIndex);
                    controlSet.Add(iterationIndex);
                }
                if (random.NextDouble() < 0.2)
                {
                    var indexToRemove = random.Next(set.Count);
                    var toRemove = set[indexToRemove];
                    set.FastRemove(toRemove);
                    controlSet.Remove(toRemove);
                }
                if (iterationIndex % 1000 == 0)
                {
                    set.EnsureCapacity(set.Count * 3);
                }
                else if (iterationIndex % 7777 == 0)
                {
                    set.Compact();
                }
            }

            Assert.IsTrue(set.Count == controlSet.Count);
            for (int i = 0; i < set.Count; ++i)
            {
                Assert.IsTrue(controlSet.Contains(set[i]));
            }
            foreach (var element in controlSet)
            {
                Assert.IsTrue(set.Contains(element));
            }
        }