/// <summary>
 /// Modifies this container to contain values from both containers.
 /// </summary>
 /// <typeparam name="T">Source type of elements</typeparam>
 /// <param name="container">Container to modify.</param>
 /// <param name="other">The container to compare to this container.</param>
 public static void UnionWith <T>(this UnsafeHashSet <T> container, FixedList32 <T> other)
     where T : unmanaged, IEquatable <T>
 {
     foreach (var item in other)
     {
         container.Add(item);
     }
 }
コード例 #2
0
 /// <summary>
 /// Modifies this container to remove all values that are present in the other container.
 /// </summary>
 /// <typeparam name="T">Source type of elements</typeparam>
 /// <param name="container">Container to modify.</param>
 /// <param name="other">The container to compare to this container.</param>
 public static void ExceptWith <T>(this NativeHashSet <T> container, FixedList32 <T> other)
     where T : unmanaged, IEquatable <T>
 {
     foreach (var item in other)
     {
         container.Remove(item);
     }
 }
コード例 #3
0
    public void FixedList32intGenericHasExpectedCapacity()
    {
        var list             = new FixedList32 <int>();
        var expectedCapacity = list.Capacity;

        for (int i = 0; i < expectedCapacity; ++i)
        {
            list.Add((int)i);
        }
        Assert.Throws <IndexOutOfRangeException> (() => { list.Add((int)expectedCapacity); });
    }
コード例 #4
0
        public static FixedList32 <int> GetDataIds <T>(T[] datas)
            where T : IGameData
        {
            var len = datas.Length;
            FixedList32 <int> ids = new FixedList32 <int>();

            for (int i = 0; i < len; i++)
            {
                //ids[i] = datas[i].DataId;
                ids.Add(datas[i].DataId);
            }
            return(ids);
        }
コード例 #5
0
    public void FixedList32byteGenericSort()
    {
        var list = new FixedList32 <byte>();

        for (var i = 0; i < 5; ++i)
        {
            list.Add((byte)(4 - i));
        }
        list.Sort();
        for (var i = 0; i < 5; ++i)
        {
            Assert.AreEqual(i, list[i]);
        }
    }
コード例 #6
0
    public void FixedList32floatGenericSort()
    {
        var list = new FixedList32 <float>();

        for (var i = 0; i < 5; ++i)
        {
            list.Add((float)(4 - i));
        }
        list.Sort();
        for (var i = 0; i < 5; ++i)
        {
            Assert.AreEqual(i, list[i]);
        }
    }
コード例 #7
0
    public void FixedList32byteGenericRemoveRange()
    {
        var list = new FixedList32 <byte>();

        list.Add(0);
        list.Add(3);
        list.Add(3);
        list.Add(1);
        list.Add(2);
        list.RemoveRange(1, 2);
        for (var i = 0; i < 3; ++i)
        {
            Assert.AreEqual(i, list[i]);
        }
    }
コード例 #8
0
    public void FixedList32intGenericInsertRange()
    {
        var list = new FixedList32 <int>();

        list.Add(0);
        list.Add(3);
        list.Add(4);
        list.InsertRange(1, 2);
        list[1] = 1;
        list[2] = 2;
        for (var i = 0; i < 5; ++i)
        {
            Assert.AreEqual(i, list[i]);
        }
    }
        /// <summary>
        /// Modifies this container to keep only values that are present in both containers.
        /// </summary>
        /// <typeparam name="T">Source type of elements</typeparam>
        /// <param name="container">Container to modify.</param>
        /// <param name="other">The container to compare to this container.</param>
        public static void IntersectWith <T>(this UnsafeHashSet <T> container, FixedList32 <T> other)
            where T : unmanaged, IEquatable <T>
        {
            var result = new UnsafeList <T>(container.Count(), Allocator.Temp);

            foreach (var item in other)
            {
                if (container.Contains(item))
                {
                    result.Add(item);
                }
            }

            container.Clear();
            container.UnionWith(result);

            result.Dispose();
        }
コード例 #10
0
    public void FixedList32intGenericHasExpectedLayout()
    {
        var actual = new FixedList32 <int>();

        for (var i = 0; i < 7; ++i)
        {
            actual.Add((int)i);
        }
        unsafe
        {
            var e = stackalloc byte[32];
            e[0] = (byte)((7 >> 0) & 0xFF);
            e[1] = (byte)((7 >> 8) & 0xFF);
            for (var i = 0; i < 7; ++i)
            {
                var s = (int)i;
                UnsafeUtility.MemCpy(e + 2 + FixedList.PaddingBytes <int>() + sizeof(int) * i, &s, sizeof(int));
            }
            Assert.AreEqual(0, UnsafeUtility.MemCmp(e, &actual.length, 32));
        }
    }
コード例 #11
0
        // This job loops over copypositions
        // This is much faster than looping over grid, as copypositions array is usually much smaller, unless your game is weird lol
        // Basically, in parallelfor, execute is run x times, x is determined by you. It cun loop over one array in parallel over many threads
        // So in this case, we loop over copypositions
        // REMEMBER THE ENITTY INDEX IS IMPLICITLY DEFINED BY COPYPOSITIONS INDEX, BECAUSE WE HAVE STRUCTURED IT TO BE ALIGNED WITH THE ENTITY QUERY
        public void Execute(int index)
        {
            float2 copyPosition = copyPositions[index];
            float  px           = copyPosition.x;
            float  py           = copyPosition.y;
            float  radius       = 0.25f;

            // Adjustement will be used later, this is the amount we need to displace the unit if it has collided
            float adjustmentX = px;
            float adjustmentY = py;

            int hash = ( int )(math.floor(px / CELL_SIZE) + math.floor(py / CELL_SIZE) * N_CELLS_ACROSS);
            int xR   = ( int )math.round(px);
            int yR   = ( int )math.round(py);
            int xD   = math.select(1, -1, xR < px);
            int yD   = math.select(1, -1, yR < py);

            // Basically we find the cell the position, and then check which other cells it is near
            // This math saves us from having to check all 8 surrounding cells to just 4
            // FixedList is a stack allocated array, ver very fast and very useful here
            FixedList32 <int> hashes = new FixedList32 <int>();

            hashes.Add(hash);

            bool xOffset = math.abs(xR - px) < 0.3f;
            bool yOffset = math.abs(yR - py) < 0.3f;

            if (xOffset)
            {
                hashes.Add(hash + xD);
            }
            if (yOffset)
            {
                hashes.Add(hash + yD * N_CELLS_ACROSS);
            }
            if (xOffset && yOffset)
            {
                hashes.Add(hash + yD * N_CELLS_ACROSS);
            }

            // Now for each cell it is in or close to, we check the positions of nearby units
            // WE CAN DO THIS BECAUSE THE SPATIAL PARTITION GRID HOLDS THE INDICES OF COPYPOSITIONS
            for (int i = 0; i < hashes.Length; i++)
            {
                int gridIndex = hashes[i] * BUCKET_SIZE;
                int count     = grid[gridIndex];
                int cellIndex = gridIndex + 1;

                for (int j = 1; j < grid[gridIndex]; j++)
                {
                    float2 testPosition = copyPositions[grid[cellIndex + j]];
                    float  px2          = testPosition.x;
                    float  py2          = testPosition.y;
                    float  radius2      = 0.25f;

                    float distance = math.sqrt((px - px2) * (px - px2) + (py - py2) * (py - py2));
                    int   overlaps = math.select(0, 1, distance < radius + radius2);

                    float overlap = 0.4f * (distance - radius - radius2);

                    adjustmentX -= overlaps * (overlap * (px - px2)) / (distance + 0.01f);
                    adjustmentY -= overlaps * (overlap * (py - py2)) / (distance + 0.01f);
                }
            }

            // Now we update the position of the unit int the array
            // This also means that if another unit has collided with this one, we have already displaced it,
            // another optimization
            copyPositions[index] = new float2(adjustmentX, adjustmentY);
        }
コード例 #12
0
        // The slop term is so that if two edges of the rect are close to the shadow edge, then both edges are stored in ShadowGeometry.
        public static void CalculateShadowGeometry(Rect rect, float2 lightSource, float slop, out ShadowGeometry sg1, out ShadowGeometry sg2)
        {
            if (rect.Contains(lightSource))
            {
                Debug.Log("TODO: Opaque object contains light source. Behavior will not be correct.");
            }

            FixedList64 <float2> corners = new FixedList32 <float2>();

            corners.Add(rect.c1 - lightSource);
            corners.Add(rect.c2 - lightSource);
            corners.Add(rect.c3 - lightSource);
            corners.Add(rect.c4 - lightSource);

            FixedList64 <float2> cornersN = new FixedList32 <float2>();

            foreach (float2 c in corners)
            {
                cornersN.Add(math.normalize(c));
            }

            float lowestDot = math.INFINITY;
            int   l1        = -1;
            int   l2        = -1;

            // The idea is to find the pair of corners which are the
            // furthest angle apart.
            for (int i = 0; i < 3; i++)
            {
                for (int j = i + 1; j < 4; j++)
                {
                    float dot = math.dot(cornersN[i], cornersN[j]);
                    if (dot < lowestDot)
                    {
                        lowestDot = dot;
                        l1        = i;
                        l2        = j;
                    }
                }
            }

            // Ensure they always have the same relative rotation. Improves
            // coherence of contact ids.
            if (Lin.Cross(cornersN[l1], cornersN[l2]) < 0)
            {
                var tmp = l1;
                l1 = l2;
                l2 = tmp;
            }


            // Finding the other 2 corners
            int o1 = 0;
            int o2 = 0;

            for (int i = 0; i < 4; i++)
            {
                if (i != l1 && i != l2)
                {
                    o1 = i;
                    break;
                }
            }
            for (int i = o1 + 1; i < 4; i++)
            {
                if (i != l1 && i != l2)
                {
                    o2 = i;
                    break;
                }
            }

            if (math.dot(cornersN[l1], cornersN[o1]) < math.dot(cornersN[l1], cornersN[o2]))
            {
                var tmp = o1;
                o1 = o2;
                o2 = tmp;
            }

            float reject1 = math.abs(Lin.Cross(cornersN[l1], corners[o1]));

            sg1 = new ShadowGeometry {
                contact1 = corners[l1] + lightSource,
                id1      = new float2(rect.id, l1).GetHashCode(),
            };
            if (reject1 < slop)
            {
                sg1.contact2 = corners[o1] + lightSource;
                sg1.id2      = new float2(rect.id, o1).GetHashCode();
            }

            float reject2 = math.abs(Lin.Cross(cornersN[l2], corners[o2]));

            sg2 = new ShadowGeometry {
                contact1 = corners[l2] + lightSource,
                id1      = new float2(rect.id, l2).GetHashCode()
            };
            if (reject2 < slop)
            {
                sg2.contact2 = corners[o2] + lightSource;
                sg2.id2      = new float2(rect.id, o2).GetHashCode();
            }
        }