public unsafe override void Initialize(ContentArchive content, Camera camera) { camera.Position = new Vector3(-20f, 13, -20f); camera.Yaw = MathHelper.Pi * 3f / 4; camera.Pitch = MathHelper.Pi * 0.1f; Simulation = Simulation.Create(BufferPool, new NoCollisionCallbacks(), new DemoPoseIntegratorCallbacks(new Vector3(0, -10, 0))); var box = new Box(0.5f, 1.5f, 1f); var capsule = new Capsule(0, 0.5f); var sphere = new Sphere(0.5f); var boxIndex = Simulation.Shapes.Add(box); var capsuleIndex = Simulation.Shapes.Add(capsule); var sphereIndex = Simulation.Shapes.Add(sphere); const int width = 16; const int height = 16; const int length = 16; var spacing = new Vector3(2.01f); var halfSpacing = spacing / 2; float randomizationSubset = 0.9f; var randomizationSpan = (spacing - new Vector3(1)) * randomizationSubset; var randomizationBase = randomizationSpan * -0.5f; var random = new Random(5); for (int i = 0; i < width; ++i) { for (int j = 0; j < height; ++j) { for (int k = 0; k < length; ++k) { var r = new Vector3((float)random.NextDouble(), (float)random.NextDouble(), (float)random.NextDouble()); var location = spacing * (new Vector3(i, j, k) + new Vector3(-width, -height, -length) * 0.5f) + randomizationBase + r * randomizationSpan; BepuUtilities.Quaternion orientation; orientation.X = -1 + 2 * (float)random.NextDouble(); orientation.Y = -1 + 2 * (float)random.NextDouble(); orientation.Z = -1 + 2 * (float)random.NextDouble(); orientation.W = 0.01f + (float)random.NextDouble(); orientation.Normalize(); TypedIndex shapeIndex; switch ((i + j + k) % 3) { case 0: shapeIndex = boxIndex; break; case 1: shapeIndex = capsuleIndex; break; default: shapeIndex = sphereIndex; break; } if ((i + j + k) % 2 == 1) { var bodyDescription = new BodyDescription { Activity = new BodyActivityDescription { MinimumTimestepCountUnderThreshold = 32, SleepThreshold = -0.1f }, Pose = new RigidPose { Orientation = orientation, Position = location }, Collidable = new CollidableDescription { Continuity = new ContinuousDetectionSettings { Mode = ContinuousDetectionMode.Discrete }, SpeculativeMargin = 0.1f, Shape = shapeIndex } }; Simulation.Bodies.Add(bodyDescription); } else { var staticDescription = new StaticDescription { Pose = new RigidPose { Orientation = orientation, Position = location }, Collidable = new CollidableDescription { Continuity = new ContinuousDetectionSettings { Mode = ContinuousDetectionMode.Discrete }, SpeculativeMargin = 0.1f, Shape = shapeIndex } }; Simulation.Statics.Add(staticDescription); } } } } 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 / 4f) * MathF.Sin(y / 4f), y - planeHeight / 2)); }, new Vector3(1, 3, 1), BufferPool, out var planeMesh); Simulation.Statics.Add(new StaticDescription( new Vector3(0, -10, 0), BepuUtilities.Quaternion.CreateFromAxisAngle(new Vector3(0, 1, 0), MathF.PI / 4), new CollidableDescription(Simulation.Shapes.Add(planeMesh), 0.1f))); int raySourceCount = 3; raySources = new QuickList <QuickList <TestRay> >(raySourceCount, BufferPool); raySources.Count = raySourceCount; //Spew rays all over the place, starting inside the shape cube. int randomRayCount = 1 << 14; ref var randomRays = ref raySources[0];
public unsafe override void Initialize(ContentArchive content, Camera camera) { camera.Position = new Vector3(-20f, 13, -20f); camera.Yaw = MathHelper.Pi * 3f / 4; camera.Pitch = MathHelper.Pi * 0.1f; //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 NoCollisionCallbacks(), new DemoPoseIntegratorCallbacks(new Vector3(0, -10, 0)), new PositionFirstTimestepper()); var sphere = new Sphere(0.5f); var capsule = new Capsule(0, 0.5f); var box = new Box(0.5f, 1.5f, 1f); var cylinder = new Cylinder(0.5f, 1); const int pointCount = 16; var points = new QuickList <Vector3>(pointCount, BufferPool); var random = new Random(5); for (int i = 0; i < pointCount; ++i) { points.AllocateUnsafely() = new Vector3(1 * (float)random.NextDouble(), 1 * (float)random.NextDouble(), 1 * (float)random.NextDouble()); } var hullShape = new ConvexHull(points, BufferPool, out _); var sphereIndex = Simulation.Shapes.Add(sphere); var capsuleIndex = Simulation.Shapes.Add(capsule); var boxIndex = Simulation.Shapes.Add(box); var cylinderIndex = Simulation.Shapes.Add(cylinder); var hullIndex = Simulation.Shapes.Add(hullShape); const int width = 16; const int height = 16; const int length = 16; var spacing = new Vector3(2.01f); var halfSpacing = spacing / 2; float randomizationSubset = 0.9f; var randomizationSpan = (spacing - new Vector3(1)) * randomizationSubset; var randomizationBase = randomizationSpan * -0.5f; for (int i = 0; i < width; ++i) { for (int j = 0; j < height; ++j) { for (int k = 0; k < length; ++k) { var r = new Vector3((float)random.NextDouble(), (float)random.NextDouble(), (float)random.NextDouble()); var location = spacing * (new Vector3(i, j, k) + new Vector3(-width, -height, -length) * 0.5f) + randomizationBase + r * randomizationSpan; Quaternion orientation; orientation.X = -1 + 2 * (float)random.NextDouble(); orientation.Y = -1 + 2 * (float)random.NextDouble(); orientation.Z = -1 + 2 * (float)random.NextDouble(); orientation.W = 0.01f + (float)random.NextDouble(); QuaternionEx.Normalize(ref orientation); var shapeIndex = ((i + j + k) % 5) switch { 0 => boxIndex, 1 => capsuleIndex, 2 => sphereIndex, 3 => cylinderIndex, _ => hullIndex, }; if ((i + j + k) % 2 == 1) { Simulation.Bodies.Add(BodyDescription.CreateKinematic(new RigidPose(location, orientation), new CollidableDescription(shapeIndex, 0.1f), new BodyActivityDescription(-0.1f))); } else { Simulation.Statics.Add(new StaticDescription(location, orientation, new CollidableDescription(shapeIndex, 0.1f))); } } } } 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 / 4f) * MathF.Sin(y / 4f), y - planeHeight / 2)); }, new Vector3(1, 3, 1), BufferPool, out var planeMesh); Simulation.Statics.Add(new StaticDescription( new Vector3(0, -10, 0), QuaternionEx.CreateFromAxisAngle(new Vector3(0, 1, 0), MathF.PI / 4), new CollidableDescription(Simulation.Shapes.Add(planeMesh), 0.1f))); int raySourceCount = 3; raySources = new QuickList <QuickList <TestRay> >(raySourceCount, BufferPool); raySources.Count = raySourceCount; //Spew rays all over the place, starting inside the shape cube. int randomRayCount = 1 << 14; ref var randomRays = ref raySources[0];