Пример #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);
                    }

                    // 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);
                        });
Пример #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);
                    }

                    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();
                        });
                    }
                }
            }
        }
Пример #3
0
        public override void Start()
        {
            //simulation = this.GetSimulation();
            simulation         = SceneSystem.SceneInstance.GetProcessor <BepuPhysicsProcessor>()?.Simulation;
            simulation.Gravity = new Vector3(0, -9, 0);

            cubeRigidBody            = cube.Get <BepuRigidbodyComponent>();
            cubeRigidBody.CanSleep   = false;
            sphereRigidBody          = sphere.Get <BepuRigidbodyComponent>();
            sphereRigidBody.CanSleep = false;

            // Create the UI
            constraintNameBlock = new TextBlock
            {
                Font      = Font,
                TextSize  = 55,
                TextColor = Color.White,
            };
            constraintNameBlock.SetCanvasPinOrigin(new Vector3(0.5f, 0.5f, 0));
            constraintNameBlock.SetCanvasRelativePosition(new Vector3(0.5f, 0.83f, 0));

            Entity.Get <UIComponent>().Page = new UIPage
            {
                RootElement = new Canvas
                {
                    Children =
                    {
                        constraintNameBlock,
                        CreateButton("Next",    Font,  1),
                        CreateButton("Previous",Font, -1)
                    }
                }
            };

            // Create and initialize constraint
            PhysicsSampleList.Add(CreatePoint2PointConstraint);
            //PhysicsSampleList.Add(CreateHingeConstraint);
            //PhysicsSampleList.Add(CreateGearConstraint);
            //PhysicsSampleList.Add(CreateSliderConstraint);
            //PhysicsSampleList.Add(CreateConeTwistConstraint);
            //PhysicsSampleList.Add(CreateGeneric6DoFConstraint);

            RemoveConstraint();
            PhysicsSampleList[constraintIndex]();

            //Add a script for the slider constraint, to apply an impulse on collision
            cubeRigidBody.ProcessCollisions = true;
            Script.AddTask(async() =>
            {
                while (Game.IsRunning)
                {
                    var collision = await cubeRigidBody.NewCollision();
                    //if (!(currentConstraint is SliderConstraint)) continue;
                    if (collision.ColliderA != sphereRigidBody && collision.ColliderB != sphereRigidBody)
                    {
                        continue;
                    }
                    sphereRigidBody.LinearVelocity = Vector3.Zero;        //clear any existing velocity
                    sphereRigidBody.ApplyImpulse(new Vector3(-25, 0, 0)); //fire impulse
                }
            });
        }