protected override void OnUpdate() { // Make sure last frame's physics jobs are complete before any new ones start m_InputDependencyToComplete.Complete(); // Combine implicit input dependency with the user one Dependency = JobHandle.CombineDependencies(Dependency, m_InputDependency); int numDynamicBodies = DynamicEntityGroup.CalculateEntityCount(); int numStaticBodies = StaticEntityGroup.CalculateEntityCount(); int numJoints = JointEntityGroup.CalculateEntityCount(); int previousStaticBodyCount = PhysicsWorld.NumStaticBodies; // Resize the world's native arrays PhysicsWorld.Reset( numStaticBodies + 1, // +1 for the default static body numDynamicBodies, numJoints); if (PhysicsWorld.NumBodies == 0) { // If the static body count has changed, make sure to set the correct value to HaveStaticBodiesChanged if (PhysicsWorld.NumStaticBodies != previousStaticBodyCount) { HaveStaticBodiesChanged[0] = 1; } else { HaveStaticBodiesChanged[0] = 0; } m_OutputDependency = Dependency; ChainDependencies(); // No bodies in the scene, no need to do anything else return; } // Extract types used by initialize jobs var entityType = GetEntityTypeHandle(); var localToWorldType = GetComponentTypeHandle <LocalToWorld>(true); var parentType = GetComponentTypeHandle <Parent>(true); var positionType = GetComponentTypeHandle <Translation>(true); var rotationType = GetComponentTypeHandle <Rotation>(true); var physicsColliderType = GetComponentTypeHandle <PhysicsCollider>(true); var physicsVelocityType = GetComponentTypeHandle <PhysicsVelocity>(true); var physicsMassType = GetComponentTypeHandle <PhysicsMass>(true); var physicsMassOverrideType = GetComponentTypeHandle <PhysicsMassOverride>(true); var physicsDampingType = GetComponentTypeHandle <PhysicsDamping>(true); var physicsGravityFactorType = GetComponentTypeHandle <PhysicsGravityFactor>(true); var physicsCustomTagsType = GetComponentTypeHandle <PhysicsCustomTags>(true); var physicsConstrainedBodyPairType = GetComponentTypeHandle <PhysicsConstrainedBodyPair>(true); var physicsJointType = GetComponentTypeHandle <PhysicsJoint>(true); // Determine if the static bodies have changed in any way that will require the static broadphase tree to be rebuilt JobHandle staticBodiesCheckHandle = default; HaveStaticBodiesChanged[0] = 0; { if (PhysicsWorld.NumStaticBodies != previousStaticBodyCount) { HaveStaticBodiesChanged[0] = 1; } else { staticBodiesCheckHandle = new Jobs.CheckStaticBodyChangesJob { LocalToWorldType = localToWorldType, ParentType = parentType, PositionType = positionType, RotationType = rotationType, PhysicsColliderType = physicsColliderType, m_LastSystemVersion = LastSystemVersion, Result = HaveStaticBodiesChanged }.ScheduleParallel(StaticEntityGroup, 1, Dependency); } } using (var jobHandles = new NativeList <JobHandle>(4, Allocator.Temp)) { // Static body changes check jobs jobHandles.Add(staticBodiesCheckHandle); // Create the default static body at the end of the body list // TODO: could skip this if no joints present jobHandles.Add(new Jobs.CreateDefaultStaticRigidBody { NativeBodies = PhysicsWorld.Bodies, BodyIndex = PhysicsWorld.Bodies.Length - 1, EntityBodyIndexMap = PhysicsWorld.CollisionWorld.EntityBodyIndexMap.AsParallelWriter(), }.Schedule(Dependency)); // Dynamic bodies. // Create these separately from static bodies to maintain a 1:1 mapping // between dynamic bodies and their motions. if (numDynamicBodies > 0) { jobHandles.Add(new Jobs.CreateRigidBodies { EntityType = entityType, LocalToWorldType = localToWorldType, ParentType = parentType, PositionType = positionType, RotationType = rotationType, PhysicsColliderType = physicsColliderType, PhysicsCustomTagsType = physicsCustomTagsType, FirstBodyIndex = 0, RigidBodies = PhysicsWorld.Bodies, EntityBodyIndexMap = PhysicsWorld.CollisionWorld.EntityBodyIndexMap.AsParallelWriter(), }.ScheduleParallel(DynamicEntityGroup, 1, Dependency)); jobHandles.Add(new Jobs.CreateMotions { PositionType = positionType, RotationType = rotationType, PhysicsVelocityType = physicsVelocityType, PhysicsMassType = physicsMassType, PhysicsMassOverrideType = physicsMassOverrideType, PhysicsDampingType = physicsDampingType, PhysicsGravityFactorType = physicsGravityFactorType, MotionDatas = PhysicsWorld.MotionDatas, MotionVelocities = PhysicsWorld.MotionVelocities }.ScheduleParallel(DynamicEntityGroup, 1, Dependency)); } // Now, schedule creation of static bodies, with FirstBodyIndex pointing after // the dynamic and kinematic bodies if (numStaticBodies > 0) { jobHandles.Add(new Jobs.CreateRigidBodies { EntityType = entityType, LocalToWorldType = localToWorldType, ParentType = parentType, PositionType = positionType, RotationType = rotationType, PhysicsColliderType = physicsColliderType, PhysicsCustomTagsType = physicsCustomTagsType, FirstBodyIndex = numDynamicBodies, RigidBodies = PhysicsWorld.Bodies, EntityBodyIndexMap = PhysicsWorld.CollisionWorld.EntityBodyIndexMap.AsParallelWriter(), }.ScheduleParallel(StaticEntityGroup, 1, Dependency)); } var handle = JobHandle.CombineDependencies(jobHandles); jobHandles.Clear(); // Build joints if (numJoints > 0) { jobHandles.Add(new Jobs.CreateJoints { ConstrainedBodyPairComponentType = physicsConstrainedBodyPairType, JointComponentType = physicsJointType, EntityType = entityType, RigidBodies = PhysicsWorld.Bodies, Joints = PhysicsWorld.Joints, DefaultStaticBodyIndex = PhysicsWorld.Bodies.Length - 1, NumDynamicBodies = numDynamicBodies, EntityBodyIndexMap = PhysicsWorld.CollisionWorld.EntityBodyIndexMap, EntityJointIndexMap = PhysicsWorld.DynamicsWorld.EntityJointIndexMap.AsParallelWriter(), }.ScheduleParallel(JointEntityGroup, 1, handle)); } // Build the broadphase // TODO: could optimize this by gathering the AABBs and filters at the same time as building the bodies above sfloat timeStep = (sfloat)Time.DeltaTime; PhysicsStep stepComponent = PhysicsStep.Default; if (HasSingleton <PhysicsStep>()) { stepComponent = GetSingleton <PhysicsStep>(); } JobHandle buildBroadphaseHandle = PhysicsWorld.CollisionWorld.ScheduleBuildBroadphaseJobs( ref PhysicsWorld, timeStep, stepComponent.Gravity, HaveStaticBodiesChanged, handle, stepComponent.MultiThreaded > 0); jobHandles.Add(buildBroadphaseHandle); m_OutputDependency = JobHandle.CombineDependencies(jobHandles); } #if ENABLE_UNITY_COLLECTIONS_CHECKS RecordIntegrity(IntegrityCheckMap); #endif ChainDependencies(); }
protected override JobHandle OnUpdate(JobHandle inputDeps) { // Make sure last frame's physics jobs are complete m_EndFramePhysicsSystem.FinalJobHandle.Complete(); // Extract types used by initialize jobs var entityType = GetArchetypeChunkEntityType(); var positionType = GetArchetypeChunkComponentType <Translation>(true); var rotationType = GetArchetypeChunkComponentType <Rotation>(true); var physicsColliderType = GetArchetypeChunkComponentType <PhysicsCollider>(true); var physicsVelocityType = GetArchetypeChunkComponentType <PhysicsVelocity>(true); var physicsMassType = GetArchetypeChunkComponentType <PhysicsMass>(true); var physicsDampingType = GetArchetypeChunkComponentType <PhysicsDamping>(true); var physicsGravityFactorType = GetArchetypeChunkComponentType <PhysicsGravityFactor>(true); var physicsCustomTagsType = GetArchetypeChunkComponentType <PhysicsCustomTags>(true); var physicsJointType = GetArchetypeChunkComponentType <PhysicsJoint>(true); int numDynamicBodies = DynamicEntityGroup.CalculateEntityCount(); int numStaticBodies = StaticEntityGroup.CalculateEntityCount(); int numJoints = JointEntityGroup.CalculateEntityCount(); m_StaticLayerChangeInfo.NumStaticBodies = numStaticBodies + 1; m_StaticLayerChangeInfo.HaveStaticBodiesChanged = 0; if (numStaticBodies != (PhysicsWorld.StaticBodies.Length - 1)) //-1 for fake static body we add { // Quick test if number of bodies changed m_StaticLayerChangeInfo.HaveStaticBodiesChanged = 1; } else { // Make a job to test for changes int numChunks; // There has to be a better way of doing this... using (NativeArray <ArchetypeChunk> chunks = StaticEntityGroup.CreateArchetypeChunkArray(Allocator.TempJob)) { numChunks = chunks.Length; } var chunksHaveChanges = new NativeArray <int>(numChunks, Allocator.TempJob); inputDeps = new Jobs.CheckStaticBodyChangesJob { PositionType = positionType, RotationType = rotationType, PhysicsColliderType = physicsColliderType, ChunkHasChangesOutput = chunksHaveChanges, m_LastSystemVersion = LastSystemVersion }.Schedule(StaticEntityGroup, inputDeps); inputDeps = new Jobs.CheckStaticBodyChangesReduceJob { ChunkHasChangesOutput = chunksHaveChanges, HaveStaticBodiesChanged = m_StaticLayerChangeInfo.HaveStaticBodiesChangedArray, NumStaticBodies = m_StaticLayerChangeInfo.NumStaticBodiesArray }.Schedule(inputDeps); } // Resize the world's native arrays PhysicsWorld.Reset( numStaticBodies: numStaticBodies + 1, // +1 for the default static body numDynamicBodies: numDynamicBodies, numJoints: numJoints); using (var jobHandles = new NativeList <JobHandle>(4, Allocator.Temp)) { // Create the default static body at the end of the body list // TODO: could skip this if no joints present jobHandles.Add(new Jobs.CreateDefaultStaticRigidBody { NativeBodies = PhysicsWorld.Bodies, BodyIndex = PhysicsWorld.Bodies.Length - 1 }.Schedule(inputDeps)); // Dynamic bodies. // Create these separately from static bodies to maintain a 1:1 mapping // between dynamic bodies and their motions. if (numDynamicBodies > 0) { jobHandles.Add(new Jobs.CreateRigidBodies { EntityType = entityType, PositionType = positionType, RotationType = rotationType, PhysicsColliderType = physicsColliderType, PhysicsCustomTagsType = physicsCustomTagsType, FirstBodyIndex = 0, RigidBodies = PhysicsWorld.Bodies }.Schedule(DynamicEntityGroup, inputDeps)); jobHandles.Add(new Jobs.CreateMotions { PositionType = positionType, RotationType = rotationType, PhysicsVelocityType = physicsVelocityType, PhysicsMassType = physicsMassType, PhysicsDampingType = physicsDampingType, PhysicsGravityFactorType = physicsGravityFactorType, MotionDatas = PhysicsWorld.MotionDatas, MotionVelocities = PhysicsWorld.MotionVelocities }.Schedule(DynamicEntityGroup, inputDeps)); } // Now, schedule creation of static bodies, with FirstBodyIndex pointing after // the dynamic and kinematic bodies if (numStaticBodies > 0) { jobHandles.Add(new Jobs.CreateRigidBodies { EntityType = entityType, PositionType = positionType, RotationType = rotationType, PhysicsColliderType = physicsColliderType, PhysicsCustomTagsType = physicsCustomTagsType, FirstBodyIndex = numDynamicBodies, RigidBodies = PhysicsWorld.Bodies }.Schedule(StaticEntityGroup, inputDeps)); } var handle = JobHandle.CombineDependencies(jobHandles); jobHandles.Clear(); // Build joints if (numJoints > 0) { jobHandles.Add(new Jobs.CreateJoints { JointComponentType = physicsJointType, EntityType = entityType, RigidBodies = PhysicsWorld.Bodies, Joints = PhysicsWorld.Joints, DefaultStaticBodyIndex = PhysicsWorld.Bodies.Length - 1, NumDynamicBodies = numDynamicBodies }.Schedule(JointEntityGroup, handle)); } // Build the broadphase // TODO: could optimize this by gathering the AABBs and filters at the same time as building the bodies above #if !UNITY_DOTSPLAYER float timeStep = UnityEngine.Time.fixedDeltaTime; #else float timeStep = Time.DeltaTime; #endif PhysicsStep stepComponent = PhysicsStep.Default; if (HasSingleton <PhysicsStep>()) { stepComponent = GetSingleton <PhysicsStep>(); } jobHandles.Add(PhysicsWorld.CollisionWorld.Broadphase.ScheduleBuildJobs(ref PhysicsWorld, timeStep, stepComponent.Gravity, stepComponent.ThreadCountHint, ref m_StaticLayerChangeInfo, handle)); FinalJobHandle = JobHandle.CombineDependencies(jobHandles); } return(JobHandle.CombineDependencies(FinalJobHandle, inputDeps)); }
protected override JobHandle OnUpdate(JobHandle inputDeps) { // Make sure last frame's physics jobs are complete m_EndFramePhysicsSystem.FinalJobHandle.Complete(); // Extract types used by initialize jobs var entityType = GetArchetypeChunkEntityType(); var localToWorldType = GetArchetypeChunkComponentType <LocalToWorld>(true); var parentType = GetArchetypeChunkComponentType <Parent>(true); // var positionType = GetArchetypeChunkComponentType<Translation>(true); // var rotationType = GetArchetypeChunkComponentType<Rotation>(true); var transformType = GetArchetypeChunkComponentType <TransformPredictedState>(true); var physicsColliderType = GetArchetypeChunkComponentType <PhysicsCollider>(true); var physicsVelocityType = GetArchetypeChunkComponentType <PhysicsVelocity>(true); var physicsMassType = GetArchetypeChunkComponentType <PhysicsMass>(true); var physicsDampingType = GetArchetypeChunkComponentType <PhysicsDamping>(true); var physicsGravityFactorType = GetArchetypeChunkComponentType <PhysicsGravityFactor>(true); var physicsCustomTagsType = GetArchetypeChunkComponentType <PhysicsCustomTags>(true); // var physicsJointType = GetArchetypeChunkComponentType<PhysicsJoint>(true); int numDynamicBodies = DynamicEntityGroup.CalculateEntityCount(); int numStaticBodies = StaticEntityGroup.CalculateEntityCount(); // int numJoints = JointEntityGroup.CalculateEntityCount(); int previousStaticBodyCount = PhysicsWorld.NumStaticBodies; // Resize the world's native arrays PhysicsWorld.Reset( numStaticBodies + 1, // +1 for the default static body numDynamicBodies, 0); // Determine if the static bodies have changed in any way that will require the static broadphase tree to be rebuilt JobHandle staticBodiesCheckHandle = default; var haveStaticBodiesChanged = new NativeArray <int>(1, Allocator.TempJob); haveStaticBodiesChanged[0] = 0; { if (PhysicsWorld.NumStaticBodies != previousStaticBodyCount) { haveStaticBodiesChanged[0] = 1; } else { // Make a job to test for changes int numChunks; using (NativeArray <ArchetypeChunk> chunks = StaticEntityGroup.CreateArchetypeChunkArray(Allocator.TempJob)) { numChunks = chunks.Length; } var chunksHaveChanges = new NativeArray <int>(numChunks, Allocator.TempJob); staticBodiesCheckHandle = new Jobs.CheckStaticBodyChangesJob { // LocalToWorldType = localToWorldType, // ParentType = parentType, // PositionType = positionType, // RotationType = rotationType, TransformType = transformType, PhysicsColliderType = physicsColliderType, ChunkHasChangesOutput = chunksHaveChanges, m_LastSystemVersion = LastSystemVersion }.Schedule(StaticEntityGroup, inputDeps); staticBodiesCheckHandle = new Jobs.CheckStaticBodyChangesReduceJob { ChunkHasChangesOutput = chunksHaveChanges, Result = haveStaticBodiesChanged }.Schedule(staticBodiesCheckHandle); } } using (var jobHandles = new NativeList <JobHandle>(4, Allocator.Temp)) { // Static body changes check jobs jobHandles.Add(staticBodiesCheckHandle); // Create the default static body at the end of the body list // TODO: could skip this if no joints present // if (numJoints > 0) { jobHandles.Add(new Jobs.CreateDefaultStaticRigidBody { NativeBodies = PhysicsWorld.Bodies, BodyIndex = PhysicsWorld.Bodies.Length - 1 }.Schedule(inputDeps)); } // Dynamic bodies. // Create these separately from static bodies to maintain a 1:1 mapping // between dynamic bodies and their motions. if (numDynamicBodies > 0) { jobHandles.Add(new Jobs.CreateRigidBodies { EntityType = entityType, LocalToWorldType = localToWorldType, ParentType = parentType, // PositionType = positionType, // RotationType = rotationType, TransformType = transformType, PhysicsColliderType = physicsColliderType, PhysicsCustomTagsType = physicsCustomTagsType, FirstBodyIndex = 0, RigidBodies = PhysicsWorld.Bodies }.Schedule(DynamicEntityGroup, inputDeps)); jobHandles.Add(new Jobs.CreateMotions { // PositionType = positionType, // RotationType = rotationType, TransformType = transformType, PhysicsVelocityType = physicsVelocityType, PhysicsMassType = physicsMassType, PhysicsDampingType = physicsDampingType, PhysicsGravityFactorType = physicsGravityFactorType, MotionDatas = PhysicsWorld.MotionDatas, MotionVelocities = PhysicsWorld.MotionVelocities }.Schedule(DynamicEntityGroup, inputDeps)); } // Now, schedule creation of static bodies, with FirstBodyIndex pointing after // the dynamic and kinematic bodies if (numStaticBodies > 0) { jobHandles.Add(new Jobs.CreateRigidBodies { EntityType = entityType, LocalToWorldType = localToWorldType, ParentType = parentType, // PositionType = positionType, // RotationType = rotationType, TransformType = transformType, PhysicsColliderType = physicsColliderType, PhysicsCustomTagsType = physicsCustomTagsType, FirstBodyIndex = numDynamicBodies, RigidBodies = PhysicsWorld.Bodies }.Schedule(StaticEntityGroup, inputDeps)); } var handle = JobHandle.CombineDependencies(jobHandles); jobHandles.Clear(); // Build joints //if (numJoints > 0) //{ // jobHandles.Add(new Jobs.CreateJoints // { // JointComponentType = physicsJointType, // EntityType = entityType, // RigidBodies = PhysicsWorld.Bodies, // Joints = PhysicsWorld.Joints, // DefaultStaticBodyIndex = PhysicsWorld.Bodies.Length - 1, // NumDynamicBodies = numDynamicBodies // }.Schedule(JointEntityGroup, handle)); //} // Build the broadphase // TODO: could optimize this by gathering the AABBs and filters at the same time as building the bodies above #if !UNITY_DOTSPLAYER float timeStep = UnityEngine.Time.fixedDeltaTime; #else float timeStep = Time.DeltaTime; #endif PhysicsStep stepComponent = PhysicsStep.Default; if (HasSingleton <PhysicsStep>()) { stepComponent = GetSingleton <PhysicsStep>(); } JobHandle buildBroadphaseHandle = PhysicsWorld.CollisionWorld.ScheduleBuildBroadphaseJobs( ref PhysicsWorld, timeStep, stepComponent.Gravity, haveStaticBodiesChanged, handle, stepComponent.ThreadCountHint); jobHandles.Add(haveStaticBodiesChanged.Dispose(buildBroadphaseHandle)); FinalJobHandle = JobHandle.CombineDependencies(jobHandles); FinalJobHandle.Complete(); } return(JobHandle.CombineDependencies(FinalJobHandle, inputDeps)); }
protected override JobHandle OnUpdate(JobHandle inputDeps) { // Extract types used by initialize jobs var entityType = GetArchetypeChunkEntityType(); var positionType = GetArchetypeChunkComponentType <Translation>(true); var rotationType = GetArchetypeChunkComponentType <Rotation>(true); var physicsColliderType = GetArchetypeChunkComponentType <PhysicsCollider>(true); var physicsVelocityType = GetArchetypeChunkComponentType <PhysicsVelocity>(true); var physicsMassType = GetArchetypeChunkComponentType <PhysicsMass>(true); var physicsDampingType = GetArchetypeChunkComponentType <PhysicsDamping>(true); var physicsGravityFactorType = GetArchetypeChunkComponentType <PhysicsGravityFactor>(true); var physicsCustomDataType = GetArchetypeChunkComponentType <PhysicsCustomData>(true); var physicsJointType = GetArchetypeChunkComponentType <PhysicsJoint>(true); int numDynamicBodies = DynamicEntityGroup.CalculateLength(); int numStaticBodies = StaticEntityGroup.CalculateLength(); int numJoints = JointEntityGroup.CalculateLength(); // Check for static body changes before the reset() bool haveStaticBodiesChanged = false; { // For now, do this before the reset() - otherwise, we need the BuildRigidBodies jobs to finish if (numStaticBodies != (PhysicsWorld.StaticBodies.Length - 1)) //-1 for fake static body we add { // Quick test if number of bodies changed haveStaticBodiesChanged = true; } else { // Make a job to test for changes int numChunks; // There has to be a better way of doing this... { var chunks = StaticEntityGroup.CreateArchetypeChunkArray(Allocator.TempJob); numChunks = chunks.Length; chunks.Dispose(); } var chunksHaveChanges = new NativeArray <int>(numChunks, Allocator.TempJob); var checkStaticChanges = new Jobs.CheckStaticBodyChangesJob { PositionType = positionType, RotationType = rotationType, PhysicsColliderType = physicsColliderType, StaticRigidBodies = PhysicsWorld.StaticBodies, ChunkHasChangesOutput = chunksHaveChanges }; checkStaticChanges.Schedule(StaticEntityGroup, inputDeps).Complete(); for (int i = 0; i < numChunks; i++) { haveStaticBodiesChanged |= chunksHaveChanges[i] != 0; } chunksHaveChanges.Dispose(); } } // Resize the world's native arrays PhysicsWorld.Reset( numStaticBodies: numStaticBodies + 1, // +1 for the default static body numDynamicBodies: numDynamicBodies, numJoints: numJoints); var jobHandles = new NativeList <JobHandle>(4, Allocator.Temp); // Create the default static body at the end of the body list // TODO: could skip this if no joints present jobHandles.Add(new Jobs.CreateDefaultStaticRigidBody { NativeBodies = PhysicsWorld.Bodies, BodyIndex = PhysicsWorld.Bodies.Length - 1 }.Schedule(inputDeps)); // Dynamic bodies. Create these separately from static bodies to maintain a 1:1 mapping // between dynamic bodies and their motions. if (numDynamicBodies > 0) { jobHandles.Add(new Jobs.CreateRigidBodies { EntityType = entityType, PositionType = positionType, RotationType = rotationType, PhysicsColliderType = physicsColliderType, PhysicsCustomDataType = physicsCustomDataType, FirstBodyIndex = 0, RigidBodies = PhysicsWorld.Bodies }.Schedule(DynamicEntityGroup, inputDeps)); jobHandles.Add(new Jobs.CreateMotions { PositionType = positionType, RotationType = rotationType, PhysicsVelocityType = physicsVelocityType, PhysicsMassType = physicsMassType, PhysicsDampingType = physicsDampingType, PhysicsGravityFactorType = physicsGravityFactorType, MotionDatas = PhysicsWorld.MotionDatas, MotionVelocities = PhysicsWorld.MotionVelocities }.Schedule(DynamicEntityGroup, inputDeps)); } // Now, schedule creation of static bodies, with FirstBodyIndex pointing after the dynamic bodies if (numStaticBodies > 0) { jobHandles.Add(new Jobs.CreateRigidBodies { EntityType = entityType, PositionType = positionType, RotationType = rotationType, PhysicsColliderType = physicsColliderType, PhysicsCustomDataType = physicsCustomDataType, FirstBodyIndex = numDynamicBodies, RigidBodies = PhysicsWorld.Bodies }.Schedule(StaticEntityGroup, inputDeps)); } var handle = JobHandle.CombineDependencies(jobHandles); jobHandles.Clear(); // Build joints if (numJoints > 0) { jobHandles.Add(new Jobs.CreateJoints { JointComponentType = physicsJointType, EntityType = entityType, RigidBodies = PhysicsWorld.Bodies, Joints = PhysicsWorld.Joints, DefaultStaticBodyIndex = PhysicsWorld.Bodies.Length - 1 }.Schedule(JointEntityGroup, handle)); } // Build the broadphase // TODO: could optimize this by gathering the AABBs and filters at the same time as building the bodies above float timeStep = UnityEngine.Time.fixedDeltaTime; PhysicsStep stepComponent = PhysicsStep.Default; if (HasSingleton <PhysicsStep>()) { stepComponent = GetSingleton <PhysicsStep>(); } jobHandles.Add(PhysicsWorld.CollisionWorld.Broadphase.ScheduleBuildJobs(ref PhysicsWorld, timeStep, stepComponent.ThreadCountHint, haveStaticBodiesChanged, handle)); FinalJobHandle = JobHandle.CombineDependencies(jobHandles); jobHandles.Dispose(); return(JobHandle.CombineDependencies(FinalJobHandle, inputDeps)); }