void AddBackWheel(Vector3 wheelOffset, Entity body)
        {
            var wheel = new Cylinder(body.Position + wheelOffset, .4m, .5m, 5);

            wheel.Material.KineticFriction = 2.5m;
            wheel.Material.StaticFriction  = 3.5m;
            wheel.Orientation = Quaternion.CreateFromAxisAngle(Vector3.Forward, MathHelper.PiOver2);

            //Preventing the occasional pointless collision pair can speed things up.
            CollisionRules.AddRule(wheel, body, CollisionRule.NoBroadPhase);

            //Connect the wheel to the body.
            var pointOnLineJoint = new PointOnLineJoint(body, wheel, wheel.Position, Vector3.Down, wheel.Position);
            var suspensionLimit  = new LinearAxisLimit(body, wheel, wheel.Position, wheel.Position, Vector3.Down, -1, 0);
            //This linear axis motor will give the suspension its springiness by pushing the wheels outward.
            var suspensionSpring = new LinearAxisMotor(body, wheel, wheel.Position, wheel.Position, Vector3.Down);

            suspensionSpring.Settings.Mode       = MotorMode.Servomechanism;
            suspensionSpring.Settings.Servo.Goal = 0;
            suspensionSpring.Settings.Servo.SpringSettings.Stiffness = 300;
            suspensionSpring.Settings.Servo.SpringSettings.Damping   = 70;

            var revoluteAngularJoint = new RevoluteAngularJoint(body, wheel, Vector3.Right);

            //Add the wheel and connection to the space.
            Space.Add(wheel);
            Space.Add(pointOnLineJoint);
            Space.Add(suspensionLimit);
            Space.Add(suspensionSpring);
            Space.Add(revoluteAngularJoint);
        }
Пример #2
0
        public Tread(Entity tankBody, Vector3 offsetToFrontOfTread, int segmentCount, Fix64 spacing, TreadSegmentDescription treadSegmentDescription)
        {
            Segments = new List <TreadSegment>();
            Vector3 nextSegmentPosition = tankBody.Position + offsetToFrontOfTread;

            //The front of the tread includes the radius of the first segment.
            nextSegmentPosition.Z += treadSegmentDescription.Radius * (Fix64)0.5m;
            for (int i = 0; i < segmentCount; ++i)
            {
                Segments.Add(new TreadSegment(nextSegmentPosition, tankBody, treadSegmentDescription));

                //The tread offset starts at the front of the vehicle and moves backward.
                nextSegmentPosition.Z += spacing;
            }


            //Don't let the tread segments rotate relative to each other.
            SegmentAngularBindings = new List <NoRotationJoint>();
            for (int i = 1; i < segmentCount; ++i)
            {
                //Create constraints linking the segments together to ensure that the power of one motor is felt by other segments.
                SegmentAngularBindings.Add(new NoRotationJoint(Segments[i - 1].Entity, Segments[i].Entity));
                //Don't let the tread segments collide.
                CollisionRules.AddRule(Segments[i - 1].Entity, Segments[i].Entity, CollisionRule.NoBroadPhase);
            }

            //Note: You can organize this in different ways. For example, you could have one motor which drives one wheel, which
            //in turn drives other wheels through these NoRotationJoints.

            //In such a one-motor model, it may be a good idea for stability to bind all wheels directly to the drive wheel with
            //NoRotationJoints rather than using a chain of one wheel to the next.

            //Per-wheel drive motors are used in this example just because it is slightly more intuitive at a glance.
            //Each segment is no different than the others.
        }
        /// <summary>
        /// Constructs a simple character controller.
        /// </summary>
        /// <param name="position">Location to initially place the character.</param>
        /// <param name="characterHeight">The height of the character.</param>
        /// <param name="characterWidth">The diameter of the character.</param>
        /// <param name="supportHeight">The distance above the ground that the bottom of the character's body floats.</param>
        /// <param name="mass">Total mass of the character.</param>
        /// <param name="scale">The scale.</param>
        public CharacterController(Vector3 position, float characterHeight, float characterWidth, float supportHeight, float mass, Vector3 scale)
        {
            IsUpdating           = false;
            characterWidth       = characterWidth * scale.X;
            this.characterHeight = characterHeight * scale.Y;
            this.scale           = scale;
            Body = new Capsule(position, characterHeight - characterWidth, characterWidth / 2, mass);
            collisionPairCollectorPositionOffset = new Vector3(0, -characterHeight / 2 - supportHeight, 0);
            collisionPairCollector = new Box(position + collisionPairCollectorPositionOffset, characterWidth, supportHeight * 2, characterWidth, 1);


            collisionPairCollector.CollisionInformation.CollisionRules.Personal = CollisionRule.NoNarrowPhaseUpdate; //Prevents collision detection/contact generation from being run.
            collisionPairCollector.IsAffectedByGravity = false;
            CollisionRules.AddRule(collisionPairCollector, Body, CollisionRule.NoBroadPhase);                        //Prevents the creation of any collision pairs between the body and the collector.
            rayOriginOffset    = new Vector3(0, -characterHeight / 2, 0);
            this.supportHeight = supportHeight;

            Body.LocalInertiaTensorInverse = new Matrix3X3();
            collisionPairCollector.LocalInertiaTensorInverse = new Matrix3X3();
            //Make the body slippery.
            //Note that this will not make all collisions have zero friction;
            //the friction coefficient between a pair of objects is based
            //on a blending of the two objects' materials.
            Body.Material.KineticFriction = 0;
            Body.Material.StaticFriction  = 0;
        }
Пример #4
0
        public TreadSegment(Vector3 segmentPosition, Entity body, TreadSegmentDescription treadSegmentDescription)
        {
            Entity = new Cylinder(segmentPosition, treadSegmentDescription.Width, treadSegmentDescription.Radius, treadSegmentDescription.Mass);

            Entity.Material.KineticFriction = treadSegmentDescription.Friction;
            Entity.Material.StaticFriction  = treadSegmentDescription.Friction;
            Entity.Orientation = Quaternion.CreateFromAxisAngle(Vector3.Forward, MathHelper.PiOver2);

            //Preventing the occasional pointless collision pair can speed things up.
            CollisionRules.AddRule(Entity, body, CollisionRule.NoBroadPhase);

            //Connect the wheel to the body.
            SuspensionAxisJoint   = new PointOnLineJoint(body, Entity, Entity.Position, Vector3.Down, Entity.Position);
            SuspensionLengthLimit = new LinearAxisLimit(body, Entity, Entity.Position, Entity.Position, Vector3.Down, -treadSegmentDescription.SuspensionLength, 0);
            //This linear axis motor will give the suspension its springiness by pushing the wheels outward.
            SuspensionSpring = new LinearAxisMotor(body, Entity, Entity.Position, Entity.Position, Vector3.Down);
            SuspensionSpring.Settings.Mode       = MotorMode.Servomechanism;
            SuspensionSpring.Settings.Servo.Goal = 0;
            SuspensionSpring.Settings.Servo.SpringSettings.Stiffness = treadSegmentDescription.SuspensionStiffness;
            SuspensionSpring.Settings.Servo.SpringSettings.Damping   = treadSegmentDescription.SuspensionDamping;

            SuspensionAngularJoint = new RevoluteAngularJoint(body, Entity, Vector3.Right);
            //Make the joint extremely rigid.  There are going to be extreme conditions when the wheels get up to speed;
            //we don't want the forces involved to torque the wheel off the frame!
            SuspensionAngularJoint.SpringSettings.Damping   *= Entity.Mass * 50;
            SuspensionAngularJoint.SpringSettings.Stiffness *= Entity.Mass * 50;
            //Motorize the wheel.
            Motor = new RevoluteMotor(body, Entity, Vector3.Left);
            Motor.Settings.VelocityMotor.Softness = treadSegmentDescription.MotorSoftness;
            Motor.Settings.MaximumForce           = treadSegmentDescription.MotorMaximumForce;
        }
        void BuildStick(Vector3 position, int linkCount, out List <Bone> bones, out List <Entity> boneEntities)
        {
            //Set up a bone chain.
            bones        = new List <Bone>();
            boneEntities = new List <Entity>();
            var previousBoneEntity = new Cylinder(position, 1, .2m);
            var previousBone       = new Bone(previousBoneEntity.Position, previousBoneEntity.Orientation, previousBoneEntity.Radius, previousBoneEntity.Height);

            bones.Add(previousBone);
            boneEntities.Add(previousBoneEntity);


            for (int i = 1; i < linkCount; i++)
            {
                var boneEntity = new Cylinder(previousBone.Position + new Vector3(0, 1, 0), 1, .2m);
                var bone       = new Bone(boneEntity.Position, boneEntity.Orientation, boneEntity.Radius, boneEntity.Height);
                bones.Add(bone);
                boneEntities.Add(boneEntity);

                //Make a relationship between the two bones and entities.
                CollisionRules.AddRule(previousBoneEntity, boneEntity, CollisionRule.NoBroadPhase);
                Vector3 anchor = (previousBoneEntity.Position + boneEntity.Position) / 2;
                //var dynamicsBallSocketJoint = new BallSocketJoint(previousBoneEntity, boneEntity, anchor);
                //var dynamicsAngularFriction = new NoRotationJoint(previousBoneEntity, boneEntity);
                //Space.Add(dynamicsBallSocketJoint);
                //Space.Add(dynamicsAngularFriction);
                var ballSocket   = new IKBallSocketJoint(previousBone, bone, anchor);
                var angularJoint = new IKAngularJoint(previousBone, bone);


                previousBone       = bone;
                previousBoneEntity = boneEntity;
            }
        }
Пример #6
0
        // Must be called by subclasses when they are able to construct an Entity.
        protected void SetEntity(Entity entity)
        {
            if (Entity != null)
            {
                _physicsSystem.RemoveObject(Entity);
                Transform.RemovePhysicsEntity();
            }

            Entity                          = entity;
            Entity.Position                 = Transform.Position;
            Entity.Orientation              = Transform.Rotation;
            Entity.IsAffectedByGravity      = IsAffectedByGravity;
            Entity.PositionUpdateMode       = MapUpdateMode(UpdateMode);
            Entity.AngularDamping           = AngularDamping;
            Entity.LinearDamping            = LinearDamping;
            Entity.Material.Bounciness      = Bounciness;
            Entity.Material.StaticFriction  = StaticFriction;
            Entity.Material.KineticFriction = KineticFriction;

            Entity.Tag = this;
            Entity.CollisionInformation.Tag = this;
            Entity.CollisionInformation.CollisionRules.Group = _physicsSystem.GetCollisionGroup(_layer);

            if (EnabledInHierarchy)
            {
                _physicsSystem.AddObject(Entity);
                Transform.SetPhysicsEntity(Entity);
                if (_isTrigger)
                {
                    SetEntityTrigger();
                }
            }

            _parentCollider = GameObject.GetComponentInParent <Collider>();
            if (_parentCollider != null)
            {
                CollisionRules.AddRule(Entity, _parentCollider.Entity, CollisionRule.NoBroadPhase);

                var jointPosition = (Entity.Position + _parentCollider.Entity.Position) / 2;
                _parentJoint = new WeldJoint(_parentCollider.Entity, Entity, jointPosition);
                _parentJoint.BallSocketJoint.SpringSettings.Stiffness = float.MaxValue;
                _parentJoint.BallSocketJoint.SpringSettings.Damping   = float.MaxValue;
                _parentJoint.BallSocketJoint.IsActive = true;

                _parentJoint.NoRotationJoint.SpringSettings.Damping   = float.MaxValue;
                _parentJoint.NoRotationJoint.SpringSettings.Stiffness = float.MaxValue;
                _parentJoint.NoRotationJoint.IsActive = true;
                _parentJoint.IsActive = true;
                _physicsSystem.AddObject(_parentJoint);
                _parentCollider.Transform.PositionManuallyChanged += OnAttachedParentManuallyMoved;
            }
        }
Пример #7
0
 public void IgnoreCollision(Collider collider1, Collider collider2, bool ignore)
 {
     if (ignore)
     {
         CollisionRules.AddRule(collider1.collisionEntity_generic.CollisionInformation, collider2.collisionEntity_generic.CollisionInformation, CollisionRule.NoBroadPhase);
         //collider1.collisionEntity_generic.CollisionInformation.CollisionRules.Group = firstStackGroup;
         //collider2.collisionEntity_generic.CollisionInformation.CollisionRules.Group = secondStackGroup;
     }
     else
     {
         CollisionRules.RemoveRule(collider1.collisionEntity_generic.CollisionInformation, collider2.collisionEntity_generic.CollisionInformation);
         //collider1.collisionEntity_generic.CollisionInformation.CollisionRules.Group = null;
         //collider2.collisionEntity_generic.CollisionInformation.CollisionRules.Group = null;
     }
 }
Пример #8
0
        public Turret(Entity tankBody, Vector3 offset)
        {
            var position = offset + tankBody.Position;

            Body = new Cylinder(position, (Fix64)0.7m, (Fix64)0.8m, 8);
            //Position the center of the arm a bit further forward since it will be laying down.
            position.Z -= 2;
            Barrel      = new Cylinder(position, 3, (Fix64)0.2m, 3);
            //Rotate the arm so that it points straight forward (that is, along {0, 0, -1}).
            Barrel.Orientation = Quaternion.CreateFromAxisAngle(new Vector3(1, 0, 0), MathHelper.PiOver2);

            TankToTurretJoint       = new RevoluteJoint(tankBody, Body, Body.Position, Vector3.Up);
            TurretBodyToBarrelJoint = new RevoluteJoint(Body, Barrel, Body.Position + new Vector3(0, 0, (Fix64)(-0.5m)), Vector3.Left);

            //Turn on the control constraints. We'll put them into servo mode, but velocity mode would also work just fine.
            TankToTurretJoint.Motor.IsActive      = true;
            TankToTurretJoint.Motor.Settings.Mode = MotorMode.Servomechanism;
            TankToTurretJoint.Motor.Settings.Servo.BaseCorrectiveSpeed = (Fix64)0.5m;
            TankToTurretJoint.Motor.Settings.MaximumForce = 500;
            TankToTurretJoint.Motor.Basis.SetLocalAxes(Vector3.Up, Vector3.Forward);

            TurretBodyToBarrelJoint.Motor.IsActive      = true;
            TurretBodyToBarrelJoint.Motor.Settings.Mode = MotorMode.Servomechanism;
            TurretBodyToBarrelJoint.Motor.Settings.Servo.BaseCorrectiveSpeed = (Fix64)0.5m;
            //We take special care to limit this motor's force to stop the turret from smashing the tank body.
            TurretBodyToBarrelJoint.Motor.Settings.MaximumForce = 300;
            TurretBodyToBarrelJoint.Motor.Basis.SetLocalAxes(Vector3.Right, Vector3.Forward);

            //Don't let the directly connected objects generate collisions. The arm can still hit the tank body, though.
            CollisionRules.AddRule(Body, tankBody, CollisionRule.NoBroadPhase);
            CollisionRules.AddRule(Barrel, Body, CollisionRule.NoBroadPhase);

            //Don't have a lot of leeway downards. The turret will quickly bump the tank body.
            MinimumPitch = -MathHelper.Pi * (Fix64)0.05m;
            MaximumPitch = MathHelper.Pi * (Fix64)0.4m;

            //Build an ammunition pool.
            shellPool = new Queue <Sphere>(MaximumShellCount);

            for (int i = 0; i < MaximumShellCount; ++i)
            {
                var shell = new Sphere(new Vector3(10000, 0, 0), (Fix64)0.2m, 2);
                shell.PositionUpdateMode = BEPUphysics.PositionUpdating.PositionUpdateMode.Continuous;
                shellPool.Enqueue(shell);
            }
        }
Пример #9
0
        public void OnCollide(object sender, CollisionEventArgs args)
        {
            if (Stuck)
            {
                return;
            }
            double len = GetVelocity().Length();

            SetPosition(args.Info.Position + (GetVelocity() / len) * 0.05f);
            SetVelocity(Location.Zero);
            Gravity = Location.Zero;
            if (HasHat)
            {
                SolidHat = new ModelEntity("invisbox", TheRegion);
                SolidHat.SetMass(0);
                SolidHat.SetPosition(GetPosition());
                SolidHat.SetOrientation(GetOrientation());
                SolidHat.scale   = new Location(0.6, 1.5, 0.6);
                SolidHat.Visible = false;
                SolidHat.CanSave = false;
                TheRegion.SpawnEntity(SolidHat);
            }
            if (args.Info.HitEnt != null)
            {
                PhysicsEntity pe = (PhysicsEntity)args.Info.HitEnt.Tag;
                if (pe is EntityDamageable)
                {
                    ((EntityDamageable)pe).Damage(Damage + DamageTimesVelocity * (double)len);
                }
                Vector3 loc     = (args.Info.Position - pe.GetPosition()).ToBVector();
                Vector3 impulse = GetVelocity().ToBVector() * DamageTimesVelocity / 1000f;
                pe.Body.ApplyImpulse(ref loc, ref impulse);
                StuckTo = pe;
                if (HasHat)
                {
                    CollisionRules.AddRule(pe.Body, SolidHat.Body, CollisionRule.NoBroadPhase); // TODO: Broadcast this info! Perhaps abuse the joint system?
                }
            }
            TheRegion.SendToAll(new PrimitiveEntityUpdatePacketOut(this));
            if (args.Info.HitEnt != null)
            {
                PhysicsEntity  pe  = (PhysicsEntity)args.Info.HitEnt.Tag;
                JointForceWeld jfw = new JointForceWeld(pe, this);
                TheRegion.AddJoint(jfw);
            }
        }
Пример #10
0
            private void onCollision(EntityCollidable sender, Collidable other, BEPUphysics.NarrowPhaseSystems.Pairs.CollidablePairHandler pair)
            {
                var otherEntity = other as EntityCollidable;

                if (otherEntity != null && FollowPlayer && otherEntity == player.character.CharacterController.Body.CollisionInformation)
                {
                    if (!player.canTakeTextures) // we absorbed textures too fast
                    {
                        FollowPlayer = false;
                        Target       = targetModel.Entity.Position;
                        linearMotor.Settings.Servo.Goal = Target;
                        try
                        {
                            CollisionRules.AddRule(Model.Entity, targetModel.Entity, CollisionRule.NoSolver);
                        }
                        catch { }
                    }
                    else
                    {
                        player.giveTexture(this);
                    }
                }
                else if (otherEntity != null && !FollowPlayer)
                {
                    if (!targetModel.Texture.Wireframe) // we launched textures too fast. turn around and go back to the player.
                    {
                        FollowPlayer = true;
                        try
                        {
                            CollisionRules.AddRule(Model.Entity, player.character.CharacterController.Body, CollisionRule.NoSolver);
                        }
                        catch { }
                        Target = player.character.CharacterController.Body.Position;
                        linearMotor.Settings.Servo.Goal = Target;
                    }
                    else
                    {
                        targetModel.GiveTexture(CarriedTex);
                        player.remove(this);
                    }
                }
            }
Пример #11
0
        public Player()
            : base(null, null, 100)
        {
            character = new CharacterControllerInput(GameManager.Space, RenderingDevice.Camera as CharacterCamera, new Vector3(-1, -16, 5));
            character.CharacterController.Body.Tag = this;
            character.CharacterController.HorizontalMotionConstraint.Speed          = 10;
            character.CharacterController.HorizontalMotionConstraint.CrouchingSpeed = 5;
            PhysicsObject = character.CharacterController.Body;                       // for posterity
            PhysicsObject.CollisionInformation.CollisionRules.Group = dynamicObjects; // also for posterity

            rayCastFilter = RayCastFilter;

            sword = new BaseModel(delegate { return(Program.Game.Loader.SwordModel); }, false, true, new Vector3(0.5f, -15, 4.2f));
            CollisionRules.AddRule(sword.Ent, PhysicsObject, CollisionRule.NoBroadPhase);
            sword.Ent.CollisionInformation.LocalPosition = new Vector3(0, -1, 0);
            sword.Ent.Orientation = Quaternion.CreateFromAxisAngle(Vector3.UnitX, -MathHelper.PiOver2);
            swordgrabber          = new MotorizedGrabSpring();
            swordgrabber.Setup(sword.Ent, sword.ModelPosition - Vector3.UnitX * 0.5f);
            sword.Ent.CollisionInformation.Events.PairTouching += onCollision;
        }
Пример #12
0
        /// <summary>
        /// Constructs a new demo.
        /// </summary>
        /// <param name="game">Game owning this demo.</param>
        public MPRCastingDemo(DemosGame game)
            : base(game)
        {
            bShape = new BoxShape(1, 0, 1);
            //bShape.CollisionMargin = 0;
            aShape = new ConeShape(1, .4f);
            //aShape.CollisionMargin = 0;
            a = new Entity(aShape);
            b = new Entity(bShape);
            CollisionRules.AddRule(a, b, CollisionRule.NoSolver);
            NarrowPhaseHelper.CollisionManagers.Remove(new TypePair(typeof(ConvexCollidable <BoxShape>), typeof(ConvexCollidable <BoxShape>)));
            Space.Add(a);
            Space.Add(b);
            a.Orientation = Quaternion.CreateFromAxisAngle(new Vector3(1, 0, 0), MathHelper.PiOver4);
            b.Orientation = Quaternion.Identity;
            aTransform    = new RigidTransform(new Vector3(-10, -10, -10), a.Orientation);
            bTransform    = new RigidTransform(new Vector3(10, 10, 10), b.Orientation);

            game.Camera.Position = new Vector3(0, 5, 17);
        }
        /// <summary>
        /// Constructs a new demo.
        /// </summary>
        /// <param name="game">Game owning this demo.</param>
        public FishInABarrelDemo(DemosGame game)
            : base(game)
        {
            game.Camera.Position = new Vector3(0, 7, 30);

            var detector = new Box(new Vector3(0, 0, 0), 1.5f, 1.5f, 1.5f);

            detector.CollisionInformation.CollisionRules.Personal = CollisionRule.NoSolver;
            var acceptedTriggerEntity = new Box(new Vector3(5, 0, 0), 1.6f, .7f, .4f, 1);

            acceptedTrigger = acceptedTriggerEntity.CollisionInformation;

            detector.Tag = "noDisplayObject";
            acceptedTriggerEntity.Tag = "noDisplayObject";
            Space.Add(detector);
            Space.Add(acceptedTriggerEntity);

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

            game.ModelDrawer.Add(new DisplayEntityModel(acceptedTriggerEntity, fish, game.ModelDrawer));

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

            Vector3[] staticTriangleVertices;
            int[]     staticTriangleIndices;
            ModelDataExtractor.GetVerticesAndIndicesFromModel(barrelAndPlatform, out staticTriangleVertices, out staticTriangleIndices);

            //Note that the final 'margin' parameter is optional, but can be used to specify a collision margin on triangles in the static triangle group.
            var fishDepositoryGroup = new StaticMesh(staticTriangleVertices, staticTriangleIndices);

            CollisionRules.AddRule(fishDepositoryGroup, detector, CollisionRule.NoBroadPhase);
            Space.Add(fishDepositoryGroup);
            game.ModelDrawer.Add(fishDepositoryGroup);


            movedBox = new Box(new Vector3(-4, 5, 0), 1, 1, 1, 1);
            detector.Space.Add(movedBox);
            detector.CollisionInformation.Events.InitialCollisionDetected += InitialCollisionDetected;
            detector.CollisionInformation.Events.CollisionEnded           += CollisionEnded;
        }
Пример #14
0
        public Entity AddWheel(Vector3 wheelPosition, Entity baseBody)
        {
            BepuEntity wheel = new BepuEntity();

            wheel.modelName = "cyl";
            wheel.LoadContent();
            wheel.body           = new Cylinder(wheelPosition, 2, 2, 2);
            wheel.localTransform = Matrix.CreateScale(2f, 2f, 2f);
            wheel.body.Material.KineticFriction = 2.5f;
            wheel.body.Material.StaticFriction  = 2.5f;
            wheel.body.Orientation = Quaternion.CreateFromAxisAngle(Vector3.Forward, MathHelper.PiOver2);
            wheel.diffuse          = new Vector3(0, 0, 0);

            //Prevents collisionf from happening
            CollisionRules.AddRule(wheel.body, baseBody, CollisionRule.NoBroadPhase);

            //Add the wheel and connection to the space.
            Game1.Instance.Space.Add(wheel.body);
            Game1.Instance.Children.Add(wheel);

            return(wheel.body);
        }
Пример #15
0
        /// <summary>
        /// Constructs a simple character controller.
        /// </summary>
        /// <param name="position">Location to initially place the character.</param>
        /// <param name="characterHeight">The height of the character.</param>
        /// <param name="characterWidth">The diameter of the character.</param>
        /// <param name="mass">Total mass of the character.</param>
        /// <param name="maximumStepHeight">Height that the character can climb up.</param>
        public CharacterControllerOld(Vector3 position, float characterHeight, float characterWidth, float mass, float maximumStepHeight)
        {
            //Create the physical body of the character.
            //The character's cylinder height and radius must be shrunk down marginally
            //to take into account the collision margin and support margin while still fitting in the defined character height/width.
            var   bodyPosition    = new Vector3(position.X, position.Y + supportMargin / 2, position.Z);
            float collisionMargin = .04f;

            Body = new Cylinder(bodyPosition,
                                characterHeight - 2 * collisionMargin - supportMargin,
                                characterWidth / 2 - collisionMargin,
                                mass);
            Body.CollisionInformation.Shape.CollisionMargin = collisionMargin;

            feetCollisionPairCollectorPositionOffset = new Vector3(0, -Body.Height / 2 - supportMargin - collisionMargin, 0);
            feetCollisionPairCollector = new Box(bodyPosition + feetCollisionPairCollectorPositionOffset, characterWidth, maximumStepHeight * 2, characterWidth, 1);
            feetCollisionPairCollector.CollisionInformation.CollisionRules.Personal = CollisionRule.NoNarrowPhaseUpdate; //Prevents collision detection/contact generation from being run.
            feetCollisionPairCollector.IsAffectedByGravity = false;
            CollisionRules.AddRule(feetCollisionPairCollector, Body, CollisionRule.NoBroadPhase);                        //Prevents the creation of any collision pairs between the body and the collector.
            feetSupportFinderOffset = new Vector3(0, feetCollisionPairCollectorPositionOffset.Y + maximumStepHeight, 0);

            headCollisionPairCollectorPositionOffset = new Vector3(0, (Body.Height + maximumStepHeight) / 2 + collisionMargin, 0);
            headCollisionPairCollector = new Box(bodyPosition + headCollisionPairCollectorPositionOffset, characterWidth, maximumStepHeight + collisionMargin, characterWidth, 1);
            headCollisionPairCollector.CollisionInformation.CollisionRules.Personal = CollisionRule.NoNarrowPhaseUpdate; //Prevents collision detection/contact generation from being run.
            headCollisionPairCollector.IsAffectedByGravity = false;
            CollisionRules.AddRule(headCollisionPairCollector, Body, CollisionRule.NoBroadPhase);                        //Prevents the creation of any collision pairs between the body and the collector.
            headBlockageFinderOffset = new Vector3(0, headCollisionPairCollectorPositionOffset.Y - maximumStepHeight / 2 - collisionMargin, 0);

            castingShape = new CylinderShape(0, Body.Radius + collisionMargin);
            castingShape.CollisionMargin = 0;

            this.maximumStepHeight = maximumStepHeight;
            this.supportMargin     = .01f;

            Body.LocalInertiaTensorInverse = new Matrix3X3();
            feetCollisionPairCollector.LocalInertiaTensorInverse = new Matrix3X3();
            headCollisionPairCollector.LocalInertiaTensorInverse = new Matrix3X3();
        }
Пример #16
0
        /// <summary>
        /// Constructs a new demo.
        /// </summary>
        /// <param name="game">Game owning this demo.</param>
        public CollisionFilteringDemo(DemosGame game)
            : base(game)
        {
            Entity toAdd;

            toAdd = new Box(new Vector3(0, -.5f, 0), 50, 1, 50);
            Space.Add(toAdd);

            //Set up two stacks which go through each other
            var firstStackGroup  = new CollisionGroup();
            var secondStackGroup = new CollisionGroup();

            //Adding this rule to the space's collision group rules will prevent entities belong to these two groups from generating collision pairs with each other.
            groupPair = new CollisionGroupPair(firstStackGroup, secondStackGroup);
            CollisionRules.CollisionGroupRules.Add(groupPair, CollisionRule.NoBroadPhase);

            for (int k = 0; k < 10; k++)
            {
                toAdd = new Box(
                    new Vector3(-4 + .12f * k, .5f + k, 0), 1f, 1f, 1f,
                    10);
                toAdd.CollisionInformation.CollisionRules.Group = firstStackGroup;
                Space.Add(toAdd);
                toAdd = new Box(new Vector3(4 - .12f * k, .5f + k, 0),
                                1f, 1f, 1f, 10);
                toAdd.CollisionInformation.CollisionRules.Group = secondStackGroup;
                Space.Add(toAdd);
            }
            //Add another two boxes which ignore each other using the specific entities method; they will still collide with the stacks since they will have the default dynamic collision group.
            toAdd = new Box(new Vector3(1, 3, 0), 1f, 4f, 2f, 10);
            var toAdd2 = new Box(new Vector3(-1, 3, 0), 1f, 4f, 2f, 15);

            CollisionRules.AddRule(toAdd, toAdd2, CollisionRule.NoBroadPhase);
            Space.Add(toAdd);
            Space.Add(toAdd2);
            game.Camera.Position = new Microsoft.Xna.Framework.Vector3(0, 6, 20);
        }
Пример #17
0
        void AddBackWheel(Vector3 suspensionOffset, Entity body, bool leftSide)
        {
            var         suspensionLeg         = new Box(body.Position + suspensionOffset, 0.25f, 0.8f, 0.25f, 10);
            const float horizontalWheelOffset = 0.2f;

            var wheel = new Cylinder(suspensionLeg.Position + new Vector3(leftSide ? -horizontalWheelOffset : horizontalWheelOffset, -suspensionLeg.HalfHeight, 0), .2f, .3f, 5f);

            wheel.Material.KineticFriction = 2.5f;
            wheel.Material.StaticFriction  = 3.5f;
            wheel.Orientation = Quaternion.CreateFromAxisAngle(Vector3.Forward, MathHelper.PiOver2);

            //Preventing the occasional pointless collision pair can speed things up.
            CollisionRules.AddRule(wheel, body, CollisionRule.NoBroadPhase);
            CollisionRules.AddRule(wheel, suspensionLeg, CollisionRule.NoBroadPhase);
            CollisionRules.AddRule(suspensionLeg, body, CollisionRule.NoBroadPhase);

            //Connect the suspension to the body.
            var bodyToSuspension = new PrismaticJoint(body, suspensionLeg, suspensionLeg.Position, Vector3.Down, suspensionLeg.Position);

            bodyToSuspension.Motor.Settings.Mode = MotorMode.Servomechanism;
            bodyToSuspension.Motor.IsActive      = true;
            bodyToSuspension.Motor.Settings.Servo.SpringSettings.Stiffness = 300;
            bodyToSuspension.Motor.Settings.Servo.SpringSettings.Damping   = 70;

            bodyToSuspension.Limit.IsActive = true;
            bodyToSuspension.Limit.Minimum  = -0.5f;
            bodyToSuspension.Limit.Maximum  = 0;

            //Connect the wheel to the suspension.
            var suspensionToWheel = new RevoluteJoint(suspensionLeg, wheel, wheel.Position, Vector3.Right);

            //Add the wheel and connection to the space.
            Space.Add(wheel);
            Space.Add(suspensionLeg);
            Space.Add(bodyToSuspension);
            Space.Add(suspensionToWheel);
        }
Пример #18
0
        public Ragdoll()
        {
            #region Ragdoll Entities
            //Create the ragdoll's bones.
            var pelvis      = new Box(Vector3.Zero, .5m, .28m, .33m, 20);
            var torsoBottom = new Box(pelvis.Position + new Vector3(0, .3m, 0), .42m, .48m, .3m, 15);
            var torsoTop    = new Box(torsoBottom.Position + new Vector3(0, .3m, 0), .5m, .38m, .32m, 20);

            var neck = new Box(torsoTop.Position + new Vector3(0, .2m, .04m), .19m, .24m, .2m, 5);
            var head = new Sphere(neck.Position + new Vector3(0, .22m, -.04m), .19m, 7);

            var leftUpperArm = new Box(torsoTop.Position + new Vector3(-.46m, .1m, 0), .52m, .19m, .19m, 6);
            var leftForearm  = new Box(leftUpperArm.Position + new Vector3(-.5m, 0, 0), .52m, .18m, .18m, 5);
            var leftHand     = new Box(leftForearm.Position + new Vector3(-.35m, 0, 0), .28m, .13m, .22m, 4);

            var rightUpperArm = new Box(torsoTop.Position + new Vector3(.46m, .1m, 0), .52m, .19m, .19m, 6);
            var rightForearm  = new Box(rightUpperArm.Position + new Vector3(.5m, 0, 0), .52m, .18m, .18m, 5);
            var rightHand     = new Box(rightForearm.Position + new Vector3(.35m, 0, 0), .28m, .13m, .22m, 4);

            var leftThigh = new Box(pelvis.Position + new Vector3(-.15m, -.4m, 0), .23m, .63m, .23m, 10);
            var leftShin  = new Box(leftThigh.Position + new Vector3(0, -.6m, 0), .21m, .63m, .21m, 7);
            var leftFoot  = new Box(leftShin.Position + new Vector3(0, -.35m, -.1m), .23m, .15m, .43m, 5);

            var rightThigh = new Box(pelvis.Position + new Vector3(.15m, -.4m, 0), .23m, .63m, .23m, 10);
            var rightShin  = new Box(rightThigh.Position + new Vector3(0, -.6m, 0), .21m, .63m, .21m, 7);
            var rightFoot  = new Box(rightShin.Position + new Vector3(0, -.35m, -.1m), .23m, .15m, .43m, 5);
            #endregion

            #region Bone List
            //Make a convenient list of all of the bones.
            bones.Add(pelvis);
            bones.Add(torsoBottom);
            bones.Add(torsoTop);
            bones.Add(neck);
            bones.Add(head);
            bones.Add(leftUpperArm);
            bones.Add(leftForearm);
            bones.Add(leftHand);
            bones.Add(rightUpperArm);
            bones.Add(rightForearm);
            bones.Add(rightHand);
            bones.Add(leftThigh);
            bones.Add(leftShin);
            bones.Add(leftFoot);
            bones.Add(rightThigh);
            bones.Add(rightShin);
            bones.Add(rightFoot);
            #endregion

            #region Collision Rules
            //Prevent adjacent limbs from colliding.
            CollisionRules.AddRule(pelvis, torsoBottom, CollisionRule.NoBroadPhase);
            CollisionRules.AddRule(torsoBottom, torsoTop, CollisionRule.NoBroadPhase);
            CollisionRules.AddRule(torsoTop, neck, CollisionRule.NoBroadPhase);
            CollisionRules.AddRule(neck, head, CollisionRule.NoBroadPhase);
            CollisionRules.AddRule(head, torsoTop, CollisionRule.NoBroadPhase);

            CollisionRules.AddRule(torsoTop, leftUpperArm, CollisionRule.NoBroadPhase);
            CollisionRules.AddRule(leftUpperArm, leftForearm, CollisionRule.NoBroadPhase);
            CollisionRules.AddRule(leftForearm, leftHand, CollisionRule.NoBroadPhase);

            CollisionRules.AddRule(torsoTop, rightUpperArm, CollisionRule.NoBroadPhase);
            CollisionRules.AddRule(rightUpperArm, rightForearm, CollisionRule.NoBroadPhase);
            CollisionRules.AddRule(rightForearm, rightHand, CollisionRule.NoBroadPhase);

            CollisionRules.AddRule(pelvis, leftThigh, CollisionRule.NoBroadPhase);
            CollisionRules.AddRule(leftThigh, leftShin, CollisionRule.NoBroadPhase);
            CollisionRules.AddRule(leftThigh, torsoBottom, CollisionRule.NoBroadPhase);
            CollisionRules.AddRule(leftShin, leftFoot, CollisionRule.NoBroadPhase);

            CollisionRules.AddRule(pelvis, rightThigh, CollisionRule.NoBroadPhase);
            CollisionRules.AddRule(rightThigh, rightShin, CollisionRule.NoBroadPhase);
            CollisionRules.AddRule(rightThigh, torsoBottom, CollisionRule.NoBroadPhase);
            CollisionRules.AddRule(rightShin, rightFoot, CollisionRule.NoBroadPhase);
            #endregion

            //Create the constraints between the bones.
            #region Pelvis up to Head Constraints
            var pelvisToTorsoBottomBallSocketJoint = new BallSocketJoint(pelvis, torsoBottom, pelvis.Position + new Vector3(0, .1m, 0));
            var pelvisToTorsoBottomTwistLimit      = new TwistLimit(pelvis, torsoBottom, Vector3.Up, Vector3.Up, -MathHelper.Pi / 6, MathHelper.Pi / 6);
            var pelvisToTorsoBottomSwingLimit      = new SwingLimit(pelvis, torsoBottom, Vector3.Up, Vector3.Up, MathHelper.Pi / 6);
            var pelvisToTorsoBottomMotor           = new AngularMotor(pelvis, torsoBottom);
            pelvisToTorsoBottomMotor.Settings.VelocityMotor.Softness = .05m;

            var torsoBottomToTorsoTopBallSocketJoint = new BallSocketJoint(torsoBottom, torsoTop, torsoBottom.Position + new Vector3(0, .25m, 0));
            var torsoBottomToTorsoTopSwingLimit      = new SwingLimit(torsoBottom, torsoTop, Vector3.Up, Vector3.Up, MathHelper.Pi / 6);
            var torsoBottomToTorsoTopTwistLimit      = new TwistLimit(torsoBottom, torsoTop, Vector3.Up, Vector3.Up, -MathHelper.Pi / 6, MathHelper.Pi / 6);
            var torsoBottomToTorsoTopMotor           = new AngularMotor(torsoBottom, torsoTop);
            torsoBottomToTorsoTopMotor.Settings.VelocityMotor.Softness = .05m;

            var torsoTopToNeckBallSocketJoint = new BallSocketJoint(torsoTop, neck, torsoTop.Position + new Vector3(0, .15m, .05m));
            var torsoTopToNeckSwingLimit      = new SwingLimit(torsoTop, neck, Vector3.Up, Vector3.Up, MathHelper.Pi / 6);
            var torsoTopToNeckTwistLimit      = new TwistLimit(torsoTop, neck, Vector3.Up, Vector3.Up, -MathHelper.Pi / 8, MathHelper.Pi / 8);
            var torsoTopToNeckMotor           = new AngularMotor(torsoTop, neck);
            torsoTopToNeckMotor.Settings.VelocityMotor.Softness = .1m;

            var neckToHeadBallSocketJoint = new BallSocketJoint(neck, head, neck.Position + new Vector3(0, .1m, .05m));
            var neckToHeadTwistLimit      = new TwistLimit(neck, head, Vector3.Up, Vector3.Up, -MathHelper.Pi / 8, MathHelper.Pi / 8);
            var neckToHeadSwingLimit      = new SwingLimit(neck, head, Vector3.Up, Vector3.Up, MathHelper.Pi / 6);
            var neckToHeadMotor           = new AngularMotor(neck, head);
            neckToHeadMotor.Settings.VelocityMotor.Softness = .1m;
            #endregion

            #region Left Arm
            var torsoTopToLeftArmBallSocketJoint = new BallSocketJoint(torsoTop, leftUpperArm, torsoTop.Position + new Vector3(-.3m, .1m, 0));
            var torsoTopToLeftArmEllipseLimit    = new EllipseSwingLimit(torsoTop, leftUpperArm, Vector3.Left, MathHelper.Pi * .75m, MathHelper.PiOver2);
            var torsoTopToLeftArmTwistLimit      = new TwistLimit(torsoTop, leftUpperArm, Vector3.Left, Vector3.Left, -MathHelper.PiOver2, MathHelper.PiOver2);
            var torsoTopToLeftArmMotor           = new AngularMotor(torsoTop, leftUpperArm);
            torsoTopToLeftArmMotor.Settings.VelocityMotor.Softness = .2m;

            var leftUpperArmToLeftForearmSwivelHingeJoint = new SwivelHingeJoint(leftUpperArm, leftForearm, leftUpperArm.Position + new Vector3(-.28m, 0, 0), Vector3.Up);
            leftUpperArmToLeftForearmSwivelHingeJoint.HingeLimit.IsActive     = true;
            leftUpperArmToLeftForearmSwivelHingeJoint.TwistLimit.IsActive     = true;
            leftUpperArmToLeftForearmSwivelHingeJoint.TwistLimit.MinimumAngle = -MathHelper.Pi / 8;
            leftUpperArmToLeftForearmSwivelHingeJoint.TwistLimit.MaximumAngle = MathHelper.Pi / 8;
            leftUpperArmToLeftForearmSwivelHingeJoint.HingeLimit.MinimumAngle = -MathHelper.Pi * .8m;
            leftUpperArmToLeftForearmSwivelHingeJoint.HingeLimit.MaximumAngle = 0;
            //The SwivelHingeJoint has motors, but they are separately defined for twist/bending.
            //The AngularMotor covers all degrees of freedom.
            var leftUpperArmToLeftForearmMotor = new AngularMotor(leftUpperArm, leftForearm);
            leftUpperArmToLeftForearmMotor.Settings.VelocityMotor.Softness = .3m;

            var leftForearmToLeftHandBallSocketJoint   = new BallSocketJoint(leftForearm, leftHand, leftForearm.Position + new Vector3(-.2m, 0, 0));
            var leftForearmToLeftHandEllipseSwingLimit = new EllipseSwingLimit(leftForearm, leftHand, Vector3.Left, MathHelper.PiOver2, MathHelper.Pi / 6);
            var leftForearmToLeftHandTwistLimit        = new TwistLimit(leftForearm, leftHand, Vector3.Left, Vector3.Left, -MathHelper.Pi / 6, MathHelper.Pi / 6);
            var leftForearmToLeftHandMotor             = new AngularMotor(leftForearm, leftHand);
            leftForearmToLeftHandMotor.Settings.VelocityMotor.Softness = .4m;
            #endregion

            #region Right Arm
            var torsoTopToRightArmBallSocketJoint = new BallSocketJoint(torsoTop, rightUpperArm, torsoTop.Position + new Vector3(.3m, .1m, 0));
            var torsoTopToRightArmEllipseLimit    = new EllipseSwingLimit(torsoTop, rightUpperArm, Vector3.Right, MathHelper.Pi * .75m, MathHelper.PiOver2);
            var torsoTopToRightArmTwistLimit      = new TwistLimit(torsoTop, rightUpperArm, Vector3.Right, Vector3.Right, -MathHelper.PiOver2, MathHelper.PiOver2);
            var torsoTopToRightArmMotor           = new AngularMotor(torsoTop, rightUpperArm);
            torsoTopToRightArmMotor.Settings.VelocityMotor.Softness = .2m;

            var rightUpperArmToRightForearmSwivelHingeJoint = new SwivelHingeJoint(rightUpperArm, rightForearm, rightUpperArm.Position + new Vector3(.28m, 0, 0), Vector3.Up);
            rightUpperArmToRightForearmSwivelHingeJoint.HingeLimit.IsActive     = true;
            rightUpperArmToRightForearmSwivelHingeJoint.TwistLimit.IsActive     = true;
            rightUpperArmToRightForearmSwivelHingeJoint.TwistLimit.MinimumAngle = -MathHelper.Pi / 8;
            rightUpperArmToRightForearmSwivelHingeJoint.TwistLimit.MaximumAngle = MathHelper.Pi / 8;
            rightUpperArmToRightForearmSwivelHingeJoint.HingeLimit.MinimumAngle = 0;
            rightUpperArmToRightForearmSwivelHingeJoint.HingeLimit.MaximumAngle = MathHelper.Pi * .8m;
            //The SwivelHingeJoint has motors, but they are separately defined for twist/bending.
            //The AngularMotor covers all degrees of freedom.
            var rightUpperArmToRightForearmMotor = new AngularMotor(rightUpperArm, rightForearm);
            rightUpperArmToRightForearmMotor.Settings.VelocityMotor.Softness = .3m;

            var rightForearmToRightHandBallSocketJoint   = new BallSocketJoint(rightForearm, rightHand, rightForearm.Position + new Vector3(.2m, 0, 0));
            var rightForearmToRightHandEllipseSwingLimit = new EllipseSwingLimit(rightForearm, rightHand, Vector3.Right, MathHelper.PiOver2, MathHelper.Pi / 6);
            var rightForearmToRightHandTwistLimit        = new TwistLimit(rightForearm, rightHand, Vector3.Right, Vector3.Right, -MathHelper.Pi / 6, MathHelper.Pi / 6);
            var rightForearmToRightHandMotor             = new AngularMotor(rightForearm, rightHand);
            rightForearmToRightHandMotor.Settings.VelocityMotor.Softness = .4m;
            #endregion

            #region Left Leg
            var pelvisToLeftThighBallSocketJoint   = new BallSocketJoint(pelvis, leftThigh, pelvis.Position + new Vector3(-.15m, -.1m, 0));
            var pelvisToLeftThighEllipseSwingLimit = new EllipseSwingLimit(pelvis, leftThigh, Vector3.Normalize(new Vector3(-.2m, -1, -.6m)), MathHelper.Pi * .7m, MathHelper.PiOver4);
            pelvisToLeftThighEllipseSwingLimit.LocalTwistAxisB = Vector3.Down;
            var pelvisToLeftThighTwistLimit = new TwistLimit(pelvis, leftThigh, Vector3.Down, Vector3.Down, -MathHelper.Pi / 6, MathHelper.Pi / 6);
            var pelvisToLeftThighMotor      = new AngularMotor(pelvis, leftThigh);
            pelvisToLeftThighMotor.Settings.VelocityMotor.Softness = .1m;

            var leftThighToLeftShinRevoluteJoint = new RevoluteJoint(leftThigh, leftShin, leftThigh.Position + new Vector3(0, -.3m, 0), Vector3.Right);
            leftThighToLeftShinRevoluteJoint.Limit.IsActive     = true;
            leftThighToLeftShinRevoluteJoint.Limit.MinimumAngle = -MathHelper.Pi * .8m;
            leftThighToLeftShinRevoluteJoint.Limit.MaximumAngle = 0;
            leftThighToLeftShinRevoluteJoint.Motor.IsActive     = true;
            leftThighToLeftShinRevoluteJoint.Motor.Settings.VelocityMotor.Softness = .2m;

            var leftShinToLeftFootBallSocketJoint = new BallSocketJoint(leftShin, leftFoot, leftShin.Position + new Vector3(0, -.3m, 0));
            var leftShinToLeftFootSwingLimit      = new SwingLimit(leftShin, leftFoot, Vector3.Forward, Vector3.Forward, MathHelper.Pi / 8);
            var leftShinToLeftFootTwistLimit      = new TwistLimit(leftShin, leftFoot, Vector3.Down, Vector3.Forward, -MathHelper.Pi / 8, MathHelper.Pi / 8);
            var leftShinToLeftFootMotor           = new AngularMotor(leftShin, leftFoot);
            leftShinToLeftFootMotor.Settings.VelocityMotor.Softness = .2m;

            #endregion

            #region Right Leg
            var pelvisToRightThighBallSocketJoint   = new BallSocketJoint(pelvis, rightThigh, pelvis.Position + new Vector3(.15m, -.1m, 0));
            var pelvisToRightThighEllipseSwingLimit = new EllipseSwingLimit(pelvis, rightThigh, Vector3.Normalize(new Vector3(.2m, -1, -.6m)), MathHelper.Pi * .7m, MathHelper.PiOver4);
            pelvisToRightThighEllipseSwingLimit.LocalTwistAxisB = Vector3.Down;
            var pelvisToRightThighTwistLimit = new TwistLimit(pelvis, rightThigh, Vector3.Down, Vector3.Down, -MathHelper.Pi / 6, MathHelper.Pi / 6);
            var pelvisToRightThighMotor      = new AngularMotor(pelvis, rightThigh);
            pelvisToRightThighMotor.Settings.VelocityMotor.Softness = .1m;

            var rightThighToRightShinRevoluteJoint = new RevoluteJoint(rightThigh, rightShin, rightThigh.Position + new Vector3(0, -.3m, 0), Vector3.Right);
            rightThighToRightShinRevoluteJoint.Limit.IsActive     = true;
            rightThighToRightShinRevoluteJoint.Limit.MinimumAngle = -MathHelper.Pi * .8m;
            rightThighToRightShinRevoluteJoint.Limit.MaximumAngle = 0;
            rightThighToRightShinRevoluteJoint.Motor.IsActive     = true;
            rightThighToRightShinRevoluteJoint.Motor.Settings.VelocityMotor.Softness = .2m;

            var rightShinToRightFootBallSocketJoint = new BallSocketJoint(rightShin, rightFoot, rightShin.Position + new Vector3(0, -.3m, 0));
            var rightShinToRightFootSwingLimit      = new SwingLimit(rightShin, rightFoot, Vector3.Forward, Vector3.Forward, MathHelper.Pi / 8);
            var rightShinToRightFootTwistLimit      = new TwistLimit(rightShin, rightFoot, Vector3.Down, Vector3.Forward, -MathHelper.Pi / 8, MathHelper.Pi / 8);
            var rightShinToRightFootMotor           = new AngularMotor(rightShin, rightFoot);
            rightShinToRightFootMotor.Settings.VelocityMotor.Softness = .2m;

            #endregion

            #region Joint List
            //Collect the joints.
            joints.Add(pelvisToTorsoBottomBallSocketJoint);
            joints.Add(pelvisToTorsoBottomTwistLimit);
            joints.Add(pelvisToTorsoBottomSwingLimit);
            joints.Add(pelvisToTorsoBottomMotor);

            joints.Add(torsoBottomToTorsoTopBallSocketJoint);
            joints.Add(torsoBottomToTorsoTopTwistLimit);
            joints.Add(torsoBottomToTorsoTopSwingLimit);
            joints.Add(torsoBottomToTorsoTopMotor);

            joints.Add(torsoTopToNeckBallSocketJoint);
            joints.Add(torsoTopToNeckTwistLimit);
            joints.Add(torsoTopToNeckSwingLimit);
            joints.Add(torsoTopToNeckMotor);

            joints.Add(neckToHeadBallSocketJoint);
            joints.Add(neckToHeadTwistLimit);
            joints.Add(neckToHeadSwingLimit);
            joints.Add(neckToHeadMotor);

            joints.Add(torsoTopToLeftArmBallSocketJoint);
            joints.Add(torsoTopToLeftArmEllipseLimit);
            joints.Add(torsoTopToLeftArmTwistLimit);
            joints.Add(torsoTopToLeftArmMotor);

            joints.Add(leftUpperArmToLeftForearmSwivelHingeJoint);
            joints.Add(leftUpperArmToLeftForearmMotor);

            joints.Add(leftForearmToLeftHandBallSocketJoint);
            joints.Add(leftForearmToLeftHandEllipseSwingLimit);
            joints.Add(leftForearmToLeftHandTwistLimit);
            joints.Add(leftForearmToLeftHandMotor);

            joints.Add(torsoTopToRightArmBallSocketJoint);
            joints.Add(torsoTopToRightArmEllipseLimit);
            joints.Add(torsoTopToRightArmTwistLimit);
            joints.Add(torsoTopToRightArmMotor);

            joints.Add(rightUpperArmToRightForearmSwivelHingeJoint);
            joints.Add(rightUpperArmToRightForearmMotor);

            joints.Add(rightForearmToRightHandBallSocketJoint);
            joints.Add(rightForearmToRightHandEllipseSwingLimit);
            joints.Add(rightForearmToRightHandTwistLimit);
            joints.Add(rightForearmToRightHandMotor);

            joints.Add(pelvisToLeftThighBallSocketJoint);
            joints.Add(pelvisToLeftThighEllipseSwingLimit);
            joints.Add(pelvisToLeftThighTwistLimit);
            joints.Add(pelvisToLeftThighMotor);

            joints.Add(leftThighToLeftShinRevoluteJoint);

            joints.Add(leftShinToLeftFootBallSocketJoint);
            joints.Add(leftShinToLeftFootSwingLimit);
            joints.Add(leftShinToLeftFootTwistLimit);
            joints.Add(leftShinToLeftFootMotor);

            joints.Add(pelvisToRightThighBallSocketJoint);
            joints.Add(pelvisToRightThighEllipseSwingLimit);
            joints.Add(pelvisToRightThighTwistLimit);
            joints.Add(pelvisToRightThighMotor);

            joints.Add(rightThighToRightShinRevoluteJoint);

            joints.Add(rightShinToRightFootBallSocketJoint);
            joints.Add(rightShinToRightFootSwingLimit);
            joints.Add(rightShinToRightFootTwistLimit);
            joints.Add(rightShinToRightFootMotor);
            #endregion
        }
Пример #19
0
            private void CreateWorld()
            {
                //Robot arm scene
                Owner.Space = new Space();
                Owner.Space.ForceUpdater.Gravity = new Vector3(0, -Owner.GRAVITY, 0);
                Entity ground = new Box(new Vector3(0, -0.5f, 0), 30, 1, 30);

                Owner.Space.Add(ground);

                var armBase = new Box(new Vector3(0, 0.25f, 0), 1, 0.5f, 1);

                Owner.Space.Add(armBase);

                var lowerArm = new Box(armBase.Position + new Vector3(0, armBase.Height / 2 + 0.75f, 0), 0.5f, 1.5f, 0.5f, 1f);

                Owner.Space.Add(lowerArm);

                var upperArm = new Box(lowerArm.Position + new Vector3(0, lowerArm.Height / 2 + 1, 0), 0.25f, 2, 0.25f, 0.1f);

                Owner.Space.Add(upperArm);

                pole = new Cylinder(upperArm.Position + new Vector3(0, upperArm.Height / 2 + 2, 0), 4, 0.0625f, 0.01f);
                Owner.Space.Add(pole);

                sphere = new Sphere(pole.Position + new Vector3(0, pole.Height / 2, 0), 0.25f, 0.001f);
                Owner.Space.Add(sphere);

                //Lower arm to base joint
                shoulder = new RevoluteJoint(armBase, lowerArm, armBase.Position + new Vector3(0, armBase.Height / 2, 0), Vector3.Forward);
                shoulder.Motor.IsActive              = true;
                shoulder.Motor.Settings.Mode         = Owner.MOTOR_MODE;
                shoulder.Motor.Settings.MaximumForce = 25;
                shoulder.Limit.IsActive              = true;

                float[] limits = GetLimits();

                shoulder.Limit.MinimumAngle = -MathHelper.Pi * limits[2];
                shoulder.Limit.MaximumAngle = MathHelper.Pi * limits[2];
                shoulder.Limit.Bounciness   = 0.0f;
                Owner.Space.Add(shoulder);

                //Upper arm to lower arm joint
                elbow = new RevoluteJoint(lowerArm, upperArm, lowerArm.Position + new Vector3(0, lowerArm.Height / 2, 0), Vector3.Left);
                elbow.Motor.IsActive = true;
                if (Owner.ELBOW_FIXED)
                {
                    elbow.Motor.Settings.Mode = MotorMode.Servomechanism;
                }
                else
                {
                    elbow.Motor.Settings.Mode = Owner.MOTOR_MODE;
                }
                elbow.Motor.Settings.MaximumForce = 2500;
                elbow.Limit.IsActive = true;

                elbow.Limit.MinimumAngle = -MathHelper.Pi * limits[1];
                elbow.Limit.MaximumAngle = MathHelper.Pi * limits[1];
                elbow.Limit.Bounciness   = 0.0f;
                Owner.Space.Add(elbow);

                if (Owner.POLE_DOF == 1)
                {
                    //Upper arm to pole joint
                    wrist = new RevoluteJoint(upperArm, pole, upperArm.Position + new Vector3(0, upperArm.Height / 2, 0), Vector3.Forward);
                    wrist.Motor.IsActive              = false;
                    wrist.Motor.Settings.Mode         = Owner.MOTOR_MODE;
                    wrist.Motor.Settings.MaximumForce = 2500;
                    wrist.Limit.IsActive              = true;
                    wrist.Limit.MinimumAngle          = -MathHelper.Pi * limits[0];
                    wrist.Limit.MaximumAngle          = -MathHelper.Pi * limits[0];
                    wrist.Limit.Bounciness            = 0.0f;
                    Owner.Space.Add(wrist);
                }
                else
                {
                    socket = new BallSocketJoint(upperArm, pole, upperArm.Position + new Vector3(0, upperArm.Height / 2, 0));
                    Owner.Space.Add(socket);
                }

                //Fixed pole to sphere joint
                var norotation = new RevoluteJoint(pole, sphere, pole.Position + new Vector3(0, pole.Height / 2 - 0.5f, 0), Vector3.Forward);

                norotation.Limit.IsActive     = true;
                norotation.Limit.MinimumAngle = 0.0f;
                norotation.Limit.MaximumAngle = 0.0f;

                Owner.Space.Add(norotation);

                CollisionRules.AddRule(armBase, lowerArm, CollisionRule.NoBroadPhase);
                CollisionRules.AddRule(lowerArm, upperArm, CollisionRule.NoBroadPhase);
                CollisionRules.AddRule(upperArm, pole, CollisionRule.NoBroadPhase);
                CollisionRules.AddRule(pole, sphere, CollisionRule.NoBroadPhase);
            }
Пример #20
0
        public JointLimitTestDemo(DemosGame game)
            : base(game)
        {
            float bounciness = 1;
            float baseMass   = 100;
            float armMass    = 10;
            //DistanceLimit
            Box boxA = new Box(new Vector3(-21, 4, 0), 3, 3, 3, baseMass);
            Box boxB = new Box(boxA.Position + new Vector3(0, 5, 0), 1, 4, 1, armMass);

            CollisionRules.AddRule(boxA, boxB, CollisionRule.NoBroadPhase);
            boxB.ActivityInformation.IsAlwaysActive = true;

            var distanceLimit = new DistanceLimit(boxA, boxB, boxA.Position, boxB.Position - new Vector3(0, 2, 0), 1, 6);

            distanceLimit.Bounciness = bounciness;

            Space.Add(boxA);
            Space.Add(boxB);
            Space.Add(distanceLimit);

            //EllipseSwingLimit
            boxA = new Box(new Vector3(-14, 4, 0), 3, 3, 3, baseMass);
            boxB = new Box(boxA.Position + new Vector3(0, 5, 0), 1, 4, 1, armMass);
            CollisionRules.AddRule(boxA, boxB, CollisionRule.NoBroadPhase);
            boxB.ActivityInformation.IsAlwaysActive = true;

            var ballSocketJoint   = new BallSocketJoint(boxA, boxB, boxB.Position + new Vector3(0, -2, 0));
            var ellipseSwingLimit = new EllipseSwingLimit(boxA, boxB, Vector3.Up, MathHelper.Pi / 1.5f, MathHelper.Pi / 3);

            ellipseSwingLimit.Bounciness = bounciness;

            Space.Add(boxA);
            Space.Add(boxB);
            Space.Add(ballSocketJoint);
            Space.Add(ellipseSwingLimit);

            //LinearAxisLimit
            boxA = new Box(new Vector3(-7, 4, 0), 3, 3, 3, baseMass);
            boxB = new Box(boxA.Position + new Vector3(0, 5, 0), 1, 4, 1, armMass);
            CollisionRules.AddRule(boxA, boxB, CollisionRule.NoBroadPhase);
            boxB.ActivityInformation.IsAlwaysActive = true;

            var pointOnLineJoint = new PointOnLineJoint(boxA, boxB, boxA.Position, Vector3.Up, boxB.Position + new Vector3(0, -2, 0));
            var linearAxisLimit  = new LinearAxisLimit(boxA, boxB, boxA.Position, boxB.Position + new Vector3(0, -2, 0), Vector3.Up, 0, 4);

            linearAxisLimit.Bounciness = bounciness;

            Space.Add(boxA);
            Space.Add(boxB);
            Space.Add(pointOnLineJoint);
            Space.Add(linearAxisLimit);

            //RevoluteLimit
            boxA = new Box(new Vector3(0, 4, 0), 3, 3, 3, baseMass);
            boxB = new Box(boxA.Position + new Vector3(0, 5, 0), 1, 4, 1, armMass);
            CollisionRules.AddRule(boxA, boxB, CollisionRule.NoBroadPhase);
            boxB.ActivityInformation.IsAlwaysActive = true;

            ballSocketJoint = new BallSocketJoint(boxA, boxB, boxB.Position + new Vector3(0, -2, 0));
            var revoluteAngularJoint = new RevoluteAngularJoint(boxA, boxB, Vector3.Forward);
            var revoluteLimit        = new RevoluteLimit(boxA, boxB, Vector3.Forward, Vector3.Up, -MathHelper.PiOver4, MathHelper.PiOver4);

            revoluteLimit.Bounciness = bounciness;

            Space.Add(boxA);
            Space.Add(boxB);
            Space.Add(ballSocketJoint);
            Space.Add(revoluteAngularJoint);
            Space.Add(revoluteLimit);

            //SwingLimit
            boxA = new Box(new Vector3(7, 4, 0), 3, 3, 3, baseMass);
            boxB = new Box(boxA.Position + new Vector3(0, 5, 0), 1, 4, 1, armMass);
            CollisionRules.AddRule(boxA, boxB, CollisionRule.NoBroadPhase);
            boxB.ActivityInformation.IsAlwaysActive = true;

            ballSocketJoint = new BallSocketJoint(boxA, boxB, boxB.Position + new Vector3(0, -2, 0));
            var swingLimit = new SwingLimit(boxA, boxB, Vector3.Up, Vector3.Up, MathHelper.PiOver4);

            swingLimit.Bounciness = bounciness;

            Space.Add(boxA);
            Space.Add(boxB);
            Space.Add(ballSocketJoint);
            Space.Add(swingLimit);

            //TwistLimit
            boxA = new Box(new Vector3(14, 4, 0), 3, 3, 3, baseMass);
            boxB = new Box(boxA.Position + new Vector3(0, 5, 0), 1, 4, 1, armMass);
            CollisionRules.AddRule(boxA, boxB, CollisionRule.NoBroadPhase);
            boxB.ActivityInformation.IsAlwaysActive = true;

            ballSocketJoint      = new BallSocketJoint(boxA, boxB, boxB.Position + new Vector3(0, -2, 0));
            revoluteAngularJoint = new RevoluteAngularJoint(boxA, boxB, Vector3.Up);
            var twistLimit = new TwistLimit(boxA, boxB, Vector3.Up, Vector3.Up, -MathHelper.PiOver4, MathHelper.PiOver4);

            twistLimit.Bounciness = bounciness;

            Space.Add(boxA);
            Space.Add(boxB);
            Space.Add(ballSocketJoint);
            Space.Add(revoluteAngularJoint);
            Space.Add(twistLimit);

            Space.Add(new Box(new Vector3(0, 0, 0), 60, 1, 60));
            game.Camera.Position = new Vector3(0, 6, 15);
        }
Пример #21
0
        protected override void InitializeSpace()
        {
            //Joints can also act like springs by modifying their springSettings.
            //Though using a bunch of DistanceJoint objects can be slower than just applying direct spring forces,
            //it is significantly more stable and allows rigid structures.
            //The extra stability can make it useful for cloth-like simulations.
            Entity          latticePiece;
            BallSocketJoint joint;

            NarrowPhaseHelper.Factories.BoxBox.Count    = 4000;
            NarrowPhaseHelper.Factories.BoxSphere.Count = 1000;

            int   numColumns = 40;
            int   numRows    = 40;
            Fix64 xSpacing   = 1.0m;
            Fix64 zSpacing   = 1.0m;
            var   lattice    = new Entity[numRows, numColumns];

            for (int i = 0; i < numRows; i++)
            {
                for (int j = 0; j < numColumns; j++)
                {
                    latticePiece = new Box(
                        new Vector3(
                            xSpacing * i - (numRows - 1) * xSpacing / 2,
                            15.58m,
                            2 + zSpacing * j - (numColumns - 1) * zSpacing / 2),
                        xSpacing, .2m, zSpacing, 10);

                    lattice[i, j] = latticePiece;

                    Space.Add(latticePiece);
                }
            }
            //The joints composing the cloth can have their max iterations set independently from the solver iterations.
            //More iterations (up to the solver's own max) will increase the quality at the cost of speed.
            int clothIterations = 3;

            //So while the above clamps joint iterations, setting the solver's iteration limit can lower the
            //rest of the solving load (collisions).
            Space.Solver.IterationLimit = 10;

            Fix64 damping = 20000, stiffness = 20000;
            Fix64 starchDamping = 5000, starchStiffness = 500;

            //Loop through the grid and set up the joints.
            for (int i = 0; i < numRows; i++)
            {
                for (int j = 0; j < numColumns; j++)
                {
                    if (i == 0 && j + 1 < numColumns)
                    {
                        //Add in column connections for left edge.
                        joint = new BallSocketJoint(lattice[0, j], lattice[0, j + 1], lattice[0, j].Position + new Vector3(-xSpacing / 2, 0, zSpacing / 2));
                        joint.SpringSettings.Damping = damping; joint.SpringSettings.Stiffness = stiffness;
                        joint.SolverSettings.MaximumIterationCount = clothIterations;
                        Space.Add(joint);
                    }
                    if (i == numRows - 1 && j + 1 < numColumns)
                    {
                        //Add in column connections for right edge.
                        joint = new BallSocketJoint(lattice[numRows - 1, j], lattice[numRows - 1, j + 1], lattice[numRows - 1, j].Position + new Vector3(xSpacing / 2, 0, zSpacing / 2));
                        joint.SpringSettings.Damping = damping; joint.SpringSettings.Stiffness = stiffness;
                        joint.SolverSettings.MaximumIterationCount = clothIterations;
                        Space.Add(joint);
                    }
                    if (i + 1 < numRows && j == 0)
                    {
                        //Add in row connections for top edge.
                        joint = new BallSocketJoint(lattice[i, 0], lattice[i + 1, 0], lattice[i, 0].Position + new Vector3(xSpacing / 2, 0, -zSpacing / 2));
                        joint.SpringSettings.Damping = damping; joint.SpringSettings.Stiffness = stiffness;
                        joint.SolverSettings.MaximumIterationCount = clothIterations;
                        Space.Add(joint);
                    }
                    if (i + 1 < numRows && j == numColumns - 1)
                    {
                        //Add in row connections for bottom edge.
                        joint = new BallSocketJoint(lattice[i, numColumns - 1], lattice[i + 1, numColumns - 1], lattice[i, numColumns - 1].Position + new Vector3(xSpacing / 2, 0, zSpacing / 2));
                        joint.SpringSettings.Damping = damping; joint.SpringSettings.Stiffness = stiffness;
                        joint.SolverSettings.MaximumIterationCount = clothIterations;
                        Space.Add(joint);
                    }


                    if (i + 1 < numRows && j + 1 < numColumns)
                    {
                        //Add in interior connections.
                        joint = new BallSocketJoint(lattice[i, j], lattice[i + 1, j], lattice[i, j].Position + new Vector3(xSpacing / 2, 0, zSpacing / 2));
                        joint.SpringSettings.Damping = damping; joint.SpringSettings.Stiffness = stiffness;
                        joint.SolverSettings.MaximumIterationCount = clothIterations;
                        Space.Add(joint);

                        joint = new BallSocketJoint(lattice[i, j], lattice[i, j + 1], lattice[i, j].Position + new Vector3(xSpacing / 2, 0, zSpacing / 2));
                        joint.SpringSettings.Damping = damping; joint.SpringSettings.Stiffness = stiffness;
                        joint.SolverSettings.MaximumIterationCount = clothIterations;
                        Space.Add(joint);

                        joint = new BallSocketJoint(lattice[i, j], lattice[i + 1, j + 1], lattice[i, j].Position + new Vector3(xSpacing / 2, 0, zSpacing / 2));
                        joint.SpringSettings.Damping = damping; joint.SpringSettings.Stiffness = stiffness;
                        joint.SolverSettings.MaximumIterationCount = clothIterations;
                        Space.Add(joint);
                    }

                    if (i + 2 < numRows && j + 2 < numColumns)
                    {
                        //Add in skipping 'starch' connections.
                        joint = new BallSocketJoint(lattice[i, j], lattice[i + 2, j], lattice[i, j].Position + new Vector3(xSpacing, 0, zSpacing));
                        joint.SpringSettings.Damping = starchDamping; joint.SpringSettings.Stiffness = starchStiffness;
                        joint.SolverSettings.MaximumIterationCount = clothIterations;
                        Space.Add(joint);

                        joint = new BallSocketJoint(lattice[i, j], lattice[i, j + 2], lattice[i, j].Position + new Vector3(xSpacing, 0, zSpacing));
                        joint.SpringSettings.Damping = starchDamping; joint.SpringSettings.Stiffness = starchStiffness;
                        joint.SolverSettings.MaximumIterationCount = clothIterations;
                        Space.Add(joint);

                        joint = new BallSocketJoint(lattice[i, j], lattice[i + 2, j + 2], lattice[i, j].Position + new Vector3(xSpacing, 0, zSpacing));
                        joint.SpringSettings.Damping = starchDamping; joint.SpringSettings.Stiffness = starchStiffness;
                        joint.SolverSettings.MaximumIterationCount = clothIterations;
                        Space.Add(joint);
                    }

                    //Add in collision rules.
                    if (j - 1 >= 0)
                    {
                        if (i - 1 >= 0)
                        {
                            CollisionRules.AddRule(lattice[i, j], lattice[i - 1, j - 1], CollisionRule.NoBroadPhase);
                        }
                        CollisionRules.AddRule(lattice[i, j], lattice[i, j - 1], CollisionRule.NoBroadPhase);
                        if (i + 1 < numRows)
                        {
                            CollisionRules.AddRule(lattice[i, j], lattice[i + 1, j - 1], CollisionRule.NoBroadPhase);
                        }
                    }

                    if (i + 1 < numRows)
                    {
                        CollisionRules.AddRule(lattice[i, j], lattice[i + 1, j], CollisionRule.NoBroadPhase);
                    }
                }
            }



            //Add some ground.
            var sphere = new Sphere(new Vector3(7, 0, 0), 10);

            sphere.Material.KineticFriction = .2m;
            Space.Add(sphere);
            Space.Add(new Box(new Vector3(0, -20.5m, 0), 100, 10, 100));
        }
Пример #22
0
        /// <summary>
        /// Constructs a new demo.
        /// </summary>
        /// <param name="game">Game owning this demo.</param>
        public ReverseTrikeDemo(DemosGame game)
            : base(game)
        {
            game.Camera.Position = new Microsoft.Xna.Framework.Vector3(0, 2, 15);
            game.Camera.Yaw      = 0;
            game.Camera.Pitch    = 0;

            Space.Add(new Box(new Vector3(0, -5, 0), 20, 1, 20));

            var body = new Box(new Vector3(0, 0, 0), 2, 1, 3, 10);

            body.CollisionInformation.LocalPosition = new Vector3(0, .8f, 0);
            Space.Add(body);

            #region First Wheel

            var wheel = new Cylinder(body.Position + new Vector3(-1.3f, 0, -1.5f), .2f, .5f, 4);
            wheel.Material    = new Material(1.5f, 1.5f, 0);
            wheel.Orientation = Quaternion.CreateFromAxisAngle(Vector3.Forward, MathHelper.PiOver2);

            //Preventing the occasional pointless collision pair can speed things up.
            CollisionRules.AddRule(body, wheel, CollisionRule.NoBroadPhase);

            //Connect the wheel to the body.
            var ballSocketJoint         = new BallSocketJoint(body, wheel, wheel.Position);
            var swivelHingeAngularJoint = new SwivelHingeAngularJoint(body, wheel, Vector3.Up, Vector3.Right);
            //Motorize the wheel.
            drivingMotor1 = new RevoluteMotor(body, wheel, Vector3.Left);
            drivingMotor1.Settings.VelocityMotor.Softness = .2f;
            //Let it roll when the user isn't giving specific commands.
            drivingMotor1.IsActive       = false;
            steeringMotor1               = new RevoluteMotor(body, wheel, Vector3.Up);
            steeringMotor1.Settings.Mode = MotorMode.Servomechanism;
            //The constructor makes a guess about how to set up the constraint.
            //It can't always be right since it doesn't have all the information;
            //in this case, it chooses the basis and test axis incorrectly.
            //This leads to a 'flipping' behavior when the wheel is rolling
            //(the test axis is 'rolling' with the wheel, and passes over
            //a singularity which causes a flip).

            //To fix this, we configure the constraint directly.
            //The basis is aligned with how the wheel is set up; we choose 'up' as
            //the motorized axis, and right/forward to define the angle measurement plane.
            //The test axis is set to be perpendicular to the wheel's rotation so that
            //it only measures the steering angle.

            //If you're curious, the angle measurement is just a Math.Atan2.
            //The current world test axis is dotted against the two plane axes (Right and Forward here).
            //This gives an x and y value.  These can be plugged into Atan2 just like when
            //you compute an angle on a normal 2d graph.
            steeringMotor1.Basis.SetWorldAxes(Vector3.Up, Vector3.Right, Vector3.Forward);
            steeringMotor1.TestAxis = Vector3.Right;


            //Add the wheel and connection to the space.
            Space.Add(wheel);
            Space.Add(ballSocketJoint);
            Space.Add(swivelHingeAngularJoint);
            Space.Add(drivingMotor1);
            Space.Add(steeringMotor1);

            #endregion

            #region Second Wheel

            wheel             = new Cylinder(body.Position + new Vector3(1.3f, 0, -1.5f), .2f, .5f, 4);
            wheel.Material    = new Material(1.5f, 1.5f, 0);
            wheel.Orientation = Quaternion.CreateFromAxisAngle(Vector3.Forward, MathHelper.PiOver2);


            //Preventing the occasional pointless collision pair can speed things up.
            CollisionRules.AddRule(body, wheel, CollisionRule.NoBroadPhase);

            //Connect the wheel to the body.
            ballSocketJoint         = new BallSocketJoint(body, wheel, wheel.Position);
            swivelHingeAngularJoint = new SwivelHingeAngularJoint(body, wheel, Vector3.Up, Vector3.Right);
            //Motorize the wheel.
            drivingMotor2 = new RevoluteMotor(body, wheel, Vector3.Left);
            drivingMotor2.Settings.VelocityMotor.Softness = .2f;
            //Let it roll when the user isn't giving specific commands.
            drivingMotor2.IsActive       = false;
            steeringMotor2               = new RevoluteMotor(body, wheel, Vector3.Up);
            steeringMotor2.Settings.Mode = MotorMode.Servomechanism;
            //Configure the motor.  See wheel 1 for more description.
            steeringMotor2.Basis.SetWorldAxes(Vector3.Up, Vector3.Right, Vector3.Forward);
            steeringMotor2.TestAxis = Vector3.Right;


            //Add the wheel and connection to the space.
            Space.Add(wheel);
            Space.Add(ballSocketJoint);
            Space.Add(swivelHingeAngularJoint);
            Space.Add(drivingMotor2);
            Space.Add(steeringMotor2);

            #endregion

            #region Third Wheel

            wheel             = new Cylinder(body.Position + new Vector3(0, -.3f, 1.5f), .2f, .5f, 4);
            wheel.Material    = new Material(1.5f, 1.5f, 0);
            wheel.Orientation = Quaternion.CreateFromAxisAngle(Vector3.Forward, MathHelper.PiOver2);

            //Preventing the occasional pointless collision pair can speed things up.
            CollisionRules.AddRule(body, wheel, CollisionRule.NoBroadPhase);

            //Connect the wheel to the body.
            ballSocketJoint = new BallSocketJoint(body, wheel, wheel.Position);
            //Notice that the third wheel isn't a swivel hinge, it's just a revolute axis.
            //This lets it roll, but prevents flopping around like the wheels of a grocery cart.
            //Could have used a RevoluteJoint solver group here, but this shows it's possible to do
            //the same things without using the combo-constraints.
            var revoluteAngularJoint = new RevoluteAngularJoint(body, wheel, Vector3.Right);

            //Add the wheel and connection to the space.
            Space.Add(wheel);
            Space.Add(ballSocketJoint);
            Space.Add(revoluteAngularJoint);

            #endregion

            int xLength = 256;
            int zLength = 256;

            float xSpacing = 8f;
            float zSpacing = 8f;
            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)(x * y / 1000f);
                    heights[i, j] = (float)(10 * (Math.Sin(x / 8) + Math.Sin(z / 8)));
                    //heights[i,j] = 3 * (float)Math.Sin(x * y / 100f);
                    //heights[i,j] = (x * x * x * y - y * y * y * x) / 1000f;
                }
            }
            //Create the terrain.
            var terrain = new Terrain(heights, new AffineTransform(
                                          new Vector3(xSpacing, 1, zSpacing),
                                          Quaternion.Identity,
                                          new Vector3(-xLength * xSpacing / 2, -10, -zLength * zSpacing / 2)));
            Space.Add(terrain);

            game.ModelDrawer.Add(terrain);
        }
        /// <summary>
        /// Constructs a new demo.
        /// </summary>
        /// <param name="game">Game owning this demo.</param>
        public MobileMeshSolidityTestDemo(DemosGame game)
            : base(game)
        {
            Vector3[] vertices;
            int[]     indices;

            //Hardcoded box
            vertices = new Vector3[]
            {
                new Vector3(0.5m, 0.5m, 0.5m),
                new Vector3(0.5m, 0.5m, -0.5m),
                new Vector3(-0.5000001m, 0.5m, -0.4999999m),
                new Vector3(-0.4999998m, 0.5m, 0.5000002m),
                new Vector3(-0.4999998m, -0.5m, 0.5000002m),
                new Vector3(-0.5000001m, -0.5m, -0.4999999m),
                new Vector3(0.5m, -0.5m, -0.5m),
                new Vector3(0.5m, -0.5m, 0.5m),
                new Vector3(0.5m, 0.5m, 0.5m),
                new Vector3(0.5m, -0.5m, 0.5m),
                new Vector3(0.5m, -0.5m, -0.5m),
                new Vector3(0.5m, 0.5m, -0.5m),
                new Vector3(0.5m, 0.5m, -0.5m),
                new Vector3(0.5m, -0.5m, -0.5m),
                new Vector3(-0.5000001m, -0.5m, -0.4999999m),
                new Vector3(-0.5000001m, 0.5m, -0.4999999m),
                new Vector3(-0.5000001m, 0.5m, -0.4999999m),
                new Vector3(-0.5000001m, -0.5m, -0.4999999m),
                new Vector3(-0.4999998m, -0.5m, 0.5000002m),
                new Vector3(-0.4999998m, 0.5m, 0.5000002m),
                new Vector3(-0.4999998m, 0.5m, 0.5000002m),
                new Vector3(-0.4999998m, -0.5m, 0.5000002m),
                new Vector3(0.5m, -0.5m, 0.5m),
                new Vector3(0.5m, 0.5m, 0.5m)
            };

            indices = new[]
            {
                2, 1, 0,
                3, 2, 0,
                6, 5, 4,
                7, 6, 4,
                10, 9, 8,
                11, 10, 8,
                14, 13, 12,
                15, 14, 12,
                18, 17, 16,
                19, 18, 16,
                22, 21, 20,
                23, 22, 20
            };

            var mesh = new MobileMesh(vertices, indices, AffineTransform.Identity, MobileMeshSolidity.Solid, 10);

            Space.Add(mesh);

            //Tube
            ModelDataExtractor.GetVerticesAndIndicesFromModel(game.Content.Load <Model>("tube"), out vertices, out indices);
            mesh          = new MobileMesh(vertices, indices, AffineTransform.Identity, MobileMeshSolidity.Solid, 10);
            mesh.Position = new Vector3(-10, 10, 0);
            Space.Add(mesh);

            //Cube
            ModelDataExtractor.GetVerticesAndIndicesFromModel(game.Content.Load <Model>("cube"), out vertices, out indices);
            mesh          = new MobileMesh(vertices, indices, AffineTransform.Identity, MobileMeshSolidity.Solid, 10);
            mesh.Position = new Vector3(10, 0, 0);
            Space.Add(mesh);

            //Guy
            ModelDataExtractor.GetVerticesAndIndicesFromModel(game.Content.Load <Model>("guy"), out vertices, out indices);
            mesh          = new MobileMesh(vertices, indices, AffineTransform.Identity, MobileMeshSolidity.Solid, 10);
            mesh.Position = new Vector3(0, 0, 10);
            Space.Add(mesh);

            //Barrel Platform
            ModelDataExtractor.GetVerticesAndIndicesFromModel(game.Content.Load <Model>("barrelandplatform"), out vertices, out indices);
            mesh          = new MobileMesh(vertices, indices, AffineTransform.Identity, MobileMeshSolidity.Solid, 10);
            mesh.Position = new Vector3(0, 0, -10);
            Space.Add(mesh);

            //FloaterTube
            ModelDataExtractor.GetVerticesAndIndicesFromModel(game.Content.Load <Model>("tube"), out vertices, out indices);
            mesh          = new MobileMesh(vertices, indices, new AffineTransform(new Vector3(1, 1, 1), Quaternion.Identity, new Vector3(0, 0, 0)), MobileMeshSolidity.Solid);
            mesh.Position = new Vector3(5, 18, 0);
            Space.Add(mesh);

            //Float a box through the last mesh to check contact generation controllably.
            var solidityTester = new Box(new Vector3(5, 8, 0), 1, 1, 1);

            solidityTester.LinearVelocity = new Vector3(0, 1, 0);
            CollisionRules.AddRule(solidityTester, mesh, CollisionRule.NoSolver);
            Space.Add(solidityTester);


            Space.Add(new Box(new Vector3(0, -5, 0), 50, 1, 50));

            game.Camera.Position = new Vector3(0, 10, 20);
        }
Пример #24
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);
        }
Пример #25
0
        public void ApplyHook(PlayerEntity player, ItemStack item, Location Position, BEPUphysics.Entities.Entity HitEnt)
        {
            RemoveHook(player);
            PhysicsEntity pe;
            double        len  = (double)(Position - player.GetCenter()).Length();
            Location      step = (player.GetCenter() - Position) / len;
            Location      forw = Utilities.VectorToAngles(step);

            forw.Yaw += 180;
            BEPUutilities.Quaternion quat = BEPUutilities.Quaternion.CreateFromAxisAngle(new Vector3(1, 0, 0), (double)(forw.Pitch * Utilities.PI180)) *
                                            BEPUutilities.Quaternion.CreateFromAxisAngle(new Vector3(0, 0, 1), (double)(forw.Yaw * Utilities.PI180));
            if (HitEnt == null)
            {
                ModelEntity mod = new ModelEntity("cube", player.TheRegion)
                {
                    Mass    = 0,
                    CanSave = false,
                    scale   = new Location(0.023, 0.05, 0.05),
                    mode    = ModelCollisionMode.AABB
                };
                mod.SetPosition(Position);
                mod.SetOrientation(quat);
                player.TheRegion.SpawnEntity(mod);
                pe = mod;
                player.Hooks.Add(new HookInfo()
                {
                    Joint = null, Hit = pe, IsBar = true
                });
            }
            else
            {
                pe = (PhysicsEntity)HitEnt.Tag;
            }
            JointDistance jd;
            //jd = new JointDistance(player, pe, 0.01f, len + 0.01f, player.GetCenter(), Position);
            //player.TheRegion.AddJoint(jd);
            //player.Hooks.Add(new HookInfo() { Joint = jd, Hit = pe, IsBar = false });
            PhysicsEntity cent = pe;

            for (double f = 0; f < len - 1f; f += 0.5f)
            {
                Location    cpos = Position + step * f;
                ModelEntity ce   = new ModelEntity("cube", player.TheRegion)
                {
                    Mass    = 15,
                    CanSave = false,
                    scale   = new Location(0.023, 0.05, 0.05),
                    mode    = ModelCollisionMode.AABB
                };
                ce.SetPosition(cpos + step * 0.5);
                ce.SetOrientation(quat);
                player.TheRegion.SpawnEntity(ce);
                jd = new JointDistance(ce, cent, 0.01f, 0.5f, ce.GetPosition(), (ReferenceEquals(cent, pe) ? Position: cent.GetPosition()));
                CollisionRules.AddRule(player.Body, ce.Body, CollisionRule.NoBroadPhase);
                player.TheRegion.AddJoint(jd);
                player.Hooks.Add(new HookInfo()
                {
                    Joint = jd, Hit = ce, IsBar = true
                });
                cent = ce;
            }
            jd = new JointDistance(cent, player, 0.01f, 0.5f, cent.GetPosition(), player.GetCenter());
            player.TheRegion.AddJoint(jd);
            player.Hooks.Add(new HookInfo()
            {
                Joint = jd, Hit = player, IsBar = false
            });
        }
Пример #26
0
 public override void Enable()
 {
     CollisionRules.AddRule(((PhysicsEntity)One).Body.CollisionInformation, ((PhysicsEntity)Two).Body.CollisionInformation, CollisionRule.NoBroadPhase);
     CollisionRules.AddRule(((PhysicsEntity)Two).Body.CollisionInformation, ((PhysicsEntity)One).Body.CollisionInformation, CollisionRule.NoBroadPhase);
     base.Enable();
 }
Пример #27
0
        /// <summary>
        /// Constructs a new demo.
        /// </summary>
        /// <param name="game">Game owning this demo.</param>
        public SelfCollidingClothDemo(DemosGame game)
            : base(game)
        {
            //Joints can also act like springs by modifying their springSettings.
            //Though using a bunch of DistanceJoint objects can be slower than just applying direct spring forces,
            //it is significantly more stable and allows rigid structures.
            //The extra stability can make it useful for cloth-like simulations.
            Entity          latticePiece;
            BallSocketJoint joint;

            NarrowPhaseHelper.Factories.BoxBox.Count    = 10000;
            NarrowPhaseHelper.Factories.BoxSphere.Count = 5000;

            int   numColumns = 70;
            int   numRows    = 70;
            float xSpacing   = .5f;
            float zSpacing   = .5f;
            var   lattice    = new Entity[numRows, numColumns];

            for (int i = 0; i < numRows; i++)
            {
                for (int j = 0; j < numColumns; j++)
                {
                    latticePiece = new Box(
                        new Vector3(
                            xSpacing * i - (numRows - 1) * xSpacing / 2f,
                            15.58f,
                            2 + zSpacing * j - (numColumns - 1) * zSpacing / 2f),
                        xSpacing, .1f, zSpacing, 1);

                    //latticePiece.LocalInertiaTensorInverse = new Matrix3X3();
                    //latticePiece.Tag = "noDisplayObject"; //The joint lines are visible enough; don't add a sphere model for this sphere.
                    lattice[i, j] = latticePiece;
                    latticePiece.Material.KineticFriction = 0;

                    Space.Add(latticePiece);
                }
            }
            //The joints composing the cloth can have their max iterations set independently from the solver iterations.
            //More iterations (up to the solver's own max) will increase the quality at the cost of speed.
            int clothIterations = 10;

            //So while the above prevents joints from using more than 1 iteration, setting the solver's iteration limit can lower the
            //rest of the solving load (collisions).
            Space.Solver.IterationLimit = 10;

            float damping = 5000, stiffness = 5000;
            float starchDamping = 5000, starchStiffness = 500;

            //Loop through the grid and set up the joints.
            for (int i = 0; i < numRows; i++)
            {
                for (int j = 0; j < numColumns; j++)
                {
                    if (i == 0 && j + 1 < numColumns)
                    {
                        //Add in column connections for left edge.
                        joint = new BallSocketJoint(lattice[0, j], lattice[0, j + 1], lattice[0, j].Position + new Vector3(-xSpacing / 2, 0, zSpacing / 2));
                        joint.SpringSettings.DampingConstant   = damping; joint.SpringSettings.StiffnessConstant = stiffness;
                        joint.SolverSettings.MaximumIterations = clothIterations;
                        Space.Add(joint);
                    }
                    if (i == numRows - 1 && j + 1 < numColumns)
                    {
                        //Add in column connections for right edge.
                        joint = new BallSocketJoint(lattice[numRows - 1, j], lattice[numRows - 1, j + 1], lattice[numRows - 1, j].Position + new Vector3(xSpacing / 2, 0, zSpacing / 2));
                        joint.SpringSettings.DampingConstant   = damping; joint.SpringSettings.StiffnessConstant = stiffness;
                        joint.SolverSettings.MaximumIterations = clothIterations;
                        Space.Add(joint);
                    }
                    if (i + 1 < numRows && j == 0)
                    {
                        //Add in row connections for top edge.
                        joint = new BallSocketJoint(lattice[i, 0], lattice[i + 1, 0], lattice[i, 0].Position + new Vector3(xSpacing / 2, 0, -zSpacing / 2));
                        joint.SpringSettings.DampingConstant   = damping; joint.SpringSettings.StiffnessConstant = stiffness;
                        joint.SolverSettings.MaximumIterations = clothIterations;
                        Space.Add(joint);
                    }
                    if (i + 1 < numRows && j == numColumns - 1)
                    {
                        //Add in row connections for bottom edge.
                        joint = new BallSocketJoint(lattice[i, numColumns - 1], lattice[i + 1, numColumns - 1], lattice[i, numColumns - 1].Position + new Vector3(xSpacing / 2, 0, zSpacing / 2));
                        joint.SpringSettings.DampingConstant   = damping; joint.SpringSettings.StiffnessConstant = stiffness;
                        joint.SolverSettings.MaximumIterations = clothIterations;
                        Space.Add(joint);
                    }


                    if (i + 1 < numRows && j + 1 < numColumns)
                    {
                        //Add in interior connections.
                        joint = new BallSocketJoint(lattice[i, j], lattice[i + 1, j], lattice[i, j].Position + new Vector3(xSpacing / 2, 0, zSpacing / 2));
                        joint.SpringSettings.DampingConstant   = damping; joint.SpringSettings.StiffnessConstant = stiffness;
                        joint.SolverSettings.MaximumIterations = clothIterations;
                        Space.Add(joint);

                        joint = new BallSocketJoint(lattice[i, j], lattice[i, j + 1], lattice[i, j].Position + new Vector3(xSpacing / 2, 0, zSpacing / 2));
                        joint.SpringSettings.DampingConstant   = damping; joint.SpringSettings.StiffnessConstant = stiffness;
                        joint.SolverSettings.MaximumIterations = clothIterations;
                        Space.Add(joint);

                        joint = new BallSocketJoint(lattice[i, j], lattice[i + 1, j + 1], lattice[i, j].Position + new Vector3(xSpacing / 2, 0, zSpacing / 2));
                        joint.SpringSettings.DampingConstant   = damping; joint.SpringSettings.StiffnessConstant = stiffness;
                        joint.SolverSettings.MaximumIterations = clothIterations;
                        Space.Add(joint);
                    }

                    if (i + 2 < numRows && j + 2 < numColumns)
                    {
                        //Add in skipping 'starch' connections.
                        joint = new BallSocketJoint(lattice[i, j], lattice[i + 2, j], lattice[i, j].Position + new Vector3(xSpacing, 0, zSpacing));
                        joint.SpringSettings.DampingConstant   = starchDamping; joint.SpringSettings.StiffnessConstant = starchStiffness;
                        joint.SolverSettings.MaximumIterations = clothIterations;
                        Space.Add(joint);

                        joint = new BallSocketJoint(lattice[i, j], lattice[i, j + 2], lattice[i, j].Position + new Vector3(xSpacing, 0, zSpacing));
                        joint.SpringSettings.DampingConstant   = starchDamping; joint.SpringSettings.StiffnessConstant = starchStiffness;
                        joint.SolverSettings.MaximumIterations = clothIterations;
                        Space.Add(joint);

                        joint = new BallSocketJoint(lattice[i, j], lattice[i + 2, j + 2], lattice[i, j].Position + new Vector3(xSpacing, 0, zSpacing));
                        joint.SpringSettings.DampingConstant   = starchDamping; joint.SpringSettings.StiffnessConstant = starchStiffness;
                        joint.SolverSettings.MaximumIterations = clothIterations;
                        Space.Add(joint);
                    }

                    //Add in collision rules.
                    if (j - 1 >= 0)
                    {
                        if (i - 1 >= 0)
                        {
                            CollisionRules.AddRule(lattice[i, j], lattice[i - 1, j - 1], CollisionRule.NoBroadPhase);
                        }
                        CollisionRules.AddRule(lattice[i, j], lattice[i, j - 1], CollisionRule.NoBroadPhase);
                        if (i + 1 < numRows)
                        {
                            CollisionRules.AddRule(lattice[i, j], lattice[i + 1, j - 1], CollisionRule.NoBroadPhase);
                        }
                    }

                    if (i + 1 < numRows)
                    {
                        CollisionRules.AddRule(lattice[i, j], lattice[i + 1, j], CollisionRule.NoBroadPhase);
                    }
                }
            }



            //Add some ground.
            Space.Add(new Sphere(new Vector3(7, 0, 0), 10));
            Space.Add(new Box(new Vector3(0, -20.5f, 0), 100f, 10, 100f));

            game.Camera.Position = new Microsoft.Xna.Framework.Vector3(0, 5, 25);
        }
Пример #28
0
        /// <summary>
        /// Constructs a simple character controller.
        /// </summary>
        /// <param name="position">Location to initially place the character.</param>
        /// <param name="height">The height of the character.</param>
        /// <param name="radius">The diameter of the character.</param>
        /// <param name="supportHeight">The distance above the ground that the bottom of the character's body floats.</param>
        /// <param name="mass">Total mass of the character.</param>
        public Character(Main main, Bindable bindable, Vector3 position, float height = Character.DefaultHeight, float crouchedHeight = Character.DefaultCrouchedHeight, float radius = Character.DefaultRadius, float supportHeight = Character.DefaultSupportHeight, float crouchedSupportHeight = Character.DefaultCrouchedSupportHeight, float mass = Character.DefaultMass)
        {
            this.main         = main;
            this.Radius.Value = radius;
            this.Mass.Value   = mass;
            this.Body         = new Capsule(position, height, radius, mass);
            this.Body.Tag     = this;
            this.Body.CollisionInformation.Tag = this;
            this.Body.IgnoreShapeChanges       = true;
            this.Body.LinearDamping            = 0.0f;
            this.Body.CollisionInformation.CollisionRules.Group = Character.CharacterGroup;
            this.NormalHeight   = height;
            this.CrouchedHeight = crouchedHeight;
            this.Body.CollisionInformation.Events.ContactCreated += new BEPUphysics.BroadPhaseEntries.Events.ContactCreatedEventHandler <EntityCollidable>(Events_ContactCreated);
            this.collisionPairCollector = new Box(position + new Vector3(0, (height * -0.5f) - supportHeight, 0), radius * 2, supportHeight * 2, radius, 1);
            this.collisionPairCollector.CollisionInformation.CollisionRules.Personal = CollisionRule.NoNarrowPhaseUpdate;             //Prevents collision detection/contact generation from being run.
            this.collisionPairCollector.IsAffectedByGravity = false;
            this.collisionPairCollector.CollisionInformation.CollisionRules.Group = Character.CharacterGroup;
            CollisionRules.AddRule(this.collisionPairCollector, this.Body, CollisionRule.NoBroadPhase);             //Prevents the creation of any collision pairs between the body and the collector.
            this.SupportHeight.Value   = supportHeight;
            this.NormalSupportHeight   = supportHeight;
            this.CrouchedSupportHeight = crouchedSupportHeight;

            this.Body.LocalInertiaTensorInverse = new BEPUutilities.Matrix3x3();
            this.collisionPairCollector.LocalInertiaTensorInverse = new BEPUutilities.Matrix3x3();

            bindable.Add(new ChangeBinding <bool>(this.Crouched, delegate(bool old, bool value)
            {
                if (value && !old)
                {
                    this.Body.Position      += new Vector3(0, (this.CrouchedSupportHeight - this.NormalSupportHeight) + 0.5f * (this.CrouchedHeight - this.NormalHeight), 0);
                    this.Height.Value        = this.CrouchedHeight;
                    this.Body.Length         = this.Height.Value - this.Radius * 2;
                    this.SupportHeight.Value = this.CrouchedSupportHeight;
                }
                else if (!value && old)
                {
                    this.Height.Value        = this.NormalHeight;
                    this.Body.Length         = this.Height.Value - this.Radius * 2;
                    this.Body.Position      += new Vector3(0, (this.NormalSupportHeight - this.CrouchedSupportHeight) + 0.5f * (this.NormalHeight - this.CrouchedHeight), 0);
                    this.SupportHeight.Value = this.NormalSupportHeight;
                }
                this.collisionPairCollector.Height = this.SupportHeight * 2;
                this.Transform.Value = this.Body.WorldTransform;
            }));

            bindable.Add(new SetBinding <Matrix>(this.Transform, delegate(Matrix m)
            {
                this.Body.WorldTransform = m;
            }));

            bindable.Add(new SetBinding <Vector3>(this.LinearVelocity, delegate(Vector3 v)
            {
                this.Body.LinearVelocity = v;
            }));

            //Make the body slippery.
            //Note that this will not make all collisions have zero friction;
            //the friction coefficient between a pair of objects is based
            //on a blending of the two objects' materials.
            this.Body.Material.KineticFriction = 0.0f;
            this.Body.Material.StaticFriction  = 0.0f;
            this.Body.Material.Bounciness      = 0.0f;

            const int rayChecks      = 4;
            float     rayCheckRadius = radius - 0.1f;

            this.rayOffsets = new[] { Vector3.Zero }.Concat(Enumerable.Range(0, rayChecks).Select(
                                                                delegate(int x)
            {
                float angle = x * ((2.0f * (float)Math.PI) / (float)rayChecks);
                return(new Vector3((float)Math.Cos(angle) * rayCheckRadius, 0, (float)Math.Sin(angle) * rayCheckRadius));
            })).ToArray();
            this.IsUpdating = false;
        }
Пример #29
0
        /// <summary>
        /// Constructs a new demo.
        /// </summary>
        /// <param name="game">Game owning this demo.</param>
        public MPRTestDemo(DemosGame game)
            : base(game)
        {
            var shapeA = new BoxShape(1, 1, 1);

            shapeA.CollisionMargin = 0;
            var shapeB = new BoxShape(1, 1, 1);

            shapeB.CollisionMargin = 0;

            var     transformA = new RigidTransform(new Vector3(0, 0, 0));
            var     transformB = new RigidTransform(new Vector3(.5m, .5m, 0));
            Vector3 overlap;
            bool    overlapped = MPRToolbox.GetLocalOverlapPosition(shapeA, shapeB, ref transformB, out overlap);
            Vector3 normal;
            Fix64   depth;
            Vector3 direction = new Vector3(0, -1, 0);

            MPRToolbox.LocalSurfaceCast(shapeA, shapeB, ref transformB, ref direction, out depth, out normal);

            ContactData contactData;

            //bool overlappedOld = MPRToolboxOld.AreObjectsColliding(shapeA, shapeB, ref transformA, ref transformB, out contactData);

            //Random rand = new Random(0);
            //for (int i = 0; i < 10000000; i++)
            //{
            //    transformA = new RigidTransform(new Vector3((Fix64)rand.NextDouble() * 10 - 5, (Fix64)rand.NextDouble() * 10 - 5, (Fix64)rand.NextDouble() * 10 - 5),
            //        Quaternion.CreateFromYawPitchRoll((Fix64)rand.NextDouble() * 1000, (Fix64)rand.NextDouble() * 1000, (Fix64)rand.NextDouble() * 1000));
            //    transformB = new RigidTransform(new Vector3((Fix64)rand.NextDouble() * 10 - 5, (Fix64)rand.NextDouble() * 10 - 5, (Fix64)rand.NextDouble() * 10 - 5),
            //        Quaternion.CreateFromYawPitchRoll((Fix64)rand.NextDouble() * 1000, (Fix64)rand.NextDouble() * 1000, (Fix64)rand.NextDouble() * 1000));

            //    overlapped = MPRTesting.GetOverlapPosition(shapeA, shapeB, ref transformA, ref transformB, out overlap);

            //    overlappedOld = MPRToolbox.AreObjectsColliding(shapeA, shapeB, ref transformA, ref transformB, out contactData);

            //    if (overlapped && !overlappedOld &&
            //        (!MPRToolbox.IsPointInsideShape(ref overlap, shapeA, ref transformA) ||
            //        !MPRToolbox.IsPointInsideShape(ref overlap, shapeB, ref transformB)))
            //        Debug.WriteLine("Break.");
            //    if (overlappedOld && !overlapped &&
            //        (!MPRToolbox.IsPointInsideShape(ref contactData.Position, shapeA, ref transformA) ||
            //        !MPRToolbox.IsPointInsideShape(ref contactData.Position, shapeB, ref transformB)))
            //        Debug.WriteLine("Break.");
            //    if (overlapped && overlappedOld &&
            //        (!MPRToolbox.IsPointInsideShape(ref overlap, shapeA, ref transformA) ||
            //        !MPRToolbox.IsPointInsideShape(ref overlap, shapeB, ref transformB) ||
            //        !MPRToolbox.IsPointInsideShape(ref contactData.Position, shapeA, ref transformA) ||
            //        !MPRToolbox.IsPointInsideShape(ref contactData.Position, shapeB, ref transformB)))
            //        Debug.WriteLine("Break.");
            //}

            //Do these tests with rotationally immobile objects.
            CollisionDetectionSettings.DefaultMargin = 0;
            groundWidth  = 10;
            groundHeight = .1m;
            groundLength = 10;
            //a = new Box(new Vector3(0, -5, 0), groundWidth, groundHeight, groundLength, 1);
            //a = new TransformableEntity(new Vector3(0,0,0), new TriangleShape(new Vector3(-5, -5, -5), new Vector3(5, -5, -5), new Vector3(-5, -5, 5)), Matrix3x3.Identity);
            a = new Triangle(new Vector3(0, -5, 0), new Vector3(5, -5, 0), new Vector3(5, -5, 5), 1);
            Space.Add(a);

            Space.ForceUpdater.Gravity = new Vector3();
            boxWidth  = .25m;
            boxHeight = .05m;
            boxLength = 1;
            b         = new TransformableEntity(new Vector3(0, 2, 0), new BoxShape(boxWidth, boxHeight, boxLength), Matrix3x3.Identity, 1);
            //b = new Cone(new Vector3(0, 2, 0), .2m, .1m, 1);
            //b = new Capsule(new Vector3(0, 2, 0), 1, .5m, 1);
            //b = new Capsule(new Vector3(0, 2, 0), 1, .5m, 1);
            b.LocalInertiaTensorInverse = new Matrix3x3();
            CollisionRules.AddRule(b, a, CollisionRule.NoSolver);
            b.ActivityInformation.IsAlwaysActive = true;
            Space.Add(b);
            //Space.Add(new TransformableEntity(new Vector3(0, 4, 0), new BoxShape(1, 1, 1), Matrix3x3.Identity, 1));
            //Space.Add( new TransformableEntity(new Vector3(0, 6, 0), new BoxShape(1, 1, 1), Matrix3x3.Identity, 1));

            //Vector3[] vertices = new Vector3[] { new Vector3(0, -5, 0), new Vector3(5, -5, 0), new Vector3(5, -5, 5), new Vector3(0, -60, 5) };
            //int[] indices = new int[] { 0, 1, 2 , 0, 2, 3 };
            //StaticMesh mesh = new StaticMesh(vertices, indices);
            //Space.Add(mesh);
            //mesh.ImproveBoundaryBehavior = true;
            //mesh.Sidedness = TriangleSidedness.Counterclockwise;
            //game.ModelDrawer.Add(mesh);
            //mesh.CollisionRules.Personal = CollisionRule.NoSolver;
        }
Пример #30
0
        void AddDriveWheel(Vector3 suspensionOffset, Entity body, bool leftSide, out RevoluteMotor drivingMotor, out RevoluteMotor steeringMotor, out Box suspensionLeg)
        {
            suspensionLeg = new Box(body.Position + suspensionOffset, 0.25f, 0.8f, 0.25f, 10);

            const float horizontalWheelOffset = 0.2f;

            var wheel = new Cylinder(suspensionLeg.Position + new Vector3(leftSide ? -horizontalWheelOffset : horizontalWheelOffset, -suspensionLeg.HalfHeight, 0), .2f, .3f, 5f);

            wheel.Material.KineticFriction = 2.5f;
            wheel.Material.StaticFriction  = 3.5f;
            wheel.Orientation = Quaternion.CreateFromAxisAngle(Vector3.Forward, MathHelper.PiOver2);

            //Preventing the occasional pointless collision pair can speed things up.
            CollisionRules.AddRule(wheel, body, CollisionRule.NoBroadPhase);
            CollisionRules.AddRule(wheel, suspensionLeg, CollisionRule.NoBroadPhase);
            CollisionRules.AddRule(suspensionLeg, body, CollisionRule.NoBroadPhase);

            //Connect the suspension to the body.
            var bodyToSuspension = new LineSliderJoint(body, suspensionLeg, suspensionLeg.Position, Vector3.Down, suspensionLeg.Position);

            bodyToSuspension.Limit.IsActive = true;
            bodyToSuspension.Limit.Minimum  = -0.5f;
            bodyToSuspension.Limit.Maximum  = 0;

            //This linear axis motor will give the suspension its springiness by pushing the wheels outward.
            bodyToSuspension.Motor.IsActive            = true;
            bodyToSuspension.Motor.Settings.Mode       = MotorMode.Servomechanism;
            bodyToSuspension.Motor.Settings.Servo.Goal = 0;
            bodyToSuspension.Motor.Settings.Servo.SpringSettings.Stiffness = 300;
            bodyToSuspension.Motor.Settings.Servo.SpringSettings.Damping   = 70;


            steeringMotor = new RevoluteMotor(body, suspensionLeg, Vector3.Up);
            steeringMotor.Settings.Mode = MotorMode.Servomechanism;
            //The constructor makes a guess about how to set up the constraint.
            //It can't always be right since it doesn't have all the information;
            //in this case, it chooses the basis and test axis incorrectly.
            //This leads to a 'flipping' behavior when the wheel is rolling
            //(the test axis is 'rolling' with the wheel, and passes over
            //a singularity which causes a flip).

            //To fix this, we configure the constraint directly.
            //The basis is aligned with how the wheel is set up; we choose 'up' as
            //the motorized axis, and right/forward to define the angle measurement plane.
            //The test axis is set to be perpendicular to the wheel's rotation so that
            //it only measures the steering angle.

            //If you're curious, the angle measurement is just a Math.Atan2.
            //The current world test axis is dotted against the two plane axes (Right and Forward here).
            //This gives an x and y value.  These can be plugged into Atan2 just like when
            //you compute an angle on a normal 2d graph.
            steeringMotor.Basis.SetWorldAxes(Vector3.Up, Vector3.Right);
            steeringMotor.TestAxis = Vector3.Right;

            //To make the steering a little more responsive, set a base speed at which error gets corrected.
            //This works on top of the default error reduction implied by the constraint's spring constants.
            steeringMotor.Settings.Servo.BaseCorrectiveSpeed = 1;


            //The revolute motor is weaker than some other types of constraints and maintaining a goal in the presence of extremely fast rotation and integration issues.
            //Laying a revolute limit on top of it can help mitigate the problem.
            var steeringConstraint = new RevoluteLimit(body, suspensionLeg, Vector3.Up, Vector3.Right, -maximumTurnAngle, maximumTurnAngle);

            //Connect the wheel to the suspension.
            var suspensionToWheel = new RevoluteJoint(suspensionLeg, wheel, wheel.Position, Vector3.Right);

            drivingMotor = suspensionToWheel.Motor;
            //The driving motor's default, created by the RevoluteJoint constructor above, chose the axis of rotation such that negatives values made the car go forward and vice versa.
            //Swap it around so that the positive values make the car roll forward instead!
            drivingMotor.Basis.SetWorldAxes(Vector3.Left, Vector3.Forward);
            drivingMotor.TestAxis = Vector3.Forward;
            drivingMotor.Settings.VelocityMotor.Softness = .3f;
            drivingMotor.Settings.MaximumForce           = 100;


            //Add the wheel and connection to the space.
            Space.Add(wheel);
            Space.Add(suspensionLeg);
            Space.Add(bodyToSuspension);
            Space.Add(drivingMotor);
            Space.Add(steeringMotor);
            Space.Add(steeringConstraint);
            Space.Add(suspensionToWheel);
        }