예제 #1
0
        private void constructPhysicsBody()
        {
            ConvexHullShape hull = new ConvexHullShape(importPhysicsHull());

            hull.CollisionMargin = 0.6f;
            var bodies = new List <CompoundShapeEntry>()
            {
                new CompoundShapeEntry(hull, Vector3.Zero, 25f)
            };

            physicsEntityBody = new CompoundBody(bodies, 60f);
            //body.CollisionInformation.LocalPosition = new Vector3(0, .5f, 0);//Moves center of gravity position to adjust stability.

            physicsEntityBody.IsAlwaysActive = true;

            //physicsBody.CenterOfMassOffset = new Vector3(0, 0f, 0);//Becareful with this as forces/impulses act from here including raycasts
            physicsEntityBody.LinearDamping            = 0.5f;//As there is rarely friction must slow ship down every update
            physicsEntityBody.AngularDamping           = 0.94f;
            physicsEntityBody.Material.KineticFriction = 2f;

            physicsEntityBody.PositionUpdateMode = PositionUpdateMode.Continuous;

            physicsEntityBody.CollisionInformation.Events.ContactCreated += new ContactCreatedEventHandler <EntityCollidable>(Events_InitialCollisionDetected);

            Physics.space.Add(physicsEntityBody);
        }
예제 #2
0
 public static Entity GetEntity(Vector3 position, UInt16 index)
 {
     switch (index)
     {
         case 0: //Terrain
             return new Box(position, 750, 5, 750);
         case 1: //Building
             return new Box(position, 15, 8, 15);
         case 2: //Core
             Entity shape = new CompoundBody(
                 new List<CompoundShapeEntry>
                 {
                     new CompoundShapeEntry(new BoxShape(2f, 2f, 3f),float.MaxValue),
                     new CompoundShapeEntry(new BoxShape(9f, 0.1f, 2f),new Vector3(0,0,0))
                 }, 50
                 );
             shape.Position = position;
             return shape;
         case 3: //Nose
             return new Box(position+new Vector3(0,0,-0.75f), 2f, 2f, 1.5f);
         case 4: //Engine
             return new Box(position+new Vector3(0, 0, 0.75f), 2f, 2f, 1.5f);
         default:
             return new Box(position, 1, 1, 1);
     }
 }
예제 #3
0
        /// <summary>
        /// Constructs a new demo.
        /// </summary>
        /// <param name="game">Game owning this demo.</param>
        public AddRemoveStressDemo(DemosGame game)
            : base(game)
        {
            NarrowPhaseHelper.Factories.BoxBox.EnsureCount(5000);
            NarrowPhaseHelper.Factories.CompoundCompound.EnsureCount(5000);
            Space.Remove(vehicle.Vehicle);

            for (int i = 0; i < 1000; i++)
            {

                var position = new Vector3(
                    (float)(random.NextDouble() - 0.5) * width,
                    (float)(random.NextDouble() - 0.5) * height,
                    (float)(random.NextDouble() - 0.5) * length);
                var toAdd =
                    new CompoundBody(new List<CompoundShapeEntry>
                    {
                        new CompoundShapeEntry(new BoxShape(1,1,1), position, 1)
                    }, 10);
                //var toAdd = new Box(position, 1, 1, 1, 1);
                toAdd.IsAffectedByGravity = false;
                toAdd.LinearVelocity = 3 * Vector3.Normalize(toAdd.Position);
                Space.Add(toAdd);
                addedEntities.Add(toAdd);

            }

            //Box ground = new Box(new Vector3(0, -.5f, 0), 50, 1, 50);
            //Space.Add(ground);
            game.Camera.Position = new Vector3(0, 6, 15);
        }
예제 #4
0
        public static Entity GetEntity(Vector3 position, UInt16 index)
        {
            switch (index)
            {
            case 0:     //Terrain
                return(new Box(position, 750, 5, 750));

            case 1:     //Building
                return(new Box(position, 15, 8, 15));

            case 2:     //Core
                Entity shape = new CompoundBody(
                    new List <CompoundShapeEntry>
                {
                    new CompoundShapeEntry(new BoxShape(2f, 2f, 3f), float.MaxValue),
                    new CompoundShapeEntry(new BoxShape(9f, 0.1f, 2f), new Vector3(0, 0, 0))
                }, 50
                    );
                shape.Position = position;
                return(shape);

            case 3:     //Nose
                return(new Box(position + new Vector3(0, 0, -0.75f), 2f, 2f, 1.5f));

            case 4:     //Engine
                return(new Box(position + new Vector3(0, 0, 0.75f), 2f, 2f, 1.5f));

            default:
                return(new Box(position, 1, 1, 1));
            }
        }
예제 #5
0
        /// <summary>
        /// Constructs a new demo.
        /// </summary>
        /// <param name="game">Game owning this demo.</param>
        public AddRemoveStressDemo(DemosGame game)
            : base(game)
        {
            NarrowPhaseHelper.Factories.BoxBox.EnsureCount(5000);
            NarrowPhaseHelper.Factories.CompoundCompound.EnsureCount(5000);
            Space.Remove(vehicle.Vehicle);


            for (int i = 0; i < 1000; i++)
            {
                var position = new Vector3(
                    (float)(random.NextDouble() - 0.5) * width,
                    (float)(random.NextDouble() - 0.5) * height,
                    (float)(random.NextDouble() - 0.5) * length);
                var toAdd =
                    new CompoundBody(new List <CompoundShapeEntry>
                {
                    new CompoundShapeEntry(new BoxShape(1, 1, 1), position, 1)
                }, 10);
                //var toAdd = new Box(position, 1, 1, 1, 1);
                toAdd.IsAffectedByGravity = false;
                toAdd.LinearVelocity      = 3 * Vector3.Normalize(toAdd.Position);
                Space.Add(toAdd);
                addedEntities.Add(toAdd);
            }

            //Box ground = new Box(new Vector3(0, -.5f, 0), 50, 1, 50);
            //Space.Add(ground);
            game.Camera.Position = new Vector3(0, 6, 15);
        }
예제 #6
0
        /// <summary>
        /// Constructs a new demo.
        /// </summary>
        /// <param name="game">Game owning this demo.</param>
        public MutableCompoundDemo(DemosGame game)
            : base(game)
        {
            int   width       = 3;
            int   height      = 3;
            int   length      = 10;
            float blockWidth  = 1f;
            float blockHeight = 1f;
            float blockLength = 1f;



            for (int q = 0; q < 1; q++)
            {
                List <CompoundShapeEntry> shapes = new List <CompoundShapeEntry>();
                float totalWeight = 0;
                float density     = 1;

                for (int i = 0; i < width; i++)
                {
                    for (int j = 0; j < height; j++)
                    {
                        for (int k = 0; k < length; k++)
                        {
                            float weight = density * blockWidth * blockLength * blockHeight;
                            totalWeight += weight;
                            shapes.Add(new CompoundShapeEntry(
                                           new BoxShape(blockWidth, blockHeight, blockLength),
                                           new Vector3(5 + q * 20 + i * blockWidth, j * blockHeight, k * blockLength), weight));
                        }
                    }
                }

                var compound = new CompoundBody(shapes, totalWeight);
                //compound.Orientation = Quaternion.CreateFromYawPitchRoll(1, 1, 1);
                //compound.AngularVelocity = new Vector3(0, 1, 0);
                Entity <CompoundCollidable> compound2, compound3;
                CompoundHelper.SplitCompound(x => x.ShapeIndex >= shapes.Count / 2, compound, out compound2);
                CompoundHelper.SplitCompound(x => x.ShapeIndex >= 3 * shapes.Count / 4, compound2, out compound3);



                //compound.ActivityInformation.IsAlwaysActive = true;
                //compound.IsAffectedByGravity = false;
                //compound2.ActivityInformation.IsAlwaysActive = true;
                //compound2.IsAffectedByGravity = false;
                //compound3.ActivityInformation.IsAlwaysActive = true;
                //compound3.IsAffectedByGravity = false;
                //compound.Tag = "noDisplayObject";
                Space.Add(compound);
                Space.Add(compound2);
                Space.Add(compound3);
            }

            Box ground = new Box(new Vector3(0, -4.5f, 0), 50, 1, 50);

            Space.Add(ground);
            game.Camera.Position = new Microsoft.Xna.Framework.Vector3(0, 6, 15);
        }
예제 #7
0
        protected override Entity CreateEntity()
        {
            CompoundBody cb = new CompoundBody(
                _shapes.Select(bse => BoxShapeDescription.Scale(bse, Transform.Scale).GetShapeEntry()).ToList(), Mass);

            EntityCenter = -cb.Position;
            return(cb);
        }
예제 #8
0
        public void Visit(CompoundBody body)
        {
            List <Body> parts = new List <Body>();

            foreach (var b in body.Parts)
            {
                b.Accept(new SurfaceAreaVisitor());
            }
        }
예제 #9
0
        /// <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);
        }
예제 #10
0
 private void TestCompoundBodyContainsPoint(CompoundBody compoundBody, double radius)
 {
     foreach (var part in compoundBody.Parts)
     {
         Assert.IsTrue(compoundBody.ContainsPoint(part.Position));
         Assert.IsFalse(compoundBody.ContainsPoint(part.Position.CreatePoint(dx: radius)));
         Assert.IsFalse(compoundBody.ContainsPoint(part.Position.CreatePoint(dy: radius)));
         Assert.IsFalse(compoundBody.ContainsPoint(part.Position.CreatePoint(dz: radius)));
     }
 }
예제 #11
0
 public void ComposeHitbox()
 {
     Hitbox = new CompoundBody(
         new List <CompoundShapeEntry> {
         new CompoundShapeEntry(new BoxShape(2f, 2f, 6f), Vector3.Zero),
         new CompoundShapeEntry(new BoxShape(Core.WingVector.X, 0.1f, Core.WingVector.Z),
                                new Vector3(0, Core.WingVector.Y, 0))
     }
         , TotalWeight);
 }
        /// <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);
        }
예제 #13
0
 public UniverseWall(Game game, BEPUutilities.Vector3 pos, int dimX, int dimY, int dimZ) : this(game)
 {
     physicsObject = new CompoundBody(new List <CompoundShapeEntry> {
         new CompoundShapeEntry(new BoxShape(10f, dimY, dimZ), new BEPUutilities.Vector3(dimX / 2, 0, 0)),
         new CompoundShapeEntry(new BoxShape(10f, dimY, dimZ), new BEPUutilities.Vector3(-dimX / 2, 0, 0)),
         new CompoundShapeEntry(new BoxShape(dimX, 10f, dimZ), new BEPUutilities.Vector3(0, dimY / 2, 0)),
         new CompoundShapeEntry(new BoxShape(dimX, 10f, dimZ), new BEPUutilities.Vector3(0, -dimY / 2, 0)),
         new CompoundShapeEntry(new BoxShape(dimX, dimY, 10f), new BEPUutilities.Vector3(0, 0, dimZ / 2)),
         new CompoundShapeEntry(new BoxShape(dimX, dimY, 10f), new BEPUutilities.Vector3(0, 0, -dimZ / 2)),
     });
     physicsObject.CollisionInformation.Tag = this;
     Game.Services.GetService <Space>().Add(physicsObject);
 }
예제 #14
0
        public void CompoundBody_Of_TwoCuboids_BoundingBox_Correct(double x0, double y0, double z0, double x1, double y1, double z1, double expectedSizeX, double expectedSizeY, double expectedSizeZ)
        {
            var compoundBody = new CompoundBody(new[]
            {
                new RectangularCuboid(new Vector3(x0, y0, z0), 4, 4, 4),
                new RectangularCuboid(new Vector3(x1, y1, z1), 4, 4, 4),
            });
            var boundingBox = compoundBody.GetBoundingBox();

            Assert.AreEqual(expectedSizeX, boundingBox.SizeX, "SizeX");
            Assert.AreEqual(expectedSizeY, boundingBox.SizeY, "SizeY");
            Assert.AreEqual(expectedSizeZ, boundingBox.SizeZ, "SizeZ");
        }
예제 #15
0
        private void CreateCompoundBody()
        {
            List <CompoundShapeEntry> shapes = new List <CompoundShapeEntry>();

            // Create parts of compound shape
            Vector3 blockPos = new Vector3();

            for (int z = 0; z < GAME_FIELD_SIZE; ++z)
            {
                for (int y = 0; y < GAME_FIELD_SIZE; ++y)
                {
                    for (int x = 0; x < GAME_FIELD_SIZE; ++x)
                    {
                        blockPos.X = (x - GAME_FIELD_SIZE * 0.5f) * BLOCK_SIZE + BLOCK_SIZE * 0.5f;
                        blockPos.Y = (y - GAME_FIELD_SIZE * 0.5f) * BLOCK_SIZE + BLOCK_SIZE * 0.5f;
                        blockPos.Z = (z - GAME_FIELD_SIZE * 0.5f) * BLOCK_SIZE + BLOCK_SIZE * 0.5f;

                        BoxShape blockShape = new BoxShape(BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE);

                        CompoundShapeEntry entry = new CompoundShapeEntry(blockShape, blockPos);
                        shapes.Add(entry);
                    }
                }
            }

            // Create compound body
            compoundBody = new CompoundBody(shapes, COMPOUND_BODY_MASS);

            compoundBody.PositionUpdateMode = BEPUphysics.PositionUpdating.PositionUpdateMode.Continuous;
            compoundBody.AngularDamping     = COMPOUND_BODY_ANGULAR_DAMPING;

            // Add constraint prevents compound body from moving
            constraint = new MaximumLinearSpeedConstraint(compoundBody, 0.0f);

            // Create collision group for removed blocks
            removedBlocksGroup = new CollisionGroup();

            // Mark all chapes in compound body to be removed for now
            foreach (CompoundChild child in compoundBody.CollisionInformation.Children)
            {
                child.CollisionInformation.CollisionRules.Group = removedBlocksGroup;
            }

            // Add compound body and its constraints to physics space
            space.Add(compoundBody);
            space.Add(constraint);

            //compoundBody.CollisionInformation.Events.ContactCreated += handleContactCreated;
        }
예제 #16
0
        public static Entity GetEntity(Vector3 position, UInt16 index)
        {
            switch (index)
            {
            case 0:     //Terrain
                return(new Box(position, 750, 5, 750));

            case 1:     //Building
                return(new Box(position, 30, 16, 30));

            case 2:     //UL Core
                Entity shape = new CompoundBody(
                    new List <CompoundShapeEntry>
                {
                    new CompoundShapeEntry(new BoxShape(.85f * 2, .85f * 2, 1 * 2), float.MaxValue),
                    new CompoundShapeEntry(new BoxShape(4.4f * 2, 0.05f * 2, 1 * 2), new Vector3(0, 0.85f, 0))
                }, 50
                    );
                shape.Position = position;
                return(shape);

            case 3:     //UL Nose
                return(new Box(position, .75f * 2, 1f * 2, .75f * 2, 20));

            case 4:     //UL Engine
                return(new Box(position, .6f * 2, .95f * 2, 0.425f * 2, 20));

            case 5:     //L Core
                shape = new CompoundBody(
                    new List <CompoundShapeEntry>
                {
                    new CompoundShapeEntry(new BoxShape(2, 2, 2), float.MaxValue),
                    new CompoundShapeEntry(new BoxShape(8, 2, 0.2f), new Vector3(0, 0, 0))
                }, 50
                    );
                shape.Position = position;
                return(shape);

            case 6:     //L Nose
                return(new Box(position, 1.35f, 1.6f, 1.6f));

            case 7:     //L Engine
                return(new Box(position, 1.8f, 1.4f, 1.05f));

            default:
                return(new Box(position, 1, 1, 1));
            }
        }
예제 #17
0
        /// <summary>
        /// Constructs a new demo.
        /// </summary>
        /// <param name="game">Game owning this demo.</param>
        public SpaceshipDemo(DemosGame game)
            : base(game)
        {
            //Build the ship
            var shipFuselage  = new CompoundShapeEntry(new CylinderShape(3, .7m), new Vector3(0, 5, 0), 4);
            var shipNose      = new CompoundShapeEntry(new ConeShape(2, .7m), new Vector3(0, 7, 0), 2);
            var shipWing      = new CompoundShapeEntry(new BoxShape(5, 2, .2m), new Vector3(0, 5, 0), 3);
            var shipThrusters = new CompoundShapeEntry(new ConeShape(1, .5m), new Vector3(0, 3.25m, 0), 1);

            var bodies = new List <CompoundShapeEntry>();

            bodies.Add(shipFuselage);
            bodies.Add(shipNose);
            bodies.Add(shipWing);
            bodies.Add(shipThrusters);

            var ship = new CompoundBody(bodies, 10);

            //Setup the launch pad and ramp
            Entity toAdd = new Box(new Vector3(10, 4, 0), 26, 1, 6);

            Space.Add(toAdd);
            toAdd             = new Box(new Vector3(32, 7.8m, 0), 20, 1, 6);
            toAdd.Orientation = Quaternion.CreateFromAxisAngle(Vector3.Forward, -MathHelper.Pi / 8);
            Space.Add(toAdd);
            toAdd             = new Box(new Vector3(32, 8.8m, -3.5m), 20, 1, 1);
            toAdd.Orientation = Quaternion.CreateFromAxisAngle(Vector3.Forward, -MathHelper.Pi / 8);
            Space.Add(toAdd);
            toAdd             = new Box(new Vector3(32, 8.8m, 3.5m), 20, 1, 1);
            toAdd.Orientation = Quaternion.CreateFromAxisAngle(Vector3.Forward, -MathHelper.Pi / 8);
            Space.Add(toAdd);
            toAdd = new Box(new Vector3(-2.75m, 5.5m, 0), .5m, 2, 3);
            Space.Add(toAdd);

            //Blast-off!
            ship.AngularDamping = .4m; //Helps keep the rocket on track for a little while longer :D
            var thruster = new Thruster(ship, new Vector3(0, -2, 0), new Vector3(0, 300, 0), 0);

            Space.Add(thruster);
            ship.Orientation = Quaternion.CreateFromAxisAngle(Vector3.Right, MathHelper.Pi / 2) * Quaternion.CreateFromAxisAngle(Vector3.Forward, MathHelper.Pi / 2);
            Space.Add(ship);


            game.Camera.Position = new Vector3(-14, 12, 25);
            game.Camera.Yaw(MathHelper.Pi / -4);
        }
        /// <summary>
        /// Constructs a new demo.
        /// </summary>
        /// <param name="game">Game owning this demo.</param>
        public SpaceshipDemo(DemosGame game)
            : base(game)
        {
            //Build the ship
            var shipFuselage = new CompoundShapeEntry(new CylinderShape(3, .7f), new Vector3(0, 5, 0), 4);
            var shipNose = new CompoundShapeEntry(new ConeShape(2, .7f), new Vector3(0, 7f, 0), 2);
            var shipWing = new CompoundShapeEntry(new BoxShape(5f, 2, .2f), new Vector3(0, 5, 0), 3);
            var shipThrusters = new CompoundShapeEntry(new ConeShape(1, .5f), new Vector3(0, 3.25f, 0), 1);

            var bodies = new List<CompoundShapeEntry>();
            bodies.Add(shipFuselage);
            bodies.Add(shipNose);
            bodies.Add(shipWing);
            bodies.Add(shipThrusters);

            var ship = new CompoundBody(bodies, 10);

            //Setup the launch pad and ramp
            Entity toAdd = new Box(new Vector3(10, 4, 0), 26, 1f, 6);
            Space.Add(toAdd);
            toAdd = new Box(new Vector3(32, 7.8f, 0), 20, 1, 6);
            toAdd.Orientation = Quaternion.CreateFromAxisAngle(Vector3.Forward, -(float)Math.PI / 8);
            Space.Add(toAdd);
            toAdd = new Box(new Vector3(32, 8.8f, -3.5f), 20, 1, 1);
            toAdd.Orientation = Quaternion.CreateFromAxisAngle(Vector3.Forward, -(float)Math.PI / 8);
            Space.Add(toAdd);
            toAdd = new Box(new Vector3(32, 8.8f, 3.5f), 20, 1, 1);
            toAdd.Orientation = Quaternion.CreateFromAxisAngle(Vector3.Forward, -(float)Math.PI / 8);
            Space.Add(toAdd);
            toAdd = new Box(new Vector3(-2.75f, 5.5f, 0), .5f, 2f, 3);
            Space.Add(toAdd);

            //Blast-off!
            ship.AngularDamping = .4f; //Helps keep the rocket on track for a little while longer :D
            var thruster = new Thruster(ship, new Vector3(0, -2, 0), new Vector3(0, 300, 0), 0);
            Space.Add(thruster);
            ship.Orientation = Quaternion.CreateFromAxisAngle(Vector3.Right, (float)Math.PI / 2) * Quaternion.CreateFromAxisAngle(Vector3.Forward, (float)Math.PI / 2);
            Space.Add(ship);


            game.Camera.Position = new Vector3(-14, 12, 25);
            game.Camera.Yaw((float)Math.PI / -4);
        }
        /// <summary>
        /// Constructs a new demo.
        /// </summary>
        /// <param name="game">Game owning this demo.</param>
        public CompoundBodiesDemo(DemosGame game)
            : base(game)
        {

            //Build the first body
            var bodies = new List<CompoundShapeEntry>
            {
                new CompoundShapeEntry(new SphereShape(.5f), new Vector3(0, 1, 0), 1),
                new CompoundShapeEntry(new ConeShape(2, .5f), new Vector3(1, 1, 0), 1),
                new CompoundShapeEntry(new SphereShape(.5f), new Vector3(-1, 1, 0), 1)
            };
            var cb1 = new CompoundBody(bodies, 45);



            //Build the second body
            bodies = new List<CompoundShapeEntry>
            {
                new CompoundShapeEntry(new BoxShape(1,1,1), new Vector3(0, 3, 0), 1),
                new CompoundShapeEntry(new BoxShape(1,1,1), new Vector3(1, 3.5f, 0), 1),
            };
            var cb2 = new CompoundBody(bodies, 4);

            bodies = new List<CompoundShapeEntry>();
            //Build the third Braum's-fry style body
            for (int k = 0; k < 7; k++)
            {
                bodies.Add(new CompoundShapeEntry(new BoxShape(1, 1, 1), new Vector3(-4 + k * .7f, 2 + .7f * k, 2 + k * .2f), 1));
            }
            var cb3 = new CompoundBody(bodies, 7);

            //Add them all to the space
            Space.Add(cb3);
            Space.Add(cb2);
            Space.Add(cb1);



            Space.Add(new Box(new Vector3(0, -.5f, 0), 10, 1, 10));
            game.Camera.Position = new Vector3(0, 3, 15);

        }
예제 #20
0
        private static void AssertCompoundBodyWithSinglePart_Contains_IsEquivalentToItsPartContains(Body part)
        {
            var random   = new Random(123123);
            var compound = new CompoundBody(new List <Body> {
                part
            });
            var compound2 = new CompoundBody(new List <Body> {
                compound
            });

            for (int i = 0; i < 1000; i++)
            {
                var p = new Vector3(
                    random.NextDouble() * 20 - 10,
                    random.NextDouble() * 20 - 10,
                    random.NextDouble() * 20 - 10);
                Assert.AreEqual(part.ContainsPoint(p), compound.ContainsPoint(p));
                Assert.AreEqual(part.ContainsPoint(p), compound2.ContainsPoint(p));
            }
        }
        /// <summary>
        /// Constructs a new demo.
        /// </summary>
        /// <param name="game">Game owning this demo.</param>
        public CompoundBodiesDemo(DemosGame game)
            : base(game)
        {
            //Build the first body
            var bodies = new List <CompoundShapeEntry>
            {
                new CompoundShapeEntry(new SphereShape(.5f), new Vector3(0, 1, 0), 1),
                new CompoundShapeEntry(new ConeShape(2, .5f), new Vector3(1, 1, 0), 1),
                new CompoundShapeEntry(new SphereShape(.5f), new Vector3(-1, 1, 0), 1)
            };
            var cb1 = new CompoundBody(bodies, 45);



            //Build the second body
            bodies = new List <CompoundShapeEntry>
            {
                new CompoundShapeEntry(new BoxShape(1, 1, 1), new Vector3(0, 3, 0), 1),
                new CompoundShapeEntry(new BoxShape(1, 1, 1), new Vector3(1, 3.5f, 0), 1),
            };
            var cb2 = new CompoundBody(bodies, 4);

            bodies = new List <CompoundShapeEntry>();
            //Build the third Braum's-fry style body
            for (int k = 0; k < 7; k++)
            {
                bodies.Add(new CompoundShapeEntry(new BoxShape(1, 1, 1), new Vector3(-4 + k * .7f, 2 + .7f * k, 2 + k * .2f), 1));
            }
            var cb3 = new CompoundBody(bodies, 7);

            //Add them all to the space
            Space.Add(cb3);
            Space.Add(cb2);
            Space.Add(cb1);



            Space.Add(new Box(new Vector3(0, -.5f, 0), 10, 1, 10));
            game.Camera.Position = new Vector3(0, 3, 15);
        }
예제 #22
0
        public SpaceShip(PlayerIndex player, Color color, Microsoft.Xna.Framework.Vector3 position)
        {
            this.playerIndex = player;

            var shape = new ProceduralCuboid(1, 1, 1);

            shape.SetColor(color);

            ShipObject = new GameObject();

            ShipObject.AddComponent(new RenderGeometryComponent(shape));
            ShipObject.AddComponent(new EffectRenderComponent(EffectLoader.LoadSM5Effect("flatshaded")));
            ShipObject.AddComponent(new ShadowCasterComponent());

            SystemCore.GameObjectManager.AddAndInitialiseGameObject(ShipObject);

            //Build the ship
            var shipFuselage = new CompoundShapeEntry(new BoxShape(1, 1f, 1), new BEPUutilities.Vector3(0, 0, 0), 4);

            bodies = new List <CompoundShapeEntry>();
            bodies.Add(shipFuselage);


            PhysicsBody = new CompoundBody(bodies, 10);

            PhysicsBody.Orientation = BEPUutilities.Quaternion.CreateFromAxisAngle(BEPUutilities.Vector3.Right, (float)Math.PI / 2) * BEPUutilities.Quaternion.CreateFromAxisAngle(BEPUutilities.Vector3.Forward, (float)Math.PI / 2);
            PhysicsBody.Position    = position.ToBepuVector();
            SystemCore.PhysicsSimulation.Add(PhysicsBody);
            PhysicsBody.IsAffectedByGravity = false;

            //used by the gravitational field to opt out of its effects
            PhysicsBody.Tag = "spaceship";



            PhysicsBody.AngularDamping = 0.99f;
            PhysicsBody.LinearDamping  = 0.99f;
        }
        /// <summary>
        /// Constructs a new demo.
        /// </summary>
        /// <param name="game">Game owning this demo.</param>
        public CharacterPlaygroundDemo(DemosGame game)
            : base(game)
        {

            game.Camera.Position = new Vector3(-10, 7, 5);
            game.Camera.ViewDirection = new Vector3(0, 0, 1);
            //Since this is the character playground, turn on the character by default.
            character.Activate();
            //Having the character body visible would be a bit distracting.
            character.CharacterController.Body.Tag = "noDisplayObject";

            //Load in mesh data for the environment.
            Vector3[] staticTriangleVertices;
            int[] staticTriangleIndices;


            var playgroundModel = game.Content.Load<Model>("CharacterControllerTestTerrain");
            //This is a little convenience method used to extract vertices and indices from a model.
            //It doesn't do anything special; any approach that gets valid vertices and indices will work.
            ModelDataExtractor.GetVerticesAndIndicesFromModel(playgroundModel, out staticTriangleVertices, out staticTriangleIndices);
            var staticMesh = new StaticMesh(staticTriangleVertices, staticTriangleIndices, new AffineTransform(new Vector3(0.01f, 0.01f, 0.01f), Quaternion.Identity, new Vector3(0, 0, 0)));
            staticMesh.Sidedness = TriangleSidedness.Counterclockwise;

            Space.Add(staticMesh);
            game.ModelDrawer.Add(staticMesh);



            //Add a spinning blade for the character to ram itself into.
            var fanBase = new Cylinder(new Vector3(-13, .5f, 50), 1.1f, 1);
            var fanBlade = new Box(fanBase.Position + new Vector3(0, .8f, 0), 5, .1f, 1f, 5);
            var fanJoint = new RevoluteJoint(fanBase, fanBlade, (fanBase.Position + fanBlade.Position) * .5f, Vector3.Up);
            fanJoint.Motor.IsActive = true;
            fanJoint.Motor.Settings.VelocityMotor.GoalVelocity = 30;
            fanJoint.Motor.Settings.MaximumForce = 300;
            Space.Add(fanBase);
            Space.Add(fanBlade);
            Space.Add(fanJoint);

            //Add a bridge connecting the two towers.
            Vector3 startPosition = new Vector3(-19.3f, 10.5f - .25f, 23 - .85f);
            var startPlatform = new Box(startPosition - new Vector3(0, 0, 2.2f), 4, .5f, 6);
            Space.Add(startPlatform);
            Vector3 offset = new Vector3(0, 0, 1.7f);
            Box previousLink = startPlatform;
            Vector3 position = new Vector3();
            for (int i = 1; i <= 7; i++)
            {
                position = startPosition + offset * i;
                Box link = new Box(position, 3, .3f, 1.5f, 50);
                link.LinearDamping = .1f;
                link.AngularDamping = .1f;
                Space.Add(link);
                Space.Add(new RevoluteJoint(previousLink, link, position - offset * .5f, Vector3.Right));

                previousLink = link;
            }
            var endPlatform = new Box(position - new Vector3(0, 0, -3.8f), 4, .5f, 6);
            Space.Add(endPlatform);

            Space.Add(new RevoluteJoint(previousLink, endPlatform, position + offset * .5f, Vector3.Right));


            //Add in a floating platform controlled by a curve to serve as an elevator.
            Entity movingEntity = new Box(new Vector3(-10, 0, -10), 3, 1, 3);

            var positionCurve = new CardinalSpline3D();

            positionCurve.PreLoop = CurveEndpointBehavior.Mirror;
            positionCurve.PostLoop = CurveEndpointBehavior.Mirror;

            positionCurve.ControlPoints.Add(-1, new Vector3(-19.3f, 0, 43));
            positionCurve.ControlPoints.Add(0, new Vector3(-19.3f, 0, 43));
            positionCurve.ControlPoints.Add(2, new Vector3(-19.3f, 0, 43));
            positionCurve.ControlPoints.Add(3, new Vector3(-19.3f, 0, 43));
            positionCurve.ControlPoints.Add(4, new Vector3(-19.3f, 5, 43));
            positionCurve.ControlPoints.Add(5f, new Vector3(-19.3f, 10, 43));
            positionCurve.ControlPoints.Add(6f, new Vector3(-19.3f, 10, 43));
            positionCurve.ControlPoints.Add(8f, new Vector3(-19.3f, 10, 43));
            positionCurve.ControlPoints.Add(9f, new Vector3(-19.3f, 10, 43));

            elevatorMover = new EntityMover(movingEntity);
            Space.Add(elevatorMover);
            Space.Add(movingEntity);

            elevatorPath = positionCurve;

            //Add in another floating platform controlled by a curve for horizontal transport.
            movingEntity = new Box(new Vector3(-10, 0, -10), 2.5f, .5f, 2.5f);

            var platformCurve = new LinearInterpolationCurve3D();

            platformCurve.PreLoop = CurveEndpointBehavior.Mirror;
            platformCurve.PostLoop = CurveEndpointBehavior.Mirror;

            platformCurve.ControlPoints.Add(0, new Vector3(-1.75f, 10, 21.5f));
            platformCurve.ControlPoints.Add(2, new Vector3(-1.75f, 10, 21.5f));
            platformCurve.ControlPoints.Add(5, new Vector3(-1.75f, 10, 15.5f));
            platformCurve.ControlPoints.Add(10, new Vector3(-19.3f, 10, 15.5f));
            platformCurve.ControlPoints.Add(12, new Vector3(-19.3f, 10, 15.5f));
            platformCurve.ControlPoints.Add(15, new Vector3(-25, 10, 15.5f));
            platformCurve.ControlPoints.Add(22, new Vector3(-25, 10, 38));
            platformCurve.ControlPoints.Add(23, new Vector3(-22.75f, 10, 38));
            platformCurve.ControlPoints.Add(25, new Vector3(-22.75f, 10, 38));

            //Make it spin too.  That'll be fun.  Or something.
            var platformRotationCurve = new QuaternionSlerpCurve();
            platformRotationCurve.PreLoop = CurveEndpointBehavior.Mirror;
            platformRotationCurve.PostLoop = CurveEndpointBehavior.Mirror;
            platformRotationCurve.ControlPoints.Add(0, Quaternion.Identity);
            platformRotationCurve.ControlPoints.Add(15, Quaternion.Identity);
            platformRotationCurve.ControlPoints.Add(22, Quaternion.CreateFromAxisAngle(Vector3.Up, MathHelper.PiOver2));
            platformRotationCurve.ControlPoints.Add(25, Quaternion.CreateFromAxisAngle(Vector3.Up, MathHelper.PiOver2));

            platformMover = new EntityMover(movingEntity);
            platformRotator = new EntityRotator(movingEntity);
            Space.Add(platformMover);
            Space.Add(platformRotator);
            Space.Add(movingEntity);

            platformPath = platformCurve;
            platformOrientationPath = platformRotationCurve;

            //Add in a diving board.

            Box divingBoardBase = new Box(new Vector3(-9, 10, 39.3f), 5, 1, 3);
            Box divingBoard = new Box(divingBoardBase.Position + new Vector3(-2, 0, 3.5f), 1, .3f, 3, 5);
            var divingBoardJoint = new RevoluteJoint(divingBoardBase, divingBoard, divingBoard.Position + new Vector3(0, 0, -1.5f), Vector3.Right);
            divingBoardJoint.Motor.IsActive = true;
            divingBoardJoint.Motor.Settings.Mode = MotorMode.Servomechanism;
            divingBoardJoint.Motor.Settings.Servo.Goal = 0;
            divingBoardJoint.Motor.Settings.Servo.SpringSettings.Stiffness = 5000;
            divingBoardJoint.Motor.Settings.Servo.SpringSettings.Damping = 0;

            Space.Add(divingBoardBase);
            Space.Add(divingBoard);
            Space.Add(divingBoardJoint);


            //Add a second diving board for comparison.

            Box divingBoard2 = new Box(divingBoardBase.Position + new Vector3(2, 0, 5f), 1, .3f, 6, 5);
            var divingBoardJoint2 = new RevoluteJoint(divingBoardBase, divingBoard2, divingBoard2.Position + new Vector3(0, 0, -3), Vector3.Right);
            divingBoardJoint2.Motor.IsActive = true;
            divingBoardJoint2.Motor.Settings.Mode = MotorMode.Servomechanism;
            divingBoardJoint2.Motor.Settings.Servo.Goal = 0;
            divingBoardJoint2.Motor.Settings.Servo.SpringSettings.Stiffness = 10000;
            divingBoardJoint2.Motor.Settings.Servo.SpringSettings.Damping = 0;

            Space.Add(divingBoard2);
            Space.Add(divingBoardJoint2);

            //Add a seesaw for people to jump on.
            Box seesawBase = new Box(new Vector3(-7, .45f, 52), 1, .9f, .3f);
            Box seesawPlank = new Box(seesawBase.Position + new Vector3(0, .65f, 0), 1.2f, .2f, 6, 3);
            RevoluteJoint seesawJoint = new RevoluteJoint(seesawBase, seesawPlank, seesawPlank.Position, Vector3.Right);
            Space.Add(seesawJoint);
            Space.Add(seesawBase);
            Space.Add(seesawPlank);

            Space.Add(new Box(seesawPlank.Position + new Vector3(0, 1.3f, 2), 1, 1, 1, 5));


            //Add in some boxes to bump and jump on.
            int numColumns = 3;
            int numRows = 3;
            int numHigh = 3;
            float xSpacing = 1.01f;
            float ySpacing = 1.01f;
            float zSpacing = 1.01f;
            for (int i = 0; i < numRows; i++)
                for (int j = 0; j < numColumns; j++)
                    for (int k = 0; k < numHigh; k++)
                    {
                        Space.Add(new Box(new Vector3(
                                                 5 + xSpacing * i - (numRows - 1) * xSpacing / 2f,
                                                 1.58f + k * (ySpacing),
                                                 45 + zSpacing * j - (numColumns - 1) * zSpacing / 2f),
                                             .5f, .5f, .5f, 5));
                    }



            //Add a log to roll!
            //Make it a compound so some boxes can be added to let the player know it's actually spinning.
            CompoundBody log = new CompoundBody(new List<CompoundShapeEntry>()
            {
                new CompoundShapeEntry(new CylinderShape(4, 1.8f), Quaternion.CreateFromAxisAngle(Vector3.Forward, MathHelper.PiOver2), 20),
                new CompoundShapeEntry(new BoxShape(.5f, .5f, 3.7f),  new Vector3(1.75f, 0,0), 0),
                new CompoundShapeEntry(new BoxShape(.5f, 3.7f, .5f), new Vector3(1.75f, 0,0), 0),
                new CompoundShapeEntry(new BoxShape(.5f, .5f, 3.7f),  new Vector3(-1.75f, 0,0), 0),
                new CompoundShapeEntry(new BoxShape(.5f, 3.7f, .5f), new Vector3(-1.75f, 0,0), 0)
            }, 50);
            log.Position = new Vector3(-14.5f, 10, 41);
            log.AngularDamping = 0;


            RevoluteJoint logJointA = new RevoluteJoint(divingBoardBase, log, log.Position + new Vector3(2.5f, 0, 0), Vector3.Right);
            RevoluteJoint logJointB = new RevoluteJoint(endPlatform, log, log.Position + new Vector3(-2.5f, 0, 0), Vector3.Right);
            Space.Add(logJointA);
            Space.Add(logJointB);

            Space.Add(log);


            //Put some planks to stand on that show various slopes.
            int numPads = 10;
            for (int i = 0; i < numPads; i++)
            {
                offset = new Vector3(0, 0, 4);
                Box a = new Box(new Vector3(i * 1.5f + 3.5f, 10, 24), 1.5f, 1, 4);
                Box b = new Box(new Vector3(i * 1.5f + 3.5f, 10, 24), 1.5f, 1, 4);
                float angle = -i * MathHelper.PiOver2 / numPads;
                b.Orientation = Quaternion.CreateFromAxisAngle(Vector3.Right, angle);
                b.Position += offset * .5f + Quaternion.Transform(offset * .5f, b.Orientation);

                Space.Add(a);
                Space.Add(b);
            }

        }
예제 #24
0
 public void ComposeHitbox()
 {
     Hitbox = new CompoundBody(
         new List<CompoundShapeEntry>{
             new CompoundShapeEntry(new BoxShape(2f, 2f, 6f),Vector3.Zero),
             new CompoundShapeEntry(new BoxShape(Core.WingVector.X, 0.1f, Core.WingVector.Z),
                 new Vector3(0,Core.WingVector.Y,0))
         }
         , TotalWeight);
 }
예제 #25
0
        /// <summary>
        /// Constructs the front end and the internal physics representation of the Vehicle.
        /// </summary>
        /// <param name="position">Position of the Vehicle.</param>
        /// <param name="space">Space to add the Vehicle to.</param>
        /// <param name="camera">Camera to attach to the Vehicle.</param>
        /// <param name="game">The running game.</param>
        /// <param name="drawer">Drawer used to draw the Vehicle.</param>
        /// <param name="wheelModel">Model of the wheels.</param>
        /// <param name="wheelTexture">Texture to use for the wheels.</param>
        public VehicleInput(Vector3 position, Space space, Camera camera, DemosGame game, ModelDrawer drawer, Model wheelModel, Texture2D wheelTexture)
        {
            var bodies = new List <CompoundShapeEntry>
            {
                new CompoundShapeEntry(new BoxShape((Fix64)2.5m, (Fix64).75m, (Fix64)4.5m), new Vector3(0, 0, 0), 60),
                new CompoundShapeEntry(new BoxShape((Fix64)2.5m, (Fix64).3m, (Fix64)2f), new Vector3(0, (Fix64).75m / 2 + (Fix64).3m / 2, (Fix64).5m), 1)
            };
            var body = new CompoundBody(bodies, 61);

            body.CollisionInformation.LocalPosition = new Vector3(0, (Fix64).5m, 0);
            body.Position = position; //At first, just keep it out of the way.
            Vehicle       = new Vehicle(body);

            var localWheelRotation = Quaternion.CreateFromAxisAngle(new Vector3(0, 0, 1), MathHelper.PiOver2);

            //The wheel model used is not aligned initially with how a wheel would normally look, so rotate them.
            Matrix wheelGraphicRotation = Matrix.CreateFromAxisAngle(Vector3.Forward, MathHelper.PiOver2);

            Vehicle.AddWheel(new Wheel(
                                 new CylinderCastWheelShape((Fix64).375m, (Fix64)0.2m, localWheelRotation, wheelGraphicRotation, false),
                                 new WheelSuspension(2000, 100, Vector3.Down, (Fix64)0.325m, new Vector3((Fix64)(-1.1m), (Fix64)(-0.1m), (Fix64)1.8m)),
                                 new WheelDrivingMotor((Fix64)2.5m, 30000, 10000),
                                 new WheelBrake((Fix64)1.5m, 2, (Fix64).02m),
                                 new WheelSlidingFriction(4, 5)));
            Vehicle.AddWheel(new Wheel(
                                 new CylinderCastWheelShape((Fix64).375m, (Fix64)0.2m, localWheelRotation, wheelGraphicRotation, false),
                                 new WheelSuspension(2000, 100, Vector3.Down, (Fix64)0.325m, new Vector3((Fix64)(-1.1m), (Fix64)(-0.1m), (Fix64)(-1.8m))),
                                 new WheelDrivingMotor((Fix64)2.5m, 30000, 10000),
                                 new WheelBrake((Fix64)1.5m, 2, (Fix64).02m),
                                 new WheelSlidingFriction(4, 5)));
            Vehicle.AddWheel(new Wheel(
                                 new CylinderCastWheelShape((Fix64).375m, (Fix64)0.2m, localWheelRotation, wheelGraphicRotation, false),
                                 new WheelSuspension(2000, 100, Vector3.Down, (Fix64)0.325m, new Vector3((Fix64)1.1m, (Fix64)(-0.1m), (Fix64)1.8m)),
                                 new WheelDrivingMotor((Fix64)2.5m, 30000, 10000),
                                 new WheelBrake((Fix64)1.5m, 2, (Fix64).02m),
                                 new WheelSlidingFriction(4, 5)));
            Vehicle.AddWheel(new Wheel(
                                 new CylinderCastWheelShape((Fix64).375m, (Fix64)0.2m, localWheelRotation, wheelGraphicRotation, false),
                                 new WheelSuspension(2000, 100, Vector3.Down, (Fix64)0.325m, new Vector3((Fix64)1.1m, (Fix64)(-0.1m), (Fix64)(-1.8m))),
                                 new WheelDrivingMotor((Fix64)2.5m, 30000, 10000),
                                 new WheelBrake((Fix64)1.5m, 2, (Fix64).02m),
                                 new WheelSlidingFriction(4, 5)));


            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.
                //However, because the suspension and friction are not really rigid,
                //the lowered accuracy is not so much of a problem.
                wheel.Suspension.SolverSettings.MaximumIterationCount      = 1;
                wheel.Brake.SolverSettings.MaximumIterationCount           = 1;
                wheel.SlidingFriction.SolverSettings.MaximumIterationCount = 1;
                wheel.DrivingMotor.SolverSettings.MaximumIterationCount    = 1;
            }

            Space = space;

            Space.Add(Vehicle);
            ModelDrawer = drawer;
            DisplayModel model;

            WheelModels = new List <DisplayModel>();
            for (int k = 0; k < 4; 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, (Fix64)0.6m, 0), true, 10, camera, game);
        }
        /// <summary>
        /// Constructs a new demo.
        /// </summary>
        /// <param name="game">Game owning this demo.</param>
        public TerrainTestDemo(DemosGame game)
            : base(game)
        {
            //x and y, in terms of heightmaps, refer to their local x and y coordinates.  In world space, they correspond to x and z.
            //Setup the heights of the terrain.
            //int xLength = 384;
            //int zLength = 384;

            //float xSpacing = .5f;
            //float zSpacing = .5f;
            //var heights = new float[xLength, zLength];
            //for (int i = 0; i < xLength; i++)
            //{
            //    for (int j = 0; j < zLength; j++)
            //    {
            //        float x = i - xLength / 2;
            //        float z = j - zLength / 2;
            //        heights[i, j] = (float)(10 * (Math.Sin(x / 8) + Math.Sin(z / 8)));
            //    }
            //}
            ////Create the terrain.
            //var terrain = new Terrain(heights, new AffineTransform(
            //        new Vector3(xSpacing, 1, zSpacing),
            //        Quaternion.Identity,
            //        new Vector3(-xLength * xSpacing / 2, 0, -zLength * zSpacing / 2)));

            //Space.Add(terrain);
            //game.ModelDrawer.Add(terrain);

            for (int i = 0; i < 7; i++)
            {
                for (int j = 0; j < 3; j++)
                {
                    Space.Add(new Box(new Vector3(i * 50, -50, j * 50), 50, 20, 50));
                }
            }


            for (int i = 0; i < 20; i++)
            {
                for (int j = 0; j < 20; j++)
                {
                    CompoundBody cb = new CompoundBody(new CompoundShapeEntry[] 
                        {
                            new CompoundShapeEntry(new CapsuleShape(2, 1), new Vector3(0, 0,0)),
                            new CompoundShapeEntry(new CapsuleShape(2, 1), new Vector3(2, 0,0)),
                            new CompoundShapeEntry(new CapsuleShape(2, 1), new Vector3(4, 0,0)),
                            new CompoundShapeEntry(new CapsuleShape(2, 1), new Vector3(6, 0,0)),
                            new CompoundShapeEntry(new CapsuleShape(2, 1), new Vector3(8, 0,0)),
                            new CompoundShapeEntry(new CapsuleShape(2, 1), new Vector3(10, 0,0)),
                            new CompoundShapeEntry(new CapsuleShape(2, 1), new Vector3(12, 0,0)),
                        }, 10);
                    cb.Position = new Vector3(i * 15, 20, j * 5);

                    //CompoundBody cb = new CompoundBody(new CompoundShapeEntry[] 
                    //{
                    //    new CompoundShapeEntry(new SphereShape(1), new Vector3(0, 0,0)),
                    //    new CompoundShapeEntry(new SphereShape(1), new Vector3(2, -2,0)),
                    //    new CompoundShapeEntry(new SphereShape(1), new Vector3(4, 0,0)),
                    //    new CompoundShapeEntry(new SphereShape(1), new Vector3(6, -2,0)),
                    //    new CompoundShapeEntry(new SphereShape(1), new Vector3(8, 0,0)),
                    //    new CompoundShapeEntry(new SphereShape(1), new Vector3(10, -2,0)),
                    //    new CompoundShapeEntry(new SphereShape(1), new Vector3(12, 0,0)),
                    //}, 10);
                    //cb.Position = new Vector3(i * 15, 20, j * 5);

                    //CompoundBody cb = new CompoundBody(new CompoundShapeEntry[] 
                    //{
                    //    new CompoundShapeEntry(new CapsuleShape(0, 1), new Vector3(0, 0,0)),
                    //    new CompoundShapeEntry(new CapsuleShape(0, 1), new Vector3(2, -2,0)),
                    //    new CompoundShapeEntry(new CapsuleShape(0, 1), new Vector3(4, 0,0)),
                    //    new CompoundShapeEntry(new CapsuleShape(0, 1), new Vector3(6, -2,0)),
                    //    new CompoundShapeEntry(new CapsuleShape(0, 1), new Vector3(8, 0,0)),
                    //    new CompoundShapeEntry(new CapsuleShape(0, 1), new Vector3(10, -2,0)),
                    //    new CompoundShapeEntry(new CapsuleShape(0, 1), new Vector3(12, 0,0)),
                    //}, 10);
                    //cb.Position = new Vector3(i * 15, 20, j * 5);

                    cb.ActivityInformation.IsAlwaysActive = true;
                    cb.AngularVelocity = new Vector3(.01f, 0, 0);

                    Space.Add(cb);
                }
            }



            game.Camera.Position = new Vector3(0, 30, 20);

        }
예제 #27
0
        /// <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);

        }
예제 #28
0
        /// <summary>
        /// Constructs a new demo.
        /// </summary>
        /// <param name="game">Game owning this demo.</param>
        public CharacterPlaygroundDemo(DemosGame game)
            : base(game)
        {
            game.Camera.Position = new Microsoft.Xna.Framework.Vector3(-10, 7, 5);
            game.Camera.Yaw      = MathHelper.Pi;
            //Since this is the character playground, turn on the character by default.
            character.Activate();
            //Having the character body visible would be a bit distracting.
            character.CharacterController.Body.Tag = "noDisplayObject";

            //Load in mesh data for the environment.
            Vector3[] staticTriangleVertices;
            int[]     staticTriangleIndices;


            var playgroundModel = game.Content.Load <Model>("CharacterControllerTestTerrain");

            //This load method wraps the TriangleMesh.GetVerticesAndIndicesFromModel method
            //to output vertices of type StaticTriangleGroupVertex instead of TriangleMeshVertex or simply Vector3.
            ModelDataExtractor.GetVerticesAndIndicesFromModel(playgroundModel, out staticTriangleVertices, out staticTriangleIndices);
            var staticMesh = new StaticMesh(staticTriangleVertices, staticTriangleIndices, new AffineTransform(new Vector3(.01f, .01f, .01f), Quaternion.Identity, new Vector3(0, 0, 0)));

            staticMesh.Sidedness = TriangleSidedness.Counterclockwise;

            Space.Add(staticMesh);
            game.ModelDrawer.Add(staticMesh);



            //Add a spinning blade for the character to ram itself into.
            var fanBase  = new Cylinder(new Vector3(-13, .5f, 50), 1.1f, 1);
            var fanBlade = new Box(fanBase.Position + new Vector3(0, .8f, 0), 5, .1f, 1f, 5);
            var fanJoint = new RevoluteJoint(fanBase, fanBlade, (fanBase.Position + fanBlade.Position) * .5f, Vector3.Up);

            fanJoint.Motor.IsActive = true;
            fanJoint.Motor.Settings.VelocityMotor.GoalVelocity = 30;
            fanJoint.Motor.Settings.MaximumForce = 300;
            Space.Add(fanBase);
            Space.Add(fanBlade);
            Space.Add(fanJoint);

            //Add a bridge connecting the two towers.
            Vector3 startPosition = new Vector3(-19.3f, 10.5f - .25f, 23 - .85f);
            var     startPlatform = new Box(startPosition - new Vector3(0, 0, 2.2f), 4, .5f, 6);

            Space.Add(startPlatform);
            Vector3 offset       = new Vector3(0, 0, 1.7f);
            Box     previousLink = startPlatform;
            Vector3 position     = new Vector3();

            for (int i = 1; i <= 7; i++)
            {
                position = startPosition + offset * i;
                Box link = new Box(position, 3, .3f, 1.5f, 50);
                link.LinearDamping  = .1f;
                link.AngularDamping = .1f;
                Space.Add(link);
                Space.Add(new RevoluteJoint(previousLink, link, position - offset * .5f, Vector3.Right));

                previousLink = link;
            }
            var endPlatform = new Box(position - new Vector3(0, 0, -3.8f), 4, .5f, 6);

            Space.Add(endPlatform);

            Space.Add(new RevoluteJoint(previousLink, endPlatform, position + offset * .5f, Vector3.Right));


            //Add in a floating platform controlled by a curve to serve as an elevator.
            Entity movingEntity = new Box(new Vector3(-10, 0, -10), 3, 1, 3);

            var positionCurve = new CardinalSpline3D();

            positionCurve.PreLoop  = CurveEndpointBehavior.Mirror;
            positionCurve.PostLoop = CurveEndpointBehavior.Mirror;

            positionCurve.ControlPoints.Add(-1, new Vector3(-19.3f, 0, 43));
            positionCurve.ControlPoints.Add(0, new Vector3(-19.3f, 0, 43));
            positionCurve.ControlPoints.Add(2, new Vector3(-19.3f, 0, 43));
            positionCurve.ControlPoints.Add(3, new Vector3(-19.3f, 0, 43));
            positionCurve.ControlPoints.Add(4, new Vector3(-19.3f, 5, 43));
            positionCurve.ControlPoints.Add(5f, new Vector3(-19.3f, 10, 43));
            positionCurve.ControlPoints.Add(6f, new Vector3(-19.3f, 10, 43));
            positionCurve.ControlPoints.Add(8f, new Vector3(-19.3f, 10, 43));
            positionCurve.ControlPoints.Add(9f, new Vector3(-19.3f, 10, 43));

            elevatorMover = new EntityMover(movingEntity);
            Space.Add(elevatorMover);
            Space.Add(movingEntity);

            elevatorPath = positionCurve;

            //Add in another floating platform controlled by a curve for horizontal transport.
            movingEntity = new Box(new Vector3(-10, 0, -10), 2.5f, .5f, 2.5f);

            var platformCurve = new LinearInterpolationCurve3D();

            platformCurve.PreLoop  = CurveEndpointBehavior.Mirror;
            platformCurve.PostLoop = CurveEndpointBehavior.Mirror;

            platformCurve.ControlPoints.Add(0, new Vector3(-1.75f, 10, 21.5f));
            platformCurve.ControlPoints.Add(2, new Vector3(-1.75f, 10, 21.5f));
            platformCurve.ControlPoints.Add(5, new Vector3(-1.75f, 10, 15.5f));
            platformCurve.ControlPoints.Add(10, new Vector3(-19.3f, 10, 15.5f));
            platformCurve.ControlPoints.Add(12, new Vector3(-19.3f, 10, 15.5f));
            platformCurve.ControlPoints.Add(15, new Vector3(-25, 10, 15.5f));
            platformCurve.ControlPoints.Add(22, new Vector3(-25, 10, 38));
            platformCurve.ControlPoints.Add(23, new Vector3(-22.75f, 10, 38));
            platformCurve.ControlPoints.Add(25, new Vector3(-22.75f, 10, 38));

            //Make it spin too.  That'll be fun.  Or something.
            var platformRotationCurve = new QuaternionSlerpCurve();

            platformRotationCurve.PreLoop  = CurveEndpointBehavior.Mirror;
            platformRotationCurve.PostLoop = CurveEndpointBehavior.Mirror;
            platformRotationCurve.ControlPoints.Add(0, Quaternion.Identity);
            platformRotationCurve.ControlPoints.Add(15, Quaternion.Identity);
            platformRotationCurve.ControlPoints.Add(22, Quaternion.CreateFromAxisAngle(Vector3.Up, MathHelper.PiOver2));
            platformRotationCurve.ControlPoints.Add(25, Quaternion.CreateFromAxisAngle(Vector3.Up, MathHelper.PiOver2));

            platformMover   = new EntityMover(movingEntity);
            platformRotator = new EntityRotator(movingEntity);
            Space.Add(platformMover);
            Space.Add(platformRotator);
            Space.Add(movingEntity);

            platformPath            = platformCurve;
            platformOrientationPath = platformRotationCurve;

            //Add in a diving board.

            Box divingBoardBase  = new Box(new Vector3(-9, 10, 39.3f), 5, 1, 3);
            Box divingBoard      = new Box(divingBoardBase.Position + new Vector3(-2, 0, 3.5f), 1, .3f, 3, 5);
            var divingBoardJoint = new RevoluteJoint(divingBoardBase, divingBoard, divingBoard.Position + new Vector3(0, 0, -1.5f), Vector3.Right);

            divingBoardJoint.Motor.IsActive            = true;
            divingBoardJoint.Motor.Settings.Mode       = MotorMode.Servomechanism;
            divingBoardJoint.Motor.Settings.Servo.Goal = 0;
            divingBoardJoint.Motor.Settings.Servo.SpringSettings.StiffnessConstant = 5000;
            divingBoardJoint.Motor.Settings.Servo.SpringSettings.DampingConstant   = 0;

            Space.Add(divingBoardBase);
            Space.Add(divingBoard);
            Space.Add(divingBoardJoint);


            //Add a second diving board for comparison.

            Box divingBoard2      = new Box(divingBoardBase.Position + new Vector3(2, 0, 5f), 1, .3f, 6, 5);
            var divingBoardJoint2 = new RevoluteJoint(divingBoardBase, divingBoard2, divingBoard2.Position + new Vector3(0, 0, -3), Vector3.Right);

            divingBoardJoint2.Motor.IsActive            = true;
            divingBoardJoint2.Motor.Settings.Mode       = MotorMode.Servomechanism;
            divingBoardJoint2.Motor.Settings.Servo.Goal = 0;
            divingBoardJoint2.Motor.Settings.Servo.SpringSettings.StiffnessConstant = 10000;
            divingBoardJoint2.Motor.Settings.Servo.SpringSettings.DampingConstant   = 0;

            Space.Add(divingBoard2);
            Space.Add(divingBoardJoint2);

            //Add a seesaw for people to jump on.
            Box           seesawBase  = new Box(new Vector3(-7, .45f, 52), 1, .9f, .3f);
            Box           seesawPlank = new Box(seesawBase.Position + new Vector3(0, .65f, 0), 1.2f, .2f, 6, 3);
            RevoluteJoint seesawJoint = new RevoluteJoint(seesawBase, seesawPlank, seesawPlank.Position, Vector3.Right);

            Space.Add(seesawJoint);
            Space.Add(seesawBase);
            Space.Add(seesawPlank);

            Space.Add(new Box(seesawPlank.Position + new Vector3(0, 1.3f, 2), 1, 1, 1, 5));


            //Add in some boxes to bump and jump on.
            int   numColumns = 3;
            int   numRows    = 3;
            int   numHigh    = 3;
            float xSpacing   = 1.01f;
            float ySpacing   = 1.01f;
            float zSpacing   = 1.01f;

            for (int i = 0; i < numRows; i++)
            {
                for (int j = 0; j < numColumns; j++)
                {
                    for (int k = 0; k < numHigh; k++)
                    {
                        Space.Add(new Box(new Vector3(
                                              5 + xSpacing * i - (numRows - 1) * xSpacing / 2f,
                                              1.58f + k * (ySpacing),
                                              45 + zSpacing * j - (numColumns - 1) * zSpacing / 2f),
                                          .5f, .5f, .5f, 5));
                    }
                }
            }



            //Add a log to roll!
            //Make it a compound so some boxes can be added to let the player know it's actually spinning.
            CompoundBody log = new CompoundBody(new List <CompoundShapeEntry>()
            {
                new CompoundShapeEntry(new CylinderShape(4, 1.8f), Quaternion.CreateFromAxisAngle(Vector3.Forward, MathHelper.PiOver2), 20),
                new CompoundShapeEntry(new BoxShape(.5f, .5f, 3.7f), new Vector3(1.75f, 0, 0), 0),
                new CompoundShapeEntry(new BoxShape(.5f, 3.7f, .5f), new Vector3(1.75f, 0, 0), 0),
                new CompoundShapeEntry(new BoxShape(.5f, .5f, 3.7f), new Vector3(-1.75f, 0, 0), 0),
                new CompoundShapeEntry(new BoxShape(.5f, 3.7f, .5f), new Vector3(-1.75f, 0, 0), 0)
            }, 50);

            log.Position       = new Vector3(-14.5f, 10, 41);
            log.AngularDamping = 0;


            RevoluteJoint logJointA = new RevoluteJoint(divingBoardBase, log, log.Position + new Vector3(2.5f, 0, 0), Vector3.Right);
            RevoluteJoint logJointB = new RevoluteJoint(endPlatform, log, log.Position + new Vector3(-2.5f, 0, 0), Vector3.Right);

            Space.Add(logJointA);
            Space.Add(logJointB);

            Space.Add(log);


            //Put some planks to stand on that show various slopes.
            int numPads = 10;

            for (int i = 0; i < numPads; i++)
            {
                offset = new Vector3(0, 0, 4);
                Box   a     = new Box(new Vector3(i * 1.5f + 3.5f, 10, 24), 1.5f, 1, 4);
                Box   b     = new Box(new Vector3(i * 1.5f + 3.5f, 10, 24), 1.5f, 1, 4);
                float angle = -i * MathHelper.PiOver2 / numPads;
                b.Orientation = Quaternion.CreateFromAxisAngle(Vector3.Right, angle);
                b.Position   += offset * .5f + Vector3.Transform(offset * .5f, b.Orientation);

                Space.Add(a);
                Space.Add(b);
            }
        }
예제 #29
0
        /// <summary>
        /// Constructs the front end and the internal physics representation of the Vehicle.
        /// </summary>
        /// <param name="position">Position of the Vehicle.</param>
        /// <param name="owningSpace">Space to add the Vehicle to.</param>
        /// <param name="cameraToUse">Camera to attach to the Vehicle.</param>
        /// <param name="drawer">Drawer used to draw the Vehicle.</param>
        /// <param name="wheelModel">Model of the wheels.</param>
        /// <param name="wheelTexture">Texture to use for the wheels.</param>
        public VehicleInput(Vector3 position, Space owningSpace, Camera cameraToUse, ModelDrawer drawer, Model wheelModel, Texture2D wheelTexture)
        {
            var bodies = new List <CompoundShapeEntry>()
            {
                new CompoundShapeEntry(new BoxShape(2.5f, .75f, 4.5f), new Vector3(0, 0, 0), 60),
                new CompoundShapeEntry(new BoxShape(2.5f, .3f, 2f), new Vector3(0, .75f / 2 + .3f / 2, .5f), 1)
            };
            var body = new CompoundBody(bodies, 61);

            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.
            Matrix wheelGraphicRotation = Matrix.CreateFromAxisAngle(Vector3.Forward, MathHelper.PiOver2);
            Vehicle.AddWheel(new Wheel(
                                 new RaycastWheelShape(.375f, wheelGraphicRotation),
                                 new WheelSuspension(2000, 100f, Vector3.Down, .8f, new Vector3(-1.1f, 0, 1.8f)),
                                 new WheelDrivingMotor(2.5f, 30000, 10000),
                                 new WheelBrake(1.5f, 2, .02f),
                                 new WheelSlidingFriction(4, 5)));
            Vehicle.AddWheel(new Wheel(
                                 new RaycastWheelShape(.375f, wheelGraphicRotation),
                                 new WheelSuspension(2000, 100f, Vector3.Down, .8f, new Vector3(-1.1f, 0, -1.8f)),
                                 new WheelDrivingMotor(2.5f, 30000, 10000),
                                 new WheelBrake(1.5f, 2, .02f),
                                 new WheelSlidingFriction(4, 5)));
            Vehicle.AddWheel(new Wheel(
                                 new RaycastWheelShape(.375f, wheelGraphicRotation),
                                 new WheelSuspension(2000, 100f, Vector3.Down, .8f, new Vector3(1.1f, 0, 1.8f)),
                                 new WheelDrivingMotor(2.5f, 30000, 10000),
                                 new WheelBrake(1.5f, 2, .02f),
                                 new WheelSlidingFriction(4, 5)));
            Vehicle.AddWheel(new Wheel(
                                 new RaycastWheelShape(.375f, wheelGraphicRotation),
                                 new WheelSuspension(2000, 100f, Vector3.Down, .8f, new Vector3(1.1f, 0, -1.8f)),
                                 new WheelDrivingMotor(2.5f, 30000, 10000),
                                 new WheelBrake(1.5f, 2, .02f),
                                 new WheelSlidingFriction(4, 5)));

            #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.
                //However, because the suspension and friction are not really rigid,
                //the lowered accuracy is not so much of a problem.
                wheel.Suspension.SolverSettings.MaximumIterations      = 1;
                wheel.Brake.SolverSettings.MaximumIterations           = 1;
                wheel.SlidingFriction.SolverSettings.MaximumIterations = 1;
                wheel.DrivingMotor.SolverSettings.MaximumIterations    = 1;
            }

            Space = owningSpace;

            Space.Add(Vehicle);
            ModelDrawer = drawer;
            DisplayModel model;
            WheelModels = new List <DisplayModel>();
            for (int k = 0; k < 4; k++)
            {
                Vehicle.Wheels[k].Shape.Detector.Tag = "noDisplayObject";
                model = new DisplayModel(wheelModel, ModelDrawer);
                ModelDrawer.Add(model);
                WheelModels.Add(model);
                model.Texture = wheelTexture;
            }


            Camera = cameraToUse;
        }
예제 #30
0
        /// <summary>
        /// Constructs a new demo.
        /// </summary>
        /// <param name="game">Game owning this demo.</param>
        public MutableCompoundDemo(DemosGame game)
            : base(game)
        {
            List<CompoundShapeEntry> shapes = new List<CompoundShapeEntry>();
            float totalWeight = 0;
            float density = 10;

            float weight = density * 2;
            totalWeight += weight;
            for (int i = 0; i < 4; i++)
            {
                shapes.Add(new CompoundShapeEntry(
                    new BoxShape(1, 1, 2),
                    new RigidTransform(
                    new Vector3(-.5f + i * 1, 0, 15),
                    Quaternion.CreateFromAxisAngle(Vector3.Forward, MathHelper.PiOver2 * 2))
                    //Quaternion.Identity)
                    , weight));
            }

            var compound = new CompoundBody(shapes, totalWeight);
            //compound.Orientation = Quaternion.CreateFromYawPitchRoll(1, 1, 1);
            //compound.AngularVelocity = new Vector3(0, 1, 0);
            Entity<CompoundCollidable> compound2, compound3;
            CompoundHelper.SplitCompound(x => x.ShapeIndex >= shapes.Count / 2, compound, out compound2);
            CompoundHelper.SplitCompound(x => x.ShapeIndex >= 3 * shapes.Count / 4, compound2, out compound3);

            //compound.ActivityInformation.IsAlwaysActive = true;
            //compound.IsAffectedByGravity = false;
            //compound2.ActivityInformation.IsAlwaysActive = true;
            //compound2.IsAffectedByGravity = false;
            //compound3.ActivityInformation.IsAlwaysActive = true;
            //compound3.IsAffectedByGravity = false;
            //compound.Tag = "noDisplayObject";
            Space.Add(compound);
            Space.Add(compound2);
            Space.Add(compound3);

            int width = 3;
            int height = 3;
            int length = 10;
            float blockWidth = 1f;
            float blockHeight = 1f;
            float blockLength = 1f;

            for (int q = 0; q < 1; q++)
            {
                shapes.Clear();
                totalWeight = 0;
                density = 1;

                for (int i = 0; i < width; i++)
                {
                    for (int j = 0; j < height; j++)
                    {
                        for (int k = 0; k < length; k++)
                        {
                            weight = density * blockWidth * blockLength * blockHeight;
                            totalWeight += weight;
                            shapes.Add(new CompoundShapeEntry(
                                new BoxShape(blockWidth, blockHeight, blockLength),
                                new RigidTransform(
                                new Vector3(5 + q * 20 + i * blockWidth, j * blockHeight, k * blockLength),
                                //Quaternion.CreateFromAxisAngle(Vector3.Forward, MathHelper.PiOver2))
                                Quaternion.Identity)
                                , weight));
                        }
                    }
                }

                compound = new CompoundBody(shapes, totalWeight);
                //compound.Orientation = Quaternion.CreateFromYawPitchRoll(1, 1, 1);
                //compound.AngularVelocity = new Vector3(0, 1, 0);
                CompoundHelper.SplitCompound(x => x.ShapeIndex >= shapes.Count / 2, compound, out compound2);
                CompoundHelper.SplitCompound(x => x.ShapeIndex >= 3 * shapes.Count / 4, compound2, out compound3);

                //compound.ActivityInformation.IsAlwaysActive = true;
                //compound.IsAffectedByGravity = false;
                //compound2.ActivityInformation.IsAlwaysActive = true;
                //compound2.IsAffectedByGravity = false;
                //compound3.ActivityInformation.IsAlwaysActive = true;
                //compound3.IsAffectedByGravity = false;
                //compound.Tag = "noDisplayObject";
                Space.Add(compound);
                Space.Add(compound2);
                Space.Add(compound3);

            }

            Box ground = new Box(new Vector3(0, -4.5f, 0), 50, 1, 50);
            Space.Add(ground);
            game.Camera.Position = new Vector3(0, 6, 15);
        }
예제 #31
0
        /// <summary>
        /// Constructs a new demo.
        /// </summary>
        /// <param name="game">Game owning this demo.</param>
        public UnfortunateGuyDemo(DemosGame game)
            : base(game)
        {
            Entity ground = new Box(Vector3.Zero, 10, 1, 10);
            Space.Add(ground);

            //Rather than add basically redundant code for every limb, this demo
            //focuses on a single arm, showing some extra details and limits.

            //Make the torso.
            var bodies = new List<CompoundShapeEntry>()
            {
                new CompoundShapeEntry(new BoxShape(2, 1.5f, 1), new Vector3(-1, 3, 0), 50),
                new CompoundShapeEntry(new SphereShape(.45f), new Vector3(.4f, 3, 0), 1),
                new CompoundShapeEntry(new SphereShape(.25f), new Vector3(-1.9f, 3.5f, 0), 1),
                new CompoundShapeEntry(new SphereShape(.25f), new Vector3(-1.9f, 2.5f, 0), 1),
                new CompoundShapeEntry(new SphereShape(.25f), new Vector3(-.3f, 2.3f, 0), 1)
            };

            var torso = new CompoundBody(bodies, 54);
            Space.Add(torso);

            //Make the upper arm.
            Entity upperArm = new Box(torso.Position + new Vector3(1, 1.4f, 0), .4f, 1.2f, .4f, 8);
            Space.Add(upperArm);

            //A ball socket joint will handle the linear degrees of freedom between the two entities.
            var ballSocketJoint = new BallSocketJoint(torso, upperArm, torso.Position + new Vector3(1, .7f, 0));
            Space.Add(ballSocketJoint);

            //Shoulders don't have a simple limit.  The EllipseSwingLimit allows angles within an ellipse, which is closer to how some joints function
            //than just flat planes (like two RevoluteLimits) or a single angle (like SwingLimits).
            var swingLimit = new EllipseSwingLimit(torso, upperArm, Vector3.Up, MathHelper.PiOver2, MathHelper.PiOver4 * 3);
            Space.Add(swingLimit);

            //Upper arms can't spin around forever.
            var twistLimit = new TwistLimit(torso, upperArm, Vector3.Up, Vector3.Up, -MathHelper.PiOver4 / 2, MathHelper.PiOver4);
            twistLimit.SpringSettings.StiffnessConstant = 100;
            twistLimit.SpringSettings.DampingConstant = 100;
            Space.Add(twistLimit);

            //Make the lower arm.
            Entity lowerArm = new Box(upperArm.Position + new Vector3(0, 1.4f, 0), .35f, 1.3f, .35f, 8);
            Space.Add(lowerArm);

            var elbow = new SwivelHingeJoint(upperArm, lowerArm, upperArm.Position + new Vector3(0, .6f, 0), Vector3.Forward);
            //Forearm can twist a little.
            elbow.TwistLimit.IsActive = true;
            elbow.TwistLimit.MinimumAngle = -MathHelper.PiOver4 / 2;
            elbow.TwistLimit.MaximumAngle = MathHelper.PiOver4 / 2;
            elbow.TwistLimit.SpringSettings.DampingConstant = 100;
            elbow.TwistLimit.SpringSettings.StiffnessConstant = 100;

            //The elbow is like a hinge, but it can't hyperflex.
            elbow.HingeLimit.IsActive = true;
            elbow.HingeLimit.MinimumAngle = 0;
            elbow.HingeLimit.MaximumAngle = MathHelper.Pi * .7f;
            Space.Add(elbow);

            Entity hand = new Box(lowerArm.Position + new Vector3(0, .9f, 0), .4f, .55f, .25f, 3);
            Space.Add(hand);

            ballSocketJoint = new BallSocketJoint(lowerArm, hand, lowerArm.Position + new Vector3(0, .7f, 0));
            Space.Add(ballSocketJoint);

            //Wrists can use an ellipse limit too.
            swingLimit = new EllipseSwingLimit(lowerArm, hand, Vector3.Up, MathHelper.PiOver4, MathHelper.PiOver2);
            Space.Add(swingLimit);

            //Allow a little extra twist beyond the forearm.
            twistLimit = new TwistLimit(lowerArm, hand, Vector3.Up, Vector3.Up, -MathHelper.PiOver4 / 2, MathHelper.PiOver4 / 2);
            twistLimit.SpringSettings.StiffnessConstant = 100;
            twistLimit.SpringSettings.DampingConstant = 100;
            Space.Add(twistLimit);

            //The hand is pretty floppy without some damping.
            var angularMotor = new AngularMotor(lowerArm, hand);
            angularMotor.Settings.VelocityMotor.Softness = .5f;
            Space.Add(angularMotor);

            //Make sure the parts of the arm don't collide.
            CollisionRules.AddRule(torso, upperArm, CollisionRule.NoBroadPhase);
            CollisionRules.AddRule(lowerArm, upperArm, CollisionRule.NoBroadPhase);
            CollisionRules.AddRule(lowerArm, hand, CollisionRule.NoBroadPhase);

            game.Camera.Position = new Vector3(0, 4, 20);
        }
예제 #32
0
        private void constructPhysicsBody()
        {
            ConvexHullShape hull = new ConvexHullShape(importPhysicsHull());
            hull.CollisionMargin = 0.6f;
            var bodies = new List<CompoundShapeEntry>()
                {
                    new CompoundShapeEntry(hull, Vector3.Zero, 25f)
                };

            physicsEntityBody = new CompoundBody(bodies, 60f);
            //body.CollisionInformation.LocalPosition = new Vector3(0, .5f, 0);//Moves center of gravity position to adjust stability.

            physicsEntityBody.IsAlwaysActive = true;

            //physicsBody.CenterOfMassOffset = new Vector3(0, 0f, 0);//Becareful with this as forces/impulses act from here including raycasts
            physicsEntityBody.LinearDamping = 0.5f;//As there is rarely friction must slow ship down every update
            physicsEntityBody.AngularDamping = 0.94f;
            physicsEntityBody.Material.KineticFriction = 2f;

            physicsEntityBody.PositionUpdateMode = PositionUpdateMode.Continuous;

            physicsEntityBody.CollisionInformation.Events.ContactCreated += new ContactCreatedEventHandler<EntityCollidable>(Events_InitialCollisionDetected);

            Physics.space.Add(physicsEntityBody);
        }
        /// <summary>
        /// Constructs a new demo.
        /// </summary>
        /// <param name="game">Game owning this demo.</param>
        public MutableCompoundDemo(DemosGame game)
            : base(game)
        {
            List <CompoundShapeEntry> shapes = new List <CompoundShapeEntry>();
            Fix64 totalWeight = 0;
            Fix64 density     = 10;


            Fix64 weight = density * 2;

            totalWeight += weight;
            for (int i = 0; i < 4; i++)
            {
                shapes.Add(new CompoundShapeEntry(
                               new BoxShape(1, 1, 2),
                               new RigidTransform(
                                   new Vector3(-.5m + i * 1, 0, 15),
                                   Quaternion.CreateFromAxisAngle(Vector3.Forward, MathHelper.PiOver2 * 2))
                               //Quaternion.Identity)
                               , weight));
            }



            var compound = new CompoundBody(shapes, totalWeight);
            //compound.Orientation = Quaternion.CreateFromYawPitchRoll(1, 1, 1);
            //compound.AngularVelocity = new Vector3(0, 1, 0);
            Entity <CompoundCollidable> compound2, compound3;

            CompoundHelper.SplitCompound(x => x.ShapeIndex >= shapes.Count / 2, compound, out compound2);
            CompoundHelper.SplitCompound(x => x.ShapeIndex >= 3 * shapes.Count / 4, compound2, out compound3);



            //compound.ActivityInformation.IsAlwaysActive = true;
            //compound.IsAffectedByGravity = false;
            //compound2.ActivityInformation.IsAlwaysActive = true;
            //compound2.IsAffectedByGravity = false;
            //compound3.ActivityInformation.IsAlwaysActive = true;
            //compound3.IsAffectedByGravity = false;
            //compound.Tag = "noDisplayObject";
            Space.Add(compound);
            Space.Add(compound2);
            Space.Add(compound3);


            int   width       = 3;
            int   height      = 3;
            int   length      = 10;
            Fix64 blockWidth  = 1;
            Fix64 blockHeight = 1;
            Fix64 blockLength = 1;



            for (int q = 0; q < 1; q++)
            {
                shapes.Clear();
                totalWeight = 0;
                density     = 1;

                for (int i = 0; i < width; i++)
                {
                    for (int j = 0; j < height; j++)
                    {
                        for (int k = 0; k < length; k++)
                        {
                            weight       = density * blockWidth * blockLength * blockHeight;
                            totalWeight += weight;
                            shapes.Add(new CompoundShapeEntry(
                                           new BoxShape(blockWidth, blockHeight, blockLength),
                                           new RigidTransform(
                                               new Vector3(5 + q * 20 + i * blockWidth, j * blockHeight, k * blockLength),
                                               //Quaternion.CreateFromAxisAngle(Vector3.Forward, MathHelper.PiOver2))
                                               Quaternion.Identity)
                                           , weight));
                        }
                    }
                }

                compound = new CompoundBody(shapes, totalWeight);
                //compound.Orientation = Quaternion.CreateFromYawPitchRoll(1, 1, 1);
                //compound.AngularVelocity = new Vector3(0, 1, 0);
                CompoundHelper.SplitCompound(x => x.ShapeIndex >= shapes.Count / 2, compound, out compound2);
                CompoundHelper.SplitCompound(x => x.ShapeIndex >= 3 * shapes.Count / 4, compound2, out compound3);



                //compound.ActivityInformation.IsAlwaysActive = true;
                //compound.IsAffectedByGravity = false;
                //compound2.ActivityInformation.IsAlwaysActive = true;
                //compound2.IsAffectedByGravity = false;
                //compound3.ActivityInformation.IsAlwaysActive = true;
                //compound3.IsAffectedByGravity = false;
                //compound.Tag = "noDisplayObject";
                Space.Add(compound);
                Space.Add(compound2);
                Space.Add(compound3);
            }

            Box ground = new Box(new Vector3(0, -4.5m, 0), 50, 1, 50);

            Space.Add(ground);
            game.Camera.Position = new Vector3(0, 6, 15);
        }
예제 #34
0
            public override void Init(int nGPU)
            {
                //Testing scene

                /*
                 * Owner.Space = new Space();
                 * Owner.Space.ForceUpdater.Gravity = new Vector3(0, -9.81f, 0);
                 *
                 * Box ground = new Box(new Vector3(0, -0.55f, 0), 30, 1, 30);
                 * Owner.Space.Add(ground);
                 *
                 * Owner.Space.Add(new Box(new Vector3(0.3f, 4, 0), 1, 1, 1, 1));
                 * Owner.Space.Add(new Box(new Vector3(0, 8, 0.3f), 1, 1, 1, 1));
                 * Owner.Space.Add(new Box(new Vector3(-0.3f, 12, 0), 1, 1, 1, 1));
                 *
                 * Owner.Space.Add(new Cylinder(new Vector3(0.7f, 15, 0), 2, 1, 1));
                 *
                 * Owner.Space.Add(new Cone(new Vector3(-0.5f, 18, 0.3f), 2, 1, 1));
                 *
                 * Owner.Space.Add(new Sphere(new Vector3(2, 10, 0), 1, 1));
                 * */

                //Robot arm scene

                Owner.Space = new Space();
                Owner.Space.ForceUpdater.Gravity = new Vector3(0, -9.81f, 0);
                Entity ground = new Box(Vector3.Zero, 30, 1, 30);

                Owner.Space.Add(ground);

                var armBase = new Cylinder(new Vector3(0, 2, 0), 2.5f, 1, 40);

                Owner.Space.Add(armBase);

                //The arm base can rotate around the Y axis.
                //Rotation is controlled by user input.
                groundToBaseJoint = new RevoluteJoint(ground, armBase, Vector3.Zero, Vector3.Up);
                groundToBaseJoint.Motor.IsActive              = true;
                groundToBaseJoint.Motor.Settings.Mode         = MotorMode.Servomechanism;
                groundToBaseJoint.Motor.Settings.MaximumForce = 3500;
                Owner.Space.Add(groundToBaseJoint);

                Entity lowerArm = new Box(armBase.Position + new Vector3(0, 2, 0), 1, 3, .5f, 10);

                Owner.Space.Add(lowerArm);

                shoulder = new RevoluteJoint(armBase, lowerArm, armBase.Position, Vector3.Forward);
                shoulder.Motor.IsActive              = true;
                shoulder.Motor.Settings.Mode         = MotorMode.Servomechanism;
                shoulder.Motor.Settings.MaximumForce = 2500;

                //Don't want it to rotate too far; this keeps the whole contraption off the ground.
                shoulder.Limit.IsActive     = true;
                shoulder.Limit.MinimumAngle = -MathHelper.Pi / 3.0f;
                shoulder.Limit.MaximumAngle = MathHelper.Pi / 3.0f;
                Owner.Space.Add(shoulder);

                //Make the next piece of the arm.
                Entity upperArm = new Cylinder(lowerArm.Position + new Vector3(0, 3, 0), 3, .25f, 10);

                Owner.Space.Add(upperArm);

                //Swivel hinges allow motion around two axes.  Imagine a tablet PC's monitor hinge.
                elbow = new SwivelHingeJoint(lowerArm, upperArm, lowerArm.Position + new Vector3(0, 1.5f, 0), Vector3.Forward);
                elbow.TwistMotor.IsActive              = true;
                elbow.TwistMotor.Settings.Mode         = MotorMode.Servomechanism;
                elbow.TwistMotor.Settings.MaximumForce = 1000;

                elbow.HingeMotor.IsActive              = true;
                elbow.HingeMotor.Settings.Mode         = MotorMode.Servomechanism;
                elbow.HingeMotor.Settings.MaximumForce = 1250;

                //Keep it from rotating too much.
                elbow.HingeLimit.IsActive     = true;
                elbow.HingeLimit.MinimumAngle = -MathHelper.PiOver2;
                elbow.HingeLimit.MaximumAngle = MathHelper.PiOver2;
                Owner.Space.Add(elbow);


                //Add a menacing claw at the end.
                var lowerPosition = upperArm.Position + new Vector3(-.65f, 1.6f, 0);

                CollisionRules clawPart1ARules = new CollisionRules();
                var            bodies          = new List <CompoundChildData>()
                {
                    new CompoundChildData()
                    {
                        Entry = new CompoundShapeEntry(new BoxShape(1, .25f, .25f), lowerPosition, 3), CollisionRules = clawPart1ARules
                    },
                    new CompoundChildData()
                    {
                        Entry = new CompoundShapeEntry(new ConeShape(1, .125f), lowerPosition + new Vector3(-.375f, .4f, 0), 3), Material = new Material(2, 2, 0)
                    }
                };

                var claw = new CompoundBody(bodies, 6);

                Owner.Space.Add(claw);

                clawHingeA = new RevoluteJoint(upperArm, claw, upperArm.Position + new Vector3(0, 1.5f, 0), Vector3.Forward);
                clawHingeA.Motor.IsActive            = true;
                clawHingeA.Motor.Settings.Mode       = MotorMode.Servomechanism;
                clawHingeA.Motor.Settings.Servo.Goal = -MathHelper.PiOver2;
                //Weaken the claw to prevent it from crushing the boxes.
                clawHingeA.Motor.Settings.Servo.SpringSettings.Damping   /= 100;
                clawHingeA.Motor.Settings.Servo.SpringSettings.Stiffness /= 100;

                clawHingeA.Limit.IsActive     = true;
                clawHingeA.Limit.MinimumAngle = -MathHelper.PiOver2;
                clawHingeA.Limit.MaximumAngle = -MathHelper.Pi / 6;
                Owner.Space.Add(clawHingeA);

                //Add one more claw to complete the contraption.
                lowerPosition = upperArm.Position + new Vector3(.65f, 1.6f, 0);

                CollisionRules clawPart1BRules = new CollisionRules();

                bodies = new List <CompoundChildData>()
                {
                    new CompoundChildData()
                    {
                        Entry = new CompoundShapeEntry(new BoxShape(1, .25f, .25f), lowerPosition, 3), CollisionRules = clawPart1BRules
                    },
                    new CompoundChildData()
                    {
                        Entry = new CompoundShapeEntry(new ConeShape(1, .125f), lowerPosition + new Vector3(.375f, .4f, 0), 3), Material = new Material(2, 2, 0)
                    }
                };
                claw = new CompoundBody(bodies, 6);
                Owner.Space.Add(claw);

                clawHingeB = new RevoluteJoint(upperArm, claw, upperArm.Position + new Vector3(0, 1.5f, 0), Vector3.Forward);
                clawHingeB.Motor.IsActive            = true;
                clawHingeB.Motor.Settings.Mode       = MotorMode.Servomechanism;
                clawHingeB.Motor.Settings.Servo.Goal = MathHelper.PiOver2;
                //Weaken the claw to prevent it from crushing the boxes.
                clawHingeB.Motor.Settings.Servo.SpringSettings.Damping   /= 100;
                clawHingeB.Motor.Settings.Servo.SpringSettings.Stiffness /= 100;

                clawHingeB.Limit.IsActive     = true;
                clawHingeB.Limit.MinimumAngle = MathHelper.Pi / 6;
                clawHingeB.Limit.MaximumAngle = MathHelper.PiOver2;
                Owner.Space.Add(clawHingeB);

                //Keep the pieces of the robot from interacting with each other.
                //The CollisionRules.AddRule method is just a convenience method that adds items to the 'specific' dictionary.
                //Sometimes, it's a little unwieldy to reference the collision rules,
                //so the convenience method just takes the owners and hides the ugly syntax.
                CollisionRules.AddRule(armBase, lowerArm, CollisionRule.NoBroadPhase);
                CollisionRules.AddRule(lowerArm, upperArm, CollisionRule.NoBroadPhase);
                CollisionRules.AddRule(clawPart1ARules, upperArm, CollisionRule.NoBroadPhase);
                CollisionRules.AddRule(clawPart1BRules, upperArm, CollisionRule.NoBroadPhase);
                //Here's an example without a convenience method.  Since they are both direct CollisionRules references, it's pretty clean.
                clawPart1BRules.Specific.Add(clawPart1ARules, CollisionRule.NoBroadPhase);

                //Put some boxes on the ground to try to pick up.
                for (double k = 0; k < Math.PI * 2; k += Math.PI / 6)
                {
                    Box box = new Box(new Vector3((float)Math.Cos(k) * 5.5f, 2, (float)Math.Sin(k) * 5.5f), 1, 1, 1, 10);
                    box.Tag = Color.LightCoral;

                    Owner.Space.Add(box);
                }
            }
예제 #35
0
 public static Entity GetEntity(Vector3 position, UInt16 index)
 {
     switch (index)
     {
         case 0: //Terrain
             return new Box(position, 750, 5, 750);
         case 1: //Building
             return new Box(position, 30, 16, 30);
         case 2: //UL Core
             Entity shape = new CompoundBody(
                 new List<CompoundShapeEntry>
                 {
                     new CompoundShapeEntry(new BoxShape(.85f * 2, .85f * 2, 1 * 2),float.MaxValue),
                     new CompoundShapeEntry(new BoxShape(4.4f * 2, 0.05f * 2, 1 * 2),new Vector3(0,0.85f,0))
                 }, 50
                 );
             shape.Position = position;
             return shape;
         case 3: //UL Nose
             return new Box(position, .75f * 2, 1f * 2, .75f * 2, 20);
         case 4: //UL Engine
             return new Box(position, .6f * 2, .95f * 2, 0.425f * 2, 20);
         case 5: //L Core
             shape = new CompoundBody(
                 new List<CompoundShapeEntry>
                 {
                     new CompoundShapeEntry(new BoxShape(2, 2, 2),float.MaxValue),
                     new CompoundShapeEntry(new BoxShape(8, 2, 0.2f),new Vector3(0,0,0))
                 }, 50
                 );
             shape.Position = position;
             return shape;
         case 6: //L Nose
             return new Box(position, 1.35f, 1.6f, 1.6f);
         case 7: //L Engine
             return new Box(position, 1.8f, 1.4f, 1.05f);
         default:
             return new Box(position, 1, 1, 1);
     }
 }
예제 #36
0
        private void SetupVehicle()
        {
            float width  = 2.5f;
            float height = 0.75f;
            float length = 4.5f;
            float scale  = 1f;

            var vehicleShape = new ProceduralCuboid(width / 2 * scale, length / 2 * scale, height / 2 * scale);

            vehicleShape.Translate(new Vector3(0, 0.5f, 0));
            vehicleShape.SetColor(Color.Red);
            vehicleObject = GameObjectFactory.CreateRenderableGameObjectFromShape(vehicleShape, EffectLoader.LoadSM5Effect("flatshaded"));
            vehicleObject.AddComponent(new ShadowCasterComponent());
            SystemCore.GameObjectManager.AddAndInitialiseGameObject(vehicleObject);


            ProceduralSphere cyl = new ProceduralSphere(10, 10);

            cyl.Scale(0.375f * scale);
            //cyl.Transform(Matrix.CreateRotationZ(MathHelper.PiOver2));
            wheel1 = GameObjectFactory.CreateRenderableGameObjectFromShape(cyl, EffectLoader.LoadSM5Effect("flatshaded"));
            SystemCore.GameObjectManager.AddAndInitialiseGameObject(wheel1);



            var bodies = new List <CompoundShapeEntry>
            {
                new CompoundShapeEntry(new BoxShape(width * scale, height * scale, length * scale), new BEPUutilities.Vector3(0, 0, 0), 60),
                //new CompoundShapeEntry(new BoxShape(2.5f, .3f, 2f), new BEPUutilities.Vector3(0, .75f / 2 + .3f / 2, .5f), 1)
            };
            var body = new CompoundBody(bodies, 61);

            body.CollisionInformation.LocalPosition = new BEPUutilities.Vector3(0, .5f, 0);
            body.Position = new BEPUutilities.Vector3(10, 20, 10);
            testVehicle   = new Vehicle(body);

            BEPUutilities.Quaternion localWheelRotation   = BEPUutilities.Quaternion.Identity;
            BEPUutilities.Matrix     wheelGraphicRotation = BEPUutilities.Matrix.Identity;
            testVehicle.AddWheel(new Wheel(
                                     new CylinderCastWheelShape(.375f * scale, 0.2f * scale, localWheelRotation, wheelGraphicRotation, false),
                                     new WheelSuspension(2000, 100f, BEPUutilities.Vector3.Down, 0.325f, new BEPUutilities.Vector3(-1.1f, -0.1f, 1.8f)),
                                     new WheelDrivingMotor(2.5f, 30000, 10000),
                                     new WheelBrake(1.5f, 2, .02f),
                                     new WheelSlidingFriction(4, 5)));
            testVehicle.AddWheel(new Wheel(
                                     new CylinderCastWheelShape(.375f * scale, 0.2f * scale, localWheelRotation, wheelGraphicRotation, false),
                                     new WheelSuspension(2000, 100f, BEPUutilities.Vector3.Down, 0.325f, new BEPUutilities.Vector3(-1.1f, -0.1f, -1.8f)),
                                     new WheelDrivingMotor(2.5f, 30000, 10000),
                                     new WheelBrake(1.5f, 2, .02f),
                                     new WheelSlidingFriction(4, 5)));
            testVehicle.AddWheel(new Wheel(
                                     new CylinderCastWheelShape(.375f * scale, 0.2f * scale, localWheelRotation, wheelGraphicRotation, false),
                                     new WheelSuspension(2000, 100f, BEPUutilities.Vector3.Down, 0.325f, new BEPUutilities.Vector3(1.1f, -0.1f, 1.8f)),
                                     new WheelDrivingMotor(2.5f, 30000, 10000),
                                     new WheelBrake(1.5f, 2, .02f),
                                     new WheelSlidingFriction(4, 5)));
            testVehicle.AddWheel(new Wheel(
                                     new CylinderCastWheelShape(.375f * scale, 0.2f * scale, localWheelRotation, wheelGraphicRotation, false),
                                     new WheelSuspension(2000, 100f, BEPUutilities.Vector3.Down, 0.325f, new BEPUutilities.Vector3(1.1f, -0.1f, -1.8f)),
                                     new WheelDrivingMotor(2.5f, 30000, 10000),
                                     new WheelBrake(1.5f, 2, .02f),
                                     new WheelSlidingFriction(4, 5)));

            foreach (Wheel wheel in testVehicle.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.
                //However, because the suspension and friction are not really rigid,
                //the lowered accuracy is not so much of a problem.
                wheel.Suspension.SolverSettings.MaximumIterationCount      = 1;
                wheel.Brake.SolverSettings.MaximumIterationCount           = 1;
                wheel.SlidingFriction.SolverSettings.MaximumIterationCount = 1;
                wheel.DrivingMotor.SolverSettings.MaximumIterationCount    = 1;
            }

            SystemCore.PhysicsSimulation.Add(testVehicle);
        }
        /// <summary>
        /// Constructs a new demo.
        /// </summary>
        /// <param name="game">Game owning this demo.</param>
        public RobotArmDemo(DemosGame game)
            : base(game)
        {
            //Since this is not a "StandardDemo" derived class, we need to set our own gravity.
            Space.ForceUpdater.Gravity = new Vector3(0, -9.81f, 0);
            Entity ground = new Box(Vector3.Zero, 30, 1, 30);

            Space.Add(ground);

            var armBase = new Cylinder(new Vector3(0, 2, 0), 2.5f, 1, 40);

            Space.Add(armBase);

            //The arm base can rotate around the Y axis.
            //Rotation is controlled by user input.
            groundToBaseJoint = new RevoluteJoint(ground, armBase, Vector3.Zero, Vector3.Up);
            groundToBaseJoint.Motor.IsActive              = true;
            groundToBaseJoint.Motor.Settings.Mode         = MotorMode.VelocityMotor;
            groundToBaseJoint.Motor.Settings.MaximumForce = 3500;
            Space.Add(groundToBaseJoint);

            lowerArm = new Box(armBase.Position + new Vector3(0, 2, 0), 1, 3, .5f, 10);
            Space.Add(lowerArm);

            shoulder = new RevoluteJoint(armBase, lowerArm, armBase.Position, Vector3.Forward);
            shoulder.Motor.IsActive              = true;
            shoulder.Motor.Settings.Mode         = MotorMode.VelocityMotor;
            shoulder.Motor.Settings.MaximumForce = 2500;

            //Don't want it to rotate too far; this keeps the whole contraption off the ground.
            shoulder.Limit.IsActive     = true;
            shoulder.Limit.MinimumAngle = 0;
            shoulder.Limit.MaximumAngle = MathHelper.PiOver4;
            Space.Add(shoulder);

            //Make the next piece of the arm.
            upperArm = new Cylinder(lowerArm.Position + new Vector3(0, 3, 0), 3, .25f, 10);
            Space.Add(upperArm);

            //Swivel hinges allow motion around two axes.  Imagine a tablet PC's monitor hinge.
            elbow = new SwivelHingeJoint(lowerArm, upperArm, lowerArm.Position + new Vector3(0, 1.5f, 0), Vector3.Forward);
            elbow.TwistMotor.IsActive              = true;
            elbow.TwistMotor.Settings.Mode         = MotorMode.VelocityMotor;
            elbow.TwistMotor.Settings.MaximumForce = 1000;

            elbow.HingeMotor.IsActive              = true;
            elbow.HingeMotor.Settings.Mode         = MotorMode.VelocityMotor;
            elbow.HingeMotor.Settings.MaximumForce = 1250;

            //Keep it from rotating too much.
            elbow.HingeLimit.IsActive     = true;
            elbow.HingeLimit.MinimumAngle = 0;
            elbow.HingeLimit.MaximumAngle = MathHelper.PiOver2;
            Space.Add(elbow);


            //Add a menacing claw at the end.
            var lowerPosition = upperArm.Position + new Vector3(-.65f, 1.6f, 0);

            CollisionRules clawPart1ARules = new CollisionRules();
            var            bodies          = new List <CompoundChildData>()
            {
                new CompoundChildData()
                {
                    Entry = new CompoundShapeEntry(new BoxShape(1, .25f, .25f), lowerPosition, 3), CollisionRules = clawPart1ARules
                },
                new CompoundChildData()
                {
                    Entry = new CompoundShapeEntry(new ConeShape(1, .125f), lowerPosition + new Vector3(-.375f, .4f, 0), 3), Material = new Material(2, 2, 0)
                }
            };

            leftClaw = new CompoundBody(bodies, 6);
            Space.Add(leftClaw);

            clawHingeA = new RevoluteJoint(upperArm, leftClaw, upperArm.Position + new Vector3(0, 1.5f, 0), Vector3.Forward);
            clawHingeA.Motor.IsActive            = true;
            clawHingeA.Motor.Settings.Mode       = MotorMode.VelocityMotor;
            clawHingeA.Motor.Settings.Servo.Goal = -MathHelper.PiOver2;
            //Weaken the claw to prevent it from crushing the boxes.
            clawHingeA.Motor.Settings.Servo.SpringSettings.Damping   /= 100;
            clawHingeA.Motor.Settings.Servo.SpringSettings.Stiffness /= 100;

            clawHingeA.Limit.IsActive     = true;
            clawHingeA.Limit.MinimumAngle = -MathHelper.PiOver2;
            clawHingeA.Limit.MaximumAngle = -MathHelper.Pi / 6;
            Space.Add(clawHingeA);

            //Add one more claw to complete the contraption.
            lowerPosition = upperArm.Position + new Vector3(.65f, 1.6f, 0);

            CollisionRules clawPart1BRules = new CollisionRules();

            bodies = new List <CompoundChildData>()
            {
                new CompoundChildData()
                {
                    Entry = new CompoundShapeEntry(new BoxShape(1, .25f, .25f), lowerPosition, 3), CollisionRules = clawPart1BRules
                },
                new CompoundChildData()
                {
                    Entry = new CompoundShapeEntry(new ConeShape(1, .125f), lowerPosition + new Vector3(.375f, .4f, 0), 3), Material = new Material(2, 2, 0)
                }
            };

            rightClaw = new CompoundBody(bodies, 6);
            Space.Add(rightClaw);

            clawHingeB = new RevoluteJoint(upperArm, rightClaw, upperArm.Position + new Vector3(0, 1.5f, 0), Vector3.Forward);
            clawHingeB.Motor.IsActive            = true;
            clawHingeB.Motor.Settings.Mode       = MotorMode.VelocityMotor;
            clawHingeB.Motor.Settings.Servo.Goal = MathHelper.PiOver2;
            //Weaken the claw to prevent it from crushing the boxes.
            clawHingeB.Motor.Settings.Servo.SpringSettings.Damping   /= 100;
            clawHingeB.Motor.Settings.Servo.SpringSettings.Stiffness /= 100;

            clawHingeB.Limit.IsActive     = true;
            clawHingeB.Limit.MinimumAngle = MathHelper.Pi / 6;
            clawHingeB.Limit.MaximumAngle = MathHelper.PiOver2;
            Space.Add(clawHingeB);

            //Keep the pieces of the robot from interacting with each other.
            //The CollisionRules.AddRule method is just a convenience method that adds items to the 'specific' dictionary.
            //Sometimes, it's a little unwieldy to reference the collision rules,
            //so the convenience method just takes the owners and hides the ugly syntax.
            CollisionRules.AddRule(armBase, lowerArm, CollisionRule.NoBroadPhase);
            CollisionRules.AddRule(lowerArm, upperArm, CollisionRule.NoBroadPhase);
            CollisionRules.AddRule(clawPart1ARules, upperArm, CollisionRule.NoBroadPhase);
            CollisionRules.AddRule(clawPart1BRules, upperArm, CollisionRule.NoBroadPhase);
            //Here's an example without a convenience method.  Since they are both direct CollisionRules references, it's pretty clean.
            clawPart1BRules.Specific.Add(clawPart1ARules, CollisionRule.NoBroadPhase);


            //Put some boxes on the ground to try to pick up.
            for (double k = 0; k < Math.PI * 2; k += Math.PI / 6)
            {
                //Space.Add(new Box(new Vector3((float)Math.Cos(k) * 5.5f, 2, (float)Math.Sin(k) * 5.5f), 1, 1, 1, 10));
            }

            game.Camera.Position = new Vector3(0, 5, 13);



            logisticFunction = new ManagedLogisticFunction();
            input            = new ManagedMemoryBlock(9);
            target           = new ManagedMemoryBlock(3);

            network           = new ManagedSimpleRecurrentNetwork(9, 256, 3, logisticFunction);
            learningAlgorithm = new ManagedTBPTT(network, 0.005f, 0.9f, 4);
        }
예제 #38
0
        /// <summary>
        /// Constructs a new demo.
        /// </summary>
        /// <param name="game">Game owning this demo.</param>
        public RobotArmDemo(DemosGame game)
            : base(game)
        {
            //Since this is not a "StandardDemo" derived class, we need to set our own gravity.
            Space.ForceUpdater.Gravity = new Vector3(0, -9.81f, 0);
            Entity ground = new Box(Vector3.Zero, 30, 1, 30);
            Space.Add(ground);

            var armBase = new Cylinder(new Vector3(0, 2, 0), 2.5f, 1, 40);
            Space.Add(armBase);

            //The arm base can rotate around the Y axis.
            //Rotation is controlled by user input.
            groundToBaseJoint = new RevoluteJoint(ground, armBase, Vector3.Zero, Vector3.Up);
            groundToBaseJoint.Motor.IsActive = true;
            groundToBaseJoint.Motor.Settings.Mode = MotorMode.Servomechanism;
            groundToBaseJoint.Motor.Settings.MaximumForce = 3500;
            Space.Add(groundToBaseJoint);

            Entity lowerArm = new Box(armBase.Position + new Vector3(0, 2, 0), 1, 3, .5f, 10);
            Space.Add(lowerArm);

            shoulder = new RevoluteJoint(armBase, lowerArm, armBase.Position, Vector3.Forward);
            shoulder.Motor.IsActive = true;
            shoulder.Motor.Settings.Mode = MotorMode.Servomechanism;
            shoulder.Motor.Settings.MaximumForce = 2500;

            //Don't want it to rotate too far; this keeps the whole contraption off the ground.
            shoulder.Limit.IsActive = true;
            shoulder.Limit.MinimumAngle = -MathHelper.PiOver4;
            shoulder.Limit.MaximumAngle = MathHelper.PiOver4;
            Space.Add(shoulder);

            //Make the next piece of the arm.
            Entity upperArm = new Cylinder(lowerArm.Position + new Vector3(0, 3, 0), 3, .25f, 10);
            Space.Add(upperArm);

            //Swivel hinges allow motion around two axes.  Imagine a tablet PC's monitor hinge.
            elbow = new SwivelHingeJoint(lowerArm, upperArm, lowerArm.Position + new Vector3(0, 1.5f, 0), Vector3.Forward);
            elbow.TwistMotor.IsActive = true;
            elbow.TwistMotor.Settings.Mode = MotorMode.Servomechanism;
            elbow.TwistMotor.Settings.MaximumForce = 1000;

            elbow.HingeMotor.IsActive = true;
            elbow.HingeMotor.Settings.Mode = MotorMode.Servomechanism;
            elbow.HingeMotor.Settings.MaximumForce = 1250;

            //Keep it from rotating too much.
            elbow.HingeLimit.IsActive = true;
            elbow.HingeLimit.MinimumAngle = -MathHelper.PiOver2;
            elbow.HingeLimit.MaximumAngle = MathHelper.PiOver2;
            Space.Add(elbow);


            //Add a menacing claw at the end.
            var lowerPosition = upperArm.Position + new Vector3(-.65f, 1.6f, 0);

            CollisionRules clawPart1ARules = new CollisionRules();
            var bodies = new List<CompoundChildData>()
            {
                new CompoundChildData() { Entry = new CompoundShapeEntry(new BoxShape(1, .25f, .25f), lowerPosition, 3), CollisionRules = clawPart1ARules },
                new CompoundChildData() { Entry = new CompoundShapeEntry(new ConeShape(1, .125f), lowerPosition + new Vector3(-.375f, .4f, 0), 3), Material = new Material(2,2,0) }
            };

            var claw = new CompoundBody(bodies, 6);
            Space.Add(claw);

            clawHingeA = new RevoluteJoint(upperArm, claw, upperArm.Position + new Vector3(0, 1.5f, 0), Vector3.Forward);
            clawHingeA.Motor.IsActive = true;
            clawHingeA.Motor.Settings.Mode = MotorMode.Servomechanism;
            clawHingeA.Motor.Settings.Servo.Goal = -MathHelper.PiOver2;
            //Weaken the claw to prevent it from crushing the boxes.
            clawHingeA.Motor.Settings.Servo.SpringSettings.DampingConstant /= 100;
            clawHingeA.Motor.Settings.Servo.SpringSettings.StiffnessConstant /= 100;

            clawHingeA.Limit.IsActive = true;
            clawHingeA.Limit.MinimumAngle = -MathHelper.PiOver2;
            clawHingeA.Limit.MaximumAngle = -MathHelper.Pi / 6;
            Space.Add(clawHingeA);

            //Add one more claw to complete the contraption.
            lowerPosition = upperArm.Position + new Vector3(.65f, 1.6f, 0);

            CollisionRules clawPart1BRules = new CollisionRules();
            bodies = new List<CompoundChildData>()
            {
                new CompoundChildData() { Entry = new CompoundShapeEntry(new BoxShape(1, .25f, .25f), lowerPosition, 3), CollisionRules = clawPart1BRules },
                new CompoundChildData() { Entry = new CompoundShapeEntry(new ConeShape(1, .125f), lowerPosition + new Vector3(.375f, .4f, 0), 3), Material = new Material(2,2,0) }
            };
            claw = new CompoundBody(bodies, 6);
            Space.Add(claw);

            clawHingeB = new RevoluteJoint(upperArm, claw, upperArm.Position + new Vector3(0, 1.5f, 0), Vector3.Forward);
            clawHingeB.Motor.IsActive = true;
            clawHingeB.Motor.Settings.Mode = MotorMode.Servomechanism;
            clawHingeB.Motor.Settings.Servo.Goal = MathHelper.PiOver2;
            //Weaken the claw to prevent it from crushing the boxes.
            clawHingeB.Motor.Settings.Servo.SpringSettings.DampingConstant /= 100;
            clawHingeB.Motor.Settings.Servo.SpringSettings.StiffnessConstant /= 100;

            clawHingeB.Limit.IsActive = true;
            clawHingeB.Limit.MinimumAngle = MathHelper.Pi / 6;
            clawHingeB.Limit.MaximumAngle = MathHelper.PiOver2;
            Space.Add(clawHingeB);

            //Keep the pieces of the robot from interacting with each other.
            //The CollisionRules.AddRule method is just a convenience method that adds items to the 'specific' dictionary.
            //Sometimes, it's a little unwieldy to reference the collision rules,
            //so the convenience method just takes the owners and hides the ugly syntax.
            CollisionRules.AddRule(armBase, lowerArm, CollisionRule.NoBroadPhase);
            CollisionRules.AddRule(lowerArm, upperArm, CollisionRule.NoBroadPhase);
            CollisionRules.AddRule(clawPart1ARules, upperArm, CollisionRule.NoBroadPhase);
            CollisionRules.AddRule(clawPart1BRules, upperArm, CollisionRule.NoBroadPhase);
            //Here's an example without a convenience method.  Since they are both direct CollisionRules references, it's pretty clean.
            clawPart1BRules.Specific.Add(clawPart1ARules, CollisionRule.NoBroadPhase);


            //Put some boxes on the ground to try to pick up.
            for (double k = 0; k < Math.PI * 2; k += Math.PI / 6)
            {
                Space.Add(new Box(new Vector3((float)Math.Cos(k) * 5.5f, 2, (float)Math.Sin(k) * 5.5f), 1, 1, 1, 10));
            }

            game.Camera.Position = new Vector3(0, 5, 13);
        }
        /// <summary>
        /// Constructs a new demo.
        /// </summary>
        /// <param name="game">Game owning this demo.</param>
        public EntityConstructionDemo(DemosGame game)
            : base(game)
        {
            //An entity is the basic physical simulation object in BEPUphysics.  It represents a rigid body which can be dynamic or kinematic.
            //Dynamic objects can bounce around and respond to collisions using forces.  Kinematic entities can move using velocity,
            //but effectively have infinite inertia and do not respond to collisions or forces.

            //For each of the below constructors, there are multiple overloads.  Half have a mass parameter, half do not.  If a mass parameter is specified,
            //the object is created as a dynamic object.  If a mass parameter is not specified, it is created as a kinematic object.  This state can be changed later
            //by using the BecomeDynamic/BecomeKinematic methods.


            //************************
            //There are a variety of ways to construct entities depending on your needs.
            //The most common approach is to use the 'prefab' types, like the Box, Sphere, ConvexHull, Cylinder, and so on (BEPUphysics.Entities.Prefabs namespace).
            //These provide a short cut to constructing the objects and generally provide convenience accessors to shape properties.

            //We'll start with such an entity for the kinematic ground.  Notice how it allows the definition of position and shape data all in the constructor.
            //It has other overloads that allow you to specify a mass (for a dynamic object) or a full MotionState instead of just a position.
            Box ground = new Box(new Vector3(0, -.5f, 0), 50, 1, 50);

            Space.Add(ground);

            //If you examine the ground's CollisionInformation property, you'll find that it is a generic method which returns a ConvexCollidable<BoxShape>.
            //So, in addition to having convenience properties, it also lets you go deeper into the object's data by knowing what the types are.


            //************************
            //Let's go one level up the hierarchy to Entity<T>.  This is the superclass of all prefab types.
            //The generic parameter is the type of the Collidable that the entity uses as its collision proxy.
            //It is also what allows prefab types' CollisionInformation property to return that type rather than EntityCollidable.

            Space.Add(new Entity <ConvexCollidable <SphereShape> >(new ConvexCollidable <SphereShape>(new SphereShape(1)), 1)
            {
                Position = new Vector3(-10, 1, 0)
            });

            //That's a bit unwieldy<<>><>, but it works.  Directly constructing entities in this manner isn't common or generally necessary.
            //If you want to have a CollisionInformation property that returns a specific type but don't want to use a specific prefab type, this is the way to go.

            //Note that the constructor itself does not include any position/motion state parameters nor does it include any direct shape data.  The position and other auxiliary
            //properties can be set after it's been constructed.  In this case, object initializer syntax is used to set the Position.
            //The shape data is included within the first EntityCollidable parameter which defines the entity's collision proxy.
            //The prefab types discussed previously all create such EntityCollidables internally using the data passed into the constructor.


            //************************
            //So let's move onto something a little more convenient.  Entity<T> has a non-generic parent Entity.  It still has a CollisionInformation property,
            //but it returns an EntityCollidable rather than a specific type.

            Space.Add(new Entity(new BoxShape(2, 2, 2), 1)
            {
                Position = new Vector3(10, 1, 0)
            });

            //Much better! No more ugly generic type syntax pollution.  Notice that there are quite a few overloads in the Entity.
            //In addition to overloads that accept EntityCollidable instances (as used in the generic entity above), Entity provides constructors that
            //take shapes directly.  Internally, the entity can create its own EntityCollidable instance based on the shape.  This further simplifies the construction process.

            //An object initializer is once again used to set the position, since the constructors do not have all the convenience constructor frills of the prefab types.


            //************************
            //All of the above entity types have read-only CollisionInformation properties.  Once an entity of those types is created, it cannot change its fundamental shape.
            //A sphere may get bigger or smaller, but a sphere entity couldn't become a box entity.

            //That's where the MorphableEntity comes in.

            var morphable = new MorphableEntity(new CylinderShape(2, 1), 1)
            {
                Position = new Vector3(10, 3, 0)
            };

            Space.Add(morphable);

            //It is constructed identically to its parent Entity class, but after being created, the EntityCollidable it uses can change!
            morphable.CollisionInformation = new ConvexCollidable <ConeShape>(new ConeShape(2, 1));

            //That's neat, but that collidable constructor with generic type is a bit ugly.  We don't care about doing any type-specific configuration
            //on the EntityCollidable itself, so we can just tell the shape to make us an EntityCollidable instance.  This is what the Entity/MorphableEntity constructors
            //do internally when given an EntityShape instead of an EntityCollidable (which in turn contains an EntityShape).
            morphable.CollisionInformation = new ConeShape(2, 1).GetCollidableInstance();

            //While this is arguably a bit prettier, its major benefit comes from the fact that you don't need to know the type of the shape to call GetCollidableInstance.
            //If it's an EntityShape, it can create an EntityCollidable for itself.



            //************************
            //That's it for the different types of entities.  Another very useful technique is to share shapes and initialization between entities.
            //Re-using convex hulls is a common use case.  They have a fairly expensive initialization, and they tend to be some of the larger shapes memory-wise.
            //Rather than having a thousand redundant copies of identical geometry, one shape can be made and reused for subsequent entities.

            //First, create the pointset that composes the convex hull.
            var vertices = new[]
            {
                new Vector3(-1, 0, -1),
                new Vector3(-1, 0, 1),
                new Vector3(1, 0, -1),
                new Vector3(1, 0, 1),
                new Vector3(0, 2, 0)
            };
            //Construct the shape itself.
            var convexHullShape = new ConvexHullShape(vertices);

            //Create an entity using the shape.
            var convexHull = new Entity(convexHullShape, 2)
            {
                Position = new Vector3(0, 1, 0)
            };

            Space.Add(convexHull);
            //Create a bunch of other shapes using that first shape's properties.
            //Instead of using a first entity's data, this could also be pulled in from some external source (deserialized save data or something).
            for (int i = 1; i <= 10; i++)
            {
                Space.Add(new Entity(convexHullShape, convexHull.Mass, convexHull.LocalInertiaTensor)
                {
                    Position = new Vector3(0, 1 + i * 3, 0)
                });
            }

            //In older versions, initializing the entity was a little expensive if the inertia tensor and some other data wasn't provided.
            //These days, the cost is done once in the shape and the entity initialization is pretty much always super cheap.
            //So, you don't need to share inertia tensors for performance reasons.

            //************************
            //All convex shapes are centered on their local origin.  If you create a box entity and assign its position to (0,1,0), the box shape's center will end up at (0,1,0).
            //For simple shapes like the box, that's always the case without doing any work just based on the definition of the shape.

            //More complicated shapes, like the ConvexHullShape, can be constructed from data which is not initially centered around the origin.  For example, consider these vertices:
            vertices = new[]
            {
                new Vector3(-5, 15, -1),
                new Vector3(-5, 15, 1),
                new Vector3(-3, 15, -1),
                new Vector3(-3, 15, 1),
                new Vector3(-4, 17, 0),
                new Vector3(-4, 13, 0)
            };
            //The center of those points is obviously going to be very far from the origin.
            //When we construct a ConvexHullShape, the points get 'recentered.'
            convexHullShape = new ConvexHullShape(vertices);

            //If you look at the convexHullShape.Vertices list, you'll see that the points are relative to a local origin now.
            //So now it's centered on the local origin, as was needed.  But there's a problem- what if you wanted your convex hull entity to end up at the original vertex positions?
            //To get it there, we need to know the offset from the original vertices to the local vertices.
            //Fortunately, there is a constructor overload which provides it!
            Vector3 center;

            convexHullShape = new ConvexHullShape(vertices, out center);

            //Now, when the entity is created, we can position it at the original point's center.  The shape still contains local data, but the entity's location ends up putting the shape in the right spot.
            convexHull = new Entity(convexHullShape, 2)
            {
                Position = center
            };
            Space.Add(convexHull);


            //************************
            //Compound bodies are unique in that they allow you to specify groups of shapes to create a concave shape.
            //Here's the common simple approach to making a compound body, using a prefab type for now.
            CompoundBody body = new CompoundBody(new List <CompoundShapeEntry>
            {
                new CompoundShapeEntry(new BoxShape(1, 1, 1), new Vector3(-7, 3, 8), 1),
                new CompoundShapeEntry(new BoxShape(1, 3, 1), new Vector3(-8, 2, 8), 5),
                new CompoundShapeEntry(new BoxShape(1, 1, 1), new Vector3(-9, 1, 8), 1)
            }, 10);

            Space.Add(body);
            //Each entry has a shape, a rigid transform (orientation and/or translation), and a weight.
            //The rigid transform defines the position of the shape in world space.  They will be recentered into local space within the CompoundShape itself (see previous convex hull example).
            //The 'weight' parameter does not correspond directly to mass, but rather to the contribution of that shape to the whole relative to other shapes.
            //It used to compute the center position of the shape.  When used by a dynamic entity, it is also used to compute a proper inertia tensor.  The resulting inertia tensor is scaled by the entity's actual mass.


            //************************
            //Just like shapes can be shared between entities, you can re-use a shape for multiple entries within a compound body.
            var compoundShape = new CompoundShape(new List <CompoundShapeEntry>
            {
                new CompoundShapeEntry(convexHullShape, new Vector3(7, 3, 8), 1),
                new CompoundShapeEntry(convexHullShape, new RigidTransform(new Vector3(8, 2, 8), Quaternion.CreateFromAxisAngle(Vector3.Forward, MathHelper.PiOver2)), 5),
                new CompoundShapeEntry(convexHullShape, new Vector3(9, 1, 8), 1)
            });

            //And just like normal convex shapes can be shared, so can compound shapes!
            for (int i = 0; i < 3; i++)
            {
                Space.Add(new Entity(compoundShape, 10)
                {
                    Position = new Vector3(8, 10 + i * 4, 8)
                });
            }

            //************************
            //You can also use compound shapes as subshapes, creating nested compounds.
            Space.Add(new Entity(new CompoundShape(new List <CompoundShapeEntry>
            {
                new CompoundShapeEntry(compoundShape, new Vector3(7, 5, 8), 1),
                new CompoundShapeEntry(compoundShape, new Vector3(9, 1, 8), 1)
            }), 10)
            {
                Position = new Vector3(8, 25, 8)
            });


            //************************
            //Sometimes, it's nice to be able to change how subshapes behave.
            //This example will use a prefab CompoundBody type, but note that there exists a CompoundCollidable that can be constructed independently as well.
            //Just like a list of CompoundShapeEntry objects can be used to construct a compound object, a list of CompoundChildData objects can too.
            //CompoundChildData objects contain CompoundShapeEntry objects as well as other data to be used by a Collidable instance.
            //That extra data includes material, events, and collision rules.

            var compoundBody = new CompoundBody(new List <CompoundChildData>
            {
                new CompoundChildData {
                    Entry = new CompoundShapeEntry(new CylinderShape(1, 1), new Vector3(0, 2, 8)), CollisionRules = new CollisionRules {
                        Personal = CollisionRule.NoBroadPhase
                    }
                },
                new CompoundChildData {
                    Entry = new CompoundShapeEntry(new BoxShape(3, 1, 3), new Vector3(0, 1, 8)), Material = new Material(3, 3, 0)
                }
            }, 10);

            Space.Add(compoundBody);

            //In this example, one of the two blocks doesn't collide with anything.  The other does collide, and has a very high friction material.

            //************************
            //While sharing shapes can help reduce load times, sometimes it's useful to eliminate the shape's initialization cost too.
            //For this purpose, all shapes have a constructor which takes a bunch of data that fully defines the shape.
            //The constructor assumes that all of it is correct; it won't catch any errors or do any additional preprocessing.

            //For example, let's construct a ConvexHullShape from the our earlier ConvexHullShape.
            //We'll need a ConvexShapeDescription that defines the data common to all convex shapes.
            var shapeDescription = new ConvexShapeDescription
            {
                CollisionMargin   = convexHullShape.CollisionMargin,
                MinimumRadius     = convexHullShape.MinimumRadius,
                MaximumRadius     = convexHullShape.MaximumRadius,
                EntityShapeVolume = new EntityShapeVolumeDescription
                {
                    Volume             = convexHullShape.Volume,
                    VolumeDistribution = convexHullShape.VolumeDistribution
                }
            };

            //Now, along with the surface vertices from the previous shape, the new shape can be created:
            var shapeFromCachedData = new ConvexHullShape(convexHullShape.Vertices, shapeDescription);

            //Usually, the data for these constructors will come from some cache or storage. For example,
            //a game could store out the above information to disk from a content development tool.
            //At load time, the matching shape can be created at virtually no cost.

            //Stuff the shape into the world!
            Space.Add(new Entity(shapeFromCachedData, 10)
            {
                Position = new Vector3(-10, 5, -5)
            });

            Game.Camera.Position = new Vector3(0, 3, 25);
        }
예제 #40
0
        /// <summary>
        /// Constructs a new demo.
        /// </summary>
        /// <param name="game">Game owning this demo.</param>
        public UnfortunateGuyDemo(DemosGame game)
            : base(game)
        {
            Entity ground = new Box(Vector3.Zero, 10, 1, 10);

            Space.Add(ground);

            //Rather than add basically redundant code for every limb, this demo
            //focuses on a single arm, showing some extra details and limits.

            //Make the torso.
            var bodies = new List <CompoundShapeEntry>()
            {
                new CompoundShapeEntry(new BoxShape(2, 1.5m, 1), new Vector3(-1, 3, 0), 50),
                new CompoundShapeEntry(new SphereShape(.45m), new Vector3(.4m, 3, 0), 1),
                new CompoundShapeEntry(new SphereShape(.25m), new Vector3(-1.9m, 3.5m, 0), 1),
                new CompoundShapeEntry(new SphereShape(.25m), new Vector3(-1.9m, 2.5m, 0), 1),
                new CompoundShapeEntry(new SphereShape(.25m), new Vector3(-.3m, 2.3m, 0), 1)
            };

            var torso = new CompoundBody(bodies, 54);

            Space.Add(torso);

            //Make the upper arm.
            Entity upperArm = new Box(torso.Position + new Vector3(1, 1.4m, 0), .4m, 1.2m, .4m, 8);

            Space.Add(upperArm);


            //A ball socket joint will handle the linear degrees of freedom between the two entities.
            var ballSocketJoint = new BallSocketJoint(torso, upperArm, torso.Position + new Vector3(1, .7m, 0));

            Space.Add(ballSocketJoint);

            //Shoulders don't have a simple limit.  The EllipseSwingLimit allows angles within an ellipse, which is closer to how some joints function
            //than just flat planes (like two RevoluteLimits) or a single angle (like SwingLimits).
            var swingLimit = new EllipseSwingLimit(torso, upperArm, Vector3.Up, MathHelper.PiOver2, MathHelper.PiOver4 * 3);

            Space.Add(swingLimit);

            //Upper arms can't spin around forever.
            var twistLimit = new TwistLimit(torso, upperArm, Vector3.Up, Vector3.Up, -MathHelper.PiOver4 / 2, MathHelper.PiOver4);

            twistLimit.SpringSettings.Stiffness = 100;
            twistLimit.SpringSettings.Damping   = 100;
            Space.Add(twistLimit);


            //Make the lower arm.
            Entity lowerArm = new Box(upperArm.Position + new Vector3(0, 1.4m, 0), .35m, 1.3m, .35m, 8);

            Space.Add(lowerArm);


            var elbow = new SwivelHingeJoint(upperArm, lowerArm, upperArm.Position + new Vector3(0, .6m, 0), Vector3.Forward);

            //Forearm can twist a little.
            elbow.TwistLimit.IsActive                 = true;
            elbow.TwistLimit.MinimumAngle             = -MathHelper.PiOver4 / 2;
            elbow.TwistLimit.MaximumAngle             = MathHelper.PiOver4 / 2;
            elbow.TwistLimit.SpringSettings.Damping   = 100;
            elbow.TwistLimit.SpringSettings.Stiffness = 100;


            //The elbow is like a hinge, but it can't hyperflex.
            elbow.HingeLimit.IsActive     = true;
            elbow.HingeLimit.MinimumAngle = 0;
            elbow.HingeLimit.MaximumAngle = MathHelper.Pi * .7m;
            Space.Add(elbow);

            Entity hand = new Box(lowerArm.Position + new Vector3(0, .9m, 0), .4m, .55m, .25m, 3);

            Space.Add(hand);

            ballSocketJoint = new BallSocketJoint(lowerArm, hand, lowerArm.Position + new Vector3(0, .7m, 0));
            Space.Add(ballSocketJoint);

            //Wrists can use an ellipse limit too.
            swingLimit = new EllipseSwingLimit(lowerArm, hand, Vector3.Up, MathHelper.PiOver4, MathHelper.PiOver2);
            Space.Add(swingLimit);

            //Allow a little extra twist beyond the forearm.
            twistLimit = new TwistLimit(lowerArm, hand, Vector3.Up, Vector3.Up, -MathHelper.PiOver4 / 2, MathHelper.PiOver4 / 2);
            twistLimit.SpringSettings.Stiffness = 100;
            twistLimit.SpringSettings.Damping   = 100;
            Space.Add(twistLimit);

            //The hand is pretty floppy without some damping.
            var angularMotor = new AngularMotor(lowerArm, hand);

            angularMotor.Settings.VelocityMotor.Softness = .5m;
            Space.Add(angularMotor);

            //Make sure the parts of the arm don't collide.
            CollisionRules.AddRule(torso, upperArm, CollisionRule.NoBroadPhase);
            CollisionRules.AddRule(lowerArm, upperArm, CollisionRule.NoBroadPhase);
            CollisionRules.AddRule(lowerArm, hand, CollisionRule.NoBroadPhase);

            game.Camera.Position = new Vector3(0, 4, 20);
        }
예제 #41
0
        /// <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="cameraToUse">Camera to attach to the vehicle.</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 cameraToUse, 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 = 7;
            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(BaseSlidingFriction, BaseSlidingFriction, 1.0f),
                    new WheelSlidingFriction(3.5f, 3.5f));
                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(BaseSlidingFriction, BaseSlidingFriction, 1.0f),
                    new WheelSlidingFriction(3.5f, 3.5f));
                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.MaximumIterations      = 1;
                wheel.Brake.SolverSettings.MaximumIterations           = 1;
                wheel.SlidingFriction.SolverSettings.MaximumIterations = 1;
                wheel.DrivingMotor.SolverSettings.MaximumIterations    = 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;
            }


            Camera = cameraToUse;
        }
        /// <summary>
        /// Constructs a new demo.
        /// </summary>
        /// <param name="game">Game owning this demo.</param>
        public TerrainTestDemo(DemosGame game)
            : base(game)
        {
            //x and y, in terms of heightmaps, refer to their local x and y coordinates.  In world space, they correspond to x and z.
            //Setup the heights of the terrain.
            //int xLength = 384;
            //int zLength = 384;

            //float xSpacing = .5f;
            //float zSpacing = .5f;
            //var heights = new float[xLength, zLength];
            //for (int i = 0; i < xLength; i++)
            //{
            //    for (int j = 0; j < zLength; j++)
            //    {
            //        float x = i - xLength / 2;
            //        float z = j - zLength / 2;
            //        heights[i, j] = (float)(10 * (Math.Sin(x / 8) + Math.Sin(z / 8)));
            //    }
            //}
            ////Create the terrain.
            //var terrain = new Terrain(heights, new AffineTransform(
            //        new Vector3(xSpacing, 1, zSpacing),
            //        Quaternion.Identity,
            //        new Vector3(-xLength * xSpacing / 2, 0, -zLength * zSpacing / 2)));

            //Space.Add(terrain);
            //game.ModelDrawer.Add(terrain);

            for (int i = 0; i < 7; i++)
            {
                for (int j = 0; j < 3; j++)
                {
                    Space.Add(new Box(new Vector3(i * 50, -50, j * 50), 50, 20, 50));
                }
            }


            for (int i = 0; i < 20; i++)
            {
                for (int j = 0; j < 20; j++)
                {
                    CompoundBody cb = new CompoundBody(new CompoundShapeEntry[]
                    {
                        new CompoundShapeEntry(new CapsuleShape(2, 1), new Vector3(0, 0, 0)),
                        new CompoundShapeEntry(new CapsuleShape(2, 1), new Vector3(2, 0, 0)),
                        new CompoundShapeEntry(new CapsuleShape(2, 1), new Vector3(4, 0, 0)),
                        new CompoundShapeEntry(new CapsuleShape(2, 1), new Vector3(6, 0, 0)),
                        new CompoundShapeEntry(new CapsuleShape(2, 1), new Vector3(8, 0, 0)),
                        new CompoundShapeEntry(new CapsuleShape(2, 1), new Vector3(10, 0, 0)),
                        new CompoundShapeEntry(new CapsuleShape(2, 1), new Vector3(12, 0, 0)),
                    }, 10);
                    cb.Position = new Vector3(i * 15, 20, j * 5);

                    //CompoundBody cb = new CompoundBody(new CompoundShapeEntry[]
                    //{
                    //    new CompoundShapeEntry(new SphereShape(1), new Vector3(0, 0,0)),
                    //    new CompoundShapeEntry(new SphereShape(1), new Vector3(2, -2,0)),
                    //    new CompoundShapeEntry(new SphereShape(1), new Vector3(4, 0,0)),
                    //    new CompoundShapeEntry(new SphereShape(1), new Vector3(6, -2,0)),
                    //    new CompoundShapeEntry(new SphereShape(1), new Vector3(8, 0,0)),
                    //    new CompoundShapeEntry(new SphereShape(1), new Vector3(10, -2,0)),
                    //    new CompoundShapeEntry(new SphereShape(1), new Vector3(12, 0,0)),
                    //}, 10);
                    //cb.Position = new Vector3(i * 15, 20, j * 5);

                    //CompoundBody cb = new CompoundBody(new CompoundShapeEntry[]
                    //{
                    //    new CompoundShapeEntry(new CapsuleShape(0, 1), new Vector3(0, 0,0)),
                    //    new CompoundShapeEntry(new CapsuleShape(0, 1), new Vector3(2, -2,0)),
                    //    new CompoundShapeEntry(new CapsuleShape(0, 1), new Vector3(4, 0,0)),
                    //    new CompoundShapeEntry(new CapsuleShape(0, 1), new Vector3(6, -2,0)),
                    //    new CompoundShapeEntry(new CapsuleShape(0, 1), new Vector3(8, 0,0)),
                    //    new CompoundShapeEntry(new CapsuleShape(0, 1), new Vector3(10, -2,0)),
                    //    new CompoundShapeEntry(new CapsuleShape(0, 1), new Vector3(12, 0,0)),
                    //}, 10);
                    //cb.Position = new Vector3(i * 15, 20, j * 5);

                    cb.ActivityInformation.IsAlwaysActive = true;
                    cb.AngularVelocity = new Vector3(.01f, 0, 0);

                    Space.Add(cb);
                }
            }



            game.Camera.Position = new Vector3(0, 30, 20);
        }
예제 #43
0
        /// <summary>
        /// Constructs the front end and the internal physics representation of the Vehicle.
        /// </summary>
        /// <param name="position">Position of the Vehicle.</param>
        /// <param name="space">Space to add the Vehicle to.</param>
        /// <param name="camera">Camera to attach to the Vehicle.</param>
        /// <param name="game">The running game.</param>
        /// <param name="drawer">Drawer used to draw the Vehicle.</param>
        /// <param name="wheelModel">Model of the wheels.</param>
        /// <param name="wheelTexture">Texture to use for the wheels.</param>
        public VehicleInput(Vector3 position, Space space, Camera camera, DemosGame game, ModelDrawer drawer, Model wheelModel, Texture2D wheelTexture)
        {
            var bodies = new List<CompoundShapeEntry>
                {
                    new CompoundShapeEntry(new BoxShape(2.5f, .75f, 4.5f), new Vector3(0, 0, 0), 60),
                    new CompoundShapeEntry(new BoxShape(2.5f, .3f, 2f), new Vector3(0, .75f / 2 + .3f / 2, .5f), 1)
                };
            var body = new CompoundBody(bodies, 61);
            body.CollisionInformation.LocalPosition = new Vector3(0, .5f, 0);
            body.Position = position; //At first, just keep it out of the way.
            Vehicle = new Vehicle(body);

            var localWheelRotation = Quaternion.CreateFromAxisAngle(new Vector3(0, 0, 1), MathHelper.PiOver2);

            //The wheel model used is not aligned initially with how a wheel would normally look, so rotate them.
            Matrix wheelGraphicRotation = Matrix.CreateFromAxisAngle(Vector3.Forward, MathHelper.PiOver2);
            Vehicle.AddWheel(new Wheel(
                                 new CylinderCastWheelShape(.375f, 0.2f, localWheelRotation, wheelGraphicRotation, false),
                                 new WheelSuspension(2000, 100f, Vector3.Down, 0.325f, new Vector3(-1.1f, -0.1f, 1.8f)),
                                 new WheelDrivingMotor(2.5f, 30000, 10000),
                                 new WheelBrake(1.5f, 2, .02f),
                                 new WheelSlidingFriction(4, 5)));
            Vehicle.AddWheel(new Wheel(
                                 new CylinderCastWheelShape(.375f, 0.2f, localWheelRotation, wheelGraphicRotation, false),
                                 new WheelSuspension(2000, 100f, Vector3.Down, 0.325f, new Vector3(-1.1f, -0.1f, -1.8f)),
                                 new WheelDrivingMotor(2.5f, 30000, 10000),
                                 new WheelBrake(1.5f, 2, .02f),
                                 new WheelSlidingFriction(4, 5)));
            Vehicle.AddWheel(new Wheel(
                                 new CylinderCastWheelShape(.375f, 0.2f, localWheelRotation, wheelGraphicRotation, false),
                                 new WheelSuspension(2000, 100f, Vector3.Down, 0.325f, new Vector3(1.1f, -0.1f, 1.8f)),
                                 new WheelDrivingMotor(2.5f, 30000, 10000),
                                 new WheelBrake(1.5f, 2, .02f),
                                 new WheelSlidingFriction(4, 5)));
            Vehicle.AddWheel(new Wheel(
                                 new CylinderCastWheelShape(.375f, 0.2f, localWheelRotation, wheelGraphicRotation, false),
                                 new WheelSuspension(2000, 100f, Vector3.Down, 0.325f, new Vector3(1.1f, -0.1f, -1.8f)),
                                 new WheelDrivingMotor(2.5f, 30000, 10000),
                                 new WheelBrake(1.5f, 2, .02f),
                                 new WheelSlidingFriction(4, 5)));

            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.
                //However, because the suspension and friction are not really rigid,
                //the lowered accuracy is not so much of a problem.
                wheel.Suspension.SolverSettings.MaximumIterationCount = 1;
                wheel.Brake.SolverSettings.MaximumIterationCount = 1;
                wheel.SlidingFriction.SolverSettings.MaximumIterationCount = 1;
                wheel.DrivingMotor.SolverSettings.MaximumIterationCount = 1;
            }

            Space = space;

            Space.Add(Vehicle);
            ModelDrawer = drawer;
            DisplayModel model;
            WheelModels = new List<DisplayModel>();
            for (int k = 0; k < 4; 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);
        }
예제 #44
0
        public static Vehicle Create(BEPUutilities.Vector3 position)
        {
            var bodies = new List <CompoundShapeEntry>
            {
                new CompoundShapeEntry(new BoxShape(2.5f, .75f, 4.5f), new BEPUutilities.Vector3(0, 0, 0), 60),
                new CompoundShapeEntry(new BoxShape(2.5f, .3f, 2f), new BEPUutilities.Vector3(0, .75f / 2 + .3f / 2, .5f), 1)
            };
            var body = new CompoundBody(bodies, 61);

            body.CollisionInformation.LocalPosition = new BEPUutilities.Vector3(0, 0.5f, 0);
            body.Position = position; //At first, just keep it out of the way.
            var Vehicle = new Vehicle(body);

            var localWheelRotation = BEPUutilities.Quaternion.CreateFromAxisAngle(new BEPUutilities.Vector3(0, 0, 1), BEPUutilities.MathHelper.PiOver2);

            /* original values
             * float wheelRadius = .375f;
             * float wheelWidth = .2f;
             * float restLength = 0.325f;
             * float wheelStiffness = 2000;
             * float wheelDamping = 100;
             * float gripFriction = 2.5f;
             * float maxForwardForce = 30000;
             * float maxBackwardForce = 10000;
             * float dynamicBrakingCoeff = 1.5f;
             * float staticBrakingCoeff = 2;
             * float rollingFrictionCoeff = 0.02f;
             * float wheelSlidingDynamicCoeff = 4;
             * float wheelSlidingStaticCoeff = 5;
             *
             * float wheelLateralPlacement = 1.1f;
             * float wheelForeAftPlacement = 1.8f;
             * float wheelHeightPlacement = 0.1f;
             */

            float wheelRadius              = .375f;
            float wheelWidth               = .2f;
            float restLength               = 0.325f;
            float wheelStiffness           = 2000;
            float wheelDamping             = 100;
            float gripFriction             = 2.5f;
            float maxForwardForce          = 30000;
            float maxBackwardForce         = 10000;
            float dynamicBrakingCoeff      = 1.5f;
            float staticBrakingCoeff       = 2;
            float rollingFrictionCoeff     = 0.02f;
            float wheelSlidingDynamicCoeff = 4;
            float wheelSlidingStaticCoeff  = 5;

            float wheelLateralPlacement = 1.1f;
            float wheelForeAftPlacement = 1.8f;
            float wheelHeightPlacement  = 0.1f;

            //The wheel model used is not aligned initially with how a wheel would normally look, so rotate them.
            BEPUutilities.Matrix wheelGraphicRotation = BEPUutilities.Matrix.CreateFromAxisAngle(BEPUutilities.Vector3.Forward, BEPUutilities.MathHelper.PiOver2);
            Vehicle.AddWheel(new Wheel(
                                 new CylinderCastWheelShape(wheelRadius, wheelWidth, localWheelRotation, wheelGraphicRotation, false),
                                 new WheelSuspension(wheelStiffness, wheelDamping, BEPUutilities.Vector3.Down, restLength, new BEPUutilities.Vector3(-wheelLateralPlacement, -wheelHeightPlacement, wheelForeAftPlacement)),
                                 new WheelDrivingMotor(gripFriction, maxForwardForce, maxBackwardForce),
                                 new WheelBrake(dynamicBrakingCoeff, staticBrakingCoeff, rollingFrictionCoeff),
                                 new WheelSlidingFriction(wheelSlidingDynamicCoeff, wheelSlidingStaticCoeff)));
            Vehicle.AddWheel(new Wheel(
                                 new CylinderCastWheelShape(wheelRadius, wheelWidth, localWheelRotation, wheelGraphicRotation, false),
                                 new WheelSuspension(wheelStiffness, wheelDamping, BEPUutilities.Vector3.Down, restLength, new BEPUutilities.Vector3(-wheelLateralPlacement, -wheelHeightPlacement, -wheelForeAftPlacement)),
                                 new WheelDrivingMotor(gripFriction, maxForwardForce, maxBackwardForce),
                                 new WheelBrake(dynamicBrakingCoeff, staticBrakingCoeff, rollingFrictionCoeff),
                                 new WheelSlidingFriction(wheelSlidingDynamicCoeff, wheelSlidingStaticCoeff)));
            Vehicle.AddWheel(new Wheel(
                                 new CylinderCastWheelShape(wheelRadius, wheelWidth, localWheelRotation, wheelGraphicRotation, false),
                                 new WheelSuspension(wheelStiffness, wheelDamping, BEPUutilities.Vector3.Down, restLength, new BEPUutilities.Vector3(wheelLateralPlacement, -wheelHeightPlacement, wheelForeAftPlacement)),
                                 new WheelDrivingMotor(gripFriction, maxForwardForce, maxBackwardForce),
                                 new WheelBrake(dynamicBrakingCoeff, staticBrakingCoeff, rollingFrictionCoeff),
                                 new WheelSlidingFriction(wheelSlidingDynamicCoeff, wheelSlidingStaticCoeff)));
            Vehicle.AddWheel(new Wheel(
                                 new CylinderCastWheelShape(wheelRadius, wheelWidth, localWheelRotation, wheelGraphicRotation, false),
                                 new WheelSuspension(wheelStiffness, wheelDamping, BEPUutilities.Vector3.Down, restLength, new BEPUutilities.Vector3(wheelLateralPlacement, -wheelHeightPlacement, -wheelForeAftPlacement)),
                                 new WheelDrivingMotor(gripFriction, maxForwardForce, maxBackwardForce),
                                 new WheelBrake(dynamicBrakingCoeff, staticBrakingCoeff, rollingFrictionCoeff),
                                 new WheelSlidingFriction(wheelSlidingDynamicCoeff, wheelSlidingStaticCoeff)));


            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.
                //However, because the suspension and friction are not really rigid,
                //the lowered accuracy is not so much of a problem.
                wheel.Suspension.SolverSettings.MaximumIterationCount      = 1;
                wheel.Brake.SolverSettings.MaximumIterationCount           = 1;
                wheel.SlidingFriction.SolverSettings.MaximumIterationCount = 1;
                wheel.DrivingMotor.SolverSettings.MaximumIterationCount    = 1;
            }



            return(Vehicle);
        }
예제 #45
0
        /// <summary>
        /// Constructs a new demo.
        /// </summary>
        /// <param name="game">Game owning this demo.</param>
        public EntityConstructionDemo(DemosGame game)
            : base(game)
        {
            //An entity is the basic physical simulation object in BEPUphysics.  It represents a rigid body which can be dynamic or kinematic.
            //Dynamic objects can bounce around and respond to collisions using forces.  Kinematic entities can move using velocity,
            //but effectively have infinite inertia and do not respond to collisions or forces.

            //For each of the below constructors, there are multiple overloads.  Half have a mass parameter, half do not.  If a mass parameter is specified,
            //the object is created as a dynamic object.  If a mass parameter is not specified, it is created as a kinematic object.  This state can be changed later
            //by using the BecomeDynamic/BecomeKinematic methods.

            //************************
            //There are a variety of ways to construct entities depending on your needs.
            //The most common approach is to use the 'prefab' types, like the Box, Sphere, ConvexHull, Cylinder, and so on (BEPUphysics.Entities.Prefabs namespace).
            //These provide a short cut to constructing the objects and generally provide convenience accessors to shape properties.

            //We'll start with such an entity for the kinematic ground.  Notice how it allows the definition of position and shape data all in the constructor.
            //It has other overloads that allow you to specify a mass (for a dynamic object) or a full MotionState instead of just a position.
            Box ground = new Box(new Vector3(0, -.5f, 0), 50, 1, 50);
            Space.Add(ground);

            //If you examine the ground's CollisionInformation property, you'll find that it is a generic method which returns a ConvexCollidable<BoxShape>.
            //So, in addition to having convenience properties, it also lets you go deeper into the object's data by knowing what the types are.

            //************************
            //Let's go one level up the hierarchy to Entity<T>.  This is the superclass of all prefab types.
            //The generic parameter is the type of the Collidable that the entity uses as its collision proxy.
            //It is also what allows prefab types' CollisionInformation property to return that type rather than EntityCollidable.

            Space.Add(new Entity<ConvexCollidable<SphereShape>>(new ConvexCollidable<SphereShape>(new SphereShape(1)), 1)
                          {
                              Position = new Vector3(-10, 1, 0)
                          });

            //That's a bit unwieldy<<>><>, but it works.  Directly constructing entities in this manner isn't common or generally necessary.
            //If you want to have a CollisionInformation property that returns a specific type but don't want to use a specific prefab type, this is the way to go.

            //Note that the constructor itself does not include any position/motion state parameters nor does it include any direct shape data.  The position and other auxiliary
            //properties can be set after it's been constructed.  In this case, object initializer syntax is used to set the Position.
            //The shape data is included within the first EntityCollidable parameter which defines the entity's collision proxy.
            //The prefab types discussed previously all create such EntityCollidables internally using the data passed into the constructor.

            //************************
            //So let's move onto something a little more convenient.  Entity<T> has a non-generic parent Entity.  It still has a CollisionInformation property,
            //but it returns an EntityCollidable rather than a specific type.

            Space.Add(new Entity(new BoxShape(2, 2, 2), 1)
                {
                    Position = new Vector3(10, 1, 0)
                });

            //Much better! No more ugly generic type syntax pollution.  Notice that there are quite a few overloads in the Entity.
            //In addition to overloads that accept EntityCollidable instances (as used in the generic entity above), Entity provides constructors that
            //take shapes directly.  Internally, the entity can create its own EntityCollidable instance based on the shape.  This further simplifies the construction process.

            //An object initializer is once again used to set the position, since the constructors do not have all the convenience constructor frills of the prefab types.

            //************************
            //All of the above entity types have read-only CollisionInformation properties.  Once an entity of those types is created, it cannot change its fundamental shape.
            //A sphere may get bigger or smaller, but a sphere entity couldn't become a box entity.

            //That's where the MorphableEntity comes in.

            var morphable = new MorphableEntity(new CylinderShape(2, 1), 1)
            {
                Position = new Vector3(10, 3, 0)
            };
            Space.Add(morphable);

            //It is constructed identically to its parent Entity class, but after being created, the EntityCollidable it uses can change!
            morphable.CollisionInformation = new ConvexCollidable<ConeShape>(new ConeShape(2, 1));

            //That's neat, but that collidable constructor with generic type is a bit ugly.  We don't care about doing any type-specific configuration
            //on the EntityCollidable itself, so we can just tell the shape to make us an EntityCollidable instance.  This is what the Entity/MorphableEntity constructors
            //do internally when given an EntityShape instead of an EntityCollidable (which in turn contains an EntityShape).
            morphable.CollisionInformation = new ConeShape(2, 1).GetCollidableInstance();

            //While this is arguably a bit prettier, its major benefit comes from the fact that you don't need to know the type of the shape to call GetCollidableInstance.
            //If it's an EntityShape, it can create an EntityCollidable for itself.

            //************************
            //That's it for the different types of entities.  Another very useful technique is to share shapes and initialization between entities.
            //Re-using convex hulls is a common use case.  They have a fairly expensive initialization, and they tend to be some of the larger shapes memory-wise.
            //Rather than having a thousand redundant copies of identical geometry, one shape can be made and reused for subsequent entities.

            //First, create the pointset that composes the convex hull.
            var vertices = new[]
            {
                new Vector3(-1,0,-1),
                new Vector3(-1,0,1),
                new Vector3(1,0,-1),
                new Vector3(1,0,1),
                new Vector3(0,2,0)
            };
            //Construct the shape itself.
            var convexHullShape = new ConvexHullShape(vertices);

            //Create an entity using the shape.
            var convexHull = new Entity(convexHullShape, 2) { Position = new Vector3(0, 1, 0) };
            Space.Add(convexHull);
            //Create a bunch of other shapes using that first shape's properties.
            //Instead of using a first entity's data, this could also be pulled in from some external source (deserialized save data or something).
            for (int i = 1; i <= 10; i++)
            {
                Space.Add(new Entity(convexHullShape, convexHull.Mass, convexHull.LocalInertiaTensor) { Position = new Vector3(0, 1 + i * 3, 0) });
            }

            //In older versions, initializing the entity was a little expensive if the inertia tensor and some other data wasn't provided.
            //These days, the cost is done once in the shape and the entity initialization is pretty much always super cheap.
            //So, you don't need to share inertia tensors for performance reasons.

            //************************
            //All convex shapes are centered on their local origin.  If you create a box entity and assign its position to (0,1,0), the box shape's center will end up at (0,1,0).
            //For simple shapes like the box, that's always the case without doing any work just based on the definition of the shape.

            //More complicated shapes, like the ConvexHullShape, can be constructed from data which is not initially centered around the origin.  For example, consider these vertices:
            vertices = new[]
            {
                new Vector3(-5,15,-1),
                new Vector3(-5,15,1),
                new Vector3(-3,15,-1),
                new Vector3(-3,15,1),
                new Vector3(-4,17,0),
                new Vector3(-4,13,0)
            };
            //The center of those points is obviously going to be very far from the origin.
            //When we construct a ConvexHullShape, the points get 'recentered.'
            convexHullShape = new ConvexHullShape(vertices);

            //If you look at the convexHullShape.Vertices list, you'll see that the points are relative to a local origin now.
            //So now it's centered on the local origin, as was needed.  But there's a problem- what if you wanted your convex hull entity to end up at the original vertex positions?
            //To get it there, we need to know the offset from the original vertices to the local vertices.
            //Fortunately, there is a constructor overload which provides it!
            Vector3 center;
            convexHullShape = new ConvexHullShape(vertices, out center);

            //Now, when the entity is created, we can position it at the original point's center.  The shape still contains local data, but the entity's location ends up putting the shape in the right spot.
            convexHull = new Entity(convexHullShape, 2) { Position = center };
            Space.Add(convexHull);

            //************************
            //Compound bodies are unique in that they allow you to specify groups of shapes to create a concave shape.
            //Here's the common simple approach to making a compound body, using a prefab type for now.
            CompoundBody body = new CompoundBody(new List<CompoundShapeEntry>
            {
                new CompoundShapeEntry(new BoxShape(1, 1, 1), new Vector3(-7, 3, 8), 1),
                new CompoundShapeEntry(new BoxShape(1, 3, 1), new Vector3(-8, 2, 8), 5),
                new CompoundShapeEntry(new BoxShape(1, 1, 1), new Vector3(-9, 1, 8), 1)
            }, 10);
            Space.Add(body);
            //Each entry has a shape, a rigid transform (orientation and/or translation), and a weight.
            //The rigid transform defines the position of the shape in world space.  They will be recentered into local space within the CompoundShape itself (see previous convex hull example).
            //The 'weight' parameter does not correspond directly to mass, but rather to the contribution of that shape to the whole relative to other shapes.
            //It used to compute the center position of the shape.  When used by a dynamic entity, it is also used to compute a proper inertia tensor.  The resulting inertia tensor is scaled by the entity's actual mass.

            //************************
            //Just like shapes can be shared between entities, you can re-use a shape for multiple entries within a compound body.
            var compoundShape = new CompoundShape(new List<CompoundShapeEntry>
            {
                new CompoundShapeEntry(convexHullShape, new Vector3(7, 3, 8), 1),
                new CompoundShapeEntry(convexHullShape, new RigidTransform(new Vector3(8, 2, 8), Quaternion.CreateFromAxisAngle(Vector3.Forward, MathHelper.PiOver2)), 5),
                new CompoundShapeEntry(convexHullShape, new Vector3(9, 1, 8), 1)
            });

            //And just like normal convex shapes can be shared, so can compound shapes!
            for (int i = 0; i < 3; i++)
                Space.Add(new Entity(compoundShape, 10) { Position = new Vector3(8, 10 + i * 4, 8) });

            //************************
            //You can also use compound shapes as subshapes, creating nested compounds.
            Space.Add(new Entity(new CompoundShape(new List<CompoundShapeEntry>
            {
                new CompoundShapeEntry(compoundShape, new Vector3(7, 5, 8), 1),
                new CompoundShapeEntry(compoundShape, new Vector3(9, 1, 8), 1)
            }), 10) { Position = new Vector3(8, 25, 8) });

            //************************
            //Sometimes, it's nice to be able to change how subshapes behave.
            //This example will use a prefab CompoundBody type, but note that there exists a CompoundCollidable that can be constructed independently as well.
            //Just like a list of CompoundShapeEntry objects can be ued to construct a compound object, a list of CompoundChildData objects can too.
            //CompoundChildData objects contain CompoundShapeEntry objects as well as other data to be used by a Collidable instance.
            //That extra data includes material, events, and collision rules.

            var compoundBody = new CompoundBody(new List<CompoundChildData>
            {
                new CompoundChildData { Entry = new CompoundShapeEntry(new CylinderShape(1, 1), new Vector3(0, 2, 8)), CollisionRules = new CollisionRules { Personal = CollisionRule.NoBroadPhase } },
                new CompoundChildData { Entry = new CompoundShapeEntry(new BoxShape(3, 1, 3), new Vector3(0, 1, 8)), Material = new Material(3, 3, 0) }
            }, 10);
            Space.Add(compoundBody);

            //In this example, one of the two blocks doesn't collide with anything.  The other does collide, and has a very high friction material.

            //************************
            //While sharing shapes can help reduce load times, sometimes it's useful to eliminate the shape's initialization cost too.
            //For this purpose, all shapes have a constructor which takes a bunch of data that fully defines the shape.
            //The constructor assumes that all of it is correct; it won't catch any errors or do any additional preprocessing.

            //For example, let's construct a ConvexHullShape from the our earlier ConvexHullShape.
            //We'll need a ConvexShapeDescription that defines the data common to all convex shapes.
            var shapeDescription = new ConvexShapeDescription
                {
                    CollisionMargin = convexHullShape.CollisionMargin,
                    MinimumRadius = convexHullShape.MinimumRadius,
                    MaximumRadius = convexHullShape.MaximumRadius,
                    EntityShapeVolume = new EntityShapeVolumeDescription
                    {
                        Volume = convexHullShape.Volume,
                        VolumeDistribution = convexHullShape.VolumeDistribution
                    }
                };

            //Now, along with the surface vertices from the previous shape, the new shape can be created:
            var shapeFromCachedData = new ConvexHullShape(convexHullShape.Vertices, shapeDescription);

            //Usually, the data for these constructors will come from some cache or storage. For example,
            //a game could store out the above information to disk from a content development tool.
            //At load time, the matching shape can be created at virtually no cost.

            //Stuff the shape into the world!
            Space.Add(new Entity(shapeFromCachedData, 10)
                {
                    Position = new Vector3(-10, 5, -5)
                });

            Game.Camera.Position = new Vector3(0, 3, 25);
        }
예제 #46
0
        public void LoadLevel(String fileName)
        {
            // Load level data
            GameLevelContent levelData = Game.Content.Load <GameLevelContent>(fileName);
            int blocksCount            = levelData.BlocksCount();

            // List of blocks chapes for compound body
            List <CompoundShapeEntry> shapes = new List <CompoundShapeEntry>();

            // Create block groups and block physics
            foreach (BlockGroupData blockGroup in levelData.BlockGroups)
            {
                // Create block group
                LoadBlockType(blockGroup.BlockTypeName, blocksCount);

                // Create physical representation of blocks in this group
                Vector3    scale;
                Quaternion rotation;
                Vector3    translation;
                foreach (BlockData blockData in blockGroup.Blocks)
                {
                    // Extract size, position and orientation values from block data transform
                    blockData.Transform.Decompose(out scale, out rotation, out translation);
                    blockData.Scale = scale;

                    // Create physical shape of the block to be part of compound body of blocks
                    BoxShape blockShape = new BoxShape(scale.X, scale.Y, scale.Z);

                    // Create compound shape entry for compund body of blocks
                    CompoundShapeEntry entry = new CompoundShapeEntry(blockShape, new RigidTransform(translation, rotation));
                    shapes.Add(entry);
                }
            }

            // Create compound body
            compoundBody = new CompoundBody(shapes, COMPOUND_BODY_MASS);

            compoundBody.PositionUpdateMode = BEPUphysics.PositionUpdating.PositionUpdateMode.Continuous;
            compoundBody.AngularDamping     = COMPOUND_BODY_ANGULAR_DAMPING;

            // Compound body has Position and LocalPosition (in Collision information)
            // Position property is position of mass center in global space - it is calculated automatically.
            // LocalPosition property is position of geometry of the body in its local space.
            // So in order to create compound body which is rotated around desired position ((0,0,0) for now)
            // We should switch Position and LocalPosition properties of our compound body.
            compoundBody.CollisionInformation.LocalPosition = compoundBody.Position;
            compoundBody.Position = Vector3.Zero;

            // Add constraint prevents compound body from moving
            constraint = new MaximumLinearSpeedConstraint(compoundBody, 0.0f);

            // Create collision group for removed blocks
            removedBlocksGroup = new CollisionGroup();

            // Create blocks
            int childCollidableIndex = 0;

            foreach (BlockGroupData blockGroup in levelData.BlockGroups)
            {
                Matrix localPosTransform = Matrix.CreateTranslation(compoundBody.CollisionInformation.LocalPosition);

                foreach (BlockData blockData in blockGroup.Blocks)
                {
                    // Obtain block type and instanced mesh for the block
                    BlockType blockType = blockTypes[blockGroup.BlockTypeName];
                    InstancedMesh <VertexData> instancedMesh = blockInstancedMeshes[blockGroup.BlockTypeName];

                    // Obtain physics body (a part of compound body) for the block
                    CompoundChild child = compoundBody.CollisionInformation.Children[childCollidableIndex];

                    // Create instance of the block in instanced mesh
                    InstancedMesh <VertexData> .Instance instance = instancedMesh.AppendInstance(Matrix.CreateScale(blockData.Scale) * child.Entry.LocalTransform.Matrix * localPosTransform);

                    // Store new block instance to the list
                    Block block = new Block(blockType, instance, child);
                    blocks.Add(block);

                    block.Scale = blockData.Scale;

                    childCollidableIndex++;
                }
            }

            // Add compound body and its constraints to physics space
            space.Add(compoundBody);
            space.Add(constraint);
        }