Exemple #1
0
        private void RunPhysicsSimulation(float time)
        {
            //read skinned meshes bone positions
            for (int i = 0; i < scenes.Count; i++)
            {
                var physicsScene = scenes[i];

                if (physicsScene.Simulation != null)
                {
                    //first process any needed cleanup
                    physicsScene.Processor.UpdateRemovals();

                    // after we took care of cleanup, are we disabled?
                    if (Simulation.DisableSimulation == false)
                    {
                        //read skinned meshes bone positions and write them to the physics engine
                        physicsScene.Processor.UpdateBones();

                        //simulate physics
                        physicsScene.Simulation.Simulate(time);

                        //update character bound entity's transforms from physics engine simulation
                        physicsScene.Processor.UpdateCharacters();

                        //Perform clean ups before test contacts in this frame
                        physicsScene.Simulation.BeginContactTesting();

                        //handle frame contacts
                        physicsScene.Processor.UpdateContacts();

                        //This is the heavy contact logic
                        physicsScene.Simulation.EndContactTesting();

                        //send contact events
                        physicsScene.Simulation.SendEvents();
                    }
                }

                if (physicsScene.BepuSimulation != null)
                {
                    // do anything before simulation (which might modify ToBeAdded or ToBeRemoved)
                    while (physicsScene.BepuSimulation.ActionsBeforeSimulationStep.TryDequeue(out Action <float> a))
                    {
                        a(time);
                    }

                    lock (physicsScene.BepuSimulation.ToBeAdded)
                    {
                        // remove all bodies set to be removed
                        physicsScene.BepuSimulation.ProcessRemovals();

                        // did we request a clear?
                        int clearMode = physicsScene.BepuSimulation.clearRequested;
                        if (clearMode > 0)
                        {
                            physicsScene.BepuSimulation.Clear(clearMode == 2, true);
                        }

                        // add everyone waiting (which could have been something just removed)
                        physicsScene.BepuSimulation.ProcessAdds();
                    }

                    if (Simulation.DisableSimulation == false)
                    {
                        // simulate!
                        float totalTime = time;
                        for (int k = 0; k < MaxSubSteps && totalTime > 0f; k++)
                        {
                            float simtime = Math.Min(MaximumSimulationTime, totalTime);
                            physicsScene.BepuSimulation.Simulate(simtime);
                            totalTime -= simtime;
                        }

                        // update all rigidbodies
                        Xenko.Core.Threading.Dispatcher.For(0, physicsScene.BepuSimulation.AllRigidbodies.Count, (j) =>
                        {
                            BepuRigidbodyComponent rb = physicsScene.BepuSimulation.AllRigidbodies[j];

                            rb.resetProcessingContactsList();
                            rb.UpdateCachedPoseAndVelocity();

                            // per-rigidbody update
                            if (rb.ActionPerSimulationTick != null)
                            {
                                rb.ActionPerSimulationTick(rb, time);
                            }

                            rb.UpdateTransformationComponent();
                        });
                    }
                }
            }
        }
Exemple #2
0
        private void RunPhysicsSimulation(float time)
        {
            //read skinned meshes bone positions
            for (int i = 0; i < scenes.Count; i++)
            {
                var physicsScene = scenes[i];

                if (physicsScene.Simulation != null)
                {
                    //first process any needed cleanup
                    physicsScene.Processor.UpdateRemovals();

                    // after we took care of cleanup, are we disabled?
                    if (Simulation.DisableSimulation == false)
                    {
                        //read skinned meshes bone positions and write them to the physics engine
                        physicsScene.Processor.UpdateBones();

                        //simulate physics
                        physicsScene.Simulation.Simulate(time);

                        //update character bound entity's transforms from physics engine simulation
                        physicsScene.Processor.UpdateCharacters();

                        //Perform clean ups before test contacts in this frame
                        physicsScene.Simulation.BeginContactTesting();

                        //handle frame contacts
                        physicsScene.Processor.UpdateContacts();

                        //This is the heavy contact logic
                        physicsScene.Simulation.EndContactTesting();

                        //send contact events
                        physicsScene.Simulation.SendEvents();
                    }
                }

                if (physicsScene.BepuSimulation != null)
                {
                    // do anything before simulation (which might modify ToBeAdded or ToBeRemoved)
                    while (physicsScene.BepuSimulation.ActionsBeforeSimulationStep.TryDequeue(out Action <float> a))
                    {
                        a(time);
                    }

                    // any static objects need to be moved?
                    while (BepuStaticColliderComponent.NeedsRepositioning.TryDequeue(out var scc))
                    {
                        // might need a writelock here because ApplyDescription can wake bodies (which can move them around)
                        using (physicsScene.BepuSimulation.simulationLocker.WriteLock())
                        {
                            scc.InternalStatic.ApplyDescription(scc.staticDescription);
                        }
                    }

                    lock (physicsScene.BepuSimulation.ToBeAdded)
                    {
                        // remove all bodies set to be removed
                        physicsScene.BepuSimulation.ProcessRemovals();

                        // did we request a clear?
                        int clearMode = physicsScene.BepuSimulation.clearRequested;
                        if (clearMode > 0)
                        {
                            physicsScene.BepuSimulation.Clear(clearMode == 2, true);
                        }

                        // add everyone waiting (which could have been something just removed)
                        physicsScene.BepuSimulation.ProcessAdds();
                    }

                    // critical actions for rigidbodies
                    while (physicsScene.BepuSimulation.CriticalActions.TryDequeue(out var a))
                    {
                        // don't worry about this if we are to be removed (or have been removed)
                        if (a.Body.InternalBody.Handle.Value == -1 || BepuSimulation.instance.ToBeRemoved.Contains(a.Body))
                        {
                            continue;
                        }

                        switch (a.Action)
                        {
                        case BepuRigidbodyComponent.RB_ACTION.IsActive:
                            using (physicsScene.BepuSimulation.simulationLocker.WriteLock())
                            {
                                a.Body.InternalBody.Awake = a.Body.wasAwake;
                            }
                            break;

                        case BepuRigidbodyComponent.RB_ACTION.ColliderShape:
                            a.Body.InternalColliderShapeReadd();
                            break;
                        }
                    }

                    if (Simulation.DisableSimulation == false)
                    {
                        // don't make changes to rigidbodies while simulating
                        BepuRigidbodyComponent.safeRun = false;

                        // simulate!
                        float totalTime = time;
                        for (int k = 0; k < MaxSubSteps && totalTime > 0f; k++)
                        {
                            float simtime = Math.Min(MaximumSimulationTime, totalTime);
                            physicsScene.BepuSimulation.Simulate(simtime);
                            totalTime -= simtime;
                        }

                        BepuRigidbodyComponent.safeRun = true;

                        // update all rigidbodies
                        Xenko.Core.Threading.Dispatcher.For(0, physicsScene.BepuSimulation.AllRigidbodies.Count, (j) =>
                        {
                            BepuRigidbodyComponent rb = physicsScene.BepuSimulation.AllRigidbodies[j];

                            // if we lost the entity, just return
                            Entity e = rb.Entity;
                            if (e == null)
                            {
                                return;
                            }

                            rb.resetProcessingContactsList();

                            // pre-sync
                            while (rb.queuedActions.TryDequeue(out var action))
                            {
                                action(rb);
                            }

                            rb.UpdateCachedPoseAndVelocity();

                            // per-rigidbody update
                            if (rb.ActionPerSimulationTick != null)
                            {
                                rb.ActionPerSimulationTick(rb, time);
                            }

                            rb.UpdateTransformationComponent(e);
                        });