Restricts linear motion while allowing one degree of angular freedom. Acts like a normal door hinge.
상속: SolverGroup
 public Waffen( Controller Kontroller, RevoluteJoint Revolute, int Lebenspunkte, float Schusswinkel, float ShootSpeed) //Controller rausgenommen 
 {
     controller = Kontroller;
     lebenspunkte = Lebenspunkte;
     schusswinkel = Schusswinkel;
     shootspeed = ShootSpeed;
     revolute = Revolute;
     
 }
        /// <summary>
        /// Creates a machine that rotates, pauses, and rotates again.
        /// </summary>
        /// <param name="machineNo">Machine number, zero for auto.</param>
        /// <param name="center">Center of the machine.</param>
        /// <param name="radiansPerRotation">Angle to rotate on each rotation.</param>
        /// <param name="rotationAxis">Axis to rotate on.</param>
        /// <param name="rotationsToOrigin">Number of rotations until the machine is back to normal.</param>
        /// <param name="deactivationTime">Time to stay still for (if automatic).</param>
        /// <param name="rotateTime">Time to rotate for.</param>
        /// <param name="models">Models.</param>
        public ContinuingRotationMachine(int machineNo, int soundIndex, Vector3 rotationAxis, Vector3 zeroAxis, float radiansPerRotation, 
            int rotationsToOrigin, float deactivationTime, float rotateTime, Vector3 center, params BaseModel[] models)
            : base(machineNo, soundIndex, models)
        {
            if(machineNo == 0)
                automatic = true;

            //Quaternion radiansToRotateQ = Quaternion.CreateFromAxisAngle(rotationAxis, radiansPerRotation);
            this.rotationsToOrigin = rotationsToOrigin;
            rotationTime = rotateTime;
            angle = radiansPerRotation;
            inactiveTime = deactivationTime;
            originalAxis = rotationAxis;

            baseJoint = new RevoluteJoint(null, modelList[0].Ent, center, rotationAxis);
            baseJoint.Motor.IsActive = true;
            baseJoint.Motor.Settings.Mode = BEPUphysics.Constraints.TwoEntity.Motors.MotorMode.Servomechanism;
            baseJoint.Motor.Settings.Servo.SpringSettings.StiffnessConstant = 0;
            baseJoint.Motor.Settings.Servo.SpringSettings.DampingConstant /= 12;
            baseJoint.Motor.Settings.Servo.Goal = 0;
            baseJoint.Motor.Settings.Servo.MaxCorrectiveVelocity = radiansPerRotation / rotateTime;
            baseJoint.Motor.Settings.Servo.BaseCorrectiveSpeed = radiansPerRotation / rotateTime;
            baseJoint.Motor.Basis.SetWorldAxes(rotationAxis, zeroAxis);
            baseJoint.Motor.TestAxis = zeroAxis;

            if(modelList.Count > 1)
                foreach(BaseModel m in modelList)
                {
                    if(m == modelList[0])
                        continue;
                    WeldJoint j = new WeldJoint(modelList[0].Ent, m.Ent);
                    joints.Add(j);
                }
            foreach(Tube t in tubeList)
                t.SetParent(modelList[0].Ent);
        }
예제 #3
0
        void createVehicle(Vector3 position)
        {
            float width = 15;
            float height = 2;
            float length = 5;
            float wheelWidth = 1;
            float wheelRadius = 2;

            BepuEntity chassis = createBox(position, width, height, length);
            chassis.LoadContent();
            chassis.body.Mass = 100;

            BepuEntity wheel;
            RevoluteJoint joint;

            wheel = createWheel(new Vector3(position.X - (width / 2) + wheelRadius, position.Y, position.Z - (length / 2) - wheelWidth), wheelWidth, wheelRadius);
            joint = new RevoluteJoint(chassis.body, wheel.body, wheel.body.Position, new Vector3(0, 0, -1));
            space.Add(joint);

            wheel = createWheel(new Vector3(position.X + (width / 2) - wheelRadius, position.Y, position.Z - (length / 2) - wheelWidth), wheelWidth, wheelRadius);
            joint = new RevoluteJoint(chassis.body, wheel.body, wheel.body.Position, new Vector3(0, 0, -1));
            space.Add(joint);

            wheel = createWheel(new Vector3(position.X - (width / 2) + wheelRadius, position.Y, position.Z + (length / 2) + wheelWidth), wheelWidth, wheelRadius);
            joint = new RevoluteJoint(chassis.body, wheel.body, wheel.body.Position, new Vector3(0, 0, -1));
            space.Add(joint);

            wheel = createWheel(new Vector3(position.X + (width / 2) - wheelRadius, position.Y, position.Z + (length / 2) + wheelWidth), wheelWidth, wheelRadius);
            joint = new RevoluteJoint(chassis.body, wheel.body, wheel.body.Position, new Vector3(0, 0, -1));
            space.Add(joint);
        }
예제 #4
0
        public Joints(SoundEffect hn, SoundEffect rotv, seeSaw ss, HelicopterBase hb, HelicopterRotor hr, HelicopterSkid hs, HelicopterTail ht, HelicopterTailRotor htr, HelicopterClawHolder hch, HelicopterClawHinge hchinge, HelicopterClawItemHolder hcih)
        {
            engineOn = false;       // Set the engine to off

            hBase = hb;
            hRotor = hr;
            hSkid = hs;
            hTail = ht;
            hTailRotor = htr;
            hClawHolder = hch;
            hClawHinge = hchinge;
            hClawItemHolder = hcih;
            seeSaw = ss;

            helicopterNoise = hn;
            hnInstance = helicopterNoise.CreateInstance();          // New instance of sound effect
            hnInstance.Volume = 0.6f;
            hnInstance.IsLooped = true;

            rideOfTheValkyries = rotv;
            rotvInstance = rideOfTheValkyries.CreateInstance();     // New instance of sound effect
            rotvInstance.Volume = 0.6f;
            rotvInstance.IsLooped = true;

            hBaseRotorJoint = new RevoluteJoint(hBase.helicopter.body, hRotor.rotor.body, hBase.helicopter.body.Position, Vector3.Up);  // Joint for rotor on top of helicopter
            hBaseRotorJoint.Motor.Settings.MaximumForce = 200;
            hBaseRotorJoint.Motor.IsActive = false;

            // Well joints for skids on bottom of helicopter and tail, attach each entity to the helicopter
            hTailJoint = new WeldJoint(hTail.tail.body, hBase.helicopter.body);
            hSkidJoint1 = new WeldJoint(hSkid.skid1.body, hBase.helicopter.body);
            hSkidJoint2 = new WeldJoint(hSkid.skid2.body, hBase.helicopter.body);

            hTailRotorJoint = new RevoluteJoint(hTailRotor.tailRotor.body, hTail.tail.body, hTailRotor.tailRotor.body.Position, Vector3.Right); // Joint for rotor on tail of the helicopter
            hTailRotorJoint.Motor.Settings.MaximumForce = 180;
            hTailRotorJoint.Motor.IsActive = false;

            hClawHolderJoint = new SwivelHingeJoint(hBase.helicopter.body, hClawHolder.clawHolder.body, hBase.helicopter.body.Position, Vector3.Right);    // Joint for claw holder below helicopter

            hClawHolderJoint.HingeLimit.IsActive = true;
            hClawHolderJoint.HingeLimit.MinimumAngle = -MathHelper.Pi / 45;
            hClawHolderJoint.HingeLimit.MaximumAngle = MathHelper.Pi / 45;

            // 4 similar joints for hinge joints between the claw holder and a part of the claw
            // The hinges code was created with help from the examuse ple Bepu Physics demo available from the website
            hClawHingeJoint1 = new RevoluteJoint(hClawHolder.clawHolder.body, hClawHinge.clawHinge1.body, hClawHolder.clawHolder.body.Position, Vector3.Forward);
            hClawHingeJoint1.Motor.IsActive = true;
            hClawHingeJoint1.Motor.Settings.Mode = MotorMode.Servomechanism;
            hClawHingeJoint1.Motor.Settings.Servo.Goal = -MathHelper.PiOver2;
            hClawHingeJoint1.Motor.Settings.Servo.SpringSettings.DampingConstant /= 20;     // Damping to quicken the claw contracting
            hClawHingeJoint1.Motor.Settings.Servo.SpringSettings.StiffnessConstant /= 20;   // Stop the claw from over moving on the axis

            hClawHingeJoint1.Limit.IsActive = true;
            hClawHingeJoint1.Limit.MinimumAngle = -MathHelper.TwoPi;
            hClawHingeJoint1.Limit.MaximumAngle = MathHelper.PiOver4;

            hClawHingeJoint2 = new RevoluteJoint(hClawHolder.clawHolder.body, hClawHinge.clawHinge2.body, hClawHolder.clawHolder.body.Position, Vector3.Backward);
            hClawHingeJoint2.Motor.IsActive = true;
            hClawHingeJoint2.Motor.Settings.Mode = MotorMode.Servomechanism;
            hClawHingeJoint2.Motor.Settings.Servo.Goal = -MathHelper.PiOver2;
            hClawHingeJoint2.Motor.Settings.Servo.SpringSettings.DampingConstant /= 20;
            hClawHingeJoint2.Motor.Settings.Servo.SpringSettings.StiffnessConstant /= 20;

            hClawHingeJoint2.Limit.IsActive = true;
            hClawHingeJoint2.Limit.MinimumAngle = -MathHelper.TwoPi;
            hClawHingeJoint2.Limit.MaximumAngle = MathHelper.PiOver4;

            hClawHingeJoint3 = new RevoluteJoint(hClawHolder.clawHolder.body, hClawHinge.clawHinge3.body, hClawHolder.clawHolder.body.Position, Vector3.Right);
            hClawHingeJoint3.Motor.IsActive = true;
            hClawHingeJoint3.Motor.Settings.Mode = MotorMode.Servomechanism;
            hClawHingeJoint3.Motor.Settings.Servo.Goal = -MathHelper.PiOver2;
            hClawHingeJoint3.Motor.Settings.Servo.SpringSettings.DampingConstant /= 20;
            hClawHingeJoint3.Motor.Settings.Servo.SpringSettings.StiffnessConstant /= 20;

            hClawHingeJoint3.Limit.IsActive = true;
            hClawHingeJoint3.Limit.MinimumAngle = -MathHelper.TwoPi;
            hClawHingeJoint3.Limit.MaximumAngle = MathHelper.PiOver4;

            hClawHingeJoint4 = new RevoluteJoint(hClawHolder.clawHolder.body, hClawHinge.clawHinge4.body, hClawHolder.clawHolder.body.Position, Vector3.Left);
            hClawHingeJoint4.Motor.IsActive = true;
            hClawHingeJoint4.Motor.Settings.Mode = MotorMode.Servomechanism;
            hClawHingeJoint4.Motor.Settings.Servo.Goal = -MathHelper.PiOver2;
            hClawHingeJoint4.Motor.Settings.Servo.SpringSettings.DampingConstant /= 20;
            hClawHingeJoint4.Motor.Settings.Servo.SpringSettings.StiffnessConstant /= 20;

            hClawHingeJoint4.Limit.IsActive = true;
            hClawHingeJoint4.Limit.MinimumAngle = -MathHelper.TwoPi;
            hClawHingeJoint4.Limit.MaximumAngle = MathHelper.PiOver4;

            // More weld joints as the claw pieces are made up off two different sections
            hClawItemHolderJoint1 = new WeldJoint(hClawHinge.clawHinge1.body, hClawItemHolder.clawItemHolder1.body);
            hClawItemHolderJoint2 = new WeldJoint(hClawHinge.clawHinge2.body, hClawItemHolder.clawItemHolder2.body);
            hClawItemHolderJoint3 = new WeldJoint(hClawHinge.clawHinge3.body, hClawItemHolder.clawItemHolder3.body);
            hClawItemHolderJoint4 = new WeldJoint(hClawHinge.clawHinge4.body, hClawItemHolder.clawItemHolder4.body);

            // Joint for the seesaw with the ball located on it
            seeSawJoint = new RevoluteJoint(seeSaw.seeSawHolder.body, seeSaw.seeSawBoard.body, seeSaw.seeSawHolder.body.Position, Vector3.Forward);

            revoluteJoints.Add(hBaseRotorJoint);
            revoluteJoints.Add(hTailRotorJoint);
            revoluteJoints.Add(hClawHingeJoint1);
            revoluteJoints.Add(hClawHingeJoint2);
            revoluteJoints.Add(hClawHingeJoint3);
            revoluteJoints.Add(hClawHingeJoint4);
            revoluteJoints.Add(seeSawJoint);

            weldJoints.Add(hTailJoint);
            weldJoints.Add(hSkidJoint1);
            weldJoints.Add(hSkidJoint2);
            weldJoints.Add(hClawItemHolderJoint1);
            weldJoints.Add(hClawItemHolderJoint2);
            weldJoints.Add(hClawItemHolderJoint3);
            weldJoints.Add(hClawItemHolderJoint4);

            entities.Add(hBase.helicopter);
            entities.Add(hRotor.rotor);
            entities.Add(hSkid.skid1);
            entities.Add(hSkid.skid2);
            entities.Add(hTail.tail);
            entities.Add(hTailRotor.tailRotor);
            entities.Add(hClawHolder.clawHolder);

            entities.Add(hClawHinge.clawHinge1);
            entities.Add(hClawHinge.clawHinge2);
            entities.Add(hClawHinge.clawHinge3);
            entities.Add(hClawHinge.clawHinge4);
            entities.Add(hClawItemHolder.clawItemHolder1);
            entities.Add(hClawItemHolder.clawItemHolder2);
            entities.Add(hClawItemHolder.clawItemHolder3);
            entities.Add(hClawItemHolder.clawItemHolder4);

            for (int i = 0; i < revoluteJoints.Count; i++)      // Add all the revolute joints to the space
            {
                Game1.Instance.Space.Add(revoluteJoints.ElementAt(i));
            }

            for (int i = 0; i < weldJoints.Count; i++)          // Add all the weld joints to the space
            {
                Game1.Instance.Space.Add(weldJoints.ElementAt(i));
            }

            Game1.Instance.Space.Add(hClawHolderJoint);     // Add the swivel hinge joint to the space
        }
        public override void LoadContent()
        {
            BepuEntity boxBase = new BepuEntity();
            boxBase.modelName = "cube";
            boxBase.localTransform = Matrix.CreateScale(new Vector3(20, 5, 20));
            boxBase.body = new Box(new Vector3(5, 1, 0), 20, 5, 20, 1);
            boxBase.body.BecomeKinematic();
            boxBase.diffuse = new Vector3((float)random.NextDouble(), (float)random.NextDouble(), (float)random.NextDouble());
            Game1.Instance.Space.Add(boxBase.body);

            Game1.Instance.Children.Add(boxBase);

               BepuEntity armBase = new BepuEntity();
               armBase.modelName = "cylinder";
               armBase.localTransform = Matrix.CreateScale(new Vector3(2.5f, 2, 5));
               armBase.body= new Cylinder(new Vector3(15, 2, 20), 2.5f, 2, 1);
               Game1.Instance.Space.Add(armBase.body);

               Game1.Instance.Children.Add(armBase);
               hinge = new RevoluteJoint(boxBase.body, armBase.body, new Vector3(10, 1.5f, 10), new Vector3(0, 1, 0));
               hinge.Motor.IsActive = true;
               hinge.Motor.Settings.Mode = BEPUphysics.Constraints.TwoEntity.Motors.MotorMode.Servomechanism;
               hinge.Motor.Settings.MaximumForce = 3500;

               BepuEntity armPart2 = new BepuEntity();
               armPart2.modelName = "cylinder2";
               armPart2.localTransform = Matrix.CreateScale(new Vector3(2.5f, 2, 5));
               armPart2.body = new Cylinder(new Vector3(15, 2, 31), 2.5f, 2, 1);
               armPart2.body.Orientation = Quaternion.CreateFromAxisAngle(new Vector3(1,0,0),90);
               Game1.Instance.Space.Add(armPart2.body);

               Game1.Instance.Children.Add(armPart2);

               Game1.Instance.Space.Add(hinge);
               hinge2 = new RevoluteJoint(armBase.body, armPart2.body,armBase.pos, new Vector3(1, 0, 0));
               hinge2.Motor.IsActive = true;
               hinge2.Motor.Settings.Mode = BEPUphysics.Constraints.TwoEntity.Motors.MotorMode.Servomechanism;
               hinge2.Motor.Settings.MaximumForce = 3500;
               Game1.Instance.Space.Add(hinge2);

               BepuEntity wheel = new BepuEntity();
               wheel.modelName = "wheel";
               wheel.localTransform = Matrix.CreateScale(new Vector3(3, 3, 3));
               wheel.body = new Cylinder(new Vector3(35, 5, 31), 2.5f, 0, 1);
               wheel.body.BecomeKinematic();
               wheel.diffuse = new Vector3((float)random.NextDouble(), (float)random.NextDouble(), (float)random.NextDouble());
               Game1.Instance.Space.Add(wheel.body);

               BepuEntity wheel2 = new BepuEntity();
               wheel2.modelName = "wheel";
               wheel2.localTransform = Matrix.CreateScale(new Vector3(3, 3, 3));
               wheel2.body = new Cylinder(new Vector3(50, 5, 31), 2.5f, 0, 1);
               wheel2.body.BecomeKinematic();
               wheel2.diffuse = new Vector3((float)random.NextDouble(), (float)random.NextDouble(), (float)random.NextDouble());
               Game1.Instance.Space.Add(wheel2.body);

               BepuEntity wheel3 = new BepuEntity();
               wheel3.modelName = "wheel";
               wheel3.localTransform = Matrix.CreateScale(new Vector3(3, 3, 3));
               wheel3.body = new Cylinder(new Vector3(35, 5, 21), 2.5f, 0, 1);
               wheel3.body.BecomeKinematic();
               wheel3.diffuse = new Vector3((float)random.NextDouble(), (float)random.NextDouble(), (float)random.NextDouble());
               Game1.Instance.Space.Add(wheel3.body);

               BepuEntity wheel4 = new BepuEntity();
               wheel4.modelName = "wheel";
               wheel4.localTransform = Matrix.CreateScale(new Vector3(3, 3, 3));
               wheel4.body = new Cylinder(new Vector3(50, 5, 21), 2.5f, 0, 1);
               wheel4.body.BecomeKinematic();
               wheel4.diffuse = new Vector3((float)random.NextDouble(), (float)random.NextDouble(), (float)random.NextDouble());
               Game1.Instance.Space.Add(wheel4.body);

               Game1.Instance.Children.Add(wheel);
               Game1.Instance.Children.Add(wheel2);
               Game1.Instance.Children.Add(wheel3);
               Game1.Instance.Children.Add(wheel4);

               BepuEntity boxBase2 = new BepuEntity();
               boxBase2.modelName = "cube";
               boxBase2.localTransform = Matrix.CreateScale(new Vector3(20, 5, 20));
               boxBase2.body = new Box(new Vector3(45, 10, 25), 20, 5, 20, 1);
               //boxBase2.body.BecomeKinematic();
               boxBase2.diffuse = new Vector3((float)random.NextDouble(), (float)random.NextDouble(), (float)random.NextDouble());
               Game1.Instance.Space.Add(boxBase2.body);
               Game1.Instance.Children.Add(boxBase2);

               wheelJoint1 = new RevoluteJoint(boxBase2.body, wheel.body, new Vector3(35, 5, 31), new Vector3(0, 0, 1));
               Game1.Instance.Space.Add(wheelJoint1);

               wheelJoint2 = new RevoluteJoint(boxBase2.body, wheel2.body, new Vector3(50, 5, 31), new Vector3(0, 0, 1));
               Game1.Instance.Space.Add(wheelJoint2);

               wheelJoint3 = new RevoluteJoint(boxBase2.body, wheel3.body, new Vector3(35, 5, 21), new Vector3(0, 0, 1));
               Game1.Instance.Space.Add(wheelJoint3);

               wheelJoint4 = new RevoluteJoint(boxBase2.body, wheel4.body, new Vector3(50, 5, 21), new Vector3(0, 0, 1));
               Game1.Instance.Space.Add(wheelJoint4);
        }
        void jointDemo()
        {
            BepuEntity e1;
            BepuEntity e2;
            Joint joint;

            // Ball & socket joint
            e1 = createBox(new Vector3(20, 5, -20), 1, 1, 5);
            e1.body.BecomeKinematic();
            e2 = createBox(new Vector3(20, 5, -10), 1, 1, 5);
            joint = new BallSocketJoint(e1.body, e2.body, new Vector3(20, 5, -15));
            space.Add(joint);

            // Hinge
            e1 = createBox(new Vector3(30, 5, -20), 1, 1, 5);
            e1.body.BecomeKinematic();
            e2 = createBox(new Vector3(30, 5, -10), 1, 1, 5);

            RevoluteJoint hinge = new RevoluteJoint(e1.body, e2.body, new Vector3(20, 5, -15), new Vector3(1, 0, 0));
            space.Add(hinge);

            // Universal
            e1 = createBox(new Vector3(40, 5, -20), 1, 1, 5);

            e2 = createBox(new Vector3(40, 5, -10), 1, 1, 5);

            UniversalJoint uni = new UniversalJoint(e1.body, e2.body, new Vector3(40, 5, -15));
            space.Add(uni);

            // Weld Joint
            e1 = createBox(new Vector3(50, 5, -20), 1, 1, 5);
            e2 = createBox(new Vector3(50, 5, -10), 1, 1, 5);

            WeldJoint weld = new WeldJoint(e1.body, e2.body);
            space.Add(weld);

            // PointOnLine Joint
            // create the line
            e1 = createBox(new Vector3(60, 5, -20), 1, 1, 5);
            e1.body.BecomeKinematic();
            e2 = createBox(new Vector3(60, 10, -10), 1, 1, 1);
            PointOnLineJoint pol = new PointOnLineJoint(e1.body, e2.body, new Vector3(60, 5, -20), new Vector3(0, 0, -1), new Vector3(60, 5, -10));
            space.Add(pol);
        }
예제 #7
0
 public void SetParent(Entity e)
 {
     Ent.BecomeDynamic(25);
     bool temp = false;
     if(motor != null && motor.Solver != null)
     {
         GameManager.Space.Remove(motor);
         temp = true;
     }
     motor = new RevoluteJoint(e, Ent, Ent.Position, rotationDirection);
     motor.Motor.IsActive = true;
     motor.Motor.Settings.Mode = MotorMode.VelocityMotor;
     if(temp)
         GameManager.Space.Add(motor);
 }
예제 #8
0
        /// <summary>
        /// Constructs a new demo.
        /// </summary>
        /// <param name="game">Game owning this demo.</param>
        public SawContraptionDemo(DemosGame game)
            : base(game)
        {
            //Add a kinematic entity that will form the base for the strange contraption.
            var pistonGroundAttachment = new Box(new Vector3(0, -1, 0), 1, 2, .5f);
            pistonGroundAttachment.AngularVelocity = new Vector3(0, .2f, 0); //Make it spin a little to rotate the whole thing.
            Space.Add(pistonGroundAttachment);

            var pistonBox1 = new Box(pistonGroundAttachment.Position + new Vector3(0f, 0, 1), 1, 1, 1, 100);
            var pistonBox2 = new Box(pistonBox1.Position + new Vector3(0, 2, 0), .5f, .8f, .5f, 10);
            Space.Add(pistonBox1);
            Space.Add(pistonBox2);

            //Connect the piston entities to the base with a revolute joint that acts like an axis joint
            var axisJoint = new RevoluteJoint(pistonGroundAttachment, pistonBox1, (pistonGroundAttachment.Position + pistonBox1.Position) / 2, Vector3.Forward);

            //Keep the axis from rotating too far so that the saw blade won't just continually ram into the ground.
            //The limit's 'basis' and test axis used to determine the position of the limits and the current angle of the constraint
            //are automatically initialized by the RevoluteJoint constructor.  The basis and testAxis can be set afterwards;
            //the initialization is just a reasonable 'guess' at the kind of limit configuration desired.
            axisJoint.Limit.IsActive = true;
            axisJoint.Limit.MinimumAngle = -MathHelper.PiOver2;
            axisJoint.Limit.MaximumAngle = MathHelper.PiOver2;
            Space.Add(axisJoint);

            var piston = new PrismaticJoint(pistonBox1, pistonBox2, pistonBox1.Position, Vector3.Up, pistonBox2.Position);
            //Set up the piston limits.
            piston.Limit.IsActive = true; //By default, the limit and motor are both inactive.
            piston.Limit.Minimum = 2;
            piston.Limit.Maximum = 5;

            //Set up the servo motor.
            piston.Motor.IsActive = true;
            piston.Motor.Settings.Mode = MotorMode.Servomechanism;
            //Distance from the anchor that the piston will try to reach.
            piston.Motor.Settings.Servo.Goal = 5;
            //Set the maximum force the motor can use to reach its goal.
            piston.Motor.Settings.MaximumForce = 100;
            //This piston, by default, moves at a constant speed, but...
            piston.Motor.Settings.Servo.BaseCorrectiveSpeed = 1;
            //... if the stiffness constant is changed to a positive value, it can also act like a spring.
            piston.Motor.Settings.Servo.SpringSettings.StiffnessConstant = 0;
            //For a non-springy constraint like the piston, the dampingConstant can also be thought of as inverse 'softness.'
            piston.Motor.Settings.Servo.SpringSettings.DampingConstant = 1000;

            //Add the piston to the space.
            Space.Add(piston);

            //Create a saw bladey object on the end of the piston.
            var blade = new Box(pistonBox2.Position + new Vector3(0, 0, .5f), .3f, 2.5f, .1f, 5);
            Space.Add(blade);

            //Connect the saw to the piston with a second axis joint.
            axisJoint = new RevoluteJoint(pistonBox2, blade, (pistonBox2.Position + blade.Position) / 2, Vector3.Forward);
            //Revolute joints can be used to make axis joints (as it is here), but you can also use them to make hinges.
            Space.Add(axisJoint);

            //Make the blade spin.
            axisJoint.Motor.IsActive = true;
            axisJoint.Motor.Settings.VelocityMotor.GoalVelocity = 30;
            axisJoint.Motor.Settings.MaximumForce = 200;

            //Add some ground.
            Space.Add(new Box(new Vector3(0, -3f, 0), 20f, 1, 20f));

            //Make some debris for the saw to chop.
            for (double k = 0; k < Math.PI * 2; k += Math.PI / 20)
            {
                Space.Add(new Box(new Vector3((float) Math.Cos(k) * 4f, -2, (float) Math.Sin(k) * 6.5f), .5f, 1f, .5f, 10));
            }

            game.Camera.Position = new Vector3(0, 2, 20);
        }
예제 #9
0
 void Extend(RevoluteJoint joint, float dt)
 {
     float extensionSpeed = 2;
     joint.Motor.Settings.Servo.Goal = MathHelper.Clamp(joint.Motor.Settings.Servo.Goal + extensionSpeed * dt, joint.Limit.MinimumAngle, joint.Limit.MaximumAngle);
 }
예제 #10
0
        void createSteerableVehicle(Vector3 position)
        {
            float width = 15;
            float height = 2;
            float length = 5;
            float wheelWidth = 1;
            float wheelRadius = 2;

            BepuEntity chassis = createBox(position, width, height, length);
            chassis.LoadContent();
            chassis.body.Mass = 100;

            RevoluteMotor motor;

            BepuEntity wheel;
            RevoluteJoint joint;
            SwivelHingeJoint steerJoint;
            Vector3 wheelPos = new Vector3(position.X - (width / 2) + wheelRadius, position.Y, position.Z - (length / 2));
            wheel = createWheel(wheelPos, wheelWidth, wheelRadius);
            motor = new RevoluteMotor(chassis.body, wheel.body, Vector3.UnitZ);
            motor.Settings.VelocityMotor.GoalVelocity = -6;
            motor.IsActive = true;
            wheelPos = new Vector3(position.X - (width / 2) + wheelRadius, position.Y, position.Z - (length / 2) - (wheelWidth * 2));
            space.Add(motor);

            joint = new RevoluteJoint(chassis.body, wheel.body, wheel.body.Position, new Vector3(0, 0, -1));
            space.Add(joint);

            wheel = createWheel(new Vector3(position.X - (width / 2) + wheelRadius, position.Y, position.Z + (length / 2) + wheelWidth), wheelWidth, wheelRadius);
            joint = new RevoluteJoint(chassis.body, wheel.body, wheel.body.Position, new Vector3(0, 0, -1));
            space.Add(joint);

            wheel = createWheel(new Vector3(position.X + (width / 2) - wheelRadius, position.Y, position.Z - (length / 2) - wheelWidth), wheelWidth, wheelRadius);
            motor = new RevoluteMotor(chassis.body, wheel.body, Vector3.UnitZ);
            motor.Settings.VelocityMotor.GoalVelocity = -6;
            motor.IsActive = true;
            joint = new RevoluteJoint(chassis.body, wheel.body, wheel.body.Position, new Vector3(0, 0, -1));
            space.Add(joint);
            space.Add(motor);

            wheel = createWheel(new Vector3(position.X + (width / 2) - wheelRadius, position.Y, position.Z + (length / 2) + wheelWidth), wheelWidth, wheelRadius);
            joint = new RevoluteJoint(chassis.body, wheel.body, wheel.body.Position, new Vector3(0, 0, -1));
            space.Add(joint);

            BepuEntity pole = new BepuEntity();
            pole.modelName = "cube";
            pole.body = new Box(new Vector3(0, position.Y + 12, 0), 2, 18, 2, 1); // I have no idea whatsoever why the height has to be one, but it won't work otherwise...
            pole.localTransform = Matrix.CreateScale(new Vector3(2, 18, 2));
            //pole.body.CollisionInformation.LocalPosition = new Vector3(0, 20, 0);
            pole.configureEvents();

            joint = new RevoluteJoint(chassis.body, pole.body, chassis.body.Position, new Vector3(-1, 0, 0));

            joint.Limit.IsActive = true;
            joint.Limit.MaximumAngle = MathHelper.ToRadians(45.0f);
            joint.Limit.MinimumAngle = MathHelper.ToRadians(-45.0f);
            joint.Motor.Settings.Mode = MotorMode.Servomechanism;
            joint.Motor.Settings.Servo.Goal = MathHelper.ToRadians(-45.0f);
            joint.Motor.Settings.Servo.BaseCorrectiveSpeed = 8f;
            joint.Motor.Settings.MaximumForce = 2;
            joint.Motor.IsActive = true;

            children.Add(pole);
            space.Add(pole.body);
            space.Add(joint);
        }
        public static Waffen createWaffe(int auswahl, Spieler spieler, Vector3 posi)//TODO
        {
            Controller newcon;
            RevoluteJoint revolute;
            Waffen dasobj;
            Vector3 startort = new Vector3(posi.X,posi.Y, -5f);

            if (auswahl == 1)//Kanone
            {
                Vector3 diff = new Vector3(0.095f, 0.1828f, 0);
                ModelObject Kanonenrohr = new ModelObject(startort + diff, Quaternion.Identity, new Vector3(0.1f, 0.1f, 0.1f), CollisionType.ExactMesh, " ", "Kanonenrohr", 0.001f);
                Kanonenrohr.RenderMaterial.Diffuse = new Vector4(1, 1, 1, 1);
                scene.Add(Kanonenrohr);

                ModelObject Kanonenhalterung = new ModelObject(startort, Quaternion.Identity, new Vector3(0.1f, 0.1f, 0.1f), CollisionType.ExactMesh, " ", "Kanonenhalterung", 1f);
                Kanonenhalterung.RenderMaterial.Diffuse = new Vector4(1, 1, 1, 1);
                scene.Add(Kanonenhalterung);

                newcon = new Controller(new Vector3(0, 0, 0));// Neuer Controller an der Position 0/0/0
                newcon.Add(Kanonenrohr);
                newcon.Add(Kanonenhalterung);

                revolute = new RevoluteJoint(Kanonenhalterung.Physics, Kanonenrohr.Physics, Kanonenhalterung.Position + new Vector3(0, 1, 0), Vector3.Backward);
                /*revolute.Limit.IsActive = true;
                revolute.Limit.MinimumAngle = -MathHelper.Pi;
                revolute.Limit.MaximumAngle = 0;*/
                scene.Physics.Add(revolute);

                revolute.Motor.IsActive = true;
                revolute.Motor.Settings.Mode = BEPUphysics.Constraints.TwoEntity.Motors.MotorMode.Servomechanism;
                revolute.Motor.Settings.Servo.Goal = -MathHelper.Pi / 4;
            }
            else //TEMPORÄR
            {
                BoxObject Box = new BoxObject(startort, new Vector3(0.4f, 0.25f, 0.3f), 0.001f);
                scene.Add(Box);//Standbox

                BoxObject Lat = new BoxObject(startort + new Vector3(0 , 0.35f , 0), new Vector3(0.35f, 0.1f, 0.1f), 0.00001f);
                scene.Add(Lat);//KanonenRohr

                newcon = new Controller(startort);
                newcon.Add(Box);
                newcon.Add(Lat);
                scene.Add(newcon);

                revolute = new RevoluteJoint(Box.Physics, Lat.Physics, Box.Position + new Vector3(0, 0.32f, 0), Vector3.Backward);
                /*revolute.Limit.IsActive = true;
                revolute.Limit.MinimumAngle = -MathHelper.Pi;
                revolute.Limit.MaximumAngle = 0;*/
                scene.Physics.Add(revolute);

                revolute.Motor.IsActive = true;
                revolute.Motor.Settings.Mode = BEPUphysics.Constraints.TwoEntity.Motors.MotorMode.Servomechanism;
                revolute.Motor.Settings.Servo.Goal = MathHelper.Pi / 6;
                
            }

            //TODO z-Achse sperren

            
            //scene.Add(newcon);
            dasobj = new Waffen( newcon, revolute, 1, (float)Math.PI / 4, 5f);
            spieler.setWaffen(dasobj);
            return dasobj;

        }
예제 #12
0
        public override void Bind(Entity result, Main main, bool creating = false)
        {
            Property<Direction> dir = result.GetOrMakeProperty<Direction>("Direction", true);
            Property<float> minimum = result.GetOrMakeProperty<float>("Minimum", true);
            Property<float> maximum = result.GetOrMakeProperty<float>("Maximum", true);
            Property<bool> locked = result.GetOrMakeProperty<bool>("Locked", true);
            Property<bool> servo = result.GetOrMakeProperty<bool>("Servo", true, true);
            Property<float> speed = result.GetOrMakeProperty<float>("Speed", true, 5);
            Property<float> goal = result.GetOrMakeProperty<float>("Goal", true);

            RevoluteJoint joint = null;

            Action setLimits = delegate()
            {
                if (joint != null)
                {
                    float min = minimum, max = maximum;
                    if (max > min)
                    {
                        joint.Limit.IsActive = true;
                        joint.Limit.MinimumAngle = minimum;
                        joint.Limit.MaximumAngle = maximum;
                    }
                    else
                        joint.Limit.IsActive = false;
                }
            };
            result.Add(new NotifyBinding(setLimits, minimum, maximum));

            Action setSpeed = delegate()
            {
                if (joint != null)
                {
                    joint.Motor.Settings.Servo.BaseCorrectiveSpeed = joint.Motor.Settings.Servo.MaxCorrectiveVelocity = speed;
                    joint.Motor.Settings.VelocityMotor.GoalVelocity = speed;
                }
            };
            result.Add(new NotifyBinding(setSpeed, speed));

            Action setGoal = delegate()
            {
                if (joint != null)
                    joint.Motor.Settings.Servo.Goal = goal;
            };
            result.Add(new NotifyBinding(setGoal, goal));

            Action setLocked = delegate()
            {
                if (joint != null)
                    joint.Motor.IsActive = locked;
            };
            result.Add(new NotifyBinding(setLocked, locked));

            DynamicMap map = result.Get<DynamicMap>();

            Action setServo = delegate()
            {
                if (joint != null)
                    joint.Motor.Settings.Mode = servo ? MotorMode.Servomechanism : MotorMode.VelocityMotor;
            };
            result.Add(new NotifyBinding(setServo, servo));

            Func<BEPUphysics.Entities.Entity, BEPUphysics.Entities.Entity, Vector3, Vector3, Vector3, ISpaceObject> createJoint = delegate(BEPUphysics.Entities.Entity entity1, BEPUphysics.Entities.Entity entity2, Vector3 pos, Vector3 direction, Vector3 anchor)
            {
                joint = new RevoluteJoint(entity1, entity2, pos, direction);
                float multiplier = Math.Max(1.0f, map.PhysicsEntity.Mass);
                joint.AngularJoint.SpringSettings.StiffnessConstant *= multiplier;
                joint.Limit.SpringSettings.StiffnessConstant *= multiplier;
                joint.Motor.Settings.Mode = MotorMode.Servomechanism;
                setLimits();
                setLocked();
                setSpeed();
                setServo();
                setGoal();
                return joint;
            };

            JointFactory.Bind(result, main, createJoint, true, creating);

            result.Add("On", new Command
            {
                Action = delegate()
                {
                    if (joint != null && locked)
                        servo.Value = false;
                },
            });

            result.Add("Off", new Command
            {
                Action = delegate()
                {
                    if (joint != null && locked)
                    {
                        BEPUphysics.Constraints.JointBasis2D basis = joint.Motor.Basis;
                        basis.RotationMatrix = joint.Motor.ConnectionA.OrientationMatrix;

                        Vector3 localTestAxis = joint.Motor.LocalTestAxis;
                        Vector3 worldTestAxis;
                        BEPUutilities.Matrix3x3 orientationMatrix = joint.Motor.ConnectionB.OrientationMatrix;
                        BEPUutilities.Matrix3x3.Transform(ref localTestAxis, ref orientationMatrix, out worldTestAxis);

                        float y, x;
                        Vector3 yAxis = Vector3.Cross(basis.PrimaryAxis, basis.XAxis);
                        Vector3.Dot(ref worldTestAxis, ref yAxis, out y);
                        x = Vector3.Dot(worldTestAxis, basis.XAxis);
                        goal.Value = (float)Math.Atan2(y, x);
                        servo.Value = true;
                    }
                },
            });

            result.Add("Forward", new Command
            {
                Action = delegate()
                {
                    if (joint != null && locked)
                        joint.Motor.Settings.Servo.Goal = maximum;
                },
            });

            result.Add("Backward", new Command
            {
                Action = delegate()
                {
                    if (joint != null && locked)
                        joint.Motor.Settings.Servo.Goal = minimum;
                },
            });

            Command hitMax = new Command();
            result.Add("HitMax", hitMax);
            Command hitMin = new Command();
            result.Add("HitMin", hitMin);

            bool lastLimitExceeded = false;
            result.Add(new Updater
            {
                delegate(float dt)
                {
                    if (joint != null)
                    {
                        bool limitExceeded = joint.Limit.IsLimitExceeded;
                        if (limitExceeded && !lastLimitExceeded)
                        {
                            if (joint.Limit.Error.X > 0)
                                hitMin.Execute();
                            else
                                hitMax.Execute();
                        }
                        lastLimitExceeded = limitExceeded;
                    }
                }
            });
        }
예제 #13
0
        public Ragdoll()
        {
            #region Ragdoll Entities
            //Create the ragdoll's bones.
            var pelvis = new Box(Vector3.Zero, .5f, .28f, .33f, 20);
            var torsoBottom = new Box(pelvis.Position + new Vector3(0, .3f, 0), .42f, .48f, .3f, 15);
            var torsoTop = new Box(torsoBottom.Position + new Vector3(0, .3f, 0), .5f, .38f, .32f, 20);

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

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

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

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

            var rightThigh = new Box(pelvis.Position + new Vector3(.15f, -.4f, 0), .23f, .63f, .23f, 10);
            var rightShin = new Box(rightThigh.Position + new Vector3(0, -.6f, 0), .21f, .63f, .21f, 7);
            var rightFoot = new Box(rightShin.Position + new Vector3(0, -.35f, -.1f), .23f, .15f, .43f, 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, .1f, 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 = .05f;

            var torsoBottomToTorsoTopBallSocketJoint = new BallSocketJoint(torsoBottom, torsoTop, torsoBottom.Position + new Vector3(0, .25f, 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 = .05f;

            var torsoTopToNeckBallSocketJoint = new BallSocketJoint(torsoTop, neck, torsoTop.Position + new Vector3(0, .15f, .05f));
            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 = .1f;

            var neckToHeadBallSocketJoint = new BallSocketJoint(neck, head, neck.Position + new Vector3(0, .1f, .05f));
            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 = .1f;
            #endregion

            #region Left Arm
            var torsoTopToLeftArmBallSocketJoint = new BallSocketJoint(torsoTop, leftUpperArm, torsoTop.Position + new Vector3(-.3f, .1f, 0));
            var torsoTopToLeftArmEllipseLimit = new EllipseSwingLimit(torsoTop, leftUpperArm, Vector3.Left, MathHelper.Pi * .75f, 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 = .2f;

            var leftUpperArmToLeftForearmSwivelHingeJoint = new SwivelHingeJoint(leftUpperArm, leftForearm, leftUpperArm.Position + new Vector3(-.28f, 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 * .8f;
            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 = .3f;

            var leftForearmToLeftHandBallSocketJoint = new BallSocketJoint(leftForearm, leftHand, leftForearm.Position + new Vector3(-.2f, 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 = .4f;
            #endregion

            #region Right Arm
            var torsoTopToRightArmBallSocketJoint = new BallSocketJoint(torsoTop, rightUpperArm, torsoTop.Position + new Vector3(.3f, .1f, 0));
            var torsoTopToRightArmEllipseLimit = new EllipseSwingLimit(torsoTop, rightUpperArm, Vector3.Right, MathHelper.Pi * .75f, 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 = .2f;

            var rightUpperArmToRightForearmSwivelHingeJoint = new SwivelHingeJoint(rightUpperArm, rightForearm, rightUpperArm.Position + new Vector3(.28f, 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 * .8f;
            //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 = .3f;

            var rightForearmToRightHandBallSocketJoint = new BallSocketJoint(rightForearm, rightHand, rightForearm.Position + new Vector3(.2f, 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 = .4f;
            #endregion

            #region Left Leg
            var pelvisToLeftThighBallSocketJoint = new BallSocketJoint(pelvis, leftThigh, pelvis.Position + new Vector3(-.15f, -.1f, 0));
            var pelvisToLeftThighEllipseSwingLimit = new EllipseSwingLimit(pelvis, leftThigh, Vector3.Normalize(new Vector3(-.2f, -1, -.6f)), MathHelper.Pi * .7f, 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 = .1f;

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

            var leftShinToLeftFootBallSocketJoint = new BallSocketJoint(leftShin, leftFoot, leftShin.Position + new Vector3(0, -.3f, 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 = .2f;

            #endregion

            #region Right Leg
            var pelvisToRightThighBallSocketJoint = new BallSocketJoint(pelvis, rightThigh, pelvis.Position + new Vector3(.15f, -.1f, 0));
            var pelvisToRightThighEllipseSwingLimit = new EllipseSwingLimit(pelvis, rightThigh, Vector3.Normalize(new Vector3(.2f, -1, -.6f)), MathHelper.Pi * .7f, 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 = .1f;

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

            var rightShinToRightFootBallSocketJoint = new BallSocketJoint(rightShin, rightFoot, rightShin.Position + new Vector3(0, -.3f, 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 = .2f;

            #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
        }
예제 #14
0
        private void setUpWand(Vector3 position)
        {
            // Make a wand
            wand = XNAGame.Instance.createBox(new Vector3(position.X, position.Y + 8, position.Z), 2, 8, 2);

            // Make the wand hinge (it's joint with the main vehicle)
            wandHinge = new RevoluteJoint(chassis.body, wand.body, chassis.body.Position, Vector3.UnitX);
            wandHinge.Limit.IsActive = true;
            wandHinge.Limit.MaximumAngle = MathHelper.ToRadians(45.0f);
            wandHinge.Limit.MinimumAngle = MathHelper.ToRadians(-46.0f);
            wandHinge.Motor.Settings.Mode = MotorMode.Servomechanism;
            wandHinge.Motor.Settings.Servo.BaseCorrectiveSpeed = 120;
            wandHinge.Motor.Settings.MaximumForce = 200;
            wandHinge.Motor.Settings.Servo.SpringSettings.StiffnessConstant /= 20;

            // Add to the space
            XNAGame.Instance.space.Add(wandHinge);
        }
        /// <summary>
        /// Creates a machine that rotates between two orientations, with or without an offset.
        /// </summary>
        /// <param name="machineNo">The machine number.</param>
        /// <param name="objects">A list of BaseModels and Tubes that the Machine contains. It will be assumed that the first is the base of the
        /// machine and all others are contained inside the machine.</param>
        /// <param name="angle">The angle of rotation.</param>
        /// <param name="rotationAxis">The axis of rotation.</param>
        /// <param name="center">The center of rotation.</param>
        /// <param name="rotateTime">The time to complete one rotation in seconds.</param>
        public ClampedRotationMachine(int machineNo, int soundIndex, float rotateTime, Vector3 rotationAxis, float angle,
            Vector3 center, Vector3 zeroAxis, params BaseModel[] objects)
            : base(machineNo, soundIndex, objects)
        {
            //if(angle < 0 || angle > MathHelper.Pi)
            //    throw new ArgumentOutOfRangeException("Angle must be between 0 and pi. Use a negative zeroAxis to simulate negative angles.");
            if(rotateTime <= 0)
                throw new ArgumentOutOfRangeException("rotateTime cannot be equal to or less than zero.");

            if(angle < 0)
            {
                negativeAngle = true;
                angle = -angle;
                atOrigin = false;
            }

            originalAxis = rotationAxis;

            //motorList = new List<RotateMotor>();
            joints = new List<WeldJoint>();
            baseJoint = new RevoluteJoint(null, modelList[0].Ent, center, rotationAxis);
            baseJoint.Motor.IsActive = true;
            baseJoint.Motor.Settings.Mode = BEPUphysics.Constraints.TwoEntity.Motors.MotorMode.Servomechanism;
            baseJoint.Motor.Settings.Servo.SpringSettings.StiffnessConstant = 0;
            baseJoint.Motor.Settings.Servo.SpringSettings.DampingConstant /= 12;
            baseJoint.Motor.Settings.Servo.Goal = negativeAngle ? angle : 0;
            baseJoint.Motor.Settings.Servo.MaxCorrectiveVelocity = angle / rotateTime;
            baseJoint.Motor.Settings.Servo.BaseCorrectiveSpeed = angle / rotateTime;
            baseJoint.Motor.Basis.SetWorldAxes(rotationAxis, zeroAxis);
            baseJoint.Motor.TestAxis = zeroAxis;
            baseJoint.Limit.IsActive = true;
            baseJoint.Limit.MinimumAngle = 0;
            baseJoint.Limit.MaximumAngle = angle;
            baseJoint.Limit.Basis.SetWorldAxes(rotationAxis, zeroAxis);
            baseJoint.Limit.TestAxis = zeroAxis;

            timeStep = rotateTime;
            this.angle = angle;

            //foreach(Tube t in tubeList)
            //    t.LocalOffset = t.Ent.Position - center;

            if(modelList.Count > 1)
                foreach(BaseModel m in modelList)
                {
                    if(m == modelList[0]) // skip first element
                        continue;
                    //m.Ent.Orientation = Quaternion.Identity;
                    //m.Ent.CollisionInformation.LocalPosition = m.Ent.Position - center;
                    //m.Ent.Position = center;
                    //m.Ent.Orientation = m.OriginalOrientation; // Resets orientation
                    //motorList.Add(new RotateMotor(m, radiansToRotate) { Time = GameManager.Space.TimeStepSettings.TimeStepDuration });
                    WeldJoint j = new WeldJoint(baseJoint.Motor.ConnectionB, m.Ent);
                    j.IsActive = true;
                    //j.Limit.IsActive = true;
                    //j.Limit.MinimumAngle = 0;
                    joints.Add(j);
                }
            foreach(Tube t in tubeList)
                t.SetParent(baseJoint.Motor.ConnectionB);
                //motorList.Add(new RotateMotor(t, radiansToRotate, t.LocalOffset) { Time = GameManager.Space.TimeStepSettings.TimeStepDuration });
        }
예제 #16
0
 void Retract(RevoluteJoint joint, float dt)
 {
     float retractionSpeed = 2;
     joint.Motor.Settings.Servo.Goal = MathHelper.Clamp(joint.Motor.Settings.Servo.Goal - retractionSpeed * dt, joint.Limit.MinimumAngle, joint.Limit.MaximumAngle);
 }
        public TruckMachine(int machineNo, int soundIndex, float translationTime, float rotationTime, float angle,
            Vector3 translationAxis, Vector3 glassRotationAxis, Vector3 wheelRotationAxis,
            Vector3 glassZeroAxis, Vector3 glassCenter1, Vector3 glassCenter2, Vector3 wheelsCenter1,
            Vector3 wheelsCenter2, BaseModel wheels1, BaseModel wheels2, BaseModel glass1,
            BaseModel glass2, params BaseModel[] models)
            : base(machineNo, soundIndex, models.Concat(new BaseModel[] { wheels1, wheels2, glass1, glass2 }).ToArray<BaseModel>())
        {
            translation = translationAxis;
            this.translationTime = translationTime;
            this.rotationTime = rotationTime;

            originalGlassAxis = glassRotationAxis;
            originalWheelAxis = wheelRotationAxis;
            unitsToTranslate = translationAxis;

            baseJoint = new PrismaticJoint(null, models[0].Ent, models[0].Ent.Position, translationAxis, models[0].Ent.Position);
            baseJoint.Motor.IsActive = true;
            baseJoint.Motor.Settings.Mode = MotorMode.Servomechanism;
            baseJoint.Motor.Settings.Servo.Goal = 0;
            baseJoint.Limit.Maximum = translationAxis.Length();
            baseJoint.Limit.Minimum = 0;
            baseJoint.Limit.IsActive = true;
            baseJoint.Motor.Settings.Servo.BaseCorrectiveSpeed = translationAxis.Length() / translationTime;
            baseJoint.Motor.Settings.Servo.MaxCorrectiveVelocity = translationAxis.Length() / translationTime;
            baseJoint.Motor.Settings.Servo.SpringSettings.StiffnessConstant = 0;
            baseJoint.Motor.Settings.Servo.SpringSettings.DampingConstant /= 11;

            glassJoint1 = new RevoluteJoint(models[0].Ent, glass1.Ent, glassCenter1, glassRotationAxis);
            glassJoint1.Motor.IsActive = true;
            glassJoint1.Motor.Settings.Mode = BEPUphysics.Constraints.TwoEntity.Motors.MotorMode.Servomechanism;
            glassJoint1.Motor.Settings.Servo.SpringSettings.StiffnessConstant = 0;
            glassJoint1.Motor.Settings.Servo.SpringSettings.DampingConstant /= 12;
            glassJoint1.Motor.Settings.Servo.Goal = 0;
            glassJoint1.Motor.Settings.Servo.MaxCorrectiveVelocity = angle / rotationTime;
            glassJoint1.Motor.Settings.Servo.BaseCorrectiveSpeed = angle / rotationTime;
            glassJoint1.Motor.Basis.SetWorldAxes(glassRotationAxis, glassZeroAxis);
            glassJoint1.Motor.TestAxis = glassZeroAxis;
            glassJoint1.Limit.IsActive = true;
            glassJoint1.Limit.MinimumAngle = 0;
            glassJoint1.Limit.MaximumAngle = angle;
            glassJoint1.Limit.Basis.SetWorldAxes(glassRotationAxis, glassZeroAxis);
            glassJoint1.Limit.TestAxis = glassZeroAxis;

            glassJoint2 = new RevoluteJoint(models[0].Ent, glass2.Ent, glassCenter2, -glassRotationAxis);
            glassJoint2.Motor.IsActive = true;
            glassJoint2.Motor.Settings.Mode = BEPUphysics.Constraints.TwoEntity.Motors.MotorMode.Servomechanism;
            glassJoint2.Motor.Settings.Servo.SpringSettings.StiffnessConstant = 0;
            glassJoint2.Motor.Settings.Servo.SpringSettings.DampingConstant /= 12;
            glassJoint2.Motor.Settings.Servo.Goal = 0;
            glassJoint2.Motor.Settings.Servo.MaxCorrectiveVelocity = angle / rotationTime;
            glassJoint2.Motor.Settings.Servo.BaseCorrectiveSpeed = angle / rotationTime;
            glassJoint2.Motor.Basis.SetWorldAxes(-glassRotationAxis, glassZeroAxis);
            glassJoint2.Motor.TestAxis = glassZeroAxis;
            glassJoint2.Limit.IsActive = true;
            glassJoint2.Limit.MinimumAngle = 0;
            glassJoint2.Limit.MaximumAngle = angle;
            glassJoint2.Limit.Basis.SetWorldAxes(-glassRotationAxis, glassZeroAxis);
            glassJoint2.Limit.TestAxis = glassZeroAxis;

            wheelsJoint1 = new RevoluteJoint(models[0].Ent, wheels1.Ent, wheelsCenter1, wheelRotationAxis);
            wheelsJoint1.Motor.Settings.Mode = MotorMode.VelocityMotor;
            wheelsJoint1.Motor.Settings.VelocityMotor.GoalVelocity = 0f;
            wheelsJoint1.Motor.Settings.VelocityMotor.Softness = 1 / glassJoint1.Motor.Settings.Servo.SpringSettings.DampingConstant;
            wheelsJoint2 = new RevoluteJoint(models[0].Ent, wheels2.Ent, wheelsCenter2, wheelRotationAxis);
            wheelsJoint2.Motor.Settings.Mode = MotorMode.VelocityMotor;
            wheelsJoint2.Motor.Settings.VelocityMotor.GoalVelocity = 0f;
            wheelsJoint2.Motor.Settings.VelocityMotor.Softness = 1 / glassJoint2.Motor.Settings.Servo.SpringSettings.DampingConstant;

            if(models.Length > 1)
                foreach(BaseModel m in models)
                {
                    if(m == models[0])
                        continue;
                    WeldJoint j = new WeldJoint(models[0].Ent, m.Ent);
                    j.IsActive = true;
                    joints.Add(j);
                }
        }
예제 #18
0
        void BuildLeg(Entity body, RigidTransform legTransform, List<RevoluteJoint> legJoints)
        {
            //Build the leg in local space.
            var upperLeg = new Box(new Vector3(.75f, 0, 0), 1.5f, .6f, .6f, 7);
            var lowerLeg = new Box(new Vector3(1.2f, -.75f, 0), .6f, 1.5f, .6f, 7);

            //Increase the feetfriction to make walking easier.
            lowerLeg.Material.KineticFriction = 3;
            lowerLeg.Material.StaticFriction = 3;

            Space.Add(upperLeg);
            Space.Add(lowerLeg);

            //Pull the leg entities into world space.
            upperLeg.WorldTransform *= legTransform.Matrix;
            lowerLeg.WorldTransform *= legTransform.Matrix;

            //Don't let the leg pieces interact with each other.
            CollisionRules.AddRule(upperLeg, body, CollisionRule.NoBroadPhase);
            CollisionRules.AddRule(upperLeg, lowerLeg, CollisionRule.NoBroadPhase);

            //Connect the body to the upper leg.
            var bodyToUpper = new RevoluteJoint(body, upperLeg, legTransform.Position, legTransform.OrientationMatrix.Forward);
            //Both the motor and limit need to be activated for this leg.
            bodyToUpper.Limit.IsActive = true;
            //While the angular joint doesn't need any extra configuration, the limit does in order to ensure that its interpretation of angles matches ours.
            bodyToUpper.Limit.LocalTestAxis = Vector3.Left;
            bodyToUpper.Limit.Basis.SetWorldAxes(legTransform.OrientationMatrix.Forward, legTransform.OrientationMatrix.Left);
            bodyToUpper.Limit.MinimumAngle = -MathHelper.PiOver4;
            bodyToUpper.Limit.MaximumAngle = MathHelper.PiOver4;
            //Similarly, the motor needs configuration.
            bodyToUpper.Motor.IsActive = true;
            bodyToUpper.Motor.LocalTestAxis = Vector3.Left;
            bodyToUpper.Motor.Basis.SetWorldAxes(legTransform.OrientationMatrix.Forward, legTransform.OrientationMatrix.Left);
            bodyToUpper.Motor.Settings.Mode = MotorMode.Servomechanism;
            //Weaken the spring to prevent it from launching too much.
            bodyToUpper.Motor.Settings.Servo.SpringSettings.Stiffness *= .01f;
            bodyToUpper.Motor.Settings.Servo.SpringSettings.Damping *= .01f;
            Space.Add(bodyToUpper);

            //Connect the upper leg to the lower leg.
            var upperToLower = new RevoluteJoint(upperLeg, lowerLeg, legTransform.Position - legTransform.OrientationMatrix.Left * 1.2f, legTransform.OrientationMatrix.Forward);
            //Both the motor and limit need to be activated for this leg.
            upperToLower.Limit.IsActive = true;
            //While the angular joint doesn't need any extra configuration, the limit does in order to ensure that its interpretation of angles matches ours.
            upperToLower.Limit.LocalTestAxis = Vector3.Down;
            upperToLower.Limit.Basis.SetWorldAxes(legTransform.OrientationMatrix.Forward, legTransform.OrientationMatrix.Down);
            upperToLower.Limit.MinimumAngle = -MathHelper.PiOver4;
            upperToLower.Limit.MaximumAngle = MathHelper.PiOver4;
            //Similarly, the motor needs configuration.
            upperToLower.Motor.IsActive = true;
            upperToLower.Motor.LocalTestAxis = Vector3.Down;
            upperToLower.Motor.Basis.SetWorldAxes(legTransform.OrientationMatrix.Forward, legTransform.OrientationMatrix.Down);
            upperToLower.Motor.Settings.Mode = MotorMode.Servomechanism;
            //Weaken the spring to prevent it from launching too much.
            upperToLower.Motor.Settings.Servo.SpringSettings.Stiffness *= .01f;
            upperToLower.Motor.Settings.Servo.SpringSettings.Damping *= .01f;
            Space.Add(upperToLower);

            legJoints.Add(upperToLower);
            legJoints.Add(bodyToUpper);

        }
예제 #19
0
 public void SetKinematicParent(Entity e)
 {
     Ent.BecomeKinematic();
     if(motor != null && motor.Solver != null)
         GameManager.Space.Remove(motor);
     motor = null;
 }
예제 #20
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);
        }
예제 #21
0
        /// <summary>
        /// Constructs a new demo.
        /// </summary>
        /// <param name="game">Game owning this demo.</param>
        public RobotArmDemo(DemosGame game)
            : base(game)
        {
            //Since this is not a "StandardDemo" derived class, we need to set our own gravity.
            Space.ForceUpdater.Gravity = new Vector3(0, -9.81f, 0);
            Entity ground = new Box(Vector3.Zero, 30, 1, 30);
            Space.Add(ground);

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

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

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

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


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

            game.Camera.Position = new Vector3(0, 5, 13);
        }
예제 #22
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);
        }
        /// <summary>
        /// Constructs a new demo.
        /// </summary>
        /// <param name="game">Game owning this demo.</param>
        public CharacterPlaygroundDemo(DemosGame game)
            : base(game)
        {

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

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


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

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



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

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

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

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


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

            var positionCurve = new CardinalSpline3D();

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

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

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

            elevatorPath = positionCurve;

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

            var platformCurve = new LinearInterpolationCurve3D();

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

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

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

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

            platformPath = platformCurve;
            platformOrientationPath = platformRotationCurve;

            //Add in a diving board.

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

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


            //Add a second diving board for comparison.

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

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

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

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


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



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


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

            Space.Add(log);


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

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

        }
예제 #24
0
        public Turret(Entity tankBody, Vector3 offset)
        {
            var position = offset + tankBody.Position;
            Body = new Cylinder(position, 0.7f, 0.8f, 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, 0.2f, 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, -0.5f), 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 = 0.5f;
            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 = 0.5f;
            //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 * 0.05f;
            MaximumPitch = MathHelper.Pi * 0.4f;

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

            for (int i = 0; i < MaximumShellCount; ++i)
            {
                var shell = new Sphere(new Vector3(100000, 0, 0), 0.2f, 2);
                shell.PositionUpdateMode = BEPUphysics.PositionUpdating.PositionUpdateMode.Continuous;
                shellPool.Enqueue(shell);
            }


        }
예제 #25
0
        /// <summary>
        /// Constructs a new demo.
        /// </summary>
        /// <param name="game">Game owning this demo.</param>
        public DogbotDemo(DemosGame game)
            : base(game)
        {
            Entity body = new Box(new Vector3(0, 0, 0), 4, 2, 2, 20);
            Space.Add(body);

            Entity head = new Cone(body.Position + new Vector3(3.2f, .3f, 0), 1.5f, .7f, 4);
            head.OrientationMatrix = Matrix3x3.CreateFromAxisAngle(Vector3.Forward, MathHelper.PiOver2);
            Space.Add(head);

            //Attach the head to the body
            var universalJoint = new UniversalJoint(body, head, head.Position + new Vector3(-.8f, 0, 0));
            Space.Add(universalJoint);
            //Keep the head from swinging around too much.
            var angleLimit = new SwingLimit(body, head, Vector3.Right, Vector3.Right, MathHelper.PiOver4);
            Space.Add(angleLimit);

            var tail = new Box(body.Position + new Vector3(-3f, 1f, 0), 1.6f, .1f, .1f, 4);
            Space.Add(tail);
            //Keep the tail from twisting itself off.
            universalJoint = new UniversalJoint(body, tail, tail.Position + new Vector3(.8f, 0, 0));
            Space.Add(universalJoint);

            //Give 'em some floppy ears.
            var ear = new Box(head.Position + new Vector3(-.2f, 0, -.65f), .01f, .7f, .2f, 1);
            Space.Add(ear);

            var ballSocketJoint = new BallSocketJoint(head, ear, head.Position + new Vector3(-.2f, .35f, -.65f));
            Space.Add(ballSocketJoint);

            ear = new Box(head.Position + new Vector3(-.2f, 0, .65f), .01f, .7f, .3f, 1);
            Space.Add(ear);

            ballSocketJoint = new BallSocketJoint(head, ear, head.Position + new Vector3(-.2f, .35f, .65f));
            Space.Add(ballSocketJoint);

            Box arm;
            Cylinder shoulder;
            PointOnLineJoint pointOnLineJoint;

            //*************  First Arm   *************//
            arm = new Box(body.Position + new Vector3(-1.8f, -.5f, 1.5f), .5f, 3, .2f, 20);
            Space.Add(arm);

            shoulder = new Cylinder(body.Position + new Vector3(-1.8f, .3f, 1.25f), .1f, .7f, 10);
            shoulder.OrientationMatrix = Matrix3x3.CreateFromAxisAngle(Vector3.Right, MathHelper.PiOver2);
            Space.Add(shoulder);

            //Connect the shoulder to the body.
            var axisJoint = new RevoluteJoint(body, shoulder, shoulder.Position, Vector3.Forward);

            //Motorize the connection.
            axisJoint.Motor.IsActive = true;
            axisJoint.Motor.Settings.VelocityMotor.GoalVelocity = 1;

            Space.Add(axisJoint);

            //Connect the arm to the shoulder.
            axisJoint = new RevoluteJoint(shoulder, arm, shoulder.Position + new Vector3(0, .6f, 0), Vector3.Forward);
            Space.Add(axisJoint);

            //Connect the arm to the body.
            pointOnLineJoint = new PointOnLineJoint(arm, body, arm.Position, Vector3.Up, arm.Position + new Vector3(0, -.4f, 0));
            Space.Add(pointOnLineJoint);

            shoulder.OrientationMatrix *= Matrix3x3.CreateFromAxisAngle(Vector3.Forward, MathHelper.Pi); //Force the walker's legs out of phase.

            //*************  Second Arm   *************//
            arm = new Box(body.Position + new Vector3(1.8f, -.5f, 1.5f), .5f, 3, .2f, 20);
            Space.Add(arm);

            shoulder = new Cylinder(body.Position + new Vector3(1.8f, .3f, 1.25f), .1f, .7f, 10);
            shoulder.OrientationMatrix = Matrix3x3.CreateFromAxisAngle(Vector3.Right, MathHelper.PiOver2);
            Space.Add(shoulder);

            //Connect the shoulder to the body.
            axisJoint = new RevoluteJoint(body, shoulder, shoulder.Position, Vector3.Forward);

            //Motorize the connection.
            axisJoint.Motor.IsActive = true;
            axisJoint.Motor.Settings.VelocityMotor.GoalVelocity = 1;

            Space.Add(axisJoint);

            //Connect the arm to the shoulder.
            axisJoint = new RevoluteJoint(shoulder, arm, shoulder.Position + new Vector3(0, .6f, 0), Vector3.Forward);
            Space.Add(axisJoint);

            //Connect the arm to the body.
            pointOnLineJoint = new PointOnLineJoint(arm, body, arm.Position, Vector3.Up, arm.Position + new Vector3(0, -.4f, 0));
            Space.Add(pointOnLineJoint);

            //*************  Third Arm   *************//
            arm = new Box(body.Position + new Vector3(-1.8f, -.5f, -1.5f), .5f, 3, .2f, 20);
            Space.Add(arm);

            shoulder = new Cylinder(body.Position + new Vector3(-1.8f, .3f, -1.25f), .1f, .7f, 10);
            shoulder.OrientationMatrix = Matrix3x3.CreateFromAxisAngle(Vector3.Right, MathHelper.PiOver2);
            Space.Add(shoulder);

            //Connect the shoulder to the body.
            axisJoint = new RevoluteJoint(body, shoulder, shoulder.Position, Vector3.Forward);

            //Motorize the connection.
            axisJoint.Motor.IsActive = true;
            axisJoint.Motor.Settings.VelocityMotor.GoalVelocity = 1;

            Space.Add(axisJoint);

            //Connect the arm to the shoulder.
            axisJoint = new RevoluteJoint(shoulder, arm, shoulder.Position + new Vector3(0, .6f, 0), Vector3.Forward);
            Space.Add(axisJoint);

            //Connect the arm to the body.
            pointOnLineJoint = new PointOnLineJoint(arm, body, arm.Position, Vector3.Up, arm.Position + new Vector3(0, -.4f, 0));
            Space.Add(pointOnLineJoint);

            shoulder.OrientationMatrix *= Matrix3x3.CreateFromAxisAngle(Vector3.Forward, MathHelper.Pi); //Force the walker's legs out of phase.

            //*************  Fourth Arm   *************//
            arm = new Box(body.Position + new Vector3(1.8f, -.5f, -1.5f), .5f, 3, .2f, 20);
            Space.Add(arm);

            shoulder = new Cylinder(body.Position + new Vector3(1.8f, .3f, -1.25f), .1f, .7f, 10);
            shoulder.OrientationMatrix = Matrix3x3.CreateFromAxisAngle(Vector3.Right, MathHelper.PiOver2);
            Space.Add(shoulder);

            //Connect the shoulder to the body.
            axisJoint = new RevoluteJoint(body, shoulder, shoulder.Position, Vector3.Forward);

            //Motorize the connection.
            axisJoint.Motor.IsActive = true;
            axisJoint.Motor.Settings.VelocityMotor.GoalVelocity = 1;

            Space.Add(axisJoint);

            //Connect the arm to the shoulder.
            axisJoint = new RevoluteJoint(shoulder, arm, shoulder.Position + new Vector3(0, .6f, 0), Vector3.Forward);
            Space.Add(axisJoint);

            //Connect the arm to the body.
            pointOnLineJoint = new PointOnLineJoint(arm, body, arm.Position, Vector3.Up, arm.Position + new Vector3(0, -.4f, 0));
            Space.Add(pointOnLineJoint);

            //Add some ground.
            Space.Add(new Box(new Vector3(0, -3.5f, 0), 20f, 1, 20f));

            game.Camera.Position = new Vector3(0, 2, 20);
        }
        /// <summary>
        /// Makes a machine that automatically translates and user-rotates.
        /// </summary>
        /// <param name="machineNo">Machine number of the machine.</param>
        /// <param name="unitsToTranslate">The distance to translate from the origin.</param>
        /// <param name="pauseTime">The time in seconds to pause at each end.</param>
        /// <param name="centerOfRotation">The center of rotation based on the starting position.</param>
        /// <param name="rotateTime">Time to take to rotate.</param>
        /// <param name="degreesToRotate">The degrees on each axis to rotate.</param>
        /// <param name="models">The models that rotate.</param>
        /// <param name="angle">The angle to rotate.</param>
        /// <param name="rotationAxis">The axis to rotate on.</param>
        /// <param name="soundIndex">The sound to use for the machine.</param>
        /// <param name="stableModels">The models that don't rotate.</param>
        /// <param name="translationTime">The time to take to translate.</param>
        public RailMachine(int machineNo, int soundIndex, bool soundWhenMoves, Vector3 unitsToTranslate, float pauseTime, float translationTime,
            Vector3 centerOfRotation, float rotateTime, Vector3 rotationAxis, float angle, Vector3 zeroAxis, BaseModel[] stableModels,
            params BaseModel[] models)
            : base(machineNo, soundIndex, models)
        {
            if(stableModels.Length == 0)
                throw new ArgumentException("There must be at least one stable model.");
            if(models.Length == 0)
                throw new ArgumentException("There must be a least rotational model.");

            this.unitsToTranslate = unitsToTranslate;
            this.translationTime = translationTime;
            this.rotateTime = rotateTime;
            this.angle = angle;
            this.soundWhenMoves = soundWhenMoves;
            lengthToPause = pauseTime;
            originalAxis = rotationAxis;

            if(angle < 0)
            {
                negativeAngle = true;
                angle = -angle;
            }

            baseJoint = new PrismaticJoint(null, stableModels[0].Ent, stableModels[0].Ent.Position, Vector3.Normalize(unitsToTranslate), stableModels[0].Ent.Position);
            baseJoint.Motor.IsActive = true;
            baseJoint.Motor.Settings.Mode = MotorMode.Servomechanism;
            baseJoint.Motor.Settings.Servo.Goal = 0;
            baseJoint.Limit.Maximum = unitsToTranslate.Length();
            baseJoint.Limit.Minimum = 0;
            baseJoint.Limit.IsActive = true;
            baseJoint.Motor.Settings.Servo.BaseCorrectiveSpeed = unitsToTranslate.Length() / translationTime;
            baseJoint.Motor.Settings.Servo.MaxCorrectiveVelocity = unitsToTranslate.Length() / translationTime;
            baseJoint.Motor.Settings.Servo.SpringSettings.StiffnessConstant = 0;
            baseJoint.Motor.Settings.Servo.SpringSettings.DampingConstant /= 2;

            rotateJoint = new RevoluteJoint(stableModels[0].Ent, models[0].Ent, centerOfRotation, rotationAxis);
            rotateJoint.Motor.IsActive = true;
            rotateJoint.Motor.Settings.Mode = BEPUphysics.Constraints.TwoEntity.Motors.MotorMode.Servomechanism;
            rotateJoint.Motor.Settings.Servo.SpringSettings.StiffnessConstant = 0;
            rotateJoint.Motor.Settings.Servo.SpringSettings.DampingConstant /= 4;
            rotateJoint.Motor.Settings.Servo.Goal = negativeAngle ? angle : 0;
            rotateJoint.Motor.Settings.Servo.MaxCorrectiveVelocity = angle / rotateTime;
            rotateJoint.Motor.Settings.Servo.BaseCorrectiveSpeed = angle / rotateTime;
            rotateJoint.Motor.Basis.SetWorldAxes(rotationAxis, zeroAxis);
            rotateJoint.Motor.TestAxis = zeroAxis;
            rotateJoint.Limit.IsActive = true;
            rotateJoint.Limit.MinimumAngle = 0;
            rotateJoint.Limit.MaximumAngle = angle;
            rotateJoint.Limit.Basis.SetWorldAxes(rotationAxis, zeroAxis);
            rotateJoint.Limit.TestAxis = zeroAxis;

            for(int i = 0; i < stableModels.Length - 1; i++)
            {
                WeldJoint j = new WeldJoint(stableModels[0].Ent, stableModels[i + 1].Ent);
                j.IsActive = true;
                welds.Add(j);
            }
            for(int i = 0; i < models.Length - 1; i++)
            {
                WeldJoint j = new WeldJoint(models[0].Ent, models[i + 1].Ent);
                j.IsActive = true;
                welds.Add(j);
            }
            foreach(Tube t in tubeList)
                t.SetParent(models[0].Ent);

            modelList.Clear();
            modelList.AddRange(stableModels);
            modelList.AddRange(models);

            //Vector3 radians = new Vector3(MathHelper.ToRadians(degreesToRotate.X),
            //    MathHelper.ToRadians(degreesToRotate.Y), MathHelper.ToRadians(degreesToRotate.Z));
            //radiansToRotate = Quaternion.CreateFromYawPitchRoll(radians.Y,
            //    radians.X, radians.Z);

            //for(int i = 1; i < modelList.Count; i++)
            //{
            //    BaseModel m = modelList[i];
            //    m.Ent.Orientation = Quaternion.Identity;
            //    m.Ent.CollisionInformation.LocalPosition = m.Ent.Position - centerOfRotation;
            //    m.Ent.Position = centerOfRotation;
            //    m.Ent.Orientation = m.OriginalOrientation; // Resets orientation
            //}
            //curve = new QuaternionSlerpCurve();
            //curve.ControlPoints.Add(0, Quaternion.Identity);
            //curve.ControlPoints.Add(rotateTime, radiansToRotate);
            //curve.PostLoop = CurveEndpointBehavior.Mirror;
            //curve.PreLoop = CurveEndpointBehavior.Mirror;
            timeStep = rotateTime * 1000;
        }