// Schedule() implementation for IBodyPairsJob when Havok Physics is available public static unsafe JobHandle Schedule <T>(this T jobData, ISimulation simulation, ref PhysicsWorld world, JobHandle inputDeps) where T : struct, IBodyPairsJobBase { switch (simulation.Type) { case SimulationType.UnityPhysics: // Call the scheduling method for Unity.Physics return(IBodyPairsJobExtensions.ScheduleUnityPhysicsBodyPairsJob(jobData, simulation, ref world, inputDeps)); case SimulationType.HavokPhysics: { var data = new BodyPairsJobData <T> { UserJobData = jobData, BlockStreamStart = ((Havok.Physics.HavokSimulation)simulation).NewBodyPairsStream, PluginIndexToLocal = ((Havok.Physics.HavokSimulation)simulation).PluginIndexToLocal, Bodies = world.Bodies }; var parameters = new JobsUtility.JobScheduleParameters( UnsafeUtility.AddressOf(ref data), BodyPairsJobProcess <T> .Initialize(), inputDeps, ScheduleMode.Batched); return(JobsUtility.Schedule(ref parameters)); } default: return(inputDeps); } }
public unsafe static void Execute(ref BodyPairsJobData <T> jobData, IntPtr additionalData, IntPtr bufferRangePatchData, ref JobRanges ranges, int jobIndex) { for (int currentIdx = 0; currentIdx < jobData.PhasedDispatchPairs.Length; currentIdx++) { DispatchPairSequencer.DispatchPair dispatchPair = jobData.PhasedDispatchPairs[currentIdx]; // Skip joint pairs and invalid pairs if (dispatchPair.IsJoint || !dispatchPair.IsValid) { continue; } var pair = new ModifiableBodyPair { BodyIndexPair = new BodyIndexPair { BodyIndexA = dispatchPair.BodyIndexA, BodyIndexB = dispatchPair.BodyIndexB }, EntityPair = new EntityPair { EntityA = jobData.Bodies[dispatchPair.BodyIndexA].Entity, EntityB = jobData.Bodies[dispatchPair.BodyIndexB].Entity } }; jobData.UserJobData.Execute(ref pair); if (pair.BodyIndexA == -1 || pair.BodyIndexB == -1) { jobData.PhasedDispatchPairs[currentIdx] = DispatchPairSequencer.DispatchPair.Invalid; } } }
public unsafe static void Execute(ref BodyPairsJobData <T> jobData, IntPtr additionalData, IntPtr bufferRangePatchData, ref JobRanges ranges, int jobIndex) { int currentIdx = 0; while (currentIdx < jobData.PhasedDispatchPairs.Length) { DispatchPairSequencer.DispatchPair dispatchPair = jobData.PhasedDispatchPairs[currentIdx]; var pair = new ModifiableBodyPair { BodyIndices = new BodyIndexPair { BodyAIndex = dispatchPair.BodyAIndex, BodyBIndex = dispatchPair.BodyBIndex }, Entities = new EntityPair { EntityA = jobData.Bodies[dispatchPair.BodyAIndex].Entity, EntityB = jobData.Bodies[dispatchPair.BodyBIndex].Entity } }; jobData.UserJobData.Execute(ref pair); if (pair.BodyIndices.BodyAIndex == -1 || pair.BodyIndices.BodyBIndex == -1) { jobData.PhasedDispatchPairs[currentIdx] = DispatchPairSequencer.DispatchPair.Invalid; } do { currentIdx++; } while (currentIdx < jobData.PhasedDispatchPairs.Length && jobData.PhasedDispatchPairs[currentIdx].IsJoint); } }
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)); }
internal static unsafe JobHandle ScheduleImpl<T>(this T jobData, ISimulation simulation, ref PhysicsWorld world, JobHandle inputDeps) where T : struct, IBodyPairsJob { if (simulation.Type == SimulationType.UnityPhysics) { var data = new BodyPairsJobData<T> { UserJobData = jobData, PhasedDispatchPairs = ((Simulation)simulation).m_Context.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); } return inputDeps; }
internal static unsafe JobHandle ScheduleUnityPhysicsBodyPairsJob <T>(T jobData, ISimulation simulation, ref PhysicsWorld world, JobHandle inputDeps) where T : struct, IBodyPairsJobBase { if (simulation.Type != SimulationType.UnityPhysics) { throw new ArgumentException($"Simulation type {simulation.Type} is not supported! Should be called only for SimulationType.UnityPhysics."); } 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)); }
public unsafe static void Execute(ref BodyPairsJobData <T> jobData, IntPtr additionalData, IntPtr bufferRangePatchData, ref JobRanges ranges, int jobIndex) { if (jobData.BlockStreamStart == null || !jobData.BlockStreamStart->HasElements) { return; } var blockStreamReader = new Havok.Physics.HpBlockStreamReader(jobData.BlockStreamStart); int *pluginIndexToLocal = jobData.PluginIndexToLocal->Data; while (blockStreamReader.HasItems) { BodyIndexPair indices = blockStreamReader.Read <BodyIndexPair>(); // Really an hknpBodyIdPair int bodyIndexA = pluginIndexToLocal[indices.BodyIndexA & 0x00ffffff]; int bodyIndexB = pluginIndexToLocal[indices.BodyIndexB & 0x00ffffff]; var pair = new ModifiableBodyPair { BodyIndexPair = new BodyIndexPair { BodyIndexA = bodyIndexA, BodyIndexB = bodyIndexB }, EntityPair = new EntityPair { EntityA = jobData.Bodies[bodyIndexA].Entity, EntityB = jobData.Bodies[bodyIndexB].Entity } }; jobData.UserJobData.Execute(ref pair); if (pair.BodyIndexA == -1 || pair.BodyIndexB == -1) { blockStreamReader.Write(BodyIndexPair.Invalid); } } }