Exemplo n.º 1
0
        public void ScheduleCreateThrows()
        {
            var list = new NativeList <int>(Allocator.Persistent);

            list.Add(2);

            BlockStream stream;
            var         jobHandle = BlockStream.ScheduleConstruct(out stream, list, 0xd3e8afdd, default(JobHandle));

            Assert.Throws <InvalidOperationException>(() => Debug.Log(stream.ForEachCount));

            jobHandle.Complete();

            Assert.AreEqual(1, stream.ForEachCount);

            stream.Dispose();
            list.Dispose();
        }
Exemplo n.º 2
0
        internal static JobHandle ScheduleProcessBodyPairsJobs(ref PhysicsWorld world, float timeStep, int numIterations, ref Simulation.Context context, JobHandle inputDeps)
        {
            var numWorkItems         = context.SolverSchedulerInfo.NumWorkItems;
            var contactsHandle       = BlockStream.ScheduleConstruct(out context.Contacts, numWorkItems, 0xcf97529c, inputDeps);
            var jointJacobiansHandle = BlockStream.ScheduleConstruct(out context.JointJacobians, numWorkItems, 0xd3185f82, inputDeps);
            var jacobiansHandle      = BlockStream.ScheduleConstruct(out context.Jacobians, numWorkItems, 0x8d8f394d, inputDeps);

            var processHandle = new ProcessBodyPairsJob
            {
                World               = world,
                TimeStep            = timeStep,
                NumIterations       = numIterations,
                PhasedDispatchPairs = context.PhasedDispatchPairs.AsDeferredJobArray(),
                SolverSchedulerInfo = context.SolverSchedulerInfo,
                ContactWriter       = context.Contacts,
                JointJacobianWriter = context.JointJacobians,
            }.ScheduleUnsafeIndex0(numWorkItems, 1, JobHandle.CombineDependencies(contactsHandle, jointJacobiansHandle, jacobiansHandle));


            context.DisposeProcessBodyPairs = NativeListUtilityTemp.DisposeHotFix(ref context.PhasedDispatchPairs, processHandle);

            return(processHandle);
        }
Exemplo n.º 3
0
        // Schedule a set of jobs which will write all overlapping body pairs to the given steam,
        // where at least one of the bodies is dynamic. The results are unsorted.
        internal JobHandle ScheduleFindOverlapsJobs(out BlockStream dynamicVsDynamicPairsStream, out BlockStream staticVsDynamicPairsStream, ref Simulation.Context context, JobHandle inputDeps)
        {
            var dynamicVsDynamicNodePairIndices = new NativeList <int2>(Allocator.TempJob);
            var staticVsDynamicNodePairIndices  = new NativeList <int2>(Allocator.TempJob);

            JobHandle allocateDeps = new AllocateDynamicVsStaticNodePairs
            {
                dynamicVsDynamicNodePairIndices = dynamicVsDynamicNodePairIndices,
                staticVsDynamicNodePairIndices  = staticVsDynamicNodePairIndices,
                dynamicBranchCount = m_DynamicTree.m_BranchCount,
                staticBranchCount  = m_StaticTree.m_BranchCount
            }.Schedule(inputDeps);

            // Build pairs of branch node indices
            JobHandle dynamicVsDynamicPairs = new DynamicVsDynamicBuildBranchNodePairsJob
            {
                Ranges          = m_DynamicTree.Ranges,
                NumBranches     = m_DynamicTree.m_BranchCount,
                NodePairIndices = dynamicVsDynamicNodePairIndices.AsDeferredJobArray()
            }.Schedule(allocateDeps);

            JobHandle staticVsDynamicPairs = new StaticVsDynamicBuildBranchNodePairsJob
            {
                DynamicRanges      = m_DynamicTree.Ranges,
                StaticRanges       = m_StaticTree.Ranges,
                NumStaticBranches  = m_StaticTree.m_BranchCount,
                NumDynamicBranches = m_DynamicTree.m_BranchCount,
                NodePairIndices    = staticVsDynamicNodePairIndices.AsDeferredJobArray()
            }.Schedule(allocateDeps);

            //@TODO: We only need a dependency on allocateDeps, but the safety system doesn't understand that we can not change length list in DynamicVsDynamicBuildBranchNodePairsJob & StaticVsDynamicBuildBranchNodePairsJob
            //       if this is a performance issue we can use [NativeDisableContainerSafetyRestriction] on DynamicVsDynamicBuildBranchNodePairsJob & StaticVsDynamicBuildBranchNodePairsJob
            JobHandle dynamicConstruct = BlockStream.ScheduleConstruct(out dynamicVsDynamicPairsStream, dynamicVsDynamicNodePairIndices, 0x0a542b34, dynamicVsDynamicPairs);
            JobHandle staticConstruct  = BlockStream.ScheduleConstruct(out staticVsDynamicPairsStream, staticVsDynamicNodePairIndices, 0x0a542666, staticVsDynamicPairs);

            // Write all overlaps to the stream (also deallocates nodePairIndices)
            JobHandle dynamicVsDynamicHandle = new DynamicVsDynamicFindOverlappingPairsJob
            {
                DynamicNodes       = m_DynamicTree.Nodes,
                BodyFilters        = m_BodyFilters,
                DynamicNodeFilters = m_DynamicTree.NodeFilters,
                PairWriter         = dynamicVsDynamicPairsStream,
                NodePairIndices    = dynamicVsDynamicNodePairIndices.AsDeferredJobArray()
            }.Schedule(dynamicVsDynamicNodePairIndices, 1, JobHandle.CombineDependencies(dynamicVsDynamicPairs, dynamicConstruct));

            // Write all overlaps to the stream (also deallocates nodePairIndices)
            JobHandle staticVsDynamicHandle = new StaticVsDynamicFindOverlappingPairsJob
            {
                StaticNodes        = m_StaticTree.Nodes,
                DynamicNodes       = m_DynamicTree.Nodes,
                BodyFilters        = m_BodyFilters,
                StaticNodeFilters  = m_StaticTree.NodeFilters,
                DynamicNodeFilters = m_DynamicTree.NodeFilters,
                PairWriter         = staticVsDynamicPairsStream,
                NodePairIndices    = staticVsDynamicNodePairIndices.AsDeferredJobArray()
            }.Schedule(staticVsDynamicNodePairIndices, 1, JobHandle.CombineDependencies(staticVsDynamicPairs, staticConstruct));

            // Dispose node pair lists
            context.DisposeOverlapPairs0 = NativeListUtilityTemp.DisposeHotFix(ref dynamicVsDynamicNodePairIndices, dynamicVsDynamicHandle);
            context.DisposeOverlapPairs1 = NativeListUtilityTemp.DisposeHotFix(ref staticVsDynamicNodePairIndices, staticVsDynamicHandle);

            return(JobHandle.CombineDependencies(dynamicVsDynamicHandle, staticVsDynamicHandle));
        }
Exemplo n.º 4
0
        // Schedule some jobs to solve the Jacobians stored in the simulation context
        internal static unsafe JobHandle ScheduleSolveJacobiansJobs(ref DynamicsWorld dynamicsWorld, float timestep, int numIterations, ref Simulation.Context context, JobHandle inputDeps)
        {
            JobHandle handle;

            int numPhases = context.SolverSchedulerInfo.NumPhases;

            // Use persistent allocator to allow these to live until the start of next step
            {
                NativeArray <int> workItemList = context.SolverSchedulerInfo.NumWorkItems;

                //TODO: Change this to Allocator.TempJob when https://github.com/Unity-Technologies/Unity.Physics/issues/7 is resolved
                JobHandle collisionEventStreamHandle = BlockStream.ScheduleConstruct(out context.CollisionEventStream, workItemList, 0xb17b474f, inputDeps, Allocator.Persistent);
                JobHandle triggerEventStreamHandle   = BlockStream.ScheduleConstruct(out context.TriggerEventStream, workItemList, 0x43875d8f, inputDeps, Allocator.Persistent);

                handle = JobHandle.CombineDependencies(collisionEventStreamHandle, triggerEventStreamHandle);

                float invNumIterations = math.rcp(numIterations);

                var phaseInfoPtrs = (Scheduler.SolverSchedulerInfo.SolvePhaseInfo *)NativeArrayUnsafeUtility.GetUnsafeBufferPointerWithoutChecks(context.SolverSchedulerInfo.PhaseInfo);

                for (int solverIterationId = 0; solverIterationId < numIterations; solverIterationId++)
                {
                    bool lastIteration = solverIterationId == numIterations - 1;
                    for (int phaseId = 0; phaseId < numPhases; phaseId++)
                    {
                        var job = new SolverJob
                        {
                            JacobianReader   = context.Jacobians,
                            PhaseIndex       = phaseId,
                            Phases           = context.SolverSchedulerInfo.PhaseInfo,
                            MotionVelocities = dynamicsWorld.MotionVelocities,
                            StepInput        = new StepInput
                            {
                                InvNumSolverIterations = invNumIterations,
                                IsLastIteration        = lastIteration,
                                Timestep    = timestep,
                                InvTimestep = timestep > 0.0f ? 1.0f / timestep : 0.0f
                            }
                        };

                        // Only initialize event writers for last solver iteration jobs
                        if (lastIteration)
                        {
                            job.CollisionEventsWriter = context.CollisionEventStream;
                            job.TriggerEventsWriter   = context.TriggerEventStream;
                        }

                        // NOTE: The last phase must be executed on a single job since it
                        // int.MaxValue can't be used as batchSize since 19.1 overflows in that case...
                        bool isLastPhase = phaseId == numPhases - 1;
                        int  batchSize   = isLastPhase ? (int.MaxValue / 2) : 1;

                        int *numWorkItems = &(phaseInfoPtrs[phaseId].NumWorkItems);
                        handle = job.Schedule(numWorkItems, batchSize, handle);
                    }
                }
            }

            // Dispose processed data
            context.DisposeJacobians           = context.Jacobians.Dispose(handle);
            context.DisposeJointJacobians      = context.JointJacobians.Dispose(handle);
            context.DisposeSolverSchedulerData = context.SolverSchedulerInfo.ScheduleDisposeJob(handle);

            return(handle);
        }