Esempio n. 1
0
        NativeList(int initialCapacity, Allocator allocator, int disposeSentinelStackDepth)
        {
            var totalSize = UnsafeUtility.SizeOf <T>() * (long)initialCapacity;

#if ENABLE_UNITY_COLLECTIONS_CHECKS
            CheckAllocator(allocator);
            CheckInitialCapacity(initialCapacity);
            CollectionHelper.CheckIsUnmanaged <T>();
            CheckTotalSize(initialCapacity, totalSize);

            DisposeSentinel.Create(out m_Safety, out m_DisposeSentinel, disposeSentinelStackDepth, allocator);
            if (s_staticSafetyId.Data == 0)
            {
                CreateStaticSafetyId();
            }
            AtomicSafetyHandle.SetStaticSafetyId(ref m_Safety, s_staticSafetyId.Data);
#endif
            m_ListData            = UnsafeList.Create(UnsafeUtility.SizeOf <T>(), UnsafeUtility.AlignOf <T>(), initialCapacity, allocator);
            m_DeprecatedAllocator = allocator;

#if ENABLE_UNITY_COLLECTIONS_CHECKS
            AtomicSafetyHandle.SetBumpSecondaryVersionOnScheduleWrite(m_Safety, true);
#endif
        }
        public static unsafe void RunWithoutJobsInternal <T>(ref T jobData, ref EntityQuery query, Entity *limitToEntityArray, int limitToEntityArrayLength)
            where T : struct, IJobEntityBatch
        {
            var prebuiltBatchList = new UnsafeList(Allocator.TempJob);

            try
            {
                ChunkIterationUtility.FindFilteredBatchesForEntityArrayWithQuery(
                    query._GetImpl(),
                    limitToEntityArray, limitToEntityArrayLength,
                    ref prebuiltBatchList);

                ArchetypeChunk *chunks      = (ArchetypeChunk *)prebuiltBatchList.Ptr;
                int             chunkCounts = prebuiltBatchList.Length;
                for (int i = 0; i != chunkCounts; i++)
                {
                    jobData.Execute(chunks[i], i);
                }
            }
            finally
            {
                prebuiltBatchList.Dispose();
            }
        }
        //The thread index is passed in because otherwise job reflection can't inject it through a pointer.
        public void Write <T>(T value, int threadIndex) where T : unmanaged
        {
            var blockList = m_perThreadBlockLists + threadIndex;

            if (blockList->nextWriteAddress > blockList->lastByteAddressInBlock)
            {
                if (blockList->elementCount == 0)
                {
                    blockList->blocks = new UnsafeList(m_allocator);
                    blockList->blocks.SetCapacity <BlockPtr>(10);
                }
                BlockPtr newBlockPtr = new BlockPtr
                {
                    ptr = (byte *)UnsafeUtility.Malloc(m_blockSize, UnsafeUtility.AlignOf <T>(), m_allocator)
                };
                blockList->nextWriteAddress       = newBlockPtr.ptr;
                blockList->lastByteAddressInBlock = newBlockPtr.ptr + m_blockSize - 1;
                blockList->blocks.Add(newBlockPtr);
            }

            UnsafeUtility.CopyStructureToPtr(ref value, blockList->nextWriteAddress);
            blockList->nextWriteAddress += m_elementSize;
            blockList->elementCount++;
        }
Esempio n. 4
0
            public static Connection Create(Peer peer)
            {
                Connection connection;

                connection.m_PeerPtr    = peer.NativeData;
                connection.Id           = peer.ID;
                connection.m_DataStream = UnsafeList.Create
                                          (
                    UnsafeUtility.SizeOf <byte>(),
                    UnsafeUtility.AlignOf <byte>(),
                    4096,
                    Allocator.Persistent,
                    NativeArrayOptions.ClearMemory
                                          );
                connection.m_IncomingEvents = UnsafeList.Create
                                              (
                    UnsafeUtility.SizeOf <DriverEvent>(),
                    UnsafeUtility.AlignOf <DriverEvent>(),
                    8,
                    Allocator.Persistent,
                    NativeArrayOptions.ClearMemory
                                              );
                return(connection);
            }
Esempio n. 5
0
 public unsafe static void Sort <T>(this UnsafeList list) where T : struct, IComparable <T>
 {
     list.Sort <T, DefaultComparer <T> >(new DefaultComparer <T>());
 }
Esempio n. 6
0
 static bool GetExtrudedVertices(UnsafeList <SegmentVertex> shapeVertices, Range range, Matrix4x4 matrix0, Matrix4x4 matrix1, in ChiselBlobBuilder builder, ref BrushMeshBlob root, out ChiselBlobBuilderArray <float3> localVertices, out NativeArray <int> segmentIndices, Allocator allocator)
Esempio n. 7
0
 void Deallocate()
 {
     UnsafeList.Destroy(m_ListData);
     m_ListData = null;
 }
Esempio n. 8
0
 public void UnsafeListIndexOf()
 {
     int num = UnsafeList.IndexOf <long>(uList, COUNT / 3 * 2);
 }
Esempio n. 9
0
 /// <summary>
 /// Sorts a list in ascending order.
 /// </summary>
 /// <typeparam name="T">Source type of elements</typeparam>
 /// <param name="list">List to perform sort.</param>
 public unsafe static void Sort <T>(this UnsafeList <T> list) where T : unmanaged, IComparable <T>
 {
     list.Sort(new DefaultComparer <T>());
 }
Esempio n. 10
0
 /// <summary>
 /// Adds elements from a list to this list.
 /// </summary>
 /// <typeparam name="T">Source type of elements</typeparam>
 /// <remarks>
 /// If the list has reached its current capacity, internal array won't be resized, and exception will be thrown.
 /// </remarks>
 public void AddRangeNoResize(UnsafeList list)
 {
     AddRangeNoResize(UnsafeUtility.SizeOf <T>(), UnsafeUtility.AlignOf <T>(), list.Ptr, list.Length);
 }
            public void Execute()
            {
                var addedEntityCount   = 0;
                var removedEntityCount = RemovedChunkEntities.Length;

                for (var i = 0; i < GatheredChanges.Length; i++)
                {
                    var changesForChunk = GatheredChanges[i];
                    addedEntityCount   += changesForChunk.AddedComponentEntities.Length;
                    removedEntityCount += changesForChunk.RemovedComponentEntities.Length;
                }

                if (addedEntityCount == 0 && removedEntityCount == 0)
                {
                    return;
                }

                var buffer            = new UnsafeList(UnsafeUtility.SizeOf <byte>(), UnsafeUtility.AlignOf <byte>(), (addedEntityCount + removedEntityCount) * ComponentSize, Allocator);
                var addedComponents   = new UnsafeList(UnsafeUtility.SizeOf <Entity>(), UnsafeUtility.AlignOf <Entity>(), addedEntityCount, Allocator);
                var removedComponents = new UnsafeList(UnsafeUtility.SizeOf <Entity>(), UnsafeUtility.AlignOf <Entity>(), removedEntityCount, Allocator);

                var chunksWithRemovedData = new NativeList <int>(GatheredChanges.Length, Allocator.Temp);

                for (var i = 0; i < GatheredChanges.Length; i++)
                {
                    var changesForChunk = GatheredChanges[i];
                    if (changesForChunk.AddedComponentDataBuffer.IsCreated)
                    {
                        buffer.AddRangeNoResize <byte>(changesForChunk.AddedComponentDataBuffer.Ptr, changesForChunk.AddedComponentDataBuffer.Length);
                        addedComponents.AddRangeNoResize <Entity>(changesForChunk.AddedComponentEntities.Ptr, changesForChunk.AddedComponentEntities.Length);

                        changesForChunk.AddedComponentDataBuffer.Dispose();
                        changesForChunk.AddedComponentEntities.Dispose();
                    }

                    if (changesForChunk.RemovedComponentDataBuffer.IsCreated)
                    {
                        chunksWithRemovedData.AddNoResize(i);
                    }
                }

                for (var i = 0; i < chunksWithRemovedData.Length; i++)
                {
                    var changesForChunk = GatheredChanges[chunksWithRemovedData[i]];
                    buffer.AddRangeNoResize <byte>(changesForChunk.RemovedComponentDataBuffer.Ptr, changesForChunk.RemovedComponentDataBuffer.Length);
                    removedComponents.AddRangeNoResize <Entity>(changesForChunk.RemovedComponentEntities.Ptr, changesForChunk.RemovedComponentEntities.Length);

                    changesForChunk.RemovedComponentDataBuffer.Dispose();
                    changesForChunk.RemovedComponentEntities.Dispose();
                }

                chunksWithRemovedData.Dispose();

                buffer.AddRangeNoResize <byte>(RemovedChunkComponentDataBuffer.GetUnsafeReadOnlyPtr(), RemovedChunkComponentDataBuffer.Length);
                removedComponents.AddRangeNoResize <Entity>(RemovedChunkEntities.GetUnsafeReadOnlyPtr(), RemovedChunkEntities.Length);

                Result.Value = new Result
                {
                    Buffer            = buffer,
                    AddedComponents   = addedComponents,
                    RemovedComponents = removedComponents
                };
            }
            public void Execute(int index)
            {
                var chunk            = Chunks[index].m_Chunk;
                var archetype        = chunk->Archetype;
                var indexInTypeArray = ChunkDataUtility.GetIndexInTypeArray(archetype, TypeIndex);

                if (indexInTypeArray == -1) // Archetype doesn't match required component
                {
                    return;
                }

                var changesForChunk = GatheredChanges + index;

                if (ShadowChunksBySequenceNumber.TryGetValue(chunk->SequenceNumber, out var shadow))
                {
                    if (!ChangeVersionUtility.DidChange(chunk->GetChangeVersion(indexInTypeArray), shadow.ComponentVersion) &&
                        !ChangeVersionUtility.DidChange(chunk->GetChangeVersion(0), shadow.EntityVersion))
                    {
                        return;
                    }

                    if (!changesForChunk->AddedComponentEntities.IsCreated)
                    {
                        changesForChunk->AddedComponentEntities     = new UnsafeList(Allocator.TempJob);
                        changesForChunk->AddedComponentDataBuffer   = new UnsafeList(Allocator.TempJob);
                        changesForChunk->RemovedComponentEntities   = new UnsafeList(Allocator.TempJob);
                        changesForChunk->RemovedComponentDataBuffer = new UnsafeList(Allocator.TempJob);
                    }

                    var entityDataPtr    = chunk->Buffer + archetype->Offsets[0];
                    var componentDataPtr = chunk->Buffer + archetype->Offsets[indexInTypeArray];

                    var currentCount  = chunk->Count;
                    var previousCount = shadow.Count;

                    var i = 0;

                    for (; i < currentCount && i < previousCount; i++)
                    {
                        var currentComponentData  = componentDataPtr + ComponentSize * i;
                        var previousComponentData = shadow.ComponentDataBuffer + ComponentSize * i;

                        var entity         = *(Entity *)(entityDataPtr + sizeof(Entity) * i);
                        var previousEntity = *(Entity *)(shadow.EntityDataBuffer + sizeof(Entity) * i);

                        if (entity != previousEntity ||
                            UnsafeUtility.MemCmp(currentComponentData, previousComponentData, ComponentSize) != 0)
                        {
                            // CHANGED COMPONENT DATA!
                            OnRemovedComponent(changesForChunk, previousEntity, previousComponentData, ComponentSize);
                            OnNewComponent(changesForChunk, entity, currentComponentData, ComponentSize);
                        }
                    }

                    for (; i < currentCount; i++)
                    {
                        // NEW COMPONENT DATA!
                        var entity = *(Entity *)(entityDataPtr + sizeof(Entity) * i);
                        var currentComponentData = componentDataPtr + ComponentSize * i;
                        OnNewComponent(changesForChunk, entity, currentComponentData, ComponentSize);
                    }

                    for (; i < previousCount; i++)
                    {
                        // REMOVED COMPONENT DATA!
                        var entity = *(Entity *)(entityDataPtr + sizeof(Entity) * i);
                        var previousComponentData = shadow.ComponentDataBuffer + ComponentSize * i;
                        OnRemovedComponent(changesForChunk, entity, previousComponentData, ComponentSize);
                    }
                }
                else
                {
                    // This is a new chunk
                    var addedComponentDataBuffer = new UnsafeList(ComponentSize, 4, chunk->Count, Allocator.TempJob);
                    var addedComponentEntities   = new UnsafeList(sizeof(Entity), 4, chunk->Count, Allocator.TempJob);

                    var entityDataPtr    = chunk->Buffer + archetype->Offsets[0];
                    var componentDataPtr = chunk->Buffer + archetype->Offsets[indexInTypeArray];

                    addedComponentDataBuffer.AddRange <byte>(componentDataPtr, chunk->Count * ComponentSize);
                    addedComponentEntities.AddRange <Entity>(entityDataPtr, chunk->Count);

                    changesForChunk->AddedComponentDataBuffer = addedComponentDataBuffer;
                    changesForChunk->AddedComponentEntities   = addedComponentEntities;
                }
            }
Esempio n. 13
0
 static unsafe uint GetListHash <T>(ref UnsafeList <T> list)
     where T : unmanaged
 {
     return(math.hash(list.Ptr, list.Length * sizeof(T)));
 }
        public unsafe static void ReplaceIfExists(ushort *hashTable, UnsafeList <ushort> *chainedIndices, UnsafeList <float3> *vertices, float3 vertex)
        {
            var centerIndex = new int3((int)(vertex.x / HashedVertices.kCellSize), (int)(vertex.y / HashedVertices.kCellSize), (int)(vertex.z / HashedVertices.kCellSize));
            var offsets     = stackalloc int3[]
            {
                new int3(-1, -1, -1), new int3(-1, -1, 0), new int3(-1, -1, +1),
                new int3(-1, 0, -1), new int3(-1, 0, 0), new int3(-1, 0, +1),
                new int3(-1, +1, -1), new int3(-1, +1, 0), new int3(-1, +1, +1),

                new int3(0, -1, -1), new int3(0, -1, 0), new int3(0, -1, +1),
                new int3(0, 0, -1), new int3(0, 0, 0), new int3(0, 0, +1),
                new int3(0, +1, -1), new int3(0, +1, 0), new int3(0, +1, +1),

                new int3(+1, -1, -1), new int3(+1, -1, 0), new int3(+1, -1, +1),
                new int3(+1, 0, -1), new int3(+1, 0, 0), new int3(+1, 0, +1),
                new int3(+1, +1, -1), new int3(+1, +1, 0), new int3(+1, +1, +1)
            };

            float3 *verticesPtr = (float3 *)vertices->Ptr;

            ushort closestVertexIndex = ushort.MaxValue;

            for (int i = 0; i < 3 * 3 * 3; i++)
            {
                var index      = centerIndex + offsets[i];
                var chainIndex = ((int)hashTable[GetHash(index)]) - 1;
                {
                    float closestDistance = CSGConstants.kSqrVertexEqualEpsilon;
                    while (chainIndex != -1)
                    {
                        var nextChainIndex = ((int)((ushort *)chainedIndices->Ptr)[chainIndex]) - 1;
                        var sqrDistance    = math.lengthsq(verticesPtr[chainIndex] - vertex);
                        if (sqrDistance < closestDistance)
                        {
                            closestVertexIndex = (ushort)chainIndex;
                            closestDistance    = sqrDistance;
                        }
                        chainIndex = nextChainIndex;
                    }
                }
            }
            if (closestVertexIndex == ushort.MaxValue)
            {
                return;
            }

            verticesPtr[closestVertexIndex] = vertex;
        }
        // Add but make the assumption we're not growing any list
        public unsafe static ushort Add(ushort *hashTable, UnsafeList <ushort> *chainedIndices, UnsafeList <float3> *vertices, float3 vertex)
        {
            var centerIndex = new int3((int)(vertex.x / HashedVertices.kCellSize), (int)(vertex.y / HashedVertices.kCellSize), (int)(vertex.z / HashedVertices.kCellSize));
            var offsets     = stackalloc int3[]
            {
                new int3(-1, -1, -1), new int3(-1, -1, 0), new int3(-1, -1, +1),
                new int3(-1, 0, -1), new int3(-1, 0, 0), new int3(-1, 0, +1),
                new int3(-1, +1, -1), new int3(-1, +1, 0), new int3(-1, +1, +1),

                new int3(0, -1, -1), new int3(0, -1, 0), new int3(0, -1, +1),
                new int3(0, 0, -1), new int3(0, 0, 0), new int3(0, 0, +1),
                new int3(0, +1, -1), new int3(0, +1, 0), new int3(0, +1, +1),

                new int3(+1, -1, -1), new int3(+1, -1, 0), new int3(+1, -1, +1),
                new int3(+1, 0, -1), new int3(+1, 0, 0), new int3(+1, 0, +1),
                new int3(+1, +1, -1), new int3(+1, +1, 0), new int3(+1, +1, +1)
            };

            float3 *verticesPtr = (float3 *)vertices->Ptr;

            ushort closestVertexIndex = ushort.MaxValue;

            for (int i = 0; i < 3 * 3 * 3; i++)
            {
                var index      = centerIndex + offsets[i];
                var chainIndex = ((int)hashTable[GetHash(index)]) - 1;
                {
                    float closestDistance = CSGConstants.kSqrVertexEqualEpsilon;
                    while (chainIndex != -1)
                    {
                        var nextChainIndex = ((int)((ushort *)chainedIndices->Ptr)[chainIndex]) - 1;
                        var sqrDistance    = math.lengthsq(verticesPtr[chainIndex] - vertex);
                        if (sqrDistance < closestDistance)
                        {
                            closestVertexIndex = (ushort)chainIndex;
                            closestDistance    = sqrDistance;
                        }
                        chainIndex = nextChainIndex;
                    }
                }
            }
            if (closestVertexIndex != ushort.MaxValue)
            {
                return(closestVertexIndex);
            }

            // Add Unique vertex
            {
                var hashCode       = GetHash(centerIndex);
                var prevChainIndex = hashTable[hashCode];
                var newChainIndex  = chainedIndices->Length;
                vertices->Add(vertex);
                chainedIndices->Add((ushort)prevChainIndex);
                hashTable[(int)hashCode] = (ushort)(newChainIndex + 1);
                return((ushort)newChainIndex);
            }
        }
Esempio n. 16
0
        public bool ConvexPartition(int curveSegments, out UnsafeList <SegmentVertex> polygonVerticesArray, out UnsafeList <int> polygonVerticesSegments, Allocator allocator)
        {
            using (var shapeVertices = new NativeList <SegmentVertex>(Allocator.Temp))
            {
                GetPathVertices(curveSegments, shapeVertices);

                //Profiler.BeginSample("ConvexPartition");
                if (shapeVertices.Length == 3)
                {
                    polygonVerticesArray    = new UnsafeList <SegmentVertex>(3, allocator);
                    polygonVerticesSegments = new UnsafeList <int>(1, allocator);

                    polygonVerticesArray.Resize(3, NativeArrayOptions.UninitializedMemory);
                    polygonVerticesArray[0] = shapeVertices[0];
                    polygonVerticesArray[1] = shapeVertices[1];
                    polygonVerticesArray[2] = shapeVertices[2];

                    polygonVerticesSegments.Resize(1, NativeArrayOptions.UninitializedMemory);
                    polygonVerticesSegments[0] = polygonVerticesArray.Length;
                }
                else
                {
                    polygonVerticesArray    = new UnsafeList <SegmentVertex>(shapeVertices.Length * math.max(1, shapeVertices.Length / 2), allocator);
                    polygonVerticesSegments = new UnsafeList <int>(shapeVertices.Length, allocator);
                    if (!External.BayazitDecomposerBursted.ConvexPartition(shapeVertices,
                                                                           ref polygonVerticesArray,
                                                                           ref polygonVerticesSegments))
                    {
                        polygonVerticesArray.Dispose();
                        polygonVerticesSegments.Dispose();
                        polygonVerticesArray    = default;
                        polygonVerticesSegments = default;
                        return(false);
                    }
                }

                for (int i = 0; i < polygonVerticesSegments.Length; i++)
                {
                    var range = new Range
                    {
                        start = i == 0 ? 0 : polygonVerticesSegments[i - 1],
                        end   = polygonVerticesSegments[i]
                    };

                    if (CalculateOrientation(polygonVerticesArray, range) < 0)
                    {
                        External.BayazitDecomposerBursted.Reverse(polygonVerticesArray, range);
                    }
                }
                //Profiler.EndSample();

                //Debug.Assert(polygonVerticesArray.Length == 0 || polygonVerticesArray.Length == polygonVerticesSegments[polygonVerticesSegments.Length - 1]);
                return(true);
            }
        }
        public void Execute(int index1)
        {
            if (allTreeBrushIndexOrders.Length == rebuildTreeBrushIndexOrders.Length)
            {
                //for (int index1 = 0; index1 < updateBrushIndicesArray.Length; index1++)
                {
                    var brush1IndexOrder    = rebuildTreeBrushIndexOrders[index1];
                    int brush1NodeOrder     = brush1IndexOrder.nodeOrder;
                    var brush1Intersections = brushBrushIntersections[brush1NodeOrder];
                    if (!brush1Intersections.IsCreated)
                    {
                        brush1Intersections = new UnsafeList <BrushIntersectWith>(16, allocator);
                    }
                    for (int index0 = 0; index0 < rebuildTreeBrushIndexOrders.Length; index0++)
                    {
                        var brush0IndexOrder = rebuildTreeBrushIndexOrders[index0];
                        int brush0NodeOrder  = brush0IndexOrder.nodeOrder;
                        if (brush0NodeOrder <= brush1NodeOrder)
                        {
                            continue;
                        }
                        var result = IntersectionUtility.FindIntersection(brush0NodeOrder, brush1NodeOrder,
                                                                          ref brushMeshLookup, ref brushTreeSpaceBounds, ref transformationCache,
                                                                          ref transformedPlanes0, ref transformedPlanes1);
                        if (result == IntersectionType.NoIntersection)
                        {
                            continue;
                        }
                        result = IntersectionUtility.Flip(result);
                        IntersectionUtility.StoreIntersection(ref brush1Intersections, brush0IndexOrder, result);
                    }
                    brushBrushIntersections[brush1NodeOrder] = brush1Intersections;
                }
                return;
            }

            NativeCollectionHelpers.EnsureMinimumSizeAndClear(ref foundBrushes, allTreeBrushIndexOrders.Length);
            NativeCollectionHelpers.EnsureMinimumSizeAndClear(ref usedBrushes, allTreeBrushIndexOrders.Length);

            // TODO: figure out a way to avoid needing this
            for (int a = 0; a < rebuildTreeBrushIndexOrders.Length; a++)
            {
                foundBrushes.Set(rebuildTreeBrushIndexOrders[a].nodeOrder, true);
            }

            //for (int index1 = 0; index1 < updateBrushIndicesArray.Length; index1++)
            {
                var brush1IndexOrder = rebuildTreeBrushIndexOrders[index1];
                int brush1NodeOrder  = brush1IndexOrder.nodeOrder;

                var brush1Intersections = brushBrushIntersections[brush1NodeOrder];
                if (!brush1Intersections.IsCreated)
                {
                    brush1Intersections = new UnsafeList <BrushIntersectWith>(16, allocator);
                }
                for (int index0 = 0; index0 < allTreeBrushIndexOrders.Length; index0++)
                {
                    var brush0IndexOrder = allTreeBrushIndexOrders[index0];
                    int brush0NodeOrder  = brush0IndexOrder.nodeOrder;
                    if (brush0NodeOrder == brush1NodeOrder)
                    {
                        continue;
                    }
                    var found = foundBrushes.IsSet(brush0NodeOrder);
                    if (brush0NodeOrder < brush1NodeOrder && found)
                    {
                        continue;
                    }
                    var result = IntersectionUtility.FindIntersection(brush0NodeOrder, brush1NodeOrder,
                                                                      ref brushMeshLookup, ref brushTreeSpaceBounds, ref transformationCache,
                                                                      ref transformedPlanes0, ref transformedPlanes1);
                    if (result == IntersectionType.NoIntersection)
                    {
                        continue;
                    }
                    if (!found)
                    {
                        if (!usedBrushes.IsSet(brush0IndexOrder.nodeOrder))
                        {
                            usedBrushes.Set(brush0IndexOrder.nodeOrder, true);
                            brushesThatNeedIndirectUpdateHashMap.Add(brush0IndexOrder);
                            result = IntersectionUtility.Flip(result);
                            IntersectionUtility.StoreIntersection(ref brush1Intersections, brush0IndexOrder, result);
                        }
                    }
                    else
                    {
                        if (brush0NodeOrder > brush1NodeOrder)
                        {
                            result = IntersectionUtility.Flip(result);
                            IntersectionUtility.StoreIntersection(ref brush1Intersections, brush0IndexOrder, result);
                        }
                    }
                }
                brushBrushIntersections[brush1NodeOrder] = brush1Intersections;
            }
        }
Esempio n. 18
0
 /// <summary>
 /// Sorts the container in ascending order.
 /// </summary>
 /// <typeparam name="T">Source type of elements</typeparam>
 /// <param name="container">The container to perform sort.</param>
 /// <param name="inputDeps">The job handle or handles for any scheduled jobs that use this container.</param>
 /// <returns>A new job handle containing the prior handles as well as the handle for the job that sorts
 /// the container.</returns>
 public unsafe static JobHandle Sort <T>(this UnsafeList <T> container, JobHandle inputDeps)
     where T : unmanaged, IComparable <T>
 {
     return(container.Sort(new DefaultComparer <T>(), inputDeps));
 }
Esempio n. 19
0
 public void Dispose()
 {
     UnsafeList.Destroy(m_ListData);
 }
Esempio n. 20
0
 /// <summary>
 /// Sorts the container using a custom comparison function.
 /// </summary>
 /// <typeparam name="T">Source type of elements</typeparam>
 /// <typeparam name="U">The comparer type.</typeparam>
 /// <param name="container">The container to perform sort.</param>
 /// <param name="comp">A comparison function that indicates whether one element in the array is less than, equal to, or greater than another element.</param>
 /// <param name="inputDeps">The job handle or handles for any scheduled jobs that use this container.</param>
 /// <returns>A new job handle containing the prior handles as well as the handle for the job that sorts
 /// the container.</returns>
 public unsafe static JobHandle Sort <T, U>(this UnsafeList <T> container, U comp, JobHandle inputDeps)
     where T : unmanaged
     where U : IComparer <T>
 {
     return(Sort(container.Ptr, container.Length, comp, inputDeps));
 }
        public void Execute(int index)
        {
            var count = input.BeginForEachIndex(index);

            if (count == 0)
            {
                return;
            }

            var brushIndexOrder = input.Read <IndexOrder>();
            var brushNodeOrder  = brushIndexOrder.nodeOrder;
            var vertexCount     = input.Read <int>();

            NativeCollectionHelpers.EnsureCapacityAndClear(ref brushVertices, vertexCount);
            for (int v = 0; v < vertexCount; v++)
            {
                var vertex = input.Read <float3>();
                brushVertices.AddNoResize(vertex);
            }


            var surfaceOuterCount = input.Read <int>();

            NativeCollectionHelpers.EnsureSizeAndClear(ref surfaceLoopIndices, surfaceOuterCount);
            for (int o = 0; o < surfaceOuterCount; o++)
            {
                UnsafeList <int> inner = default;
                var surfaceInnerCount  = input.Read <int>();
                if (surfaceInnerCount > 0)
                {
                    inner = new UnsafeList <int>(surfaceInnerCount, Allocator.Temp);
                    //inner.ResizeUninitialized(surfaceInnerCount);
                    for (int i = 0; i < surfaceInnerCount; i++)
                    {
                        inner.AddNoResize(input.Read <int>());
                    }
                }
                surfaceLoopIndices[o] = inner;
            }

            var surfaceLoopCount = input.Read <int>();

            NativeCollectionHelpers.EnsureMinimumSizeAndClear(ref surfaceLoopAllInfos, surfaceLoopCount);
            NativeCollectionHelpers.EnsureSizeAndClear(ref surfaceLoopAllEdges, surfaceLoopCount);
            for (int l = 0; l < surfaceLoopCount; l++)
            {
                surfaceLoopAllInfos[l] = input.Read <SurfaceInfo>();
                var edgeCount = input.Read <int>();
                if (edgeCount > 0)
                {
                    var edgesInner = new UnsafeList <Edge>(edgeCount, Allocator.Temp);
                    //edgesInner.ResizeUninitialized(edgeCount);
                    for (int e = 0; e < edgeCount; e++)
                    {
                        edgesInner.AddNoResize(input.Read <Edge>());
                    }
                    surfaceLoopAllEdges[l] = edgesInner;
                }
            }
            input.EndForEachIndex();



            if (!basePolygonCache[brushNodeOrder].IsCreated)
            {
                return;
            }

            var maxLoops   = 0;
            var maxIndices = 0;

            for (int s = 0; s < surfaceLoopIndices.Length; s++)
            {
                if (!surfaceLoopIndices[s].IsCreated)
                {
                    continue;
                }
                var length = surfaceLoopIndices[s].Length;
                maxIndices += length;
                maxLoops    = math.max(maxLoops, length);
            }


            ref var baseSurfaces                = ref basePolygonCache[brushNodeOrder].Value.surfaces;
Esempio n. 22
0
 /// <summary>
 /// Binary search for the value in the sorted container.
 /// </summary>
 /// <typeparam name="T">Source type of elements</typeparam>
 /// <param name="container">The container to perform search.</param>
 /// <param name="value">The value to search for.</param>
 /// <returns>Positive index of the specified value if value is found. Otherwise bitwise complement of index of first greater value.</returns>
 /// <remarks>Array must be sorted, otherwise value searched might not be found even when it is in array. IComparer corresponds to IComparer used by sort.</remarks>
 public static int BinarySearch <T>(this UnsafeList <T> container, T value)
     where T : unmanaged, IComparable <T>
 {
     return(container.BinarySearch(value, new DefaultComparer <T>()));
 }
Esempio n. 23
0
            public void Execute(int index)
            {
                var chunk     = Chunks[index].m_Chunk;
                var archetype = chunk->Archetype;

                if (!archetype->CompareMask(QueryMask)) // Archetype doesn't match required query
                {
                    return;
                }

                var changesForChunk = GatheredChanges + index;

                if (ShadowChunksBySequenceNumber.TryGetValue(chunk->SequenceNumber, out var shadow))
                {
                    if (!ChangeVersionUtility.DidChange(chunk->GetChangeVersion(0), shadow.Version))
                    {
                        return;
                    }

                    if (!changesForChunk->AddedEntities.IsCreated)
                    {
                        changesForChunk->AddedEntities   = new UnsafeList(Allocator.TempJob);
                        changesForChunk->RemovedEntities = new UnsafeList(Allocator.TempJob);
                    }

                    var currentEntity    = (Entity *)(chunk->Buffer + archetype->Offsets[0]);
                    var entityFromShadow = (Entity *)shadow.EntityBuffer;

                    var currentCount = chunk->Count;
                    var shadowCount  = shadow.Count;

                    var i = 0;

                    for (; i < currentCount && i < shadowCount; i++)
                    {
                        if (currentEntity[i] == entityFromShadow[i])
                        {
                            continue;
                        }

                        // Was a valid entity but version was incremented, thus destroyed
                        if (entityFromShadow[i].Version != 0)
                        {
                            changesForChunk->RemovedEntities.Add(entityFromShadow[i]);
                            changesForChunk->AddedEntities.Add(currentEntity[i]);
                        }
                    }

                    for (; i < currentCount; i++)
                    {
                        // NEW ENTITY!
                        changesForChunk->AddedEntities.Add(currentEntity[i]);
                    }

                    for (; i < shadowCount; i++)
                    {
                        // REMOVED ENTITY!
                        changesForChunk->RemovedEntities.Add(entityFromShadow[i]);
                    }
                }
                else
                {
                    // This is a new chunk
                    var addedComponentEntities = new UnsafeList(sizeof(Entity), 4, chunk->Count, Allocator.TempJob);

                    var entityDataPtr = chunk->Buffer + archetype->Offsets[0];

                    addedComponentEntities.AddRange <Entity>(entityDataPtr, chunk->Count);

                    changesForChunk->AddedEntities = addedComponentEntities;
                }
            }
Esempio n. 24
0
 /// <summary>
 /// Binary search for the value in the sorted container.
 /// </summary>
 /// <typeparam name="T">Source type of elements</typeparam>
 /// <typeparam name="U">The comparer type.</typeparam>
 /// <param name="container">The container to perform search.</param>
 /// <param name="value">The value to search for.</param>
 /// <returns>Positive index of the specified value if value is found. Otherwise bitwise complement of index of first greater value.</returns>
 /// <remarks>Array must be sorted, otherwise value searched might not be found even when it is in array. IComparer corresponds to IComparer used by sort.</remarks>
 public unsafe static int BinarySearch <T, U>(this UnsafeList <T> container, T value, U comp)
     where T : unmanaged
     where U : IComparer <T>
 {
     return(BinarySearch(container.Ptr, container.Length, value, comp));
 }
Esempio n. 25
0
        public void DestroyEntities(Entity *entities, int count)
        {
            var entityIndex = 0;

            var additionalDestroyList = new UnsafeList(Allocator.Persistent);
            int minDestroyStride      = int.MaxValue;
            int maxDestroyStride      = 0;

            while (entityIndex != count)
            {
                var entityBatchInChunk =
                    GetFirstEntityBatchInChunk(entities + entityIndex, count - entityIndex);
                var chunk        = entityBatchInChunk.Chunk;
                var batchCount   = entityBatchInChunk.Count;
                var indexInChunk = entityBatchInChunk.StartIndex;

                if (chunk == null)
                {
                    entityIndex += batchCount;
                    continue;
                }

                AddToDestroyList(chunk, indexInChunk, batchCount, count, ref additionalDestroyList,
                                 ref minDestroyStride, ref maxDestroyStride);

                DestroyBatch(new EntityBatchInChunk {
                    Chunk = chunk, StartIndex = indexInChunk, Count = batchCount
                });

                entityIndex += batchCount;
            }

            // Apply additional destroys from any LinkedEntityGroup
            if (additionalDestroyList.Ptr != null)
            {
                var additionalDestroyPtr = (Entity *)additionalDestroyList.Ptr;
                // Optimal for destruction speed is if entities with same archetype/chunk are followed one after another.
                // So we lay out the to be destroyed objects assuming that the destroyed entities are "similar":
                // Reorder destruction by index in entityGroupArray...

                //@TODO: This is a very specialized fastpath that is likely only going to give benefits in the stress test.
                ///      Figure out how to make this more general purpose.
                if (minDestroyStride == maxDestroyStride)
                {
                    var reordered = (Entity *)UnsafeUtility.Malloc(additionalDestroyList.Length * sizeof(Entity), 16,
                                                                   Allocator.TempJob);
                    int batchCount = additionalDestroyList.Length / minDestroyStride;
                    for (int i = 0; i != batchCount; i++)
                    {
                        for (int j = 0; j != minDestroyStride; j++)
                        {
                            reordered[j * batchCount + i] = additionalDestroyPtr[i * minDestroyStride + j];
                        }
                    }

                    DestroyEntities(reordered, additionalDestroyList.Length);
                    UnsafeUtility.Free(reordered, Allocator.TempJob);
                }
                else
                {
                    DestroyEntities(additionalDestroyPtr, additionalDestroyList.Length);
                }

                UnsafeUtility.Free(additionalDestroyPtr, Allocator.Persistent);
            }
        }
Esempio n. 26
0
        /// <summary>
        /// Decompose the polygon into several smaller non-concave polygon.
        /// If the polygon is already convex, it will return the original polygon, unless it is over MaxPolygonVertices.
        /// </summary>
        public static bool ConvexPartition(NativeList <SegmentVertex> srcVertices, ref UnsafeList <SegmentVertex> outputVertices, ref UnsafeList <int> outputRanges, int defaultSegment = 0)
        {
            Debug.Assert(srcVertices.Length > 3);

            var allVertices = new NativeList <SegmentVertex>(Allocator.Temp);
            var ranges      = new NativeList <Range>(Allocator.Temp);

            try
            {
                allVertices.AddRange(srcVertices);
                ranges.Add(new Range {
                    start = 0, end = srcVertices.Length
                });

                var originalVertexCount = srcVertices.Length * 2;

                int counter = 0;
                while (counter < ranges.Length)
                {
                    var vertices = allVertices;
                    var range    = ranges[counter];

                    counter++;
                    if (counter > originalVertexCount)
                    {
                        Debug.LogWarning($"counter > {originalVertexCount}");
                        return(false);
                    }

                    var count = range.Length;
                    if (count == 0)
                    {
                        continue;
                    }

                    ForceCounterClockWise(vertices, range);

                    int reflexIndex;
                    for (reflexIndex = 0; reflexIndex < count; ++reflexIndex)
                    {
                        if (Reflex(reflexIndex, vertices, range))
                        {
                            break;
                        }
                    }

                    // Check if polygon is already convex
                    if (reflexIndex == count)
                    {
                        // Check if polygon is degenerate, in which case we skip it
                        if (math.abs(GetSignedDoubleArea(vertices, range)) <= 0.0f)
                        {
                            continue;
                        }

                        var desiredCapacity = outputVertices.Length + range.Length;
                        if (outputVertices.Capacity < desiredCapacity)
                        {
                            outputVertices.Capacity = desiredCapacity;
                        }
                        for (int n = range.start; n < range.end; n++)
                        {
                            outputVertices.Add(vertices[n]);
                        }
                        outputRanges.Add(outputVertices.Length);
                        continue;
                    }

                    int i = reflexIndex;

                    var lowerDist  = float.PositiveInfinity;
                    var lowerInt   = float2.zero;
                    var lowerIndex = 0;

                    var upperDist  = float.PositiveInfinity;
                    var upperInt   = float2.zero;
                    var upperIndex = 0;
                    for (int j = 0; j < count; ++j)
                    {
                        // if line intersects with an edge
                        if (Left(At(i - 1, vertices, range).position, At(i, vertices, range).position, At(j, vertices, range).position) &&
                            RightOn(At(i - 1, vertices, range).position, At(i, vertices, range).position, At(j - 1, vertices, range).position))
                        {
                            // find the point of intersection
                            var p = LineIntersect(At(i - 1, vertices, range).position,
                                                  At(i, vertices, range).position,
                                                  At(j, vertices, range).position,
                                                  At(j - 1, vertices, range).position);
                            if (RightOn(At(i + 1, vertices, range).position,
                                        At(i, vertices, range).position, p))
                            {
                                // make sure it's inside the poly
                                var d = SquareDist(At(i, vertices, range).position, p);
                                if (d < lowerDist)
                                {
                                    // keep only the closest intersection
                                    lowerDist  = d;
                                    lowerInt   = p;
                                    lowerIndex = j;
                                }
                            }
                        }

                        if (Left(At(i + 1, vertices, range).position, At(i, vertices, range).position, At(j + 1, vertices, range).position) &&
                            RightOn(At(i + 1, vertices, range).position, At(i, vertices, range).position, At(j, vertices, range).position))
                        {
                            var p = LineIntersect(At(i + 1, vertices, range).position,
                                                  At(i, vertices, range).position,
                                                  At(j, vertices, range).position,
                                                  At(j + 1, vertices, range).position);
                            if (LeftOn(At(i - 1, vertices, range).position,
                                       At(i, vertices, range).position, p))
                            {
                                var d = SquareDist(At(i, vertices, range).position, p);
                                if (d < upperDist)
                                {
                                    upperDist  = d;
                                    upperIndex = j;
                                    upperInt   = p;
                                }
                            }
                        }
                    }


                    // if there are no vertices to connect to, choose a float2 in the middle
                    if (lowerIndex == (upperIndex + 1) % count)
                    {
                        var sp = ((lowerInt + upperInt) / 2.0f);

                        var newRange = Copy(i, upperIndex, vertices, range, allVertices);
                        allVertices.Add(new SegmentVertex {
                            position = sp, segmentIndex = defaultSegment
                        });
                        newRange.end++;
                        ranges.Add(newRange);

                        newRange = Copy(lowerIndex, i, vertices, range, allVertices);
                        allVertices.Add(new SegmentVertex {
                            position = sp, segmentIndex = defaultSegment
                        });
                        newRange.end++;
                        ranges.Add(newRange);
                    }
                    else
                    {
                        double highestScore = 0;
                        double bestIndex    = lowerIndex;
                        while (upperIndex < lowerIndex)
                        {
                            upperIndex += count;
                        }

                        for (int j = lowerIndex; j <= upperIndex; ++j)
                        {
                            if (!CanSee(i, j, vertices, range))
                            {
                                continue;
                            }

                            double score = 1 / (SquareDist(At(i, vertices, range).position,
                                                           At(j, vertices, range).position) + 1);
                            if (Reflex(j, vertices, range))
                            {
                                if (RightOn(At(j - 1, vertices, range).position, At(j, vertices, range).position, At(i, vertices, range).position) &&
                                    LeftOn(At(j + 1, vertices, range).position, At(j, vertices, range).position, At(i, vertices, range).position))
                                {
                                    score += 3;
                                }
                                else
                                {
                                    score += 2;
                                }
                            }
                            else
                            {
                                score += 1;
                            }

                            if (score > highestScore)
                            {
                                bestIndex    = j;
                                highestScore = score;
                            }
                        }

                        ranges.Add(Copy(i, (int)(bestIndex), vertices, range, allVertices));
                        ranges.Add(Copy((int)(bestIndex), i, vertices, range, allVertices));
                    }
                }
                return(outputRanges.Length > 0);
            }
            finally
            {
                allVertices.Dispose();
                allVertices = default;
                ranges.Dispose();
                ranges = default;
            }
        }
Esempio n. 27
0
 public List(int initialCapacity, Allocator allocator)
 {
     _list      = UnsafeList.Create(UnsafeUtility.SizeOf <T>(), UnsafeUtility.AlignOf <T>(), initialCapacity, allocator);
     _allocator = allocator;
 }
            public void Execute(int index)
            {
                var chunk            = Chunks[index].m_Chunk;
                var archetype        = chunk->Archetype;
                var indexInTypeArray = ChunkDataUtility.GetIndexInTypeArray(archetype, TypeIndex);

                if (indexInTypeArray == -1) // Archetype doesn't match required component
                {
                    return;
                }

                var changesForChunk = GatheredChanges + index;

                if (ShadowChunksBySequenceNumber.TryGetValue(chunk->SequenceNumber, out var shadow))
                {
                    if (!ChangeVersionUtility.DidChange(chunk->GetChangeVersion(0), shadow.Version))
                    {
                        return;
                    }

                    if (!changesForChunk->AddedEntities.IsCreated)
                    {
                        changesForChunk->Chunk           = chunk;
                        changesForChunk->AddedEntities   = new UnsafeList(Allocator.TempJob);
                        changesForChunk->RemovedEntities = new UnsafeList(Allocator.TempJob);
                    }

                    var entityDataPtr = (Entity *)(chunk->Buffer + archetype->Offsets[0]);
                    var currentCount  = chunk->Count;
                    var previousCount = shadow.EntityCount;
                    var i             = 0;
                    for (; i < currentCount && i < previousCount; i++)
                    {
                        var currentEntity  = entityDataPtr[i];
                        var previousEntity = shadow.EntityDataBuffer[i];

                        if (currentEntity != previousEntity)
                        {
                            // CHANGED ENTITY!
                            changesForChunk->RemovedEntities.Add(previousEntity);
                            changesForChunk->AddedEntities.Add(currentEntity);
                        }
                    }

                    for (; i < currentCount; i++)
                    {
                        // NEW ENTITY!
                        changesForChunk->AddedEntities.Add(entityDataPtr[i]);
                    }

                    for (; i < previousCount; i++)
                    {
                        // REMOVED ENTITY!
                        changesForChunk->RemovedEntities.Add(shadow.EntityDataBuffer[i]);
                    }
                }
                else
                {
                    // This is a new chunk
                    var addedEntities = new UnsafeList(sizeof(Entity), 4, chunk->Count, Allocator.TempJob);
                    var entityDataPtr = chunk->Buffer + archetype->Offsets[0];
                    addedEntities.AddRange <Entity>(entityDataPtr, chunk->Count);
                    changesForChunk->Chunk         = chunk;
                    changesForChunk->AddedEntities = addedEntities;
                }
            }
Esempio n. 29
0
 public unsafe static void Sort <T, U>(this UnsafeList list, U comp) where T : struct where U : IComparer <T>
 {
     IntroSort <T, U>(list.Ptr, list.Length, comp);
 }
 internal void Construct()
 {
     m_TypeHashToIndex = new UnsafeHashMap <long, int>(64, Allocator.Persistent);
     m_Delegates       = new UnsafeList <UnmanagedComponentSystemDelegates>(64, Allocator.Persistent);
     m_DebugNames      = new UnsafeList <FixedString64>(64, Allocator.Persistent);
 }