protected override void OnUpdate()
        {
            // Make sure last frame's physics jobs are complete before any new ones start
            m_InputDependencyToComplete.Complete();

            float timeStep = Time.DeltaTime;

            // Tweak if you want a different simulation for this world
            PhysicsStep stepComponent = PhysicsStep.Default;

            if (HasSingleton <PhysicsStep>())
            {
                stepComponent = GetSingleton <PhysicsStep>();
            }

            #region Build World

            Dependency = PhysicsWorldBuilder.SchedulePhysicsWorldBuild(this, ref PhysicsData,
                                                                       Dependency, timeStep, stepComponent.MultiThreaded > 0, stepComponent.Gravity, LastSystemVersion);

            #endregion

            #region Step World

            // Early-out to prevent simulation context creation in stepper, generally not required
            if (PhysicsData.PhysicsWorld.NumBodies <= 1)
            {
                return;
            }

            var stepInput = new SimulationStepInput()
            {
                World    = PhysicsData.PhysicsWorld,
                TimeStep = timeStep,
                Gravity  = stepComponent.Gravity,
                SynchronizeCollisionWorld            = false,
                NumSolverIterations                  = stepComponent.SolverIterationCount,
                SolverStabilizationHeuristicSettings = stepComponent.SolverStabilizationHeuristicSettings,
                HaveStaticBodiesChanged              = PhysicsData.HaveStaticBodiesChanged,
            };

            m_Stepper.ScheduleSimulationStepJobs(stepComponent.SimulationType, WorldFilter.Value, stepInput, Dependency, stepComponent.MultiThreaded > 0);

            // Include the final simulation handle
            // (Not FinalJobHandle since other systems shouldn't need to depend on the dispose jobs)
            Dependency = JobHandle.CombineDependencies(Dependency, m_Stepper.FinalSimulationJobHandle);

            #endregion

            #region Export World

            Dependency = PhysicsWorldExporter.SchedulePhysicsWorldExport(this, in PhysicsData.PhysicsWorld, Dependency, PhysicsData.DynamicEntityGroup);

            #endregion

            // Just to make sure current server step jobs are complete before next step starts
            m_InputDependencyToComplete = Dependency;
        }
Ejemplo n.º 2
0
        protected override void OnUpdate()
        {
            // Combine implicit input dependency with the user one
            var handle = JobHandle.CombineDependencies(Dependency, m_InputDependency);

            PhysicsStep stepComponent = PhysicsStep.Default;

            if (HasSingleton <PhysicsStep>())
            {
                stepComponent = GetSingleton <PhysicsStep>();
            }

            // Swap the simulation implementation if the requested type changed
            if (Simulation.Type != stepComponent.SimulationType)
            {
                Simulation.Dispose();
                Simulation = m_SimulationCreators[(int)stepComponent.SimulationType]();
            }

#if !UNITY_DOTSPLAYER
            float timeStep = UnityEngine.Time.fixedDeltaTime;
#else
            float timeStep = Time.DeltaTime;
#endif

            // Schedule the simulation jobs
            Simulation.ScheduleStepJobs(new SimulationStepInput()
            {
                World    = m_BuildPhysicsWorldSystem.PhysicsWorld,
                TimeStep = timeStep,
                Gravity  = stepComponent.Gravity,
                SynchronizeCollisionWorld            = stepComponent.SynchronizeCollisionWorld > 0,
                NumSolverIterations                  = stepComponent.SolverIterationCount,
                SolverStabilizationHeuristicSettings = stepComponent.SolverStabilizationHeuristicSettings
            }, m_Callbacks, handle, stepComponent.ThreadCountHint);

            // Clear the callbacks. User must enqueue them again before the next step.
            m_Callbacks.Clear();

            // Return the final simulation handle
            // (Not FinalJobHandle since other systems shouldn't need to depend on the dispose jobs)
            m_OutputDependency = FinalSimulationJobHandle;

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

            // Inform next systems in the pipeline of their dependency
            m_ExportPhysicsWorldSystem.AddInputDependency(m_OutputDependency);
            m_EndFramePhysicsSystem.AddInputDependency(Simulation.FinalJobHandle);

            // Invalidate input dependency since it's been used now
            m_InputDependency = default;
        }
Ejemplo n.º 3
0
        void SetSimulationType(SimulationType simulationType, Scene scene, LoadSceneMode mode)
        {
            var entityManager = World.Active.EntityManager;
            var entities      = entityManager.GetAllEntities();

            foreach (var entity in entities)
            {
                if (entityManager.HasComponent <PhysicsStep>(entity))
                {
                    PhysicsStep componentData = entityManager.GetComponentData <PhysicsStep>(entity);
                    componentData.SimulationType = simulationType;
                    entityManager.SetComponentData <PhysicsStep>(entity, componentData);
                    break;
                }
            }
        }
Ejemplo n.º 4
0
        protected override JobHandle OnUpdate(JobHandle inputDeps)
        {
            var handle = JobHandle.CombineDependencies(m_BuildPhysicsWorldSystem.FinalJobHandle, inputDeps);

            PhysicsStep stepComponent = PhysicsStep.Default;

            if (HasSingleton <PhysicsStep>())
            {
                stepComponent = GetSingleton <PhysicsStep>();
            }

            // Swap the simulation implementation if the requested type changed
            if (Simulation.Type != stepComponent.SimulationType)
            {
                Simulation.Dispose();
                Simulation = m_SimulationCreators[(int)stepComponent.SimulationType]();
            }

#if !UNITY_DOTSPLAYER
            float timeStep = UnityEngine.Time.fixedDeltaTime;
#else
            float timeStep = Time.DeltaTime;
#endif

            // Schedule the simulation jobs
            var stepInput = new SimulationStepInput
            {
                World                     = m_BuildPhysicsWorldSystem.PhysicsWorld,
                TimeStep                  = timeStep,
                ThreadCountHint           = stepComponent.ThreadCountHint,
                Gravity                   = stepComponent.Gravity,
                SynchronizeCollisionWorld = false,
                NumSolverIterations       = stepComponent.SolverIterationCount,
                Callbacks                 = m_Callbacks
            };
            Simulation.ScheduleStepJobs(stepInput, handle);
            FinalSimulationJobHandle = Simulation.FinalSimulationJobHandle;
            FinalJobHandle           = Simulation.FinalJobHandle;

            // Clear the callbacks. User must enqueue them again before the next step.
            m_Callbacks.Clear();

            return(handle);
        }
Ejemplo n.º 5
0
    void StepWorldXTimes(int stepAmount)
    {
        PhysicsStep stepComponent = PhysicsStep.Default;

        var stepInput = new SimulationStepInput
        {
            World               = m_BuildPhysicsWorld.PhysicsWorld,
            TimeStep            = Time.DeltaTime,
            NumSolverIterations = stepComponent.SolverIterationCount,
            SolverStabilizationHeuristicSettings = stepComponent.SolverStabilizationHeuristicSettings,
            Gravity = stepComponent.Gravity,
            SynchronizeCollisionWorld = true
        };

        for (int i = 0; i < stepAmount; i++)
        {
            SimulationContext.Reset(stepInput);
            Debug.Log("Ball position in simulation " + GetBallPosition());
            Simulation.StepImmediate(stepInput, ref SimulationContext);
        }
    }
Ejemplo n.º 6
0
    protected override JobHandle OnUpdate(JobHandle inputDeps)
    {
        Random random = new Random();

        PhysicsStep stepComponent = PhysicsStep.Default;

        if (HasSingleton <PhysicsStep>())
        {
            stepComponent = GetSingleton <PhysicsStep>();
        }

        var job = new RandomMotionJob
        {
            gravity   = stepComponent.Gravity,
            deltaTime = UnityEngine.Time.fixedDeltaTime,
            random    = random
        };
        var jobHandle = job.Schedule(this, inputDeps);

        return(jobHandle);
    }
        protected override void OnUpdate()
        {
            // Make sure dependencies are complete, we'll run everything immediately
            Dependency.Complete();

            float timeStep = Time.DeltaTime;

            // Tweak if you want a different simulation for this world
            PhysicsStep stepComponent = PhysicsStep.Default;

            if (HasSingleton <PhysicsStep>())
            {
                stepComponent = GetSingleton <PhysicsStep>();
            }

            // Build PhysicsWorld immediately
            PhysicsWorldBuilder.BuildPhysicsWorldImmediate(this, ref PhysicsData, timeStep, stepComponent.Gravity, LastSystemVersion);

            // Early out if world is static
            if (PhysicsData.PhysicsWorld.NumDynamicBodies == 0)
            {
                return;
            }

            // Run simulation on main thread
            m_Stepper.StepImmediate(stepComponent.SimulationType, ref PhysicsData.PhysicsWorld,
                                    new SimulationStepInput()
            {
                World    = PhysicsData.PhysicsWorld,
                TimeStep = timeStep,
                Gravity  = stepComponent.Gravity,
                SynchronizeCollisionWorld            = false,
                NumSolverIterations                  = 4,
                SolverStabilizationHeuristicSettings = Solver.StabilizationHeuristicSettings.Default,
                HaveStaticBodiesChanged              = PhysicsData.HaveStaticBodiesChanged
            });

            // Export physics world only (don't copy CollisionWorld)
            PhysicsWorldExporter.ExportPhysicsWorldImmediate(this, in PhysicsData.PhysicsWorld, PhysicsData.DynamicEntityGroup);
        }
Ejemplo n.º 8
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();
        }
        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));
        }
Ejemplo n.º 10
0
        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));
        }
Ejemplo n.º 11
0
    protected override void OnCreate()
    {
        base.OnCreate();
        Instance = this;
        UnityEngine.Physics.autoSimulation = false;

        matPropBlock = new MaterialPropertyBlock();

        // setup physics parameters
        World.GetOrCreateSystem <FixedStepSimulationSystemGroup>().Timestep = (float)(sfloat.One / (sfloat)60.0f);
        Entity      physicsStep       = EntityManager.CreateEntity(typeof(PhysicsStep));
        PhysicsStep physicsStepParams = PhysicsStep.Default;

        physicsStepParams.SolverStabilizationHeuristicSettings = new Solver.StabilizationHeuristicSettings
        {
            EnableSolverStabilization = true,
            EnableFrictionVelocities  = true,
            InertiaScalingFactor      = (sfloat)0.0f,
            VelocityClippingFactor    = (sfloat)1.0f
        };

        physicsStepParams.SolverIterationCount = 3;
        physicsStepParams.MultiThreaded        = 1;
        physicsStepParams.Gravity = new float3(sfloat.Zero, (sfloat)(-60.0f), sfloat.Zero);
        EntityManager.SetComponentData(physicsStep, physicsStepParams);

        UnityS.Physics.Material material = UnityS.Physics.Material.Default;
        material.Friction = sfloat.One;

        PhysicsParams physicsParamsStatic = PhysicsParams.Default;

        physicsParamsStatic.isDynamic = false;

        PhysicsParams physicsParamsDynamic = PhysicsParams.Default;

        physicsParamsDynamic.isDynamic = true;

        CreateBox(new float3(sfloat.Zero, sfloat.Zero, sfloat.Zero), new float3((sfloat)500.0f, (sfloat)2.0f, (sfloat)500.0f), quaternion.identity, material, physicsParamsStatic);

        sfloat radius  = (sfloat)10.0f;
        int    count   = 7;
        sfloat sfcount = (sfloat)count;

        int layers = 4;

        sfloat size          = (sfloat)6.0f;
        sfloat anglePerLayer = (sfloat)0.25f;

        // set up stacked boxes
        for (int l = 0; l < layers; l++)
        {
            sfloat offsetY     = sfloat.One + ((sfloat)l + (sfloat)0.5f) * size;
            sfloat angleOffset = anglePerLayer * (sfloat)l;

            for (int i = 0; i < count; i++)
            {
                sfloat t = (sfloat)i / sfcount * math.PI * (sfloat)2.0f + angleOffset;
                math.sincos(t, out sfloat sin, out sfloat cos);
                float3 pos = new float3(radius * cos, offsetY, radius * sin);

                CreateBox(pos, new float3(size, size, size),
                          quaternion.AxisAngle(new float3(sfloat.Zero, sfloat.One, sfloat.Zero), -t),
                          material, physicsParamsDynamic);
            }
        }
    }
Ejemplo n.º 12
0
        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));
        }