コード例 #1
0
 internal SharedComponentDataArray(SharedComponentDataManager sharedComponentDataManager,
                                   int sharedComponentIndex, ComponentChunkIterator iterator, int length, AtomicSafetyHandle safety)
コード例 #2
0
 internal void SetAtomicSafetyHandle(AtomicSafetyHandle safety)
 {
     m_Safety = safety;
 }
コード例 #3
0
        internal static unsafe JobHandle ScheduleInternal <T>(
            ref T jobData,
            EntityQuery query,
            JobHandle dependsOn,
            ScheduleMode mode,
            int batchesPerChunk,
            bool isParallel = true,
            NativeArray <Entity> limitToEntityArray = default(NativeArray <Entity>))
            where T : struct, IJobEntityBatchWithIndex
        {
            var queryImpl = query._GetImpl();
            var queryData = queryImpl->_QueryData;

            var batchCount                     = 0;
            var filteredChunkCount             = 0;
            var useEntityArray                 = limitToEntityArray.IsCreated;
            var prebuiltBatchList              = new UnsafeList(Allocator.TempJob);
            var perBatchMatchingArchetypeIndex = new UnsafeIntList(0, Allocator.TempJob);

            if (useEntityArray)
            {
                // Forces the creation of an EntityQueryMask, which is necessary to filter batches.
                var access = queryImpl->_Access;
                access->EntityQueryManager->GetEntityQueryMask(queryData, access->EntityComponentStore);

                ChunkIterationUtility.FindBatchesForEntityArrayWithQuery(
                    queryImpl->_Access->EntityComponentStore,
                    queryData,
                    ref queryImpl->_Filter,
                    (Entity *)limitToEntityArray.GetUnsafePtr(),
                    limitToEntityArray.Length,
                    ref prebuiltBatchList,
                    ref perBatchMatchingArchetypeIndex);

                batchCount = prebuiltBatchList.Length;
            }
            else
            {
                filteredChunkCount = query.CalculateChunkCount();
                batchCount         = filteredChunkCount * batchesPerChunk;
            }

            // Allocate one buffer for all prefilter data and distribute it
            // We keep the full buffer as a "dummy array" so we can deallocate it later with [DeallocateOnJobCompletion]
            var sizeofBatchArray  = sizeof(ArchetypeChunk) * batchCount;
            var sizeofIndexArray  = sizeof(int) * batchCount;
            var prefilterDataSize = sizeofBatchArray + sizeofIndexArray + sizeof(int);

            var prefilterData      = (byte *)Memory.Unmanaged.Allocate(prefilterDataSize, 64, Allocator.TempJob);
            var prefilterDataArray = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <byte>(prefilterData, prefilterDataSize, Allocator.TempJob);

#if ENABLE_UNITY_COLLECTIONS_CHECKS
            NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref prefilterDataArray, AtomicSafetyHandle.Create());
#endif

            var prefilterHandle = dependsOn;
            if (useEntityArray)
            {
                var prefilterJob = new PrefilterForJobEntityBatchWithIndex_EntityArray
                {
                    MatchingArchetypes             = queryImpl->_QueryData->MatchingArchetypes,
                    Filter                         = queryImpl->_Filter,
                    EntityComponentStore           = queryImpl->_Access->EntityComponentStore,
                    PrefilterData                  = prefilterData,
                    PrebuiltBatches                = prebuiltBatchList,
                    PerBatchMatchingArchetypeIndex = perBatchMatchingArchetypeIndex
                };

                if (mode != ScheduleMode.Run)
                {
                    prefilterHandle = prefilterJob.Schedule(dependsOn);
                }
                else
                {
                    prefilterJob.Run();
                }

                prefilterHandle = prebuiltBatchList.Dispose(prefilterHandle);
                prefilterHandle = perBatchMatchingArchetypeIndex.Dispose(prefilterHandle);
            }
            else
            {
                var prefilterJob = new PrefilterForJobEntityBatchWithIndex
                {
                    MatchingArchetypes   = queryImpl->_QueryData->MatchingArchetypes,
                    Filter               = queryImpl->_Filter,
                    BatchesPerChunk      = batchesPerChunk,
                    EntityComponentStore = queryImpl->_Access->EntityComponentStore,
                    PrefilterData        = prefilterData,
                    FilteredChunkCount   = filteredChunkCount
                };

                if (mode != ScheduleMode.Run)
                {
                    prefilterHandle = prefilterJob.Schedule(dependsOn);
                }
                else
                {
                    prefilterJob.Run();
                }
            }


            JobEntityBatchIndexWrapper <T> jobEntityBatchIndexWrapper = new JobEntityBatchIndexWrapper <T>
            {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
                // All IJobEntityBatchWithIndex jobs have a EntityManager safety handle to ensure that BeforeStructuralChange throws an error if
                // jobs without any other safety handles are still running (haven't been synced).
                safety = new EntitySafetyHandle {
                    m_Safety = queryImpl->SafetyHandles->GetEntityManagerSafetyHandle()
                },
#endif

                JobData       = jobData,
                PrefilterData = prefilterDataArray,

                JobsPerChunk = batchesPerChunk,
                IsParallel   = isParallel ? 1 : 0
            };

            var scheduleParams = new JobsUtility.JobScheduleParameters(
                UnsafeUtility.AddressOf(ref jobEntityBatchIndexWrapper),
                isParallel
                ? JobEntityBatchIndexProducer <T> .InitializeParallel()
                : JobEntityBatchIndexProducer <T> .InitializeSingle(),
                prefilterHandle,
                mode);

#if UNITY_DOTSRUNTIME
            // This should just be a call to FinalizeScheduleChecked, but DOTSR requires the JobsUtility calls to be
            // in this specific function.
#if ENABLE_UNITY_COLLECTIONS_CHECKS
            try
            {
#endif
            if (!isParallel)
            {
                return(JobsUtility.Schedule(ref scheduleParams));
            }
            else
            {
                return(JobsUtility.ScheduleParallelFor(ref scheduleParams, batchCount, 1));
            }
#if ENABLE_UNITY_COLLECTIONS_CHECKS
        }

        catch (InvalidOperationException e)
        {
            prefilterHandle.Complete();
            prefilterDataArray.Dispose();
            throw e;
        }
#endif
#else
            // We can't use try {} catch {} with 2020.2 as we will be burst compiling the schedule code.
            // Burst doesn't support exception handling.
            bool executedManaged = false;
            JobHandle result     = default;
            FinalizeScheduleChecked(isParallel, batchCount, prefilterHandle, prefilterDataArray, ref scheduleParams, ref executedManaged, ref result);

            if (executedManaged)
            {
                return(result);
            }

            return(FinalizeScheduleNoExceptions(isParallel, batchCount, ref scheduleParams));
#endif
        }
コード例 #4
0
 internal ScriptableRenderContext(IntPtr ptr, AtomicSafetyHandle safety)
 {
     m_Ptr    = ptr;
     m_Safety = safety;
 }
コード例 #5
0
        void CheckRead()
        {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
            AtomicSafetyHandle.CheckReadAndThrow(m_Safety);
#endif
        }
コード例 #6
0
 private static void DisposeSafetyChecks(AtomicSafetyHandle handle)
 {
     AtomicSafetyHandle.Release(handle);
 }
コード例 #7
0
        unsafe NativeList(int capacity, Allocator i_label, int stackDepth)
        {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
#if UNITY_2018_3_OR_NEWER
            var guardian = new NativeBufferSentinel(stackDepth, i_label);
            m_Safety = (i_label == Allocator.Temp) ? AtomicSafetyHandle.GetTempMemoryHandle() : AtomicSafetyHandle.Create();
#else
            var guardian = new NativeBufferSentinel(stackDepth);
            m_Safety = AtomicSafetyHandle.Create();
#endif
            m_Impl = new NativeListImpl <T, DefaultMemoryManager, NativeBufferSentinel>(capacity, i_label, guardian);
#else
            m_Impl = new NativeListImpl <T, DefaultMemoryManager>(capacity, i_label);
#endif
        }
コード例 #8
0
    protected override void OnUpdate()
    {
        Entities.ForEach((MeshFilter meshFilter, VertexClothGarment garment) =>
        {
            var mesh        = meshFilter.mesh;
            var vertexCount = mesh.vertexCount;

            var archetype = DstEntityManager.CreateArchetype(
                typeof(ClothProjectedPosition),
                typeof(ClothCurrentPosition),
                typeof(ClothPreviousPosition),
                typeof(ClothDistanceConstraint),
                typeof(ClothPositionOrigin),
                typeof(ClothPinWeight),
                typeof(ClothTotalTime),
                typeof(ClothTimestepData),
                typeof(ClothSourceMeshData));
            var entity = DstEntityManager.CreateEntity(archetype);

            // Add reference to source mesh data and set it as read/write
            mesh.MarkDynamic();

            var meshHandle  = GCHandle.Alloc(mesh, GCHandleType.Pinned);
            var srcMeshData = new ClothSourceMeshData
            {
                SrcMeshHandle = meshHandle
            };
            DstEntityManager.SetComponentData(entity, srcMeshData);
            DstEntityManager.SetComponentData(entity, new ClothTotalTime {
                TotalTime = 0.0f
            });
            DstEntityManager.SetComponentData(entity, new ClothTimestepData {
                FixedTimestep = 1.0f / 60.0f, IterationCount = 0
            });

            // Copy initial vert data to buffer
            var projectedPositionBuffer = DstEntityManager.GetBuffer <ClothProjectedPosition>(entity);
            projectedPositionBuffer.Reserve(vertexCount);

            var currentPositionBuffer = DstEntityManager.GetBuffer <ClothCurrentPosition>(entity);
            currentPositionBuffer.Reserve(vertexCount);

            var previousPositionBuffer = DstEntityManager.GetBuffer <ClothPreviousPosition>(entity);
            previousPositionBuffer.Reserve(vertexCount);

            var originPositionBuffer = DstEntityManager.GetBuffer <ClothPositionOrigin>(entity);
            originPositionBuffer.Reserve(vertexCount);

            fixed(Vector3 * positions = mesh.vertices)
            {
                var currentPositionsAsNativeArray   = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <ClothCurrentPosition>((float3 *)positions, vertexCount, Allocator.Invalid);
                var projectedPositionsAsNativeArray = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <ClothProjectedPosition>((float3 *)positions, vertexCount, Allocator.Invalid);
                var previousPositionsAsNativeArray  = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <ClothPreviousPosition>((float3 *)positions, vertexCount, Allocator.Invalid);
                var originPositionsAsNativeArray    = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <ClothPositionOrigin>((float3 *)positions, vertexCount, Allocator.Invalid);

#if ENABLE_UNITY_COLLECTIONS_CHECKS
                NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref currentPositionsAsNativeArray, AtomicSafetyHandle.Create());
                NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref projectedPositionsAsNativeArray, AtomicSafetyHandle.Create());
                NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref previousPositionsAsNativeArray, AtomicSafetyHandle.Create());
                NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref originPositionsAsNativeArray, AtomicSafetyHandle.Create());
#endif
                currentPositionBuffer.CopyFrom(currentPositionsAsNativeArray);
                projectedPositionBuffer.CopyFrom(projectedPositionsAsNativeArray);
                previousPositionBuffer.CopyFrom(previousPositionsAsNativeArray);
                originPositionBuffer.CopyFrom(originPositionsAsNativeArray);
            }

            // Add constraints to the entity
            // todo: no garbage
            var barLookup = new HashSet <Vector2Int>();
            var triangles = mesh.triangles;
            for (int i = 0; i < triangles.Length; i += 3)
            {
                for (int j = 0; j < 3; j++)
                {
                    Vector2Int pair = new Vector2Int
                    {
                        x = triangles[i + j],
                        y = triangles[i + (j + 1) % 3]
                    };

                    if (pair.x > pair.y)
                    {
                        var newY = pair.x;
                        pair.x   = pair.y;
                        pair.y   = newY;
                    }

                    if (barLookup.Contains(pair) == false)
                    {
                        barLookup.Add(pair);
                    }
                }
            }

            // todo: no garbage
            var barList         = new List <Vector2Int>(barLookup);
            var constraintCount = barList.Count;

            var constraintsBuffer = DstEntityManager.GetBuffer <ClothDistanceConstraint>(entity);
            constraintsBuffer.Reserve(constraintCount);

            var vertices = mesh.vertices;
            for (int i = 0; i < constraintCount; ++i)
            {
                Vector3 p1 = vertices[barList[i].x];
                Vector3 p2 = vertices[barList[i].y];

                constraintsBuffer.Add(new ClothDistanceConstraint
                {
                    RestLengthSqr = (p2 - p1).sqrMagnitude,
                    VertexA       = barList[i].x,
                    VertexB       = barList[i].y
                });
            }

            // Add pin weights
            var pinWeightBuffer = DstEntityManager.GetBuffer <ClothPinWeight>(entity);
            pinWeightBuffer.Reserve(vertexCount);

            var normals = mesh.normals;
            for (int i = 0; i < vertexCount; ++i)
            {
                if (normals[i].y > .9f && vertices[i].y > .3f)
                {
                    pinWeightBuffer.Add(new ClothPinWeight {
                        InvPinWeight = 0.0f
                    });
                }
                else
                {
                    pinWeightBuffer.Add(new ClothPinWeight {
                        InvPinWeight = 1.0f
                    });
                }
            }
        });
    }
コード例 #9
0
 static extern void RemoveQuerySafety(IntPtr navMeshQuery, AtomicSafetyHandle handle);
コード例 #10
0
 public void *GetUnsafePtrReadOnly()
 {
     AtomicSafetyHandle.CheckReadAndThrow(m_Safety);
     return(m_Buffer);
 }
コード例 #11
0
 /// <summary>
 /// Create a parallel version of the object
 /// </summary>
 ///
 /// <param name="value">
 /// Pointer to the value
 /// </param>
 ///
 /// <param name="safety">
 /// Atomic safety handle for the object
 /// </param>
 internal Parallel(int *value, AtomicSafetyHandle safety)
 {
     m_Buffer      = value;
     m_ThreadIndex = 0;
     m_Safety      = safety;
 }
コード例 #12
0
 public void *GetUnsafePtr()
 {
     AtomicSafetyHandle.CheckWriteAndThrow(m_Safety);
     return(m_Buffer);
 }
コード例 #13
0
 private void RequireWriteAccess()
 {
     AtomicSafetyHandle.CheckWriteAndThrow(m_Safety);
 }
コード例 #14
0
 private void RequireReadAccess()
 {
     AtomicSafetyHandle.CheckReadAndThrow(m_Safety);
 }
コード例 #15
0
 internal static BufferAccessor <T> GetChunkBufferAccessor <T>(Chunk *chunk, bool isWriting, int typeIndexInArchetype, uint systemVersion, AtomicSafetyHandle safety0, AtomicSafetyHandle safety1)
コード例 #16
0
 public bool IsValid(PolygonId polygon)
 {
     AtomicSafetyHandle.CheckReadAndThrow(m_Safety);
     return(polygon.polyRef != 0 && IsValidPolygon(m_NavMeshQuery, polygon));
 }
コード例 #17
0
        internal static JobHandle PreparePrefilteredChunkLists(int unfilteredChunkCount, UnsafeMatchingArchetypePtrList archetypes, EntityQueryFilter filter, JobHandle dependsOn, ScheduleMode mode, out NativeArray <byte> prefilterDataArray, out void *deferredCountData)
        {
            // Allocate one buffer for all prefilter data and distribute it
            // We keep the full buffer as a "dummy array" so we can deallocate it later with [DeallocateOnJobCompletion]
            var sizeofChunkArray  = sizeof(ArchetypeChunk) * unfilteredChunkCount;
            var sizeofIndexArray  = sizeof(int) * unfilteredChunkCount;
            var prefilterDataSize = sizeofChunkArray + sizeofIndexArray + sizeof(int);

            var prefilterData = (byte *)UnsafeUtility.Malloc(prefilterDataSize, 64, Allocator.TempJob);

            prefilterDataArray = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <byte>(prefilterData, prefilterDataSize, Allocator.TempJob);

#if ENABLE_UNITY_COLLECTIONS_CHECKS
            NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref prefilterDataArray, AtomicSafetyHandle.Create());
#endif

            JobHandle prefilterHandle = default(JobHandle);

            if (filter.RequiresMatchesFilter)
            {
                var prefilteringJob = new GatherChunksAndOffsetsWithFilteringJob
                {
                    Archetypes           = archetypes,
                    Filter               = filter,
                    PrefilterData        = prefilterData,
                    UnfilteredChunkCount = unfilteredChunkCount
                };
                if (mode == ScheduleMode.Batched)
                {
                    prefilterHandle = prefilteringJob.Schedule(dependsOn);
                }
                else
                {
                    prefilteringJob.Run();
                }
            }
            else
            {
                var gatherJob = new GatherChunksAndOffsetsJob
                {
                    Archetypes           = archetypes,
                    PrefilterData        = prefilterData,
                    UnfilteredChunkCount = unfilteredChunkCount,
                    entityComponentStore = archetypes.entityComponentStore
                };
                if (mode == ScheduleMode.Batched)
                {
                    prefilterHandle = gatherJob.Schedule(dependsOn);
                }
                else
                {
                    gatherJob.Run();
                }
            }

            // ScheduleParallelForDeferArraySize expects a ptr to a structure with a void* and a count.
            // It only uses the count, so this is safe to fudge
            deferredCountData = prefilterData + sizeofChunkArray + sizeofIndexArray;
            deferredCountData = (byte *)deferredCountData - sizeof(void *);

            return(prefilterHandle);
        }
コード例 #18
0
 public int GetAgentTypeIdForPolygon(PolygonId polygon)
 {
     AtomicSafetyHandle.CheckReadAndThrow(m_Safety);
     return(GetAgentTypeIdForPolygon(m_NavMeshQuery, polygon));
 }
コード例 #19
0
 internal BufferArray(ComponentChunkIterator iterator, int length, bool isReadOnly,
                      AtomicSafetyHandle safety, AtomicSafetyHandle arrayInvalidationSafety)
コード例 #20
0
 public NavMeshLocation MapLocation(Vector3 position, Vector3 extents, int agentTypeID, int areaMask = NavMesh.AllAreas)
 {
     AtomicSafetyHandle.CheckReadAndThrow(m_Safety);
     return(MapLocation(m_NavMeshQuery, position, extents, agentTypeID, areaMask));
 }
コード例 #21
0
        private void RequireWriteAccess()
        {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
            AtomicSafetyHandle.CheckWriteAndThrow(m_Safety);
#endif
        }
コード例 #22
0
 public NavMeshLocation MoveLocation(NavMeshLocation location, Vector3 target, int areaMask = NavMesh.AllAreas)
 {
     AtomicSafetyHandle.CheckReadAndThrow(m_Safety);
     return(MoveLocation(m_NavMeshQuery, location, target, areaMask));
 }
コード例 #23
0
 static void CreateStaticSafetyId()
 {
     s_staticSafetyId.Data = AtomicSafetyHandle.NewStaticSafetyId <NativeMultiHashMap <TKey, TValue> >();
 }
コード例 #24
0
 public bool GetPortalPoints(PolygonId polygon, PolygonId neighbourPolygon, out Vector3 left, out Vector3 right)
 {
     AtomicSafetyHandle.CheckReadAndThrow(m_Safety);
     return(GetPortalPoints(m_NavMeshQuery, polygon, neighbourPolygon, out left, out right));
 }
コード例 #25
0
        void CheckWrite()
        {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
            AtomicSafetyHandle.CheckWriteAndBumpSecondaryVersion(m_Safety);
#endif
        }
コード例 #26
0
 public Matrix4x4 PolygonWorldToLocalMatrix(PolygonId polygon)
 {
     AtomicSafetyHandle.CheckReadAndThrow(m_Safety);
     return(PolygonWorldToLocalMatrix(m_NavMeshQuery, polygon));
 }
コード例 #27
0
        public void CheckAccess()
        {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
            AtomicSafetyHandle.CheckWriteAndThrow(m_Safety);
#endif
        }
コード例 #28
0
 public NavMeshPolyTypes GetPolygonType(PolygonId polygon)
 {
     AtomicSafetyHandle.CheckReadAndThrow(m_Safety);
     return(GetPolygonType(m_NavMeshQuery, polygon));
 }
コード例 #29
0
ファイル: NativeQueue.cs プロジェクト: Elizafur/FPS-Transfer
 private static void CreateStaticSafetyId()
 {
     s_staticSafetyId.Data = AtomicSafetyHandle.NewStaticSafetyId <NativeQueue <T> >();
 }
コード例 #30
0
        /// <summary>
        /// Signal how many bytes have been written to the buffer used by the data
        /// stream using one of the unsafe pointer getters.
        /// </summary>
        /// <param name="strm"></param>
        /// <param name="length">Amount of data written to the buffer.</param>
        /// <exception cref="ArgumentOutOfRangeException">If the length specified brings the total length to a value higher than the capacity of the buffer.</exception>
        public unsafe static void WriteBytesWithUnsafePointer(this DataStreamWriter strm, int length)
        {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
            AtomicSafetyHandle.CheckWriteAndThrow(strm.m_Safety);
            if (strm.m_Data->length + length > strm.m_Data->capacity)
                throw new ArgumentOutOfRangeException(); }