private ICollisionJoint[] GetCarConstraints(List <ICollisionShape> shape)
        {
            ICollisionJoint[] constraints = new ICollisionJoint[4];

            //Wheels Joints

            constraints[0] = new Hinge2Joint(
                shape[1],
                shape[2],
                shape[3],
                new Vector3d(-1.1, -0.5, -1.5),
                new Vector3d(0.0, 1.0, 0.0),
                new Vector3d(1.0, 0.0, 0.0),
                0.8,
                0.01,
                0.01);

            constraints[0].SetAxis1AngularLimit(0.0, 0.0);

            constraints[1] = new Hinge2Joint(
                shape[1],
                shape[4],
                shape[5],
                new Vector3d(1.1, -0.5, 1.5),
                new Vector3d(0.0, 1.0, 0.0),
                new Vector3d(1.0, 0.0, 0.0),
                0.8,
                0.01,
                0.01);

            constraints[1].SetAxis1AngularLimit(-0.78539816339, 0.78539816339);

            constraints[2] = new Hinge2Joint(
                shape[1],
                shape[3],
                shape[2],
                new Vector3d(1.1, -0.5, -1.5),
                new Vector3d(0.0, 1.0, 0.0),
                new Vector3d(1.0, 0.0, 0.0),
                0.8,
                0.01,
                0.01);

            constraints[2].SetAxis1AngularLimit(0.0, 0.0);

            constraints[3] = new Hinge2Joint(
                shape[1],
                shape[5],
                shape[4],
                new Vector3d(-1.1, -0.5, 1.5),
                new Vector3d(0.0, 1.0, 0.0),
                new Vector3d(1.0, 0.0, 0.0),
                0.8,
                0.01,
                0.01);

            constraints[3].SetAxis1AngularLimit(-0.78539816339, 0.78539816339);

            return(constraints);
        }
        public ConstraintCarSample(Microsoft.Xna.Framework.Game game)
            : base(game)
        {
            // Add basic force effects.
            Simulation.ForceEffects.Add(new Gravity());
            Simulation.ForceEffects.Add(new Damping());

            // Create a material with high friction - this will be used for the ground and the wheels
            // to give the wheels some traction.
            UniformMaterial roughMaterial = new UniformMaterial
            {
                DynamicFriction = 1,
                StaticFriction  = 1,
            };

            // Add a ground plane.
            RigidBody groundPlane = new RigidBody(new PlaneShape(Vector3.UnitY, 0), null, roughMaterial)
            {
                MotionType = MotionType.Static,
            };

            Simulation.RigidBodies.Add(groundPlane);

            // Now, we build a car out of one box for the chassis and 4 cylindric wheels.
            // Front wheels are fixed with Hinge2Joints and motorized with AngularVelocityMotors.
            // Back wheels are fixed with HingeJoints and not motorized. - This creates a sloppy
            // car configuration. Please note that cars for racing games are not normally built with
            // simple constraints - nevertheless, it is funny to do and play with it.

            // Check out the "Vehicle Sample" (not included in this project)! The "Vehicle Sample"
            // provides a robust ray-car implementation.)

            // ----- Chassis
            BoxShape  chassisShape = new BoxShape(1.7f, 1, 4f);
            MassFrame chassisMass  = MassFrame.FromShapeAndDensity(chassisShape, Vector3.One, 200, 0.01f, 3);

            // Here is a trick: The car topples over very easily. By lowering the center of mass we
            // make it more stable.
            chassisMass.Pose = new Pose(new Vector3(0, -1, 0));
            RigidBody chassis = new RigidBody(chassisShape, chassisMass, null)
            {
                Pose = new Pose(new Vector3(0, 1, 0)),
            };

            Simulation.RigidBodies.Add(chassis);

            // ------ Wheels
            CylinderShape cylinderShape  = new CylinderShape(0.4f, 0.3f);
            MassFrame     wheelMass      = MassFrame.FromShapeAndDensity(cylinderShape, Vector3.One, 500, 0.01f, 3);
            RigidBody     wheelFrontLeft = new RigidBody(cylinderShape, wheelMass, roughMaterial)
            {
                Pose = new Pose(new Vector3(0, 1, 0), Matrix.CreateRotationZ(ConstantsF.PiOver2)),
            };

            Simulation.RigidBodies.Add(wheelFrontLeft);
            RigidBody wheelFrontRight = new RigidBody(cylinderShape, wheelMass, roughMaterial)
            {
                Pose = new Pose(new Vector3(0, 1, 0), Matrix.CreateRotationZ(ConstantsF.PiOver2)),
            };

            Simulation.RigidBodies.Add(wheelFrontRight);
            RigidBody wheelBackLeft = new RigidBody(cylinderShape, wheelMass, roughMaterial)
            {
                Pose = new Pose(new Vector3(0, 1, 0), Matrix.CreateRotationZ(ConstantsF.PiOver2)),
            };

            Simulation.RigidBodies.Add(wheelBackLeft);
            RigidBody wheelBackRight = new RigidBody(cylinderShape, wheelMass, roughMaterial)
            {
                Pose = new Pose(new Vector3(0, 1, 0), Matrix.CreateRotationZ(ConstantsF.PiOver2)),
            };

            Simulation.RigidBodies.Add(wheelBackRight);

            // ----- Hinge2Joints for the front wheels.
            // A Hinge2Joint allows a limited rotation on the first constraint axis - the steering
            // axis. The second constraint axis is locked and the third constraint axis is the
            // rotation axis of the wheels.
            _frontLeftHinge = new Hinge2Joint
            {
                BodyA = chassis,
                // --> To define the constraint anchor orientation for the chassis:
                // The columns are the axes. We set the local y axis in the first column. This is
                // steering axis. In the last column we set the -x axis. This is the wheel rotation axis.
                // In the middle column is a vector that is normal to the first and last axis.
                // (All three columns are orthonormal and form a valid rotation matrix.)
                AnchorPoseALocal = new Pose(new Vector3(-0.9f, -0.4f, -1.4f),
                                            new Matrix(0, 0, -1,
                                                       1, 0, 0,
                                                       0, -1, 0)),
                BodyB = wheelFrontLeft,
                // --> To define the constraint anchor orientation for the chassis:
                // The columns are the axes. We set the local x axis in the first column. This is
                // steering axis. In the last column we set the y axis. This is the wheel rotation axis.
                // (In local space of a cylinder the cylinder axis is the +y axis.)
                // In the middle column is a vector that is normal to the first and last axis.
                // (All three columns are orthonormal and form a valid rotation matrix.)
                AnchorPoseBLocal = new Pose(new Matrix(1, 0, 0,
                                                       0, 0, 1,
                                                       0, -1, 0)),
                CollisionEnabled = false,
                Minimum          = new Vector2F(-0.7f, float.NegativeInfinity),
                Maximum          = new Vector2F(0.7f, float.PositiveInfinity),
            };
            Simulation.Constraints.Add(_frontLeftHinge);

            _frontRightHinge = new Hinge2Joint
            {
                BodyA            = chassis,
                BodyB            = wheelFrontRight,
                AnchorPoseALocal = new Pose(new Vector3(0.9f, -0.4f, -1.4f),
                                            new Matrix(0, 0, -1,
                                                       1, 0, 0,
                                                       0, -1, 0)),
                AnchorPoseBLocal = new Pose(new Matrix(1, 0, 0,
                                                       0, 0, 1,
                                                       0, -1, 0)),
                CollisionEnabled = false,
                Minimum          = new Vector2F(-0.7f, float.NegativeInfinity),
                Maximum          = new Vector2F(0.7f, float.PositiveInfinity),
            };
            Simulation.Constraints.Add(_frontRightHinge);

            // ----- HingeJoints for the back wheels.
            // Hinges allow free rotation on the first constraint axis.
            HingeJoint backLeftHinge = new HingeJoint
            {
                BodyA            = chassis,
                AnchorPoseALocal = new Pose(new Vector3(-0.9f, -0.4f, 1.4f)),
                BodyB            = wheelBackLeft,
                // --> To define the constraint anchor orientation:
                // The columns are the axes. We set the local y axis in the first column. This is
                // cylinder axis and should be the hinge axis. In the other two columns we set two
                // orthonormal vectors.
                // (All three columns are orthonormal and form a valid rotation matrix.)
                AnchorPoseBLocal = new Pose(new Matrix(0, 0, 1,
                                                       1, 0, 0,
                                                       0, 1, 0)),
                CollisionEnabled = false,
            };

            Simulation.Constraints.Add(backLeftHinge);
            HingeJoint backRightHinge = new HingeJoint
            {
                BodyA            = chassis,
                AnchorPoseALocal = new Pose(new Vector3(0.9f, -0.4f, 1.4f)),
                BodyB            = wheelBackRight,
                AnchorPoseBLocal = new Pose(new Matrix(0, 0, 1,
                                                       1, 0, 0,
                                                       0, 1, 0)),
                CollisionEnabled = false,
            };

            Simulation.Constraints.Add(backRightHinge);

            // ----- Motors for the front wheels.
            // (Motor axes and target velocities are set in Update() below.)
            _frontLeftMotor = new AngularVelocityMotor
            {
                BodyA            = chassis,
                BodyB            = wheelFrontLeft,
                CollisionEnabled = false,

                // We use "single axis mode", which means the motor drives only on axis and does not
                // block motion orthogonal to this axis. - Rotation about the orthogonal axes is already
                // controlled by the Hinge2Joint.
                UseSingleAxisMode = true,

                // The motor has only limited power:
                MaxForce = 50000,
            };
            Simulation.Constraints.Add(_frontLeftMotor);

            _frontRightMotor = new AngularVelocityMotor
            {
                BodyA             = chassis,
                BodyB             = wheelFrontRight,
                CollisionEnabled  = false,
                UseSingleAxisMode = true,
                MaxForce          = 50000,
            };
            Simulation.Constraints.Add(_frontRightMotor);

            // ----- Drop a few boxes to create obstacles.
            BoxShape  boxShape = new BoxShape(1, 1, 1);
            MassFrame boxMass  = MassFrame.FromShapeAndDensity(boxShape, Vector3.One, 100, 0.01f, 3);

            for (int i = 0; i < 20; i++)
            {
                Vector3 position = RandomHelper.Random.NextVector3(-20, 20);
                position.Y = 5;
                Quaternion orientation = RandomHelper.Random.NextQuaternion();

                RigidBody body = new RigidBody(boxShape, boxMass, null)
                {
                    Pose = new Pose(position, orientation),
                };
                Simulation.RigidBodies.Add(body);
            }
        }
示例#3
0
        public ICollisionJoint[] LoadSimulationJoints(
            ICollisionShape[] objects)
        {
            var xmlDoc = new XmlDocument();

            xmlDoc.Load(FileNameObjectProperties);

            XmlNodeList xmlList = xmlDoc.SelectNodes(nodePathJoints);

            ICollisionJoint[] joints = new ICollisionJoint[xmlList.Count];

            for (int i = 0; i < xmlList.Count; i++)
            {
                //Object index A
                int indexA = Convert.ToInt32(xmlList[i][objectIndexAAttribute].InnerText);

                //Object index B
                int indexB = Convert.ToInt32(xmlList[i][objectIndexBAttribute].InnerText);

                XmlNodeList jointPropertiesList = xmlList[i].SelectNodes(jointProperties);

                ICollisionJoint[] joint = new ICollisionJoint[jointPropertiesList.Count];

                for (int j = 0; j < jointPropertiesList.Count; j++)
                {
                    //Joint type
                    var jointType = (JointType)Convert.ToInt32(jointPropertiesList[j][this.jointType].InnerText);

                    //Restore coefficient
                    double K = Convert.ToDouble(jointPropertiesList[j][restoreCoeffAttribute].InnerText);

                    //Stretch coefficient
                    double C = Convert.ToDouble(jointPropertiesList[j][stretchCoeffAttribute].InnerText);

                    //Position
                    var startAnchorPosition = new Vector3d(
                        Convert.ToDouble(jointPropertiesList[j][positionJointAttribute].Attributes["x"].Value),
                        Convert.ToDouble(jointPropertiesList[j][positionJointAttribute].Attributes["y"].Value),
                        Convert.ToDouble(jointPropertiesList[j][positionJointAttribute].Attributes["z"].Value));

                    //Action Axis
                    var actionAxis = new Vector3d(
                        Convert.ToDouble(jointPropertiesList[j][this.actionAxis].Attributes["x"].Value),
                        Convert.ToDouble(jointPropertiesList[j][this.actionAxis].Attributes["y"].Value),
                        Convert.ToDouble(jointPropertiesList[j][this.actionAxis].Attributes["z"].Value));

                    switch (jointType)
                    {
                    case JointType.Fixed:
                        joint [j] = new FixedJoint(
                            objects[indexA],
                            objects[indexB],
                            K,
                            C);
                        break;

                    case JointType.BallAndSocket:
                        joint[j] = new BallAndSocketJoint(
                            objects[indexA],
                            objects[indexB],
                            startAnchorPosition,
                            K,
                            C);
                        break;

                    case JointType.Slider:
                        joint[j] = new SliderJoint(
                            objects[indexA],
                            objects[indexB],
                            startAnchorPosition,
                            actionAxis,
                            K,
                            C);

                        joint[j].SetLinearLimit(Convert.ToDouble(jointPropertiesList[j][linearLimitMin].InnerText), Convert.ToDouble(jointPropertiesList[j][linearLimitMax].InnerText));

                        break;

                    case JointType.Piston:
                        joint[j] = new PistonJoint(
                            objects[indexA],
                            objects[indexB],
                            startAnchorPosition,
                            actionAxis,
                            K,
                            C);

                        joint[j].SetAxis1AngularLimit(
                            Convert.ToDouble(jointPropertiesList[j][angularLimitMin].InnerText),
                            Convert.ToDouble(jointPropertiesList[j][angularLimitMax].InnerText));

                        joint[j].SetLinearLimit(
                            Convert.ToDouble(jointPropertiesList[j][linearLimitMin].InnerText),
                            Convert.ToDouble(jointPropertiesList[j][linearLimitMax].InnerText));

                        break;

                    case JointType.Hinge:
                        joint[j] = new HingeJoint(
                            objects[indexA],
                            objects[indexB],
                            startAnchorPosition,
                            actionAxis,
                            K,
                            C);

                        joint[j].SetAxis1AngularLimit(
                            Convert.ToDouble(jointPropertiesList[j][angularLimitMin].InnerText),
                            Convert.ToDouble(jointPropertiesList[j][angularLimitMax].InnerText));

                        joint[j].SetAxis1Motor(3.0, 0.15);
                        break;

                    case JointType.Universal:
                        joint[j] = new UniversalJoint(
                            objects[indexA],
                            objects[indexB],
                            startAnchorPosition,
                            actionAxis,
                            new Vector3d(1.0, 0.0, 0.0),
                            K,
                            C);

                        joint[j].SetAxis1AngularLimit(
                            Convert.ToDouble(jointPropertiesList[j][angularLimitMin].InnerText),
                            Convert.ToDouble(jointPropertiesList[j][angularLimitMax].InnerText));
                        joint[j].SetAxis2AngularLimit(
                            Convert.ToDouble(jointPropertiesList[j][angularLimitMin].InnerText),
                            Convert.ToDouble(jointPropertiesList[j][angularLimitMax].InnerText));
                        break;

                    case JointType.Hinge2:
                        joint[j] = new Hinge2Joint(
                            objects[indexA],
                            objects[indexB],
                            startAnchorPosition,
                            actionAxis,
                            new Vector3d(1.0, 0.0, 0.0),
                            K,
                            1.0,
                            C);

                        joint[j].SetAxis1AngularLimit(
                            Convert.ToDouble(jointPropertiesList[j][angularLimitMin].InnerText),
                            Convert.ToDouble(jointPropertiesList[j][angularLimitMax].InnerText));

                        //joint[j].SetAxis2Motor(4.0, 3.0);

                        break;

                    case JointType.Angular:
                        joint[j] = new AngularJoint(
                            objects[indexA],
                            objects[indexB],
                            startAnchorPosition,
                            new Vector3d(1.0, 0.0, 0.0),
                            new Vector3d(0.0, 1.0, 0.0),
                            0.16,
                            0.008,
                            0.008);

                        break;
                    }
                    joints[i] = joint[j];
                }
            }

            return(joints);
        }