Ejemplo n.º 1
0
        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();
        }
Ejemplo n.º 2
0
        protected override void OnUpdate()
        {
            // Make sure last frame's physics jobs are complete before any new ones start
            m_EndFramePhysicsSystem.GetOutputDependency().Complete();

            // Combine implicit input dependency with the user one
            Dependency = JobHandle.CombineDependencies(Dependency, m_InputDependency);

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

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

            // 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,
                        PhysicsColliderType   = physicsColliderType,
                        ChunkHasChangesOutput = chunksHaveChanges,
                        m_LastSystemVersion   = LastSystemVersion
                    }.Schedule(StaticEntityGroup, Dependency);

                    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
                jobHandles.Add(new Jobs.CreateDefaultStaticRigidBody
                {
                    NativeBodies = PhysicsWorld.Bodies,
                    BodyIndex    = PhysicsWorld.Bodies.Length - 1
                }.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
                    }.Schedule(DynamicEntityGroup, 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
                    }.Schedule(DynamicEntityGroup, 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
                    }.Schedule(StaticEntityGroup, 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
                    }.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));

                m_OutputDependency = JobHandle.CombineDependencies(jobHandles);
            }

            // Combine implicit output dependency with user one
            Dependency = JobHandle.CombineDependencies(m_OutputDependency, Dependency);

            // Inform next system in the pipeline of its dependency
            m_StepPhysicsWorldSystem.AddInputDependency(Dependency);

            // Invalidate input dependency since it's been used by now
            m_InputDependency = default;
        }