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)); }