/// <inheritdoc /> public override void Update(GameTime gameTime) { // In the demos, we use one time step per frame. We don't bother modifying the physics time step duration for different monitors so different refresh rates // change the rate of simulation. This doesn't actually change the result of the simulation, though, and the simplicity is a good fit for the demos. // In the context of a 'real' application, you could instead use a time accumulator to take time steps of fixed length as needed, or // fully decouple simulation and rendering rates across different threads. // (In either case, you'd also want to interpolate or extrapolate simulation results during rendering for smoothness.) // Note that taking steps of variable length can reduce stability. Gradual or one-off changes can work reasonably well. Simulation.Timestep(1 / 60f, ThreadDispatcher); Camera.Update(gameTime); if (Game.CurrentKeyboardState.IsKeyDown(Keys.Z) && CanShoot) { CanShoot = false; // Create the shape that we'll launch at the pyramids when the user presses a button. var radius = 0.5f + 5 * (float)Random.NextDouble(); var bulletShape = new Sphere(radius); // Note that the use of radius^3 for mass can produce some pretty serious mass ratios. // Observe what happens when a large ball sits on top of a few boxes with a fraction of the mass- // the collision appears much squishier and less stable. For most games, if you want to maintain rigidity, you'll want to use some combination of: // 1) Limit the ratio of heavy object masses to light object masses when those heavy objects depend on the light objects. // 2) Use a shorter timestep duration and update more frequently. // 3) Use a greater number of solver iterations. // #2 and #3 can become very expensive. In pathological cases, it can end up slower than using a quality-focused solver for the same simulation. // Unfortunately, at the moment, bepuphysics v2 does not contain any alternative solvers, so if you can't afford to brute force the the problem away, // the best solution is to cheat as much as possible to avoid the corner cases. var position = new NumericVector3(-40 + 210 * (float)Random.NextDouble(), 130, 130); var bodyDescription = BodyDescription.CreateConvexDynamic(position, new BodyVelocity(new NumericVector3((float)Random.NextDouble(), 0, -110)), bulletShape.Radius * bulletShape.Radius * bulletShape.Radius, Simulation.Shapes, bulletShape); var bodyHandle = Simulation.Bodies.Add(bodyDescription); Radii.Add(radius); SphereHandles.Add(bodyHandle); } if (Game.CurrentKeyboardState.IsKeyUp(Keys.Z)) { CanShoot = true; } BoxesWorld.Clear(); var boxHandleCount = BoxHandles.Count; for (var index = 0; index < boxHandleCount; index++) { var pose = Simulation.Bodies.GetBodyReference(BoxHandles[index]).Pose; var position = pose.Position; var quaternion = pose.Orientation; var world = Matrix.CreateFromQuaternion(new Quaternion(quaternion.X, quaternion.Y, quaternion.Z, quaternion.W)) * Matrix.CreateTranslation(new Vector3(position.X, position.Y, position.Z)); BoxesWorld.Add(world); } SpheresWorld.Clear(); var sphereHandleCount = SphereHandles.Count; for (var index = 0; index < sphereHandleCount; index++) { var pose = Simulation.Bodies.GetBodyReference(SphereHandles[index]).Pose; var position = pose.Position; var quaternion = pose.Orientation; var world = Matrix.CreateScale(Radii[index]) * Matrix.CreateFromQuaternion(new Quaternion(quaternion.X, quaternion.Y, quaternion.Z, quaternion.W)) * Matrix.CreateTranslation(new Vector3(position.X, position.Y, position.Z)); SpheresWorld.Add(world); } Game.Gizmos.UpdateViewProjection(Camera.View, Camera.Projection); base.Update(gameTime); }
private void UpdatePhysics() { //Physics Simulation.Timestep(1 / 60f, ThreadDispatcher); SpheresWorld.Clear(); var sphereBody = Simulation.Bodies.GetBodyReference(SphereHandles[0]); var playerAceleration = 5; //var plataforma = Simulation.Statics.GetStaticReference(StaticHandle[0]); //var spheresHandleCount = SphereHandles.Count; if (Keyboard.GetState().IsKeyDown(Keys.Up)) { sphereBody.Awake = true; sphereBody.Velocity.Linear = sphereBody.Velocity.Linear + NumericVector3Utils.Forward * playerAceleration; } if (Keyboard.GetState().IsKeyDown(Keys.Down)) { sphereBody.Awake = true; sphereBody.Velocity.Linear = sphereBody.Velocity.Linear + NumericVector3Utils.Backward * playerAceleration; } if (Keyboard.GetState().IsKeyDown(Keys.Left)) { sphereBody.Awake = true; sphereBody.Velocity.Linear = sphereBody.Velocity.Linear + NumericVector3Utils.Left * playerAceleration; } if (Keyboard.GetState().IsKeyDown(Keys.Right)) { sphereBody.Awake = true; sphereBody.Velocity.Linear = sphereBody.Velocity.Linear + NumericVector3Utils.Right * playerAceleration; } if (Keyboard.GetState().IsKeyDown(Keys.Space)) { //sphereBody.Velocity.Linear = sphereBody.Velocity.Linear + new NumericVector3(0, 100, 0); if (puedoSaltar) { var jumpImpulseForce = 1000; sphereBody.Awake = true; sphereBody.ApplyLinearImpulse(NumericVector3Utils.Up * jumpImpulseForce); puedoSaltar = false; } } if (Keyboard.GetState().IsKeyDown(Keys.R) || PositionE.Y < -500) { sphereBody.Awake = true; sphereBody.Pose.Position = new NumericVector3(0f, 10f, 0f); sphereBody.Velocity.Linear = NumericVector3.Zero; sphereBody.Velocity.Angular = NumericVector3.Zero; puedoSaltar = true; } var pose = sphereBody.Pose; var position = pose.Position; var quaternion = pose.Orientation; var world = Matrix.CreateScale(0.05f) * Matrix.CreateFromQuaternion(new Quaternion(quaternion.X, quaternion.Y, quaternion.Z, quaternion.W)) * Matrix.CreateTranslation(new Vector3(position.X, position.Y, position.Z)); SpheresWorld.Add(world); PositionE = new Vector3(position.X, position.Y, position.Z); }