internal DigitalRunePrismaticJoint(PrismaticJointDescriptor descriptor)
        {
            WrappedPrismaticJoint = new PrismaticJoint();

            #region set RigidBodies
            if (!(descriptor.RigidBodyA is RigidBody))
                throw new ArgumentException(String.Format("The type of the property 'RigidBodyA' must be '{0}'.", typeof(RigidBody)));
            WrappedPrismaticJoint.BodyA = ((RigidBody)descriptor.RigidBodyA).WrappedRigidBody;
            _rigidBodyA = descriptor.RigidBodyA;

            if (!(descriptor.RigidBodyB is RigidBody))
                throw new ArgumentException("The type of the property 'RigidBodyB' must be 'System.Physics.DigitalRune.RigidBody'.");
            WrappedPrismaticJoint.BodyB = ((RigidBody)descriptor.RigidBodyB).WrappedRigidBody;
            _rigidBodyB = descriptor.RigidBodyB;
            #endregion
            WrappedPrismaticJoint.AnchorPoseALocal = descriptor.AnchorPoseALocal.ToDigitalRune();
            WrappedPrismaticJoint.AnchorPoseBLocal = descriptor.AnchorPoseBLocal.ToDigitalRune();
            WrappedPrismaticJoint.Maximum = descriptor.MaximumDistance;
            WrappedPrismaticJoint.Minimum = descriptor.MinimumDistance; 



            Descriptor = descriptor;
        }
예제 #2
0
    public ConstraintSample3(Microsoft.Xna.Framework.Game game)
      : base(game)
    {
      // Add basic force effects.
      Simulation.ForceEffects.Add(new Gravity());
      Simulation.ForceEffects.Add(new Damping());

      // Add a ground plane.
      RigidBody groundPlane = new RigidBody(new PlaneShape(Vector3F.UnitY, 0))
      {
        Name = "GroundPlane",           // Names are not required but helpful for debugging.
        MotionType = MotionType.Static,
      };
      Simulation.RigidBodies.Add(groundPlane);

      // ----- HingeJoint with AngularVelocityMotor
      // A board is fixed on a pole like a wind wheel.
      // An AngularVelocityMotor creates a rotation with constant angular velocity around the
      // hinge axis.
      RigidBody box0 = new RigidBody(new BoxShape(0.1f, 2f, 0.1f))
      {
        Pose = new Pose(new Vector3F(-2, 1, 0)),
        MotionType = MotionType.Static,
      };
      Simulation.RigidBodies.Add(box0);
      RigidBody box1 = new RigidBody(new BoxShape(0.1f, 0.4f, 1f))
      {
        Pose = new Pose(new Vector3F(-2 + 0.05f, 1.8f, 0))
      };
      Simulation.RigidBodies.Add(box1);
      HingeJoint hingeJoint = new HingeJoint
      {
        BodyA = box0,
        BodyB = box1,
        AnchorPoseALocal = new Pose(new Vector3F(0.05f, 0.8f, 0)),
        AnchorPoseBLocal = new Pose(new Vector3F(-0.05f, 0, 0)),
        CollisionEnabled = false,
      };
      Simulation.Constraints.Add(hingeJoint);
      AngularVelocityMotor angularVelocityMotor = new AngularVelocityMotor
      {
        BodyA = box0,
        // The rotation axis is the local x axis of BodyA.
        AxisALocal = Vector3F.UnitX,
        BodyB = box1,
        TargetVelocity = 10,
        // The motor power is limit, so that the rotation can be stopped by other objects blocking
        // the movement.
        MaxForce = 10000,
        // The HingeJoint controls all other axes. So this motor must only act on the hinge
        // axis.
        UseSingleAxisMode = true,
        CollisionEnabled = false,
      };
      Simulation.Constraints.Add(angularVelocityMotor);

      // ----- A PrismaticJoint with a LinearVelocityMotor.
      RigidBody box2 = new RigidBody(new BoxShape(0.7f, 0.7f, 0.7f))
      {
        Pose = new Pose(new Vector3F(0, 2, 0)),
        MotionType = MotionType.Static,
      };
      Simulation.RigidBodies.Add(box2);
      RigidBody box3 = new RigidBody(new BoxShape(0.5f, 1.5f, 0.5f))
      {
        Pose = new Pose(new Vector3F(0, 1, 0))
      };
      Simulation.RigidBodies.Add(box3);
      _prismaticJoint = new PrismaticJoint
      {
        BodyA = box2,
        BodyB = box3,
        AnchorPoseALocal = new Pose(new Vector3F(0, 0, 0), new Matrix33F(0, 1, 0,
                                                                        -1, 0, 0,
                                                                         0, 0, 1)),
        AnchorPoseBLocal = new Pose(new Vector3F(0, 0, 0), new Matrix33F(0, 1, 0,
                                                                        -1, 0, 0,
                                                                         0, 0, 1)),
        CollisionEnabled = false,
      };
      Simulation.Constraints.Add(_prismaticJoint);
      _linearVelocityMotor = new LinearVelocityMotor
      {
        BodyA = box2,
        AxisALocal = -Vector3F.UnitY,
        BodyB = box3,
        TargetVelocity = 1,
        CollisionEnabled = false,
        MaxForce = 10000,
        UseSingleAxisMode = true,
      };
      Simulation.Constraints.Add(_linearVelocityMotor);

      // ----- A BallJoint with a TwistSwingLimit and a QuaternionMotor
      // The ball joint connects a cylinder to a static box.
      // The twist-swing limits rotational movement.
      // The quaternion motor acts like a spring that controls the angle of joint.
      RigidBody box4 = new RigidBody(new BoxShape(0.5f, 0.5f, 0.5f))
      {
        Pose = new Pose(new Vector3F(2, 2, 0)),
        MotionType = MotionType.Static,
      };
      Simulation.RigidBodies.Add(box4);
      RigidBody cylinder0 = new RigidBody(new CylinderShape(0.1f, 0.75f))
      {
        Pose = new Pose(new Vector3F(2, 2 - 0.75f / 2 - 0.25f, 0))
      };
      Simulation.RigidBodies.Add(cylinder0);
      _ballJoint = new BallJoint
      {
        BodyA = box4,
        BodyB = cylinder0,
        AnchorPositionALocal = new Vector3F(0, -0.25f, 0),
        AnchorPositionBLocal = new Vector3F(0, 0.75f / 2, 0),
        CollisionEnabled = false,
      };
      Simulation.Constraints.Add(_ballJoint);
      _twistSwingLimit = new TwistSwingLimit
      {
        BodyA = box4,
        // The first column is the twist axis (-y). The other two columns are the swing axes.
        AnchorOrientationALocal = new Matrix33F(0, 1, 0,
                                               -1, 0, 0,
                                                0, 0, 1),
        BodyB = cylinder0,
        AnchorOrientationBLocal = new Matrix33F(0, 1, 0,
                                               -1, 0, 0,
                                                0, 0, 1),
        CollisionEnabled = false,
        // The twist is limited to +/- 10°. The swing limits are +/- 40° and +/- 60°. This creates
        // a deformed cone that limits the swing movements (see visualization).
        Minimum = new Vector3F(-MathHelper.ToRadians(10), -MathHelper.ToRadians(40), -MathHelper.ToRadians(60)),
        Maximum = new Vector3F(MathHelper.ToRadians(10), MathHelper.ToRadians(40), MathHelper.ToRadians(60)),
      };
      Simulation.Constraints.Add(_twistSwingLimit);
      QuaternionMotor quaternionMotor = new QuaternionMotor
      {
        BodyA = box4,
        AnchorOrientationALocal = Matrix33F.Identity,
        BodyB = cylinder0,
        AnchorOrientationBLocal = Matrix33F.Identity,
        CollisionEnabled = false,
        // The QuaternionMotor controls the orientation of the second body relative to the first
        // body. Here, we define that the cylinder should swing 30° away from the default 
        // orientation.
        TargetOrientation = QuaternionF.CreateRotationZ(MathHelper.ToRadians(30)),
        // Position and orientation motors are similar to damped-springs. We can control
        // the stiffness and damping of the spring. (It is also possible to set the SpringConstant
        // to 0 if the QuaternionMotor should only act as a rotational damping.)
        SpringConstant = 100,
        DampingConstant = 20,
      };
      Simulation.Constraints.Add(quaternionMotor);
    }
예제 #3
0
    public ConstraintSample1(Microsoft.Xna.Framework.Game game)
      : base(game)
    {
      // Add basic force effects.
      Simulation.ForceEffects.Add(new Gravity());
      Simulation.ForceEffects.Add(new Damping());

      // Add a ground plane.
      RigidBody groundPlane = new RigidBody(new PlaneShape(Vector3F.UnitY, 0))
      {
        Name = "GroundPlane",           // Names are not required but helpful for debugging.
        MotionType = MotionType.Static,
      };
      Simulation.RigidBodies.Add(groundPlane);

      // Tip: It is best to initialize bodies in a position where the constraints are 
      // satisfied - but even if they are initialized in other poses, the simulation
      // will try to move them to the correct positions.

      // ----- FixedJoint
      // Create two boxes and connect them with a FixedJoint.      
      RigidBody box0 = new RigidBody(new BoxShape(1, 1, 1))
      {
        Pose = new Pose(new Vector3F(-5, 3, 0)),
        MotionType = MotionType.Static,
      };
      Simulation.RigidBodies.Add(box0);
      RigidBody box1 = new RigidBody(new BoxShape(1.2f, 1.2f, 1.2f))
      {
        Pose = new Pose(new Vector3F(-5, 3 - 1.2f, 0))
      };
      Simulation.RigidBodies.Add(box1);
      FixedJoint fixedJoint = new FixedJoint
      {
        BodyA = box0,
        // The attachment point on the first box is at the bottom of the box.
        AnchorPoseALocal = new Pose(new Vector3F(0, -0.5f, 0)),

        BodyB = box1,
        // The attachment point on the second box is at the top of the box.
        AnchorPoseBLocal = new Pose(new Vector3F(0, 0.6f, 0)),

        // Disable collision between the connected bodies.
        CollisionEnabled = false,
      };
      Simulation.Constraints.Add(fixedJoint);

      // ----- BallJoint
      // Create two boxes and connect a corner of the second box with a ball-and-socked joint
      // to the first box.
      RigidBody box2 = new RigidBody(new BoxShape(1, 1, 1))
      {
        Pose = new Pose(new Vector3F(-3, 3, 0)),
        MotionType = MotionType.Static,
      };
      Simulation.RigidBodies.Add(box2);
      RigidBody box3 = new RigidBody(new BoxShape(1.2f, 1.2f, 1.2f))
      {
        Pose = new Pose(new Vector3F(-3, 3, 0))
      };
      Simulation.RigidBodies.Add(box3);
      BallJoint ballJoint = new BallJoint
      {
        BodyA = box2,
        // The attachment point on the first box is at the box bottom.
        AnchorPositionALocal = new Vector3F(0, -0.5f, 0),

        BodyB = box3,
        // The attachment point on the second box is a corner of the box.
        AnchorPositionBLocal = new Vector3F(0.6f, 0.6f, 0.6f),
      };
      Simulation.Constraints.Add(ballJoint);

      // ----- PrismaticJoint
      // A prismatic joint is like a slider (without rotation around the slider axis).
      RigidBody box4 = new RigidBody(new BoxShape(1, 1, 1))
      {
        Pose = new Pose(new Vector3F(-1, 3, 0)),
      };
      Simulation.RigidBodies.Add(box4);
      RigidBody box5 = new RigidBody(new BoxShape(0.5f, 1.5f, 0.5f))
      {
        Pose = new Pose(new Vector3F(-1, 3 - 0.5f, 0))
      };
      Simulation.RigidBodies.Add(box5);
      PrismaticJoint prismaticJoint = new PrismaticJoint
      {
        BodyA = box4,
        // The attachment point on the first box is in the center of the box.
        // The slider joint allows linear movement along the first constraint axis.
        // --> To define the constraint anchor orientation:
        // The columns are the axes. We set the local -y axis in the first column. This is the
        // slider axis. The other two columns are two orthonormal axes.
        // (All three columns are orthonormal and form a valid rotation matrix.)
        AnchorPoseALocal = new Pose(new Vector3F(0, 0, 0), new Matrix33F(0, 1, 0,
                                                                        -1, 0, 0,
                                                                         0, 0, 1)),
        BodyB = box5,
        // The attachment point on the second box is at the top of the box.
        AnchorPoseBLocal = new Pose(new Vector3F(0, 0.75f, 0), new Matrix33F(0, 1, 0,
                                                                            -1, 0, 0,
                                                                             0, 0, 1)),
        CollisionEnabled = false,
        // The slider axis is -y. We limit the up movement, so that the anchor point on the second
        // body can slide up to the anchor point on the first body, but not higher.
        Minimum = 0,
        // The second body can slide down until the anchor points have a max. distance of 0.5.
        Maximum = 0.5f,
      };
      Simulation.Constraints.Add(prismaticJoint);

      // ----- CylindricalJoint
      // A cylindrical joint is a slider that allows rotation around the slider axis.
      RigidBody box6 = new RigidBody(new BoxShape(1, 1, 1))
      {
        Pose = new Pose(new Vector3F(1, 3, 0)),
      };
      Simulation.RigidBodies.Add(box6);
      RigidBody box7 = new RigidBody(new BoxShape(0.5f, 1.5f, 0.5f))
      {
        Pose = new Pose(new Vector3F(1, 3 - 0.5f, 0))
      };
      Simulation.RigidBodies.Add(box7);
      CylindricalJoint cylindricalJoint = new CylindricalJoint
      {
        BodyA = box6,
        AnchorPoseALocal = new Pose(new Vector3F(0, 0, 0), new Matrix33F(0, 1, 0,
                                                                        -1, 0, 0,
                                                                         0, 0, 1)),
        BodyB = box7,
        AnchorPoseBLocal = new Pose(new Vector3F(0, 0.75f, 0), new Matrix33F(0, 1, 0,
                                                                            -1, 0, 0,
                                                                             0, 0, 1)),
        CollisionEnabled = false,
        // The linear movement limits on the slider axis.
        LinearMinimum = 0,
        LinearMaximum = 0.5f,
        // The rotation limits around the slider axis (in radians). Here, we allow free 
        // rotations.
        AngularMinimum = float.NegativeInfinity,
        AngularMaximum = float.PositiveInfinity,
      };
      Simulation.Constraints.Add(cylindricalJoint);

      // ----- HingeJoint
      // Hinge joints allow rotations around one axis. They can be used to model swinging doors
      // or rotating wheels.
      RigidBody cylinder0 = new RigidBody(new CylinderShape(0.1f, 2f))
      {
        Pose = new Pose(new Vector3F(3, 1, 0)),
        MotionType = MotionType.Static
      };
      Simulation.RigidBodies.Add(cylinder0);
      RigidBody box8 = new RigidBody(new BoxShape(1f, 1.8f, 0.1f))
      {
        Pose = new Pose(new Vector3F(3 + 0.5f, 1, 0))
      };
      Simulation.RigidBodies.Add(box8);
      HingeJoint hingeJoint = new HingeJoint
      {
        BodyA = cylinder0,
        AnchorPoseALocal = new Pose(new Vector3F(0, 0, 0), new Matrix33F(0, 1, 0,
                                                                        -1, 0, 0,
                                                                         0, 0, 1)),
        BodyB = box8,
        AnchorPoseBLocal = new Pose(new Vector3F(-0.5f, 0, 0), new Matrix33F(0, 1, 0,
                                                                            -1, 0, 0,
                                                                             0, 0, 1)),
        CollisionEnabled = false,
        // The rotation limits around the hinge axis (in radians).
        Minimum = -ConstantsF.PiOver2,
        Maximum = ConstantsF.PiOver2,
      };
      Simulation.Constraints.Add(hingeJoint);
    }