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