public RollingSphereSample(Microsoft.Xna.Framework.Game game) : base(game) { // To demonstrate the problems with triangle meshes we increase the gravity and let a // sphere roll over a curved surface. // Add basic force effects. Simulation.ForceEffects.Add(new Gravity { Acceleration = new Vector3F(0, -30, 0) }); // Higher gravity to make the problem more visible. Simulation.ForceEffects.Add(new Damping()); // Use the custom contact filter to improve sphere contacts. _sphereContactFilter = new SphereContactFilter(); Simulation.CollisionDomain.CollisionDetection.ContactFilter = _sphereContactFilter; // The triangle mesh could be loaded from a file, such as an XNA Model. // In this example will create a height field and convert the height field into a triangle mesh. var numberOfSamplesX = 60; var numberOfSamplesZ = 10; var samples = new float[numberOfSamplesX * numberOfSamplesZ]; for (int z = 0; z < numberOfSamplesZ; z++) for (int x = 0; x < numberOfSamplesX; x++) samples[z * numberOfSamplesX + x] = (float)(Math.Sin(x / 6f) * 10f + 5f); var heightField = new HeightField(0, 0, 70, 30, samples, numberOfSamplesX, numberOfSamplesZ); // Convert the height field to a triangle mesh. ITriangleMesh mesh = heightField.GetMesh(0.01f, 3); // Create a shape for the triangle mesh. _triangleMeshShape = new TriangleMeshShape(mesh); // Enable contact welding. And set the welding limit to 1 for maximal effect. _triangleMeshShape.EnableContactWelding = true; _originalWeldingLimit = TriangleMeshAlgorithm.WeldingLimit; TriangleMeshAlgorithm.WeldingLimit = 1; // Optional: Assign a spatial partitioning scheme to the triangle mesh. (A spatial partition // adds an additional memory overhead, but it improves collision detection speed tremendously!) _triangleMeshShape.Partition = new CompressedAabbTree() { BottomUpBuildThreshold = 0 }; // Create a static rigid body using the shape and add it to the simulation. // We explicitly specify a mass frame. We can use any mass frame for static bodies (because // static bodies are effectively treated as if they have infinite mass). If we do not specify // a mass frame in the rigid body constructor, the constructor will automatically compute an // approximate mass frame (which can take some time for large meshes). var ground = new RigidBody(_triangleMeshShape, new MassFrame(), null) { Pose = new Pose(new Vector3F(-34, 0, -40f)), MotionType = MotionType.Static, }; Simulation.RigidBodies.Add(ground); SphereShape sphereShape = new SphereShape(0.5f); _sphere = new RigidBody(sphereShape); Simulation.RigidBodies.Add(_sphere); _enableSmoothMovement = true; _timeUntilReset = TimeSpan.Zero; }
public RollingSphereSample(Microsoft.Xna.Framework.Game game) : base(game) { // To demonstrate the problems with triangle meshes we increase the gravity and let a // sphere roll over a curved surface. // Add basic force effects. Simulation.ForceEffects.Add(new Gravity { Acceleration = new Vector3(0, -30, 0) }); // Higher gravity to make the problem more visible. Simulation.ForceEffects.Add(new Damping()); // Use the custom contact filter to improve sphere contacts. _sphereContactFilter = new SphereContactFilter(); Simulation.CollisionDomain.CollisionDetection.ContactFilter = _sphereContactFilter; // The triangle mesh could be loaded from a file, such as an XNA Model. // In this example will create a height field and convert the height field into a triangle mesh. var numberOfSamplesX = 60; var numberOfSamplesZ = 10; var samples = new float[numberOfSamplesX * numberOfSamplesZ]; for (int z = 0; z < numberOfSamplesZ; z++) { for (int x = 0; x < numberOfSamplesX; x++) { samples[z * numberOfSamplesX + x] = (float)(Math.Sin(x / 6f) * 10f + 5f); } } var heightField = new HeightField(0, 0, 70, 30, samples, numberOfSamplesX, numberOfSamplesZ); // Convert the height field to a triangle mesh. ITriangleMesh mesh = heightField.GetMesh(0.01f, 3); // Create a shape for the triangle mesh. _triangleMeshShape = new TriangleMeshShape(mesh); // Enable contact welding. And set the welding limit to 1 for maximal effect. _triangleMeshShape.EnableContactWelding = true; _originalWeldingLimit = TriangleMeshAlgorithm.WeldingLimit; TriangleMeshAlgorithm.WeldingLimit = 1; // Optional: Assign a spatial partitioning scheme to the triangle mesh. (A spatial partition // adds an additional memory overhead, but it improves collision detection speed tremendously!) _triangleMeshShape.Partition = new CompressedAabbTree() { BottomUpBuildThreshold = 0 }; // Create a static rigid body using the shape and add it to the simulation. // We explicitly specify a mass frame. We can use any mass frame for static bodies (because // static bodies are effectively treated as if they have infinite mass). If we do not specify // a mass frame in the rigid body constructor, the constructor will automatically compute an // approximate mass frame (which can take some time for large meshes). var ground = new RigidBody(_triangleMeshShape, new MassFrame(), null) { Pose = new Pose(new Vector3(-34, 0, -40f)), MotionType = MotionType.Static, }; Simulation.RigidBodies.Add(ground); SphereShape sphereShape = new SphereShape(0.5f); _sphere = new RigidBody(sphereShape); Simulation.RigidBodies.Add(_sphere); _enableSmoothMovement = true; _timeUntilReset = TimeSpan.Zero; }