internal static unsafe JobHandle ScheduleUnityPhysicsBodyPairsJob <T>(T jobData, ISimulation simulation, ref PhysicsWorld world, JobHandle inputDeps)
            where T : struct, IBodyPairsJobBase
        {
            SafetyChecks.CheckAreEqualAndThrow(SimulationType.UnityPhysics, simulation.Type);

            var data = new BodyPairsJobData <T>
            {
                UserJobData         = jobData,
                PhasedDispatchPairs = ((Simulation)simulation).StepContext.PhasedDispatchPairs.AsDeferredJobArray(),
                Bodies = world.Bodies
            };
            var parameters = new JobsUtility.JobScheduleParameters(
                UnsafeUtility.AddressOf(ref data),
                BodyPairsJobProcess <T> .Initialize(), inputDeps, ScheduleMode.Batched);

            return(JobsUtility.Schedule(ref parameters));
        }
        // Schedules a trigger events job only for UnityPhysics simulation
        internal static unsafe JobHandle ScheduleUnityPhysicsTriggerEventsJob <T>(T jobData, ISimulation simulation, ref PhysicsWorld world, JobHandle inputDeps)
            where T : struct, ITriggerEventsJobBase
        {
            SafetyChecks.CheckAreEqualAndThrow(SimulationType.UnityPhysics, simulation.Type);

            var data = new TriggerEventJobData <T>
            {
                UserJobData = jobData,
                EventReader = ((Simulation)simulation).TriggerEvents
            };

            // Ensure the input dependencies include the end-of-simulation job, so events will have been generated
            inputDeps = JobHandle.CombineDependencies(inputDeps, simulation.FinalSimulationJobHandle);

            var parameters = new JobsUtility.JobScheduleParameters(UnsafeUtility.AddressOf(ref data), TriggerEventJobProcess <T> .Initialize(), inputDeps, ScheduleMode.Batched);

            return(JobsUtility.Schedule(ref parameters));
        }