示例#1
0
        public static void RemoveRange <T>(this NativeListArray <T> .NativeList list, int index, int count) where T : unmanaged
        {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
            AtomicSafetyHandle.CheckWriteAndThrow(list.m_Safety);
#endif
            if (count == 0)
            {
                return;
            }
            if (index < 0 || index + count > list.Length)
            {
                LogRangeError();
                return;
            }
            if (index == 0 && count == list.Length)
            {
                list.Clear();
                return;
            }

            if (index + count < list.Length)
            {
                var listPtr = (T *)list.GetUnsafePtr();
                int size    = sizeof(T);
                UnsafeUtility.MemMove(listPtr + index, listPtr + (index + count), (list.Length - (index + count)) * size);
            }
            list.Resize(list.Length - count, NativeArrayOptions.ClearMemory);
        }
示例#2
0
        public int AllocateItemAndAddValues(NativeListArray <T> .NativeList other)
        {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
            AtomicSafetyHandle.CheckWriteAndBumpSecondaryVersion(m_Safety);
#endif
            var index = m_Array->AllocateItem();
            var ptr   = m_Array->Ptr[index];

            if (ptr == null || !ptr->IsCreated)
            {
                m_Array->InitializeIndex(index, UnsafeUtility.SizeOf <T>(), UnsafeUtility.AlignOf <T>(), other.Length);
            }
            else
            {
                ptr->Clear();
                if (ptr->Capacity < other.Length)
                {
                    ptr->SetCapacity <T>(other.Length);
                }
            }
#if ENABLE_UNITY_COLLECTIONS_CHECKS
            CheckAllocated(m_Array->Ptr[index]);
            var dstList = new NativeList(m_Array->Ptr[index], ref m_Safety);
#else
            var dstList = new NativeList(m_Array->Ptr[index]);
#endif
            dstList.AddRangeNoResize(other);
            return(index);
        }
        public static void CopyFrom <T>(this NativeListArray <T> .NativeList list, NativeList <T> elements, int start, int count) where T : unmanaged
        {
            CheckLengthInRange(count, elements.Length);
            CheckIndexInRangeInc(start, elements.Length - count);

            list.Clear();
            list.AddRangeNoResize((T *)elements.GetUnsafeReadOnlyPtr() + start, count);
        }
示例#4
0
        public static void *GetUnsafePtr <T>(this NativeListArray <T> .NativeList list)
            where T : unmanaged
        {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
            AtomicSafetyHandle.CheckWriteAndThrow(list.m_Safety);
#endif
            return(list.m_ListData->Ptr);
        }
示例#5
0
 /*
  * public static void RemoveAt<T>(this NativeListArray<T>.NativeList list, int index)
  *  where T : unmanaged, IEquatable<T>
  * {
  *  RemoveRange(list, index, 1);
  * }
  *
  * public static void Remove<T>(this NativeListArray<T>.NativeList list, T item)
  *  where T : unmanaged, IEquatable<T>
  * {
  *  for (int index = 0; index < list.Length; index++)
  *  {
  *      if (list[index].Equals(item))
  *      {
  *          RemoveRange(list, index, 1);
  *          return;
  *      }
  *  }
  * }
  */
 public static void Remove(this NativeListArray <int> .NativeList list, int item)
 {
     for (int index = 0; index < list.Length; index++)
     {
         if (list[index] == item)
         {
             RemoveRange(list, index, 1);
             return;
         }
     }
 }
示例#6
0
 public static void Remove(this NativeListArray <Edge> .NativeList list, Edge item)
 {
     for (int index = 0; index < list.Length; index++)
     {
         if (list[index].index1 == item.index1 &&
             list[index].index2 == item.index2)
         {
             RemoveRange(list, index, 1);
             return;
         }
     }
 }
示例#7
0
        public unsafe void ReplaceIfExists(NativeListArray <float3> .NativeList uniqueVertices)
        {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
            AtomicSafetyHandle.CheckWriteAndThrow(m_Safety);
#endif
            // Add Unique vertex
            for (int i = 0; i < uniqueVertices.Length; i++)
            {
                var vertex = uniqueVertices[i];
                HashedVerticesUtility.ReplaceIfExists((ushort *)m_HashTable, m_ChainedIndices, m_Vertices, vertex);
            }
        }
示例#8
0
 public static void EnsureConstantSizeAndClear <T>(ref NativeListArray <T> array, int constantSize, Allocator allocator = Allocator.Temp)
     where T : unmanaged
 {
     if (!array.IsCreated)
     {
         array = new NativeListArray <T>(constantSize, allocator);
     }
     else
     {
         array.ClearChildren();
     }
 }
示例#9
0
 public static bool Contains <T>(this NativeListArray <T> .NativeList array, T item)
     where T : unmanaged, IEquatable <T>
 {
     for (int index = 0; index < array.Length; index++)
     {
         if (array[index].Equals(item))
         {
             return(true);
         }
     }
     return(false);
 }
示例#10
0
 public static bool Contains(this NativeListArray <Edge> .NativeList array, Edge item)
 {
     for (int index = 0; index < array.Length; index++)
     {
         if (array[index].index1 == item.index1 &&
             array[index].index2 == item.index2)
         {
             return(true);
         }
     }
     return(false);
 }
 public static int IndexOf(NativeListArray <Edge> .NativeList edges, Edge edge, out bool inverted)
 {
     for (int e = 0; e < edges.Length; e++)
     {
         if (edges[e].index1 == edge.index1 && edges[e].index2 == edge.index2)
         {
             inverted = false; return(e);
         }
         if (edges[e].index1 == edge.index2 && edges[e].index2 == edge.index1)
         {
             inverted = true; return(e);
         }
     }
     inverted = false;
     return(-1);
 }
示例#12
0
 public static void EnsureSizeAndClear <T>(ref NativeListArray <T> array, int exactSize, Allocator allocator = Allocator.Temp)
     where T : unmanaged
 {
     if (!array.IsCreated || array.Capacity < exactSize)
     {
         if (array.IsCreated)
         {
             array.Dispose();
         }
         array = new NativeListArray <T>(exactSize, allocator);
     }
     else
     {
         array.ClearChildren();
     }
     array.ResizeExact(exactSize);
 }
示例#13
0
        public static void RemoveDuplicates(ref NativeListArray <Edge> .NativeList edges)
        {
            if (edges.Length < 3)
            {
                edges.Clear();
                return;
            }

            for (int e = edges.Length - 1; e >= 0; e--)
            {
                if (edges[e].index1 != edges[e].index2)
                {
                    continue;
                }
                edges.RemoveAtSwapBack(e);
            }
        }
示例#14
0
        public unsafe void AddUniqueVertices(NativeListArray <float3> .NativeList uniqueVertices)
        {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
            AtomicSafetyHandle.CheckWriteAndThrow(m_Safety);
#endif
            // Add Unique vertex
            for (int i = 0; i < uniqueVertices.Length; i++)
            {
                var vertex         = uniqueVertices[i];
                var centerIndex    = new int3((int)(vertex.x / kCellSize), (int)(vertex.y / kCellSize), (int)(vertex.z / kCellSize));
                var hashCode       = HashedVerticesUtility.GetHash(centerIndex);
                var prevChainIndex = ((ushort *)m_HashTable)[hashCode];
                var newChainIndex  = m_ChainedIndices->Length;
                m_Vertices->AddNoResize(vertex);
                m_ChainedIndices->AddNoResize((ushort)prevChainIndex);
                ((ushort *)m_HashTable)[(int)hashCode] = (ushort)(newChainIndex + 1);
            }
        }
示例#15
0
 static int IndexOf(NativeListArray <Edge> .NativeList edges, Edge edge, out bool inverted)
 {
     //var builder = new System.Text.StringBuilder();
     for (int e = 0; e < edges.Length; e++)
     {
         //builder.AppendLine($"{e}/{edges.Count}: {edges[e]} {edge}");
         if (edges[e].index1 == edge.index1 && edges[e].index2 == edge.index2)
         {
             inverted = false; return(e);
         }
         if (edges[e].index1 == edge.index2 && edges[e].index2 == edge.index1)
         {
             inverted = true;  return(e);
         }
     }
     //Debug.Log(builder.ToString());
     inverted = false;
     return(-1);
 }
示例#16
0
        static bool AddEdgesNoResize(NativeListArray <Edge> .NativeList dstEdges, NativeListArray <Edge> .NativeList srcEdges)
        {
            if (srcEdges.Length == 0)
            {
                return(false);
            }

            for (int ae = srcEdges.Length - 1; ae >= 0; ae--)
            {
                var addEdge = srcEdges[ae];
                for (int e = dstEdges.Length - 1; e >= 0;)
                {
                    if (addEdge.Equals(dstEdges[e]))
                    {
                        NotUniqueEdgeException();
                        dstEdges.RemoveAtSwapBack(e);
                    }
                    else
                    {
                        e--;
                    }
                }
            }

            bool duplicates = false;

            for (int v = 0; v < srcEdges.Length; v++)
            {
                var addEdge = srcEdges[v];
                var index   = IndexOf(dstEdges, addEdge, out bool _);
                if (index != -1)
                {
                    //Debug.Log($"Duplicate edge {inverted}  {values[v].index1}/{values[v].index2} {edges[index].index1}/{edges[index].index2}");
                    duplicates = true;
                    continue;
                }
                dstEdges.AddNoResize(addEdge);
            }

            return(duplicates);
        }
示例#17
0
        public JobHandle Dispose(JobHandle dependency)
        {
            JobHandle lastJobHandle = default;

            if (meshDescriptions.IsCreated)
            {
                lastJobHandle = JobHandle.CombineDependencies(lastJobHandle, meshDescriptions.Dispose(dependency));
            }
            if (subMeshSections.IsCreated)
            {
                lastJobHandle = JobHandle.CombineDependencies(lastJobHandle, subMeshSections.Dispose(dependency));
            }
            if (meshes.IsCreated)
            {
                lastJobHandle = JobHandle.CombineDependencies(lastJobHandle, meshes.Dispose(dependency));
            }
            if (triangleBrushIndices.IsCreated)
            {
                lastJobHandle = JobHandle.CombineDependencies(lastJobHandle, triangleBrushIndices.Dispose(dependency));
            }

            if (renderDescriptors.IsCreated)
            {
                lastJobHandle = JobHandle.CombineDependencies(lastJobHandle, renderDescriptors.Dispose(dependency));
            }
            if (colliderDescriptors.IsCreated)
            {
                lastJobHandle = JobHandle.CombineDependencies(lastJobHandle, colliderDescriptors.Dispose(dependency));
            }

            meshDescriptions     = default;
            subMeshSections      = default;
            meshes               = default;
            triangleBrushIndices = default;
            renderDescriptors    = default;
            colliderDescriptors  = default;
            return(lastJobHandle);
        }
示例#18
0
        public void EnsureInitialized()
        {
            if (!meshDescriptions.IsCreated)
            {
                meshDescriptions = new NativeList <GeneratedMeshDescription>(Allocator.Persistent);
            }
            else
            {
                meshDescriptions.Clear();
            }
            if (!subMeshSections.IsCreated)
            {
                subMeshSections = new NativeList <SubMeshSection>(Allocator.Persistent);
            }
            else
            {
                subMeshSections.Clear();
            }
            if (!meshes.IsCreated)
            {
                meshes = new NativeList <Mesh.MeshData>(Allocator.Persistent);
            }
            if (!triangleBrushIndices.IsCreated)
            {
                triangleBrushIndices = new NativeListArray <int>(Allocator.Persistent);
            }

            if (!renderDescriptors.IsCreated)
            {
                renderDescriptors = new NativeArray <VertexAttributeDescriptor>(s_RenderDescriptors, Allocator.Persistent);
            }
            if (!colliderDescriptors.IsCreated)
            {
                colliderDescriptors = new NativeArray <VertexAttributeDescriptor>(s_ColliderDescriptors, Allocator.Persistent);
            }
        }
示例#19
0
        public void Execute(int index)
        {
            //var brushNodeIndex = treeBrushNodeIndices[index];
            var count = input.BeginForEachIndex(index);

            if (count == 0)
            {
                return;
            }

            HashedVertices           brushVertices;
            NativeListArray <int>    surfaceLoopIndices;
            NativeList <SurfaceInfo> surfaceLoopAllInfos;
            NativeListArray <Edge>   surfaceLoopAllEdges;


            var brushNodeIndex = input.Read <int>();
            var vertexCount    = input.Read <int>();

            brushVertices = new HashedVertices(vertexCount, allocator);
            for (int v = 0; v < vertexCount; v++)
            {
                var vertex = input.Read <float3>();
                brushVertices.AddNoResize(vertex);
            }


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

            surfaceLoopIndices = new NativeListArray <int>(surfaceOuterCount, allocator);
            surfaceLoopIndices.ResizeExact(surfaceOuterCount);
            for (int o = 0; o < surfaceOuterCount; o++)
            {
                var surfaceInnerCount = input.Read <int>();
                if (surfaceInnerCount > 0)
                {
                    var inner = surfaceLoopIndices.AllocateWithCapacityForIndex(o, surfaceInnerCount);
                    //inner.ResizeUninitialized(surfaceInnerCount);
                    for (int i = 0; i < surfaceInnerCount; i++)
                    {
                        inner.AddNoResize(input.Read <int>());
                    }
                }
            }

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

            surfaceLoopAllInfos = new NativeList <SurfaceInfo>(surfaceLoopCount, allocator);
            surfaceLoopAllEdges = new NativeListArray <Edge>(surfaceLoopCount, allocator);

            surfaceLoopAllInfos.ResizeUninitialized(surfaceLoopCount);
            surfaceLoopAllEdges.ResizeExact(surfaceLoopCount);
            for (int l = 0; l < surfaceLoopCount; l++)
            {
                surfaceLoopAllInfos[l] = input.Read <SurfaceInfo>();
                var edgeCount = input.Read <int>();
                if (edgeCount > 0)
                {
                    var edgesInner = surfaceLoopAllEdges.AllocateWithCapacityForIndex(l, edgeCount);
                    //edgesInner.ResizeUninitialized(edgeCount);
                    for (int e = 0; e < edgeCount; e++)
                    {
                        edgesInner.AddNoResize(input.Read <Edge>());
                    }
                }
            }
            input.EndForEachIndex();



            var maxLoops   = 0;
            var maxIndices = 0;

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


            ref var baseSurfaces                = ref basePolygons[brushNodeIndex].Value.surfaces;
示例#20
0
 public void AddRangeNoResize(NativeListArray <T> .NativeList list)
 {
     AddRangeNoResize(list.GetUnsafeReadOnlyPtr(), list.Length);
 }
示例#21
0
 void CopyFrom(NativeListArray <Edge> dst, int index, ref BrushIntersectionLoop brushIntersectionLoop, HashedVertices hashedTreeSpaceVertices, int extraCapacity)
 {
     ref var vertexIndex     = ref brushIntersectionLoop.loopVertexIndex;
示例#22
0
        void IntersectLoopsJob(HashedVertices brushVertices,

                               NativeListArray <int> .NativeList loopIndices,
                               int surfaceLoopIndex,

                               NativeListArray <int> holeIndices,
                               NativeList <SurfaceInfo> allInfos,
                               NativeListArray <Edge> allEdges,

                               NativeListArray <Edge> .NativeList intersectionLoop,
                               CategoryGroupIndex intersectionCategory,
                               SurfaceInfo intersectionInfo)
        {
            if (intersectionLoop.Length == 0)
            {
                return;
            }

            //Debug.Assert(allEdges.Length == allInfos.Length);
            //Debug.Assert(allInfos.Length == holeIndices.Length);

            var currentLoopEdges   = allEdges[surfaceLoopIndex];
            var currentInfo        = allInfos[surfaceLoopIndex];
            var currentHoleIndices = holeIndices[surfaceLoopIndex];

            // It might look like we could just set the interiorCategory of brush_intersection here, and let all other cut loops copy from it below,
            // but the same brush_intersection might be used by another categorized_loop and then we'd try to reroute it again, which wouldn't work
            //brush_intersection.interiorCategory = newHoleCategory;

            if (currentLoopEdges.Length == 0)
            {
                return;
            }

            var maxLength = math.max(intersectionLoop.Length, currentLoopEdges.Length);

            if (maxLength < 3)
            {
                return;
            }

            int inside2 = 0, outside2 = 0;
            var categories2      = stackalloc EdgeCategory[currentLoopEdges.Length];
            var treeSpacePlanes1 = brushTreeSpacePlanes[intersectionInfo.brushNodeIndex];

            for (int e = 0; e < currentLoopEdges.Length; e++)
            {
                var category = BooleanEdgesUtility.CategorizeEdge(currentLoopEdges[e], ref treeSpacePlanes1.Value.treeSpacePlanes, intersectionLoop, brushVertices);
                categories2[e] = category;
                if (category == EdgeCategory.Inside)
                {
                    inside2++;
                }
                else if (category == EdgeCategory.Outside)
                {
                    outside2++;
                }
            }
            var aligned2 = currentLoopEdges.Length - (inside2 + outside2);

            int inside1 = 0, outside1 = 0;
            var categories1      = stackalloc EdgeCategory[intersectionLoop.Length];
            var treeSpacePlanes2 = brushTreeSpacePlanes[currentInfo.brushNodeIndex];

            for (int e = 0; e < intersectionLoop.Length; e++)
            {
                var category = BooleanEdgesUtility.CategorizeEdge(intersectionLoop[e], ref treeSpacePlanes2.Value.treeSpacePlanes, currentLoopEdges, brushVertices);
                categories1[e] = category;
                if (category == EdgeCategory.Inside)
                {
                    inside1++;
                }
                else if (category == EdgeCategory.Outside)
                {
                    outside1++;
                }
            }
            var aligned1 = intersectionLoop.Length - (inside1 + outside1);

            // Completely outside
            if ((inside1 + aligned1) == 0 && (aligned2 + inside2) == 0)
            {
                return;
            }

            if ((inside1 + (inside2 + aligned2)) < 3)
            {
                return;
            }

            // Completely aligned
            if (((outside1 + inside1) == 0 && (outside2 + inside2) == 0) ||
                // polygon1 edges Completely inside polygon2
                (inside1 == 0 && outside2 == 0))
            {
                // New polygon overrides the existing polygon
                currentInfo.interiorCategory = intersectionCategory;
                allInfos[surfaceLoopIndex]   = currentInfo;
                //Debug.Assert(holeIndices.IsAllocated(surfaceLoopIndex));
                return;
            }


            var outEdges       = stackalloc Edge[maxLength];
            var outEdgesLength = 0;

            // polygon2 edges Completely inside polygon1
            if (outside1 == 0 && inside2 == 0)
            {
                // polygon1 Completely inside polygon2
                for (int n = 0; n < intersectionLoop.Length; n++)
                {
                    outEdges[outEdgesLength] = intersectionLoop[n];
                    outEdgesLength++;
                }
                //OperationResult.Polygon1InsidePolygon2;
            }
            else
            {
                //int outEdgesLength = 0; // Can't read from outEdges.Length since it's marked as WriteOnly
                for (int e = 0; e < intersectionLoop.Length; e++)
                {
                    var category = categories1[e];
                    if (category == EdgeCategory.Inside)
                    {
                        outEdges[outEdgesLength] = intersectionLoop[e];
                        outEdgesLength++;
                    }
                }

                for (int e = 0; e < currentLoopEdges.Length; e++)
                {
                    var category = categories2[e];
                    if (category != EdgeCategory.Outside)
                    {
                        outEdges[outEdgesLength] = currentLoopEdges[e];
                        outEdgesLength++;
                    }
                }
                //OperationResult.Cut;
            }

            if (outEdgesLength < 3)
            {
                return;
            }

            // FIXME: when brush_intersection and categorized_loop are grazing each other,
            //          technically we cut it but we shouldn't be creating it as a separate polygon + hole (bug7)

            // the output of cutting operations are both holes for the original polygon (categorized_loop)
            // and new polygons on the surface of the brush that need to be categorized
            intersectionInfo.interiorCategory = intersectionCategory;


            if (currentHoleIndices.Length > 0 &&
                // TODO: fix touching not being updated properly
                brushesTouchedByBrushes.ContainsKey(currentInfo.brushNodeIndex))
            {
                // Figure out why this is seemingly not necessary?
                var intersectedHoleIndices       = stackalloc int[currentHoleIndices.Length];
                var intersectedHoleIndicesLength = 0;

                // the output of cutting operations are both holes for the original polygon (categorized_loop)
                // and new polygons on the surface of the brush that need to be categorized

                ref var brushesTouchedByBrush = ref brushesTouchedByBrushes[currentInfo.brushNodeIndex].Value;
                ref var brushIntersections    = ref brushesTouchedByBrushes[currentInfo.brushNodeIndex].Value.brushIntersections;
示例#23
0
 public static void AddRangeNoResize <T>(this NativeList <T> list, NativeListArray <T> .NativeList elements) where T : unmanaged
 {
     list.AddRangeNoResize(elements.GetUnsafeReadOnlyPtr(), elements.Length);
 }