float FrictionBlender(float wheelFriction, float supportFriction, bool isKineticFriction, Wheel wheel) { //The default friction blender is multiplicative. This tank had its coefficients designed for averaged coefficients. //So, let's average the friction coefficients! //Try to fiddle with the configuration and this blender to see how you like other approaches. return (wheelFriction + supportFriction) / 2; }
/// <summary> /// Create a car Actor which can interface with the BEPU physics engine /// </summary> /// <param name="position"></param> /// <param name="orientation"></param> public BepuCarActor(Game game, CarModelRenderer renderer, Matrix worldMatrix) : base(game, renderer) { emitter_ = new AudioEmitter(); CarSoundEmitters.AudioEmitters.Add(emitter_); // create a pin (for keeping the car stuck to the track) Capsule pin = new Capsule(new Vector3(0, -0.7f, -2), 0.6f, 0.12f, 1); pin.Bounciness = 0f; pin.DynamicFriction = 0f; pin.StaticFriction = 0f; // create a body: CompoundBody body = new CompoundBody(); body.AddBody(new Box(new Vector3(0, 0, 0), 2.5f, .75f, 4.5f, 60)); body.AddBody(new Box(new Vector3(0, .75f / 2 + .3f / 2, .5f), 2.5f, .3f, 2f, 1)); body.AddBody(pin); body.CenterOfMassOffset = new Vector3(0, -.5f, 0); body.WorldTransform = worldMatrix; body.LinearVelocity = Vector3.Zero; body.AngularVelocity = Vector3.Zero; // construct the car: car = new Vehicle(body); // attach wheels: Matrix wheelGraphicRotation = Matrix.CreateFromAxisAngle(Vector3.Forward, MathHelper.PiOver2); for (int i = 0; i < 4; i++) { Wheel wheel = new Wheel( new RaycastWheelShape(.375f, wheelGraphicRotation), new WheelSuspension(2000, 100f, Vector3.Down, .8f, new Vector3( ( i <= 1 ) ? -1.1f : 1.1f, 0, ( (i & 1) == 0 ) ? 1.8f : - 1.8f)), new WheelDrivingMotor(2.5f, 30000, 10000), new WheelBrake(1.5f, 2, .02f), new WheelSlidingFriction(4, 5)); car.AddWheel(wheel); // adjust additional values wheel.Shape.FreezeWheelsWhileBraking = true; wheel.Suspension.SolverSettings.MaximumIterations = 2; wheel.Brake.SolverSettings.MaximumIterations = 2; wheel.SlidingFriction.SolverSettings.MaximumIterations = 2; wheel.DrivingMotor.SolverSettings.MaximumIterations = 2; } // add it to physics Engine.currentWorld.Space.Add(car); }
internal WheelSlidingFriction(Wheel wheel) { Wheel = wheel; }
/// <summary> /// Function which takes the friction values from a wheel and a supporting material and computes the blended friction. /// </summary> /// <param name="wheelFriction">Friction coefficient associated with the wheel.</param> /// <param name="materialFriction">Friction coefficient associated with the support material.</param> /// <param name="usingKineticFriction">True if the friction coefficients passed into the blender are kinetic coefficients, false otherwise.</param> /// <param name="wheel">Wheel being blended.</param> /// <returns>Blended friction coefficient.</returns> public static float BlendFriction(float wheelFriction, float materialFriction, bool usingKinematicFriction, Wheel wheel) { return wheelFriction * materialFriction; }
/// <summary> /// Constructs the front end and the internal physics representation of the vehicle. /// </summary> /// <param name="position">Position of the tank.</param> /// <param name="owningSpace">Space to add the vehicle to.</param> /// <param name="camera">Camera to attach to the vehicle.</param> /// <param name="game">Running game.</param> /// <param name="drawer">Drawer used to draw the tank.</param> /// <param name="wheelModel">Model to use for the 'wheels' of the tank.</param> /// <param name="wheelTexture">Texture of the wheels on the tank.</param> public TankInput(Vector3 position, Space owningSpace, Camera camera, DemosGame game, ModelDrawer drawer, Model wheelModel, Texture2D wheelTexture) { var bodies = new List<CompoundShapeEntry>() { new CompoundShapeEntry(new BoxShape(4f, 1, 8), new Vector3(0, 0, 0), 500), new CompoundShapeEntry(new BoxShape(3, .7f, 4f), new Vector3(0, .5f + .35f, .5f), 1) }; var body = new CompoundBody(bodies, 501); body.CollisionInformation.LocalPosition = new Vector3(0, .5f, 0); body.Position = (position); //At first, just keep it out of the way. Vehicle = new Vehicle(body); #region RaycastWheelShapes //The wheel model used is not aligned initially with how a wheel would normally look, so rotate them. MaximumDriveForce = 1800; BaseSlidingFriction = 3; Matrix wheelGraphicRotation = Matrix.CreateFromAxisAngle(Vector3.Forward, MathHelper.PiOver2); for (int i = 0; i < 6; i++) { var toAdd = new Wheel( new RaycastWheelShape(.375f, wheelGraphicRotation), new WheelSuspension(2000, 300f, Vector3.Down, 1.3f, new Vector3(-1.9f, 0, -2.9f + i * 1.15f)), new WheelDrivingMotor(10, MaximumDriveForce, MaximumDriveForce), new WheelBrake(7, 7, 1.0f), new WheelSlidingFriction(BaseSlidingFriction, BaseSlidingFriction)); toAdd.DrivingMotor.GripFrictionBlender = FrictionBlender; toAdd.Brake.FrictionBlender = FrictionBlender; toAdd.SlidingFriction.FrictionBlender = FrictionBlender; Vehicle.AddWheel(toAdd); leftTrack.Add(toAdd); } for (int i = 0; i < 6; i++) { var toAdd = new Wheel( new RaycastWheelShape(.375f, wheelGraphicRotation), new WheelSuspension(2000, 300f, Vector3.Down, 1.3f, new Vector3(1.9f, 0, -2.9f + i * 1.15f)), new WheelDrivingMotor(10, 2000, 1000), new WheelBrake(7, 7, 1.0f), new WheelSlidingFriction(BaseSlidingFriction, BaseSlidingFriction)); toAdd.DrivingMotor.GripFrictionBlender = FrictionBlender; toAdd.Brake.FrictionBlender = FrictionBlender; toAdd.SlidingFriction.FrictionBlender = FrictionBlender; Vehicle.AddWheel(toAdd); rightTrack.Add(toAdd); } #endregion foreach (Wheel wheel in Vehicle.Wheels) { //This is a cosmetic setting that makes it looks like the car doesn't have antilock brakes. wheel.Shape.FreezeWheelsWhileBraking = true; //By default, wheels use as many iterations as the space. By lowering it, //performance can be improved at the cost of a little accuracy. wheel.Suspension.SolverSettings.MaximumIterationCount = 1; wheel.Brake.SolverSettings.MaximumIterationCount = 1; wheel.SlidingFriction.SolverSettings.MaximumIterationCount = 1; wheel.DrivingMotor.SolverSettings.MaximumIterationCount = 1; } Space = owningSpace; Space.Add(Vehicle); ModelDrawer = drawer; DisplayModel model; WheelModels = new List<DisplayModel>(); for (int k = 0; k < Vehicle.Wheels.Count; k++) { Vehicle.Wheels[k].Shape.Detector.Tag = "noDisplayObject"; model = new DisplayModel(wheelModel, ModelDrawer); ModelDrawer.Add(model); WheelModels.Add(model); model.Texture = wheelTexture; } CameraControlScheme = new ChaseCameraControlScheme(Vehicle.Body, new Vector3(0, 0.6f, 0), true, 10, camera, game); }
internal WheelBrake(Wheel wheel) { Wheel = wheel; }
internal WheelSuspension(Wheel wheel) { Wheel = wheel; }
internal WheelDrivingMotor(Wheel wheel) { Wheel = wheel; }
/// <summary> /// Removes a wheel from the vehicle. /// </summary> /// <param name="wheel">WheelTest to remove.</param> public void RemoveWheel(Wheel wheel) { if (wheel.vehicle == this) { wheel.OnRemovedFromVehicle(); Wheels.Remove(wheel); } else throw new InvalidOperationException("Can't remove a wheel from a vehicle that does not own it."); }
/// <summary> /// Adds a wheel to the vehicle. /// </summary> /// <param name="wheel">WheelTest to add.</param> public void AddWheel(Wheel wheel) { if (wheel.vehicle == null) { Wheels.Add(wheel); wheel.OnAddedToVehicle(this); } else throw new InvalidOperationException("Can't add a wheel to a vehicle if it already belongs to a vehicle."); }
private void DrawWheel(Wheel wheel, Model model, Matrix[] wheelModelTransforms_) { foreach (ModelMesh mesh in model.Meshes) { DrawModelMesh(mesh, wheelModelTransforms_[mesh.ParentBone.Index] * wheel.Shape.WorldTransform, false); } }
/// <summary> /// Function which takes the friction values from a wheel and a supporting material and computes the blended friction. /// </summary> /// <param name="wheelFriction">Friction coefficient associated with the wheel.</param> /// <param name="materialFriction">Friction coefficient associated with the support material.</param> /// <param name="usingKineticFriction">True if the friction coefficients passed into the blender are kinetic coefficients, false otherwise.</param> /// <param name="wheel">Wheel being blended.</param> /// <returns>Blended friction coefficient.</returns> public static float BlendFriction(float wheelFriction, float materialFriction, bool usingKineticFriction, Wheel wheel) { return(wheelFriction * materialFriction); }