예제 #1
0
        public override void Initialize(ContentArchive content, Camera camera)
        {
            camera.Position = new Vector3(0, 8, -10);
            camera.Yaw      = MathHelper.Pi;

            Simulation = Simulation.Create(BufferPool, new DemoNarrowPhaseCallbacks(), new DemoPoseIntegratorCallbacks(new Vector3(0, -10, 0)), new PositionFirstTimestepper());

            DemoMeshHelper.LoadModel(content, BufferPool, @"Content\newt.obj", Vector3.One, out var mesh);
            new Box(2.5f, 1, 4).ComputeInertia(1, out var approximateInertia);
            var meshShapeIndex = Simulation.Shapes.Add(mesh);

            for (int meshIndex = 0; meshIndex < 3; ++meshIndex)
            {
                Simulation.Bodies.Add(
                    BodyDescription.CreateDynamic(new Vector3(0, 2 + meshIndex * 2, 0), approximateInertia,
                                                  new CollidableDescription(meshShapeIndex, 0.1f), new BodyActivityDescription(0.01f)));
            }

            var compoundBuilder = new CompoundBuilder(BufferPool, Simulation.Shapes, 12);

            for (int i = 0; i < mesh.Triangles.Length; ++i)
            {
                compoundBuilder.Add(mesh.Triangles[i], RigidPose.Identity, 1);
            }
            compoundBuilder.BuildDynamicCompound(out var children, out var compoundInertia);
            var compound           = new BigCompound(children, Simulation.Shapes, BufferPool);
            var compoundShapeIndex = Simulation.Shapes.Add(compound);

            compoundBuilder.Dispose();
            for (int i = 0; i < 3; ++i)
            {
                Simulation.Bodies.Add(BodyDescription.CreateDynamic(new Vector3(5, 2 + i * 2, 0), compoundInertia, new CollidableDescription(compoundShapeIndex, 0.1f), new BodyActivityDescription(0.01f)));
            }

            var staticShape      = new Box(1500, 1, 1500);
            var staticShapeIndex = Simulation.Shapes.Add(staticShape);

            Simulation.Statics.Add(new StaticDescription(new Vector3(0, -0.5f, 0), new CollidableDescription(staticShapeIndex, 0.1f)));
        }
예제 #2
0
        public override void Initialize(ContentArchive content, Camera camera)
        {
            camera.Position = new Vector3(0, 5, 10);
            camera.Yaw      = 0;
            camera.Pitch    = 0;

            bodyProperties = new CollidableProperty <TankDemoBodyProperties>();
            //We assign velocities outside of the timestep to fire bullets, so using the PositionLastTimestepper avoids integrating those velocities into positions before the solver has a chance to intervene.
            //We could have also modified velocities in the PositionFirstTimestepper's BeforeCollisionDetection callback, but it's just a little simpler to do this with very little cost.
            Simulation = Simulation.Create(BufferPool, new TankCallbacks()
            {
                Properties = bodyProperties
            }, new DemoPoseIntegratorCallbacks(new Vector3(0, -10, 0)), new PositionLastTimestepper());

            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);

            var projectileShape = new Sphere(0.1f);

            projectileShape.ComputeInertia(0.2f, out var projectileInertia);
            var tankDescription = new TankDescription
            {
                Body         = TankPartDescription.Create(10, new Box(4f, 1, 5), RigidPose.Identity, 0.5f, Simulation.Shapes),
                Turret       = TankPartDescription.Create(1, new Box(1.5f, 0.7f, 2f), new RigidPose(new Vector3(0, 0.85f, 0.4f)), 0.5f, Simulation.Shapes),
                Barrel       = TankPartDescription.Create(0.5f, new Box(0.2f, 0.2f, 3f), new RigidPose(new Vector3(0, 0.85f, 0.4f - 1f - 1.5f)), 0.5f, Simulation.Shapes),
                TurretAnchor = new Vector3(0f, 0.5f, 0.4f),
                BarrelAnchor = new Vector3(0, 0.5f + 0.35f, 0.4f - 1f),
                TurretBasis  = Quaternion.Identity,
                TurretServo  = new ServoSettings(1f, 0f, 40f),
                TurretSpring = new SpringSettings(10f, 1f),
                BarrelServo  = new ServoSettings(1f, 0f, 40f),
                BarrelSpring = new SpringSettings(10f, 1f),

                ProjectileShape            = Simulation.Shapes.Add(projectileShape),
                ProjectileSpeed            = 100f,
                BarrelLocalProjectileSpawn = new Vector3(0, 0, -1.5f),
                ProjectileInertia          = projectileInertia,

                LeftTreadOffset    = new Vector3(-1.9f, 0f, 0),
                RightTreadOffset   = new Vector3(1.9f, 0f, 0),
                SuspensionLength   = 1f,
                SuspensionSettings = new SpringSettings(2.5f, 1.5f),
                WheelShape         = wheelShapeIndex,
                WheelInertia       = wheelInertia,
                WheelFriction      = 2f,
                TreadSpacing       = 1f,
                WheelCountPerTread = 5,
                WheelOrientation   = QuaternionEx.CreateFromAxisAngle(Vector3.UnitZ, MathF.PI * -0.5f),
            };

            playerController = new TankController(Tank.Create(Simulation, bodyProperties, BufferPool, new RigidPose(new Vector3(0, 10, 0), Quaternion.Identity), tankDescription), 20, 5, 2, 1, 3.5f);


            const int   planeWidth          = 257;
            const float terrainScale        = 3;
            const float inverseTerrainScale = 1f / terrainScale;
            var         terrainPosition     = new Vector2(1 - planeWidth, 1 - planeWidth) * terrainScale * 0.5f;

            random = new Random(5);

            //Add some building-ish landmarks.
            var landmarkMin  = new Vector3(planeWidth * terrainScale * -0.45f, 0, planeWidth * terrainScale * -0.45f);
            var landmarkMax  = new Vector3(planeWidth * terrainScale * 0.45f, 0, planeWidth * terrainScale * 0.45f);
            var landmarkSpan = landmarkMax - landmarkMin;

            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);
                var position      = landmarkMin + landmarkSpan * new Vector3((float)random.NextDouble(), (float)random.NextDouble(), (float)random.NextDouble());
                Simulation.Statics.Add(new StaticDescription(
                                           new Vector3(0, buildingShape.HalfHeight - 4f + GetHeightForPosition(position.X, position.Z, planeWidth, inverseTerrainScale, terrainPosition), 0) + position,
                                           QuaternionEx.CreateFromAxisAngle(Vector3.UnitY, (float)random.NextDouble() * MathF.PI),
                                           new CollidableDescription(Simulation.Shapes.Add(buildingShape), 0.1f)));
            }

            DemoMeshHelper.CreateDeformedPlane(planeWidth, planeWidth,
                                               (int vX, int vY) =>
            {
                var position2D = new Vector2(vX, vY) * terrainScale + terrainPosition;
                return(new Vector3(position2D.X, GetHeightForPosition(position2D.X, position2D.Y, planeWidth, inverseTerrainScale, terrainPosition), position2D.Y));
            }, new Vector3(1, 1, 1), BufferPool, out var planeMesh);
            Simulation.Statics.Add(new StaticDescription(new Vector3(0, 0, 0),
                                                         new CollidableDescription(Simulation.Shapes.Add(planeMesh), 0.1f)));

            explosions = new QuickList <Explosion>(32, BufferPool);

            //Create the AI tanks.
            const int aiTankCount = 100;

            aiTanks     = new QuickList <AITank>(aiTankCount, BufferPool);
            playAreaMin = new Vector2(landmarkMin.X, landmarkMin.Z);
            playAreaMax = new Vector2(landmarkMax.X, landmarkMax.Z);
            var playAreaSpan = playAreaMax - playAreaMin;

            for (int i = 0; i < aiTankCount; ++i)
            {
                var horizontalPosition = playAreaMin + new Vector2((float)random.NextDouble(), (float)random.NextDouble()) * playAreaSpan;
                aiTanks.AllocateUnsafely() = new AITank
                {
                    Controller = new TankController(
                        Tank.Create(Simulation, bodyProperties, BufferPool, new RigidPose(
                                        new Vector3(horizontalPosition.X, 10, horizontalPosition.Y),
                                        QuaternionEx.CreateFromAxisAngle(new Vector3(0, 1, 0), (float)random.NextDouble() * 0.1f)),
                                    tankDescription), 20, 5, 2, 1, 3.5f),
                    HitPoints = 5
                };
            }
        }
예제 #3
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)));
        }