private void LoadPhysics() { //Physics BufferPool = new BufferPool(); Radii = new List <float>(); SphereHandles = new List <BodyHandle>(); var targetThreadCount = Math.Max(1, Environment.ProcessorCount > 4 ? Environment.ProcessorCount - 2 : Environment.ProcessorCount - 1); ThreadDispatcher = new SimpleThreadDispatcher(targetThreadCount); Simulation = Simulation.Create(BufferPool, new NarrowPhaseCallbacks(), new PoseIntegratorCallbacks(new NumericVector3(0, -500, 0)), new PositionFirstTimestepper()); // Simulation.Statics.Add(new StaticDescription(new NumericVector3(0, 0, 0), //new CollidableDescription(Simulation.Shapes.Add(new Box(2000, 100, 5000)), 1))); // for (int i=0;i<MatrixWorld.Count;i++) // { // Matrix world = MatrixWorld[i]; // Simulation.Statics.Add(new StaticDescription(new NumericVector3(world.Translation.X, world.Translation.Y, world.Translation.Z), // new CollidableDescription(Simulation.Shapes.Add(new Box(200, 100, 500)), 1))); // } //Simulation.Statics.Add(new StaticDescription(new NumericVector3(0, -20, 0), // new CollidableDescription(Simulation.Shapes.Add(new Box(200, 100, 500)), 1))); //Simulation.Statics.Add(new StaticDescription(new NumericVector3(9, 28, 200), new CollidableDescription(Simulation.Shapes.Add(new Sphere(2f)),1))); //Simulation.Statics.Add(new StaticDescription(new )) /* for (int i = 0; i < MatrixWorld.Count(); i++) * { * Simulation.Statics.Add(new StaticDescription(MatrixWorld[i].)) * Floor.Draw(MatrixWorld[i], Camera.View, Camera.Projection); * }*/ //Simulation.Statics.Add(new StaticDescription(new NumericVector3(0, -20, 0), new CollidableDescription(Simulation.Shapes.Add( // new Box(2000, 100, 2000)), 1))); //Esfera SpheresWorld = new List <Matrix>(); var radius = 5f; var sphereShape = new Sphere(radius); var position = Vector3Utils.toNumeric(PlayerInitialPosition); var bodyDescription = BodyDescription.CreateConvexDynamic(position, 1 / radius * radius * radius, Simulation.Shapes, sphereShape); var bodyHandle = Simulation.Bodies.Add(bodyDescription); SphereHandles.Add(bodyHandle); Radii.Add(radius); }
public override void Initialize(ContentArchive content, Camera camera) { camera.Position = new Vector3(0, 4, -6); camera.Yaw = MathHelper.Pi; Simulation = Simulation.Create(BufferPool, new DemoNarrowPhaseCallbacks(), new DemoPoseIntegratorCallbacks(new Vector3(0, 0, 0))); Simulation.Bodies.Add(BodyDescription.CreateConvexKinematic(new Vector3(), Simulation.Shapes, new Box(3, 1, 4))); Simulation.Bodies.Add(BodyDescription.CreateConvexDynamic(new Vector3(0, 1.1f, 0), 1, Simulation.Shapes, new Box(2, 1, 3))); }
public override void Initialize(ContentArchive content, Camera camera) { camera.Position = new Vector3(0, 2, -5); camera.Yaw = MathHelper.Pi; camera.Pitch = 0; //Note the lack of damping- we want the gyroscope to keep spinning. Simulation = Simulation.Create(BufferPool, new DemoNarrowPhaseCallbacks(), new GyroscopicIntegratorCallbacks(new Vector3(0, -10, 0), 0f, 0f), new SubsteppingTimestepper(4), 2); Simulation.Statics.Add(new StaticDescription(new Vector3(), new CollidableDescription(Simulation.Shapes.Add(new Box(100, 1, 100)), 0.1f))); var gyroBaseBody = Simulation.Bodies.Add(BodyDescription.CreateConvexKinematic(new Vector3(0, 2, 0), Simulation.Shapes, new Box(.1f, 4, .1f))); var gyroSpinnerBody = Simulation.Bodies.Add(BodyDescription.CreateConvexDynamic(new Vector3(2, 4, 0), new BodyVelocity(default, new Vector3(300, 0, 0)), 1, Simulation.Shapes, new Box(0.1f, 1f, 1f)));
public override void Initialize(ContentArchive content, Camera camera) { camera.Position = new Vector3(0, 5, 25); camera.Yaw = 0; camera.Pitch = 0; //The PositionFirstTimestepper is the simplest timestepping mode, but since it integrates velocity into position at the start of the frame, directly modified velocities outside of the timestep //will be integrated before collision detection or the solver has a chance to intervene. That's fine in this demo. Other built-in options include the PositionLastTimestepper and the SubsteppingTimestepper. //Note that the timestepper also has callbacks that you can use for executing logic between processing stages, like BeforeCollisionDetection. Simulation = Simulation.Create(BufferPool, new DemoNarrowPhaseCallbacks(), new DemoPoseIntegratorCallbacks(new Vector3(0, -10, 0)), new PositionFirstTimestepper()); //Drop a pyramid on top of the sensor so there are more contacts to look at. var boxShape = new Box(1, 1, 1); boxShape.ComputeInertia(1, out var boxInertia); var boxIndex = Simulation.Shapes.Add(boxShape); const int rowCount = 20; for (int rowIndex = 0; rowIndex < rowCount; ++rowIndex) { int columnCount = rowCount - rowIndex; for (int columnIndex = 0; columnIndex < columnCount; ++columnIndex) { Simulation.Bodies.Add(BodyDescription.CreateDynamic(new Vector3( (-columnCount * 0.5f + columnIndex) * boxShape.Width, (rowIndex + 0.5f) * boxShape.Height + 10, 0), boxInertia, new CollidableDescription(boxIndex, 0.1f), new BodyActivityDescription(0.01f))); } } sensorBodyHandle = Simulation.Bodies.Add(BodyDescription.CreateConvexDynamic(new Vector3(0, 0, 1), 10, Simulation.Shapes, new Box(4, 2, 6))); //Put a mesh under the sensor so that nonconvex contacts are shown. const int planeWidth = 128; const int planeHeight = 128; DemoMeshHelper.CreateDeformedPlane(planeWidth, planeHeight, (int x, int y) => { return(new Vector3(x - planeWidth / 2, 1 * MathF.Cos(x / 2f) * MathF.Sin(y / 2f), y - planeHeight / 2)); }, new Vector3(2, 1, 2), BufferPool, out var planeMesh); Simulation.Statics.Add(new StaticDescription(new Vector3(0, -2, 0), QuaternionEx.CreateFromAxisAngle(new Vector3(0, 1, 0), MathF.PI / 2), new CollidableDescription(Simulation.Shapes.Add(planeMesh), 0.1f))); }
public override void Initialize(ContentArchive content, Camera camera) { camera.Position = new Vector3(0, 5, 25); camera.Yaw = 0; camera.Pitch = 0; Simulation = Simulation.Create(BufferPool, new DemoNarrowPhaseCallbacks(), new DemoPoseIntegratorCallbacks(new Vector3(0, -10, 0))); //Drop a pyramid on top of the sensor so there are more contacts to look at. var boxShape = new Box(1, 1, 1); boxShape.ComputeInertia(1, out var boxInertia); var boxIndex = Simulation.Shapes.Add(boxShape); const int rowCount = 20; for (int rowIndex = 0; rowIndex < rowCount; ++rowIndex) { int columnCount = rowCount - rowIndex; for (int columnIndex = 0; columnIndex < columnCount; ++columnIndex) { Simulation.Bodies.Add(BodyDescription.CreateDynamic(new Vector3( (-columnCount * 0.5f + columnIndex) * boxShape.Width, (rowIndex + 0.5f) * boxShape.Height + 10, 0), boxInertia, new CollidableDescription(boxIndex, 0.1f), new BodyActivityDescription(0.01f))); } } sensorBodyHandle = Simulation.Bodies.Add(BodyDescription.CreateConvexDynamic(new Vector3(0, 0, 1), 10, Simulation.Shapes, new Box(4, 2, 6))); //Put a mesh under the sensor so that nonconvex contacts are shown. const int planeWidth = 128; const int planeHeight = 128; DemoMeshHelper.CreateDeformedPlane(planeWidth, planeHeight, (int x, int y) => { return(new Vector3(x - planeWidth / 2, 1 * MathF.Cos(x / 2f) * MathF.Sin(y / 2f), y - planeHeight / 2)); }, new Vector3(2, 1, 2), BufferPool, out var planeMesh); Simulation.Statics.Add(new StaticDescription(new Vector3(0, -2, 0), QuaternionEx.CreateFromAxisAngle(new Vector3(0, 1, 0), MathF.PI / 2), new CollidableDescription(Simulation.Shapes.Add(planeMesh), 0.1f))); }
public unsafe override void Initialize(ContentArchive content, Camera camera) { camera.Position = new Vector3(-5f, 5.5f, 5f); camera.Yaw = MathHelper.Pi / 4; camera.Pitch = MathHelper.Pi * 0.15f; var filters = new BodyProperty <DeformableCollisionFilter>(); Simulation = Simulation.Create(BufferPool, new DeformableCallbacks { Filters = filters }, new DemoPoseIntegratorCallbacks(new Vector3(0, -10, 0))); var meshContent = content.Load <MeshContent>("Content\\newt.obj"); float cellSize = 0.1f; DumbTetrahedralizer.Tetrahedralize(meshContent.Triangles, cellSize, BufferPool, out var vertices, out var vertexSpatialIndices, out var cellVertexIndices, out var tetrahedraVertexIndices); var weldSpringiness = new SpringSettings(30f, 0); var volumeSpringiness = new SpringSettings(30f, 1); for (int i = 0; i < 5; ++i) { NewtDemo.CreateDeformable(Simulation, new Vector3(i * 3, 5 + i * 1.5f, 0), Quaternion.CreateFromAxisAngle(new Vector3(1, 0, 0), MathF.PI * (i * 0.55f)), 1f, cellSize, weldSpringiness, volumeSpringiness, i, filters, ref vertices, ref vertexSpatialIndices, ref cellVertexIndices, ref tetrahedraVertexIndices); } BufferPool.Return(ref vertices); vertexSpatialIndices.Dispose(BufferPool); BufferPool.Return(ref cellVertexIndices); BufferPool.Return(ref tetrahedraVertexIndices); Simulation.Bodies.Add(BodyDescription.CreateConvexDynamic(new Vector3(0, 100, -.5f), 10, Simulation.Shapes, new Sphere(5))); Simulation.Statics.Add(new StaticDescription(new Vector3(0, -0.5f, 0), new CollidableDescription(Simulation.Shapes.Add(new Box(1500, 1, 1500)), 0.1f))); Simulation.Statics.Add(new StaticDescription(new Vector3(0, -1.5f, 0), new CollidableDescription(Simulation.Shapes.Add(new Sphere(3)), 0.1f))); var bulletShape = new Sphere(0.5f); bulletShape.ComputeInertia(.25f, out var bulletInertia); bulletDescription = BodyDescription.CreateDynamic(RigidPose.Identity, bulletInertia, new CollidableDescription(Simulation.Shapes.Add(bulletShape), 1f), new BodyActivityDescription(0.01f)); DemoMeshHelper.LoadModel(content, BufferPool, "Content\\newt.obj", new Vector3(20), out var mesh); Simulation.Statics.Add(new StaticDescription(new Vector3(200, 0.5f, 120), Quaternion.CreateFromAxisAngle(Vector3.UnitY, -3 * MathHelper.PiOver4), new CollidableDescription(Simulation.Shapes.Add(mesh), 0.1f))); }
public override void Update(Window window, Camera camera, Input input, float dt) { if (input != null && input.WasPushed(OpenTK.Input.Key.Z)) { //Create the shape that we'll launch at the pyramids when the user presses a button. var bulletShape = new Sphere(6); //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 bodyDescription = BodyDescription.CreateConvexDynamic( new Vector3(0, 8, -500), new BodyVelocity(new Vector3(0, 0, 110)), 50000, Simulation.Shapes, bulletShape); Simulation.Bodies.Add(bodyDescription); } base.Update(window, camera, input, dt); }
public override void Update(Window window, Camera camera, Input input, float dt) { frameIndex++; if (frameIndex % 64 == 0) { var bulletShape = new Sphere(0.5f + 5 * (float)random.NextDouble()); bulletShape.ComputeInertia(bulletShape.Radius * bulletShape.Radius * bulletShape.Radius, out var bulletInertia); var bulletShapeIndex = Simulation.Shapes.Add(bulletShape); var bodyDescription = BodyDescription.CreateConvexDynamic( new Vector3(0, 8, -130), new BodyVelocity(new Vector3(0, 0, 350)), bulletShape.Radius * bulletShape.Radius * bulletShape.Radius, Simulation.Shapes, bulletShape); Simulation.Bodies.Add(bodyDescription); } if (frameIndex % 192 == 0) { Simulation.Dispose(); BufferPool.Clear(); for (int i = 0; i < ThreadDispatcher.ThreadCount; ++i) { ThreadDispatcher.GetThreadMemoryPool(i).Clear(); } Initialize(null, camera); } base.Update(window, camera, input, dt); }
public unsafe override void Initialize(ContentArchive content, Camera camera) { camera.Position = new Vector3(20, 10, 20); camera.Yaw = MathF.PI; camera.Pitch = 0; characters = new CharacterControllers(BufferPool); Simulation = Simulation.Create(BufferPool, new CharacterNarrowphaseCallbacks(characters), new DemoPoseIntegratorCallbacks(new Vector3(0, -10, 0))); CreateCharacter(new Vector3(0, 2, -4)); //Create a bunch of legos to hurt your feet on. var random = new Random(5); var origin = new Vector3(-3f, 0.5f, 0); var spacing = new Vector3(0.5f, 0, -0.5f); for (int i = 0; i < 12; ++i) { for (int j = 0; j < 12; ++j) { var position = origin + new Vector3(i, 0, j) * spacing; var orientation = QuaternionEx.CreateFromAxisAngle(Vector3.Normalize(new Vector3(0.0001f) + new Vector3((float)random.NextDouble(), (float)random.NextDouble(), (float)random.NextDouble())), 10 * (float)random.NextDouble()); var shape = new Box(0.1f + 0.3f * (float)random.NextDouble(), 0.1f + 0.3f * (float)random.NextDouble(), 0.1f + 0.3f * (float)random.NextDouble()); var collidable = new CollidableDescription(Simulation.Shapes.Add(shape), 0.1f); shape.ComputeInertia(1, out var inertia); var choice = (i + j) % 3; switch (choice) { case 0: Simulation.Bodies.Add(BodyDescription.CreateDynamic(new RigidPose(position, orientation), inertia, collidable, new BodyActivityDescription(0.01f))); break; case 1: Simulation.Bodies.Add(BodyDescription.CreateKinematic(new RigidPose(position, orientation), collidable, new BodyActivityDescription(0.01f))); break; case 2: Simulation.Statics.Add(new StaticDescription(position, orientation, collidable)); break; } } } //Add some spinning fans to get slapped by. var bladeDescription = BodyDescription.CreateConvexDynamic(new Vector3(), 3, Simulation.Shapes, new Box(10, 0.2f, 2)); var bladeBaseDescription = BodyDescription.CreateConvexKinematic(new Vector3(), Simulation.Shapes, new Box(0.2f, 1, 0.2f)); for (int i = 0; i < 3; ++i) { bladeBaseDescription.Pose.Position = new Vector3(-22, 1, i * 11); bladeDescription.Pose.Position = new Vector3(-22, 1.7f, i * 11); var baseHandle = Simulation.Bodies.Add(bladeBaseDescription); var bladeHandle = Simulation.Bodies.Add(bladeDescription); Simulation.Solver.Add(baseHandle, bladeHandle, new Hinge { LocalHingeAxisA = Vector3.UnitY, LocalHingeAxisB = Vector3.UnitY, LocalOffsetA = new Vector3(0, 0.7f, 0), LocalOffsetB = new Vector3(0, 0, 0), SpringSettings = new SpringSettings(30, 1) }); Simulation.Solver.Add(baseHandle, bladeHandle, new AngularAxisMotor { LocalAxisA = Vector3.UnitY, TargetVelocity = (i + 1) * (i + 1) * (i + 1) * (i + 1) * 0.2f, Settings = new MotorSettings(5 * (i + 1), 0.0001f) }); } //Include a giant newt to test character-newt behavior and to ensure thematic consistency. DemoMeshHelper.LoadModel(content, BufferPool, @"Content\newt.obj", new Vector3(15, 15, 15), out var newtMesh); Simulation.Statics.Add(new StaticDescription(new Vector3(0, 0.5f, 0), new CollidableDescription(Simulation.Shapes.Add(newtMesh), 0.1f))); //Give the newt a tongue, I guess. var tongueBase = Simulation.Bodies.Add(BodyDescription.CreateKinematic(new Vector3(0, 8.4f, 24), default, default));
/// <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); }