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;
        }
Esempio n. 2
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);
        }
    public void Update()
    {
        // +1 for the default static body
        PhysicsWorld.Reset(m_NumStaticBodies + 1, m_NumDynamicBodies, m_NumJoints);

        SimulationStepInput input = new SimulationStepInput
        {
            World               = PhysicsWorld,
            TimeStep            = Time.fixedDeltaTime,
            NumSolverIterations = PhysicsStep.Default.SolverIterationCount,
            Gravity             = PhysicsStep.Default.Gravity
        };

        int numOfBodies = m_NumDynamicBodies + m_NumStaticBodies;

        NativeHashMap <int, int> indexMap = new NativeHashMap <int, int>(m_Bodies.Length, Allocator.TempJob);

        SimulationContext.Reset(ref PhysicsWorld);

        new SingleThreadedPhysicsSimulationJob
        {
            Bodies            = m_Bodies,
            Joints            = m_Joints,
            Input             = input,
            SimulationContext = SimulationContext,
            IndexMap          = indexMap
        }.Schedule().Complete();

        // Map the results to GameObjects
        for (int i = 0; i < numOfBodies; i++)
        {
            if (!m_Bodies[i].IsDynamic)
            {
                continue;
            }

            m_BodyIndexToGameObjectMapping.TryGetValue(i, out GameObject g);
            var t = g.GetComponent <Transform>();
            t.position = m_Bodies[i].Position;
            t.rotation = m_Bodies[i].Orientation;
        }

        indexMap.Dispose();
    }
Esempio n. 4
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);
        }
    }
        public virtual IEnumerator LoadScenes([ValueSource(nameof(GetScenes))] string scenePath)
        {
            // Log scene name in case Unity crashes and test results aren't written out.
            Debug.Log("Loading " + scenePath);
            LogAssert.Expect(LogType.Log, "Loading " + scenePath);

            // Wait for next frame
            yield return(null);

            // Number of steps to simulate
            const int k_StopAfterStep = 100;

            // Number of worlds to simulate
            const int k_NumWorlds = 4;

            // Number of threads in each of the runs (3rd run is single threaded simulation)
            NativeArray <int> numThreadsPerRun = new NativeArray <int>(k_NumWorlds, Allocator.Persistent);

            numThreadsPerRun[0] = 8;
            numThreadsPerRun[1] = 4;
            numThreadsPerRun[2] = 0;
            numThreadsPerRun[3] = -1;

            // Load the scene and wait 2 frames
            SceneManager.LoadScene(scenePath);

            yield return(null);

            yield return(null);

            var sampler = DefaultWorld.GetOrCreateSystem <BuildPhysicsWorldSampler>();

            sampler.BeginSampling();

            while (!sampler.FinishedSampling)
            {
                yield return(new WaitForSeconds(0.05f));
            }

            var buildPhysicsWorld = DefaultWorld.GetOrCreateSystem <BuildPhysicsWorld>();
            var stepComponent     = PhysicsStep.Default;

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

            // Extract original world and make copies
            List <PhysicsWorld> physicsWorlds = new List <PhysicsWorld>(k_NumWorlds);

            physicsWorlds.Add(sampler.PhysicsWorld.Clone());

            physicsWorlds.Add(physicsWorlds[0].Clone());
            physicsWorlds.Add(physicsWorlds[1].Clone());
            physicsWorlds.Add(physicsWorlds[2].Clone());

            NativeArray <int> buildStaticTree = new NativeArray <int>(1, Allocator.Persistent);

            buildStaticTree[0] = 1;

            // Simulation step input
            var stepInput = new SimulationStepInput()
            {
                Gravity                   = stepComponent.Gravity,
                NumSolverIterations       = stepComponent.SolverIterationCount,
                SynchronizeCollisionWorld = true,
                TimeStep                  = Time.fixedDeltaTime
            };

            // Step the simulation on all worlds
            for (int i = 0; i < physicsWorlds.Count; i++)
            {
                int threadCountHint = numThreadsPerRun[i];
                if (threadCountHint == -1)
                {
                    stepInput.World = physicsWorlds[i];
                    stepInput.World.CollisionWorld.BuildBroadphase(
                        ref stepInput.World, stepInput.TimeStep, stepInput.Gravity, true);

#if HAVOK_PHYSICS_EXISTS
                    if (SimulateHavok)
                    {
                        var simulationContext = new Havok.Physics.SimulationContext(Havok.Physics.HavokConfiguration.Default);
                        for (int step = 0; step < k_StopAfterStep; step++)
                        {
                            simulationContext.Reset(ref stepInput.World);
                            new StepHavokJob
                            {
                                Input             = stepInput,
                                SimulationContext = simulationContext
                            }.Schedule().Complete();
                        }

                        simulationContext.Dispose();
                    }
                    else
#endif
                    {
                        var simulationContext = new SimulationContext();
                        for (int step = 0; step < k_StopAfterStep; step++)
                        {
                            simulationContext.Reset(ref stepInput.World);
                            new StepJob
                            {
                                Input             = stepInput,
                                SimulationContext = simulationContext
                            }.Schedule().Complete();
                        }

                        simulationContext.Dispose();
                    }
                }
                else
                {
#if HAVOK_PHYSICS_EXISTS
                    if (SimulateHavok)
                    {
                        var simulation = new Havok.Physics.HavokSimulation(Havok.Physics.HavokConfiguration.Default);
                        stepInput.World = physicsWorlds[i];
                        stepInput.World.CollisionWorld.ScheduleBuildBroadphaseJobs(
                            ref stepInput.World, stepInput.TimeStep, stepInput.Gravity, buildStaticTree, default, threadCountHint).Complete();
Esempio n. 6
0
        internal static void CreateRigidBodiesAndMotions(SimulationStepInput input,
                                                         NativeList <BodyInfo> bodies, NativeHashMap <int, int> indexMap)
        {
            NativeArray <RigidBody>      dynamicBodies    = input.World.DynamicBodies;
            NativeArray <RigidBody>      staticBodies     = input.World.StaticBodies;
            NativeArray <MotionData>     motionDatas      = input.World.MotionDatas;
            NativeArray <MotionVelocity> motionVelocities = input.World.MotionVelocities;

            int dynamicBodyIndex = 0;
            int staticBodyIndex  = 0;

            for (int i = 0; i < bodies.Length; i++)
            {
                BodyInfo bodyInfo = bodies[i];

                unsafe
                {
                    Unity.Physics.Collider *collider = (Unity.Physics.Collider *)bodyInfo.Collider.GetUnsafePtr();

                    if (bodyInfo.IsDynamic)
                    {
                        dynamicBodies[dynamicBodyIndex] = new RigidBody
                        {
                            WorldFromBody = new RigidTransform(bodyInfo.Orientation, bodyInfo.Position),
                            Collider      = bodyInfo.Collider,
                            Entity        = Entity.Null,
                            CustomTags    = 0
                        };
                        motionDatas[dynamicBodyIndex] = new MotionData
                        {
                            WorldFromMotion = new RigidTransform(
                                math.mul(bodyInfo.Orientation, collider->MassProperties.MassDistribution.Transform.rot),
                                math.rotate(bodyInfo.Orientation, collider->MassProperties.MassDistribution.Transform.pos) + bodyInfo.Position
                                ),
                            BodyFromMotion = new RigidTransform(collider->MassProperties.MassDistribution.Transform.rot, collider->MassProperties.MassDistribution.Transform.pos),
                            LinearDamping  = 0.0f,
                            AngularDamping = 0.0f
                        };
                        motionVelocities[dynamicBodyIndex] = new MotionVelocity
                        {
                            LinearVelocity         = bodyInfo.LinearVelocity,
                            AngularVelocity        = bodyInfo.AngularVelocity,
                            InverseInertia         = math.rcp(collider->MassProperties.MassDistribution.InertiaTensor * bodyInfo.Mass),
                            InverseMass            = math.rcp(bodyInfo.Mass),
                            AngularExpansionFactor = collider->MassProperties.AngularExpansionFactor,
                            GravityFactor          = 1.0f
                        };

                        indexMap.Add(i, dynamicBodyIndex);
                        dynamicBodyIndex++;
                    }
                    else
                    {
                        staticBodies[staticBodyIndex] = new RigidBody
                        {
                            WorldFromBody = new RigidTransform(bodyInfo.Orientation, bodyInfo.Position),
                            Collider      = bodyInfo.Collider,
                            Entity        = Entity.Null,
                            CustomTags    = 0
                        };

                        staticBodyIndex++;
                    }
                }
            }

            // Create default static body
            unsafe
            {
                staticBodies[staticBodyIndex] = new RigidBody
                {
                    WorldFromBody = new RigidTransform(quaternion.identity, float3.zero),
                    Collider      = default,
Esempio n. 7
0
 public static void StepImmediate(SimulationStepInput input, ref SimulationContext simulationContext)
 {
     ref PhysicsWorld world = ref input.World;
Esempio n. 8
0
 public SimulationJobHandles ScheduleStepJobs(SimulationStepInput input, SimulationCallbacks callbacks, JobHandle inputDeps, int threadCountHint = 0) =>
 new SimulationJobHandles(inputDeps);
Esempio n. 9
0
 public void Step(SimulationStepInput input)
 {
 }
Esempio n. 10
0
    public void Update()
    {
        // +1 default static body
        var NumStaticBodies = (m_BodyInfos.Length - m_NumDynamicBodies) + 1;

        PhysicsWorld.Reset(NumStaticBodies, m_NumDynamicBodies, m_JointInfos.Length);

        SimulationStepInput input = new SimulationStepInput
        {
            World               = PhysicsWorld,
            TimeStep            = World.DefaultGameObjectInjectionWorld.GetExistingSystem <FixedStepSimulationSystemGroup>().Timestep,
            NumSolverIterations = PhysicsStep.Default.SolverIterationCount,
            SolverStabilizationHeuristicSettings = PhysicsStep.Default.SolverStabilizationHeuristicSettings,
            Gravity = PhysicsStep.Default.Gravity
        };

        int numOfBodies = m_NumDynamicBodies + NumStaticBodies;

        using (var indexMap = new NativeHashMap <int, int>(m_BodyInfos.Length, Allocator.TempJob))
        {
#if HAVOK_PHYSICS_EXISTS
            if (SimulateHavok)
            {
                HavokSimulationContext.Reset(ref PhysicsWorld);

                new SingleThreadedPhysicsHavokSimulationJob
                {
                    Bodies                   = m_BodyInfos,
                    Joints                   = m_JointInfos,
                    Input                    = input,
                    SimulationContext        = HavokSimulationContext,
                    BodyInfoToBodiesIndexMap = indexMap
                }.Run();
            }
            else
#endif
            {
                SimulationContext.Reset(input);

                new SingleThreadedPhysicsSimulationJob
                {
                    BodyInfos                = m_BodyInfos,
                    JointInfos               = m_JointInfos,
                    Input                    = input,
                    SimulationContext        = SimulationContext,
                    BodyInfoToBodiesIndexMap = indexMap
                }.Run();
            }
        }

        // Map the results to GameObjects
        for (int i = 0; i < m_BodyInfos.Length; i++)
        {
            if (!m_BodyInfos[i].IsDynamic)
            {
                continue;
            }

            m_BodyInfoIndexToGameObjectMapping.TryGetValue(i, out GameObject g);
            g.transform.position = m_BodyInfos[i].Position;
            g.transform.rotation = m_BodyInfos[i].Orientation;
        }
    }
Esempio n. 11
0
 void ISimulation.ScheduleStepJobs(SimulationStepInput input, JobHandle inputDeps, out JobHandle finalSimulationJobHandle, out JobHandle finalJobHandle) =>
 throw new NotImplementedException();
Esempio n. 12
0
 public void ScheduleStepJobs(SimulationStepInput input, JobHandle inputDeps)
 {
 }
Esempio n. 13
0
 public void ScheduleStepJobs(SimulationStepInput input, JobHandle inputDeps,
                              out JobHandle finalSimulationJobHandle, out JobHandle finalJobHandle)
 {
     finalSimulationJobHandle = new JobHandle();
     finalJobHandle           = new JobHandle();
 }
Esempio n. 14
0
 public SimulationJobHandles ScheduleStepJobs(SimulationStepInput input, SimulationCallbacks callbacks, JobHandle inputDeps, bool multiThreaded = true) =>
 new SimulationJobHandles(inputDeps);