Пример #1
0
 static public int constructor(IntPtr l)
 {
     try {
         Unity.Jobs.JobHandle o;
         o = new Unity.Jobs.JobHandle();
         pushValue(l, true);
         pushValue(l, o);
         return(2);
     }
     catch (Exception e) {
         return(error(l, e));
     }
 }
        protected override JobHandle OnUpdate(Unity.Jobs.JobHandle inputDeps)
        {
            if (_enemy.Position.Length == 0 || _player.Positions.Length == 0)
            {
                return(inputDeps);
            }

            float3 player_pos = _player.Positions[0].Value;

            return(new ControlEnemy
            {
                PlayerPos = player_pos,
                // UnitPos = _enemy.Position[0].Value,
                Dt = Time.deltaTime
            }.Schedule(this, inputDeps));
        }
Пример #3
0
        public Unity.Jobs.JobHandle AllocateNodesJob <T>(T[] result, int count, System.Func <T> createNode) where T : GraphNode
        {
            if (!queue.AllReceiversBlocked)
            {
                throw new System.Exception("Trying to initialize a node when it is not safe to initialize any nodes. Must be done during a graph update. See http://arongranberg.com/astar/docs/graph-updates.php#direct");
            }

            // Get all node indices that we are going to recycle and store them in a new buffer.
            // It's best to store them in a new buffer to avoid multithreading issues.
            var numRecycledNodeIndices = math.min(nodeIndexPool.Count, count);
            var recyledNodeIndices     = ArrayPool <int> .Claim(numRecycledNodeIndices);

            nodeIndexPool.PopMany(recyledNodeIndices, numRecycledNodeIndices);

            // Highest node index + 1 in the new list of nodes
            var newNextNodeIndex = nextNodeIndex + (count - numRecycledNodeIndices);

            reservedPathNodeData = math.max(reservedPathNodeData, math.ceilpow2(newNextNodeIndex));

            // It may be tempting to use a parallel job for this
            // but it seems like allocation (new) in C# uses some kind of locking.
            // Therefore it is not faster (it may even be slower) to try to allocate the nodes in multiple threads in parallel.
            lastAllocationJob = new JobAllocateNodes <T> {
                result                 = result,
                count                  = count,
                pathProcessor          = this,
                recyledNodeIndices     = recyledNodeIndices,
                numRecycledNodeIndices = numRecycledNodeIndices,
                startingNodeIndex      = nextNodeIndex,
                reservedPathNodeData   = reservedPathNodeData,
                createNode             = createNode,
            }.ScheduleManaged(lastAllocationJob);

            // Mark the node indices as used
            nextNodeIndex = newNextNodeIndex;

            return(lastAllocationJob);
        }
        unsafe public static JobHandle Schedule <T>(this T jobData, int arrayLength, int innerloopBatchCount, JobHandle dependsOn = new JobHandle()) where T : struct, IJobParallelFor
        {
            var scheduleParams = new JobsUtility.JobScheduleParameters(UnsafeUtility.AddressOf(ref jobData), GetReflectionData <T>(), dependsOn, ScheduleMode.Parallel);

            return(JobsUtility.ScheduleParallelFor(ref scheduleParams, arrayLength, innerloopBatchCount));
        }
Пример #5
0
        public static unsafe JobHandle ScheduleFilter <T>(this T jobData, NativeList <int> indices, int innerloopBatchCount, JobHandle dependsOn = new JobHandle()) where T : struct, IJobParallelForFilter
        {
            JobStructProduce <T> .JobDataWithFiltering fullData = new JobStructProduce <T> .JobDataWithFiltering()
            {
                data          = jobData,
                outputIndices = indices,
                appendCount   = -1
            };

            var scheduleParams = new JobsUtility.JobScheduleParameters(UnsafeUtility.AddressOf(ref fullData), JobStructProduce <T> .Initialize(), dependsOn, ScheduleMode.Batched);

            return(JobsUtility.Schedule(ref scheduleParams));
        }
 public static JobHandle ScheduleParallel <T>(this T jobData, int arrayLength, int innerloopBatchCount, JobHandle dependency) where T : struct, IJobFor
 {
     JobsUtility.JobScheduleParameters jobScheduleParameters = new JobsUtility.JobScheduleParameters(UnsafeUtility.AddressOf <T>(ref jobData), IJobForExtensions.ForJobStruct <T> .Initialize(), dependency, ScheduleMode.Batched);
     return(JobsUtility.ScheduleParallelFor(ref jobScheduleParameters, arrayLength, innerloopBatchCount));
 }
Пример #7
0
        unsafe static public JobHandle ScheduleBatch <T>(this T jobData, int arrayLength, int minIndicesPerJobCount, JobHandle dependsOn = new JobHandle()) where T : struct, IJobParallelForBatch
        {
            var scheduleParams = new JobsUtility.JobScheduleParameters(UnsafeUtility.AddressOf(ref jobData), ParallelForBatchJobStruct <T> .Initialize(), dependsOn, ScheduleMode.Parallel);

            return(JobsUtility.ScheduleParallelFor(ref scheduleParams, arrayLength, minIndicesPerJobCount));
        }
        public static unsafe JobHandle ScheduleBatch <T>(this T jobData, int arrayLength, int minIndicesPerJobCount, JobHandle dependsOn = new JobHandle()) where T : struct, IJobParallelForBatch
        {
#if UNITY_SINGLETHREADED_JOBS
            jobData.Execute(0, arrayLength);
            DoDeallocateOnJobCompletion(jobData);
            return(new JobHandle());
#elif UNITY_DOTSPLAYER
            var jobStruct = new ParallelForBatchJobStruct <T>()
            {
                JobData = jobData,
                Ranges  = new JobRanges()
                {
                    ArrayLength     = arrayLength,
                    IndicesPerPhase = JobsUtility.GetDefaultIndicesPerPhase(arrayLength)
                },
            };

            var jobDataPtr = UnsafeUtility.Malloc(UnsafeUtility.SizeOf <ParallelForBatchJobStruct <T> >(),
                                                  UnsafeUtility.AlignOf <ParallelForBatchJobStruct <T> >(), Allocator.TempJob);
            UnsafeUtility.CopyStructureToPtr(ref jobStruct, jobDataPtr);

            var scheduleParams = new JobsUtility.JobScheduleParameters(jobDataPtr, ParallelForBatchJobStruct <T> .Initialize(),
                                                                       dependsOn, ScheduleMode.Batched);
            return(JobsUtility.ScheduleParallelFor(ref scheduleParams, arrayLength, minIndicesPerJobCount));
#else
            var scheduleParams = new JobsUtility.JobScheduleParameters(UnsafeUtility.AddressOf(ref jobData), ParallelForBatchJobStruct <T> .Initialize(), dependsOn, ScheduleMode.Batched);
            return(JobsUtility.ScheduleParallelFor(ref scheduleParams, arrayLength, minIndicesPerJobCount));
#endif
        }
Пример #9
0
        public static unsafe JobHandle ScheduleBatch <T>(this T jobData, int arrayLength, int minIndicesPerJobCount, JobHandle dependsOn = new JobHandle()) where T : struct, IJobParallelForBatch
        {
#if UNITY_AVOID_REFLECTION
            // Protect against garbage collection
            if (!ParallelForBatchJobStruct <T> .ExecuteHandle.IsAllocated)
            {
                ParallelForBatchJobStruct <T> .ExecuteDelegate    = ParallelForBatchJobStruct <T> .Execute;
                ParallelForBatchJobStruct <T> .ExecuteHandle      = GCHandle.Alloc(ParallelForBatchJobStruct <T> .ExecuteDelegate);
                ParallelForBatchJobStruct <T> .ExecuteFunctionPtr = Marshal.GetFunctionPointerForDelegate(ParallelForBatchJobStruct <T> .ExecuteDelegate);
            }

            // Protect against garbage collection
            if (!ParallelForBatchJobStruct <T> .CleanupHandle.IsAllocated)
            {
                ParallelForBatchJobStruct <T> .CleanupDelegate    = ParallelForBatchJobStruct <T> .Cleanup;
                ParallelForBatchJobStruct <T> .CleanupHandle      = GCHandle.Alloc(ParallelForBatchJobStruct <T> .CleanupDelegate);
                ParallelForBatchJobStruct <T> .CleanupFunctionPtr = Marshal.GetFunctionPointerForDelegate(ParallelForBatchJobStruct <T> .CleanupDelegate);
            }

            var jobFunctionPtr    = ParallelForBatchJobStruct <T> .ExecuteFunctionPtr;
            var completionFuncPtr = ParallelForBatchJobStruct <T> .CleanupFunctionPtr;

            var jobStruct = new ParallelForBatchJobStruct <T>()
            {
                JobData = jobData,
                Ranges  = new JobRanges()
                {
                    ArrayLength     = arrayLength,
                    IndicesPerPhase = JobsUtility.GetDefaultIndicesPerPhase(arrayLength)
                },
            };

            var jobDataPtr = UnsafeUtility.Malloc(UnsafeUtility.SizeOf <ParallelForBatchJobStruct <T> >(),
                                                  UnsafeUtility.AlignOf <ParallelForBatchJobStruct <T> >(), Allocator.TempJob);
            UnsafeUtility.CopyStructureToPtr(ref jobStruct, jobDataPtr);

            return(JobsUtility.ScheduleJobForEach(jobFunctionPtr, completionFuncPtr, new IntPtr(jobDataPtr),
                                                  arrayLength, minIndicesPerJobCount, dependsOn));
#else
            var scheduleParams = new JobsUtility.JobScheduleParameters(UnsafeUtility.AddressOf(ref jobData), ParallelForBatchJobStruct <T> .Initialize(), dependsOn, ScheduleMode.Batched);
            return(JobsUtility.ScheduleParallelFor(ref scheduleParams, arrayLength, minIndicesPerJobCount));
#endif
        }
        /// <summary>
        /// Schedule the job for execution on worker threads.
        /// list.Length is used as the iteration count.
        /// Note that it is required to embed the list on the job struct as well.
        /// </summary>
        /// <param name="jobData">The job and data to schedule.</param>
        /// <param name="list">list.Length is used as the iteration count.</param>
        /// <param name="innerloopBatchCount">Granularity in which workstealing is performed. A value of 32, means the job queue will steal 32 iterations and then perform them in an efficient inner loop.</param>
        /// <param name="dependsOn">Dependencies are used to ensure that a job executes on workerthreads after the dependency has completed execution. Making sure that two jobs reading or writing to same data do not run in parallel.</param>
        /// <returns>JobHandle The handle identifying the scheduled job. Can be used as a dependency for a later job or ensure completion on the main thread.</returns>
        unsafe public static JobHandle Schedule <T, U>(this T jobData, NativeList <U> list, int innerloopBatchCount, JobHandle dependsOn = new JobHandle())
            where T : struct, IJobParallelForDefer
            where U : struct
        {
            var scheduleParams = new JobsUtility.JobScheduleParameters(UnsafeUtility.AddressOf(ref jobData), JobStructDefer <T> .Initialize(), dependsOn, ScheduleMode.Batched);

            void *atomicSafetyHandlePtr = null;

#if ENABLE_UNITY_COLLECTIONS_CHECKS
            var safety = NativeListUnsafeUtility.GetAtomicSafetyHandle(ref list);
            atomicSafetyHandlePtr = UnsafeUtility.AddressOf(ref safety);
#endif
            return(JobsUtility.ScheduleParallelForDeferArraySize(ref scheduleParams, innerloopBatchCount, NativeListUnsafeUtility.GetInternalListDataPtrUnchecked(ref list), atomicSafetyHandlePtr));
        }
        /// <summary>
        /// Schedule the job for execution on worker threads.
        /// forEachCount is a pointer to the number of iterations, when dependsOn has completed.
        /// This API is unsafe, it is recommended to use the NativeList based Schedule method instead.
        /// </summary>
        /// <param name="jobData"></param>
        /// <param name="forEachCount"></param>
        /// <param name="innerloopBatchCount"></param>
        /// <param name="dependsOn"></param>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        unsafe public static JobHandle Schedule <T>(this T jobData, int *forEachCount, int innerloopBatchCount, JobHandle dependsOn = new JobHandle())
            where T : struct, IJobParallelForDefer
        {
            var scheduleParams = new JobsUtility.JobScheduleParameters(UnsafeUtility.AddressOf(ref jobData), JobStructDefer <T> .Initialize(), dependsOn, ScheduleMode.Batched);
            var forEachListPtr = (byte *)forEachCount - sizeof(void *);

            return(JobsUtility.ScheduleParallelForDeferArraySize(ref scheduleParams, innerloopBatchCount, forEachListPtr, null));
        }
Пример #12
0
    // Update is called once per frame
    void Update()
    {
        var ProjMatrix = Camera.main.projectionMatrix;
        var ViewMatrix = Camera.main.worldToCameraMatrix;

        var ViewProjMatrix = ProjMatrix * ViewMatrix;

        var Row3 = ViewProjMatrix.GetRow(3);
        var Row0 = ViewProjMatrix.GetRow(0);
        var Row1 = ViewProjMatrix.GetRow(1);
        var Row2 = ViewProjMatrix.GetRow(2);

        var PlaneL = NormalizePlane(Row3 + Row0);
        var PlaneR = NormalizePlane(Row3 - Row0);
        var PlaneT = NormalizePlane(Row3 - Row1);
        var PlaneB = NormalizePlane(Row3 + Row1);

        var PlaneN = NormalizePlane(Row3 + Row2);
        var PlaneF = NormalizePlane(Row3 - Row2);

        var PointNTL = PointFrom3Planes(PlaneN, PlaneT, PlaneL);
        var PointNTR = PointFrom3Planes(PlaneN, PlaneT, PlaneR);
        var PointNBL = PointFrom3Planes(PlaneN, PlaneB, PlaneL);
        var PointNBR = PointFrom3Planes(PlaneN, PlaneB, PlaneR);

        DebugDrawCross(PointNTL, RayDirFromPlanes(PlaneT, PlaneL), 0.3f);
        DebugDrawCross(PointNTR, RayDirFromPlanes(PlaneR, PlaneT), 0.3f);
        DebugDrawCross(PointNBL, RayDirFromPlanes(PlaneL, PlaneB), 0.3f);
        DebugDrawCross(PointNBR, RayDirFromPlanes(PlaneB, PlaneR), 0.3f);

        var PointFTL = PointFrom3Planes(PlaneF, PlaneT, PlaneL);
        var PointFTR = PointFrom3Planes(PlaneF, PlaneT, PlaneR);
        var PointFBL = PointFrom3Planes(PlaneF, PlaneB, PlaneL);
        var PointFBR = PointFrom3Planes(PlaneF, PlaneB, PlaneR);

        var FrustumAABBMin =
            Vector3.Min(Vector3.Min(Vector3.Min(PointFTL, PointFTR), Vector3.Min(PointFBL, PointFBR)),
                        Vector3.Min(Vector3.Min(PointNTL, PointNTR), Vector3.Min(PointNBL, PointNBR)));

        var FrustumAABBMax =
            Vector3.Max(Vector3.Max(Vector3.Max(PointFTL, PointFTR), Vector3.Max(PointFBL, PointFBR)),
                        Vector3.Max(Vector3.Max(PointNTL, PointNTR), Vector3.Max(PointNBL, PointNBR)));


        DebugDrawCross(PointFTL, -RayDirFromPlanes(PlaneT, PlaneL), 1.3f);
        DebugDrawCross(PointFTR, -RayDirFromPlanes(PlaneR, PlaneT), 1.3f);
        DebugDrawCross(PointFBL, -RayDirFromPlanes(PlaneL, PlaneB), 1.3f);
        DebugDrawCross(PointFBR, -RayDirFromPlanes(PlaneB, PlaneR), 1.3f);

        FrustumData.Array[0] = PlaneL;
        FrustumData.Array[1] = PlaneR;
        FrustumData.Array[2] = PlaneT;
        FrustumData.Array[3] = PlaneB;
        FrustumData.Array[4] = PlaneN;
        FrustumData.Array[5] = PlaneF;
        FrustumData.Array[6] = new Vector4(FrustumAABBMin.x, FrustumAABBMax.x, FrustumAABBMin.y, FrustumAABBMax.y);
        FrustumData.Array[7] = new Vector4(FrustumAABBMin.z, FrustumAABBMax.z, FrustumAABBMin.z, FrustumAABBMax.z);

        int NumSoAPackets = (NumMeshTranforms + 3) >> 2;

        NumMeshTranforms = NumSoAPackets << 2;

        if (PrevNumMeshTransforms != NumMeshTranforms)
        {
            Debug.Log("Re-allocate AABB data because of size change.");

            VisibilityMask.Reserve((NumSoAPackets + 1) >> 1);

            VisibilityMaskForParallel = new byte[NumSoAPackets];

            BoxesMinMaxAoSoA.Reserve(NumSoAPackets * 6);

            Debug.Log("Native" + BoxesMinMaxAoSoANative);
            if (BoxesMinMaxAoSoANative.IsCreated)
            {
                BoxesMinMaxAoSoANative.Dispose();
            }

            BoxesMinMaxAoSoANative = new NativeArray <Vector4>(BoxesMinMaxAoSoA.Array, Allocator.Persistent);

            MeshTransforms = new Matrix4x4[NumMeshTranforms];
            RandomizeBoxes = true;
        }
        PrevNumMeshTransforms = NumMeshTranforms;

        if (RandomizeBoxes)
        {
            UnityEngine.Random.InitState((int)(Time.time * 1000.0f));
            for (int i = 0; i < NumSoAPackets; ++i)
            {
                var c0 = RandomCenter();
                var e0 = RandomExtent();

                var c1 = RandomCenter();
                var e1 = RandomExtent();

                var c2 = RandomCenter();
                var e2 = RandomExtent();

                var c3 = RandomCenter();
                var e3 = RandomExtent();

                BoxesMinMaxAoSoA.Array[i * 6 + 0] = new Vector4(c0[0] - e0[0], c1[0] - e1[0], c2[0] - e2[0], c3[0] - e3[0]);
                BoxesMinMaxAoSoA.Array[i * 6 + 1] = new Vector4(c0[0] + e0[0], c1[0] + e1[0], c2[0] + e2[0], c3[0] + e3[0]);
                BoxesMinMaxAoSoA.Array[i * 6 + 2] = new Vector4(c0[1] - e0[1], c1[1] - e1[1], c2[1] - e2[1], c3[1] - e3[1]);
                BoxesMinMaxAoSoA.Array[i * 6 + 3] = new Vector4(c0[1] + e0[1], c1[1] + e1[1], c2[1] + e2[1], c3[1] + e3[1]);
                BoxesMinMaxAoSoA.Array[i * 6 + 4] = new Vector4(c0[2] - e0[2], c1[2] - e1[2], c2[2] - e2[2], c3[2] - e3[2]);
                BoxesMinMaxAoSoA.Array[i * 6 + 5] = new Vector4(c0[2] + e0[2], c1[2] + e1[2], c2[2] + e2[2], c3[2] + e3[2]);
            }
            BoxesMinMaxAoSoANative.CopyFrom(BoxesMinMaxAoSoA.Array);
            RandomizeBoxes = false;
        }

        if (CullingJobType == JobType.ReferenceSerialOnly || CullingJobType == JobType.NativePluginSerialOnly)
        {
            CullingJobParallel = false;
        }

        if (CullingJobType == JobType.ReferenceSerialOnly)
        {
            UnityEngine.Profiling.Profiler.BeginSample("CullBoxesAoSoA_Default");
            CullBoxesAoSoA_Default(
                ref VisibilityMask.Array,
                ref BoxesMinMaxAoSoA.Array,
                ref FrustumData.Array,
                FrustumAABBMax,
                FrustumAABBMin,
                TestFrustumCorners);
            UnityEngine.Profiling.Profiler.EndSample();
        }
        else if (CullingJobType == JobType.NativePluginSerialOnly)
        {
            UnityEngine.Profiling.Profiler.BeginSample("UnityNativePlugin_CountCulledBoxesAoSoA");
            UnityNativePlugin_CountCulledBoxesAoSoA(
                VisibilityMask.Address(),
                BoxesMinMaxAoSoA.Address(),
                FrustumData.Address(),
                NumSoAPackets);
            UnityEngine.Profiling.Profiler.EndSample();
        }
        else
        {
            if (CullingJobParallel)
            {
                UnityEngine.Profiling.Profiler.BeginSample("BeginCullBoxesAoSoA_Parallel");
                if (CullingJobType == JobType.MathematicsBurstOptimized)
                {
                    ParallelCullingJob = new CullingJob_Parallel();
                    CullingJobHandle   = ParallelCullingJob.Run(ref BoxesMinMaxAoSoANative, ref FrustumData.Array, TestFrustumCorners);
                }
                else
                {
                    ParallelCullingJobNoBurst = new CullingJob_ParallelNoBurst();
                    CullingJobHandle          = ParallelCullingJobNoBurst.Run(ref BoxesMinMaxAoSoANative, ref FrustumData.Array, TestFrustumCorners);
                }
                UnityEngine.Profiling.Profiler.EndSample();
            }
            else
            {
                UnityEngine.Profiling.Profiler.BeginSample("BeginCullBoxesAoSoA_Serial");
                if (CullingJobType == JobType.MathematicsBurstOptimized)
                {
                    SerialCullingJob = new CullingJob_Serial();
                    CullingJobHandle = SerialCullingJob.Run(ref BoxesMinMaxAoSoANative, ref FrustumData.Array, TestFrustumCorners);
                }
                else
                {
                    SerialCullingJobNoBurst = new CullingJob_SerialNoBurst();
                    CullingJobHandle        = SerialCullingJobNoBurst.Run(ref BoxesMinMaxAoSoANative, ref FrustumData.Array, TestFrustumCorners);
                }
                UnityEngine.Profiling.Profiler.EndSample();
            }
        }
    }
Пример #13
0
 public void Complete(Unity.Jobs.JobHandle Handle, ref byte[] VisibilityMask)
 {
     Handle.Complete();
     UnityEngine.Assertions.Assert.IsTrue(Handle.IsCompleted);
     JobData.OnComplete(ref VisibilityMask);
 }