public SimpleCarController(SimpleCar car, float forwardSpeed, float forwardForce, float zoomMultiplier, float backwardSpeed, float backwardForce, float idleForce, float brakeForce, float steeringSpeed, float maximumSteeringAngle) { Car = car; ForwardSpeed = forwardSpeed; ForwardForce = forwardForce; ZoomMultiplier = zoomMultiplier; BackwardSpeed = backwardSpeed; BackwardForce = backwardForce; IdleForce = idleForce; BrakeForce = brakeForce; SteeringSpeed = steeringSpeed; MaximumSteeringAngle = maximumSteeringAngle; steeringAngle = 0; previousTargetForce = 0; previousTargetSpeed = 0; }
public override void Initialize(ContentArchive content, Camera camera) { camera.Position = new Vector3(0, 5, 10); camera.Yaw = 0; camera.Pitch = 0; var properties = new BodyProperty <CarBodyProperties>(); Simulation = Simulation.Create(BufferPool, new CarCallbacks() { Properties = properties }, new DemoPoseIntegratorCallbacks(new Vector3(0, -10, 0))); var builder = new CompoundBuilder(BufferPool, Simulation.Shapes, 2); builder.Add(new Box(1.85f, 0.7f, 4.73f), RigidPose.Identity, 10); builder.Add(new Box(1.85f, 0.6f, 2.5f), new RigidPose(new Vector3(0, 0.65f, -0.35f)), 0.5f); builder.BuildDynamicCompound(out var children, out var bodyInertia, out _); builder.Dispose(); var bodyShape = new Compound(children); var bodyShapeIndex = Simulation.Shapes.Add(bodyShape); var wheelShape = new Cylinder(0.4f, .18f); wheelShape.ComputeInertia(0.25f, out var wheelInertia); var wheelShapeIndex = Simulation.Shapes.Add(wheelShape); const float x = 0.9f; const float y = -0.1f; const float frontZ = 1.7f; const float backZ = -1.7f; playerController = new SimpleCarController(SimpleCar.Create(Simulation, properties, new RigidPose(new Vector3(0, 10, 0), Quaternion.Identity), bodyShapeIndex, bodyInertia, 0.5f, wheelShapeIndex, wheelInertia, 2f, new Vector3(-x, y, frontZ), new Vector3(x, y, frontZ), new Vector3(-x, y, backZ), new Vector3(x, y, backZ), new Vector3(0, -1, 0), 0.25f, new SpringSettings(5f, 0.7f), Quaternion.CreateFromAxisAngle(Vector3.UnitZ, MathF.PI * 0.5f)), forwardSpeed: 75, forwardForce: 6, zoomMultiplier: 2, backwardSpeed: 30, backwardForce: 4, idleForce: 0.25f, brakeForce: 7, steeringSpeed: 1.5f, maximumSteeringAngle: MathF.PI * 0.23f); //Create a bunch of AI cars to race against. const int aiCount = 384; BufferPool.Take(aiCount, out aiControllers); const int planeWidth = 257; const float scale = 3; Vector2 terrainPosition = new Vector2(1 - planeWidth, 1 - planeWidth) * scale * 0.5f; raceTrack = new RaceTrack { QuadrantRadius = (planeWidth - 32) * scale * 0.25f, Center = default }; var random = new Random(5); //Add some building-ish landmarks in the middle of each of the four racetrack quadrants. for (int i = 0; i < 4; ++i) { var landmarkCenter = new Vector3((i & 1) * raceTrack.QuadrantRadius * 2 - raceTrack.QuadrantRadius, -20, (i & 2) * raceTrack.QuadrantRadius - raceTrack.QuadrantRadius); var landmarkMin = landmarkCenter - new Vector3(raceTrack.QuadrantRadius * 0.5f, 0, raceTrack.QuadrantRadius * 0.5f); var landmarkSpan = new Vector3(raceTrack.QuadrantRadius, 0, raceTrack.QuadrantRadius); for (int j = 0; j < 25; ++j) { var buildingShape = new Box(10 + (float)random.NextDouble() * 10, 20 + (float)random.NextDouble() * 20, 10 + (float)random.NextDouble() * 10); Simulation.Statics.Add(new StaticDescription( new Vector3(0, buildingShape.HalfHeight, 0) + landmarkMin + landmarkSpan * new Vector3((float)random.NextDouble(), (float)random.NextDouble(), (float)random.NextDouble()), Quaternion.CreateFromAxisAngle(Vector3.UnitY, (float)random.NextDouble() * MathF.PI), new CollidableDescription(Simulation.Shapes.Add(buildingShape), 0.1f))); } } Vector3 min = new Vector3(-planeWidth * scale * 0.45f, 10, -planeWidth * scale * 0.45f); Vector3 span = new Vector3(planeWidth * scale * 0.9f, 15, planeWidth * scale * 0.9f); for (int i = 0; i < aiCount; ++i) { //The AI cars are very similar, except... we handicap them a little to make the player good about themselves. var position = min + span * new Vector3((float)random.NextDouble(), (float)random.NextDouble(), (float)random.NextDouble()); var orientation = Quaternion.CreateFromAxisAngle(new Vector3(0, 1, 0), (float)random.NextDouble() * MathF.PI * 2); aiControllers[i].Controller = new SimpleCarController(SimpleCar.Create(Simulation, properties, new RigidPose(position, orientation), bodyShapeIndex, bodyInertia, 0.5f, wheelShapeIndex, wheelInertia, 2f, new Vector3(-x, y, frontZ), new Vector3(x, y, frontZ), new Vector3(-x, y, backZ), new Vector3(x, y, backZ), new Vector3(0, -1, 0), 0.25f, new SpringSettings(5, 0.7f), Quaternion.CreateFromAxisAngle(Vector3.UnitZ, MathF.PI * 0.5f)), forwardSpeed: 50, forwardForce: 5, zoomMultiplier: 2, backwardSpeed: 10, backwardForce: 4, idleForce: 0.25f, brakeForce: 7, steeringSpeed: 1.5f, maximumSteeringAngle: MathF.PI * 0.23f); aiControllers[i].LaneOffset = (float)random.NextDouble() * 20 - 10; } DemoMeshHelper.CreateDeformedPlane(planeWidth, planeWidth, (int vX, int vY) => { var octave0 = (MathF.Sin((vX + 5f) * 0.05f) + MathF.Sin((vY + 11) * 0.05f)) * 1.8f; var octave1 = (MathF.Sin((vX + 17) * 0.15f) + MathF.Sin((vY + 19) * 0.15f)) * 0.9f; var octave2 = (MathF.Sin((vX + 37) * 0.35f) + MathF.Sin((vY + 93) * 0.35f)) * 0.4f; var octave3 = (MathF.Sin((vX + 53) * 0.65f) + MathF.Sin((vY + 47) * 0.65f)) * 0.2f; var octave4 = (MathF.Sin((vX + 67) * 1.50f) + MathF.Sin((vY + 13) * 1.5f)) * 0.125f; var distanceToEdge = planeWidth / 2 - Math.Max(Math.Abs(vX - planeWidth / 2), Math.Abs(vY - planeWidth / 2)); var edgeRamp = 25f / (distanceToEdge + 1); var terrainHeight = octave0 + octave1 + octave2 + octave3 + octave4; var vertexPosition = new Vector2(vX * scale, vY * scale) + terrainPosition; var distanceToTrack = raceTrack.GetDistance(vertexPosition); var trackWeight = MathF.Min(1f, 3f / (distanceToTrack * 0.1f + 1f)); var height = trackWeight * -10f + terrainHeight * (1 - trackWeight); return(new Vector3(vertexPosition.X, height + edgeRamp, vertexPosition.Y)); }, new Vector3(1, 1, 1), BufferPool, out var planeMesh); Simulation.Statics.Add(new StaticDescription(new Vector3(0, -15, 0), Quaternion.CreateFromAxisAngle(new Vector3(0, 1, 0), MathF.PI / 2), new CollidableDescription(Simulation.Shapes.Add(planeMesh), 0.1f))); }