예제 #1
0
        public static SliderJoint CreateSliderJoint(World world, Body bodyA, Body bodyB, Vector2 anchorA, Vector2 anchorB, float minLength, float maxLength)
        {
            SliderJoint sliderJoint = new SliderJoint(bodyA, bodyB, anchorA, anchorB, minLength, maxLength);

            world.AddJoint(sliderJoint);
            return(sliderJoint);
        }
        /// <summary>
        /// Creates GUI elements for fields specific to the slider joint.
        /// </summary>
        protected void BuildGUI(SliderJoint joint)
        {
            enableLimitField.OnChanged += x =>
            {
                joint.SetFlag(SliderJointFlag.Limit, x);
                MarkAsModified();
                ConfirmModify();

                ToggleLimitFields(x);
            };

            Layout.AddElement(enableLimitField);
            limitLayout = Layout.AddLayoutX();
            {
                limitLayout.AddSpace(10);

                GUILayoutY limitContentsLayout = limitLayout.AddLayoutY();
                limitGUI            = new LimitLinearRangeGUI(joint.Limit, limitContentsLayout, Persistent);
                limitGUI.OnChanged += (x, y) =>
                {
                    joint.Limit = x;
                    joint.Limit.SetBase(y);

                    MarkAsModified();
                };
                limitGUI.OnConfirmed += ConfirmModify;
            }

            ToggleLimitFields(joint.HasFlag(SliderJointFlag.Limit));

            base.BuildGUI(joint, true);
        }
예제 #3
0
        /// <summary>
        /// Attaches the bodies with revolute joints.
        /// </summary>
        /// <param name="world">The world.</param>
        /// <param name="bodies">The bodies.</param>
        /// <param name="localAnchorA">The local anchor A.</param>
        /// <param name="localAnchorB">The local anchor B.</param>
        /// <param name="connectFirstAndLast">if set to <c>true</c> [connect first and last].</param>
        /// <param name="collideConnected">if set to <c>true</c> [collide connected].</param>
        /// <param name="minLength">Minimum length of the slider joint.</param>
        /// <param name="maxLength">Maximum length of the slider joint.</param>
        /// <returns></returns>
        public static List <SliderJoint> AttachBodiesWithSliderJoint(World world, List <Body> bodies, Vector2 localAnchorA,
                                                                     Vector2 localAnchorB, bool connectFirstAndLast,
                                                                     bool collideConnected, float minLength,
                                                                     float maxLength)
        {
            List <SliderJoint> joints = new List <SliderJoint>(bodies.Count + 1);

            for (int i = 1; i < bodies.Count; i++)
            {
                SliderJoint joint = new SliderJoint(bodies[i], bodies[i - 1], localAnchorA, localAnchorB, minLength,
                                                    maxLength);
                joint.CollideConnected = collideConnected;
                world.AddJoint(joint);
                joints.Add(joint);
            }

            if (connectFirstAndLast)
            {
                SliderJoint lastjoint = new SliderJoint(bodies[0], bodies[bodies.Count - 1], localAnchorA, localAnchorB,
                                                        minLength, maxLength);
                lastjoint.CollideConnected = collideConnected;
                world.AddJoint(lastjoint);
                joints.Add(lastjoint);
            }

            return(joints);
        }
예제 #4
0
        public SliderJoint CreateSliderJoint(Body body1, Vector2 anchor1, Body body2, Vector2 anchor2, float min,
                                             float max)
        {
            SliderJoint sliderJoint = new SliderJoint(body1, anchor1, body2, anchor2, min, max);

            return(sliderJoint);
        }
예제 #5
0
        private static void DrawSliderJoint(SliderJoint joint)
        {
            Vector3 anchor = GetAnchor(joint, JointBody.Anchor);
            Vector3 target = GetAnchor(joint, JointBody.Target);
            Vector3 normal = -joint.SceneObject.Right;

            if (joint.HasFlag(SliderJointFlag.Limit))
            {
                LimitLinearRange limit = joint.Limit;

                float max = MathEx.Min(10000.0f, limit.upper);
                float min = MathEx.Clamp(limit.lower, 0.0f, max);
                max = MathEx.Max(max, min);

                Gizmos.Color = Color.Red;
                Gizmos.DrawLine(anchor, anchor + normal * min);

                Gizmos.Color = Color.Green;
                Gizmos.DrawLine(anchor + normal * min, anchor + normal * max);
            }
            else
            {
                Gizmos.Color = Color.Green;

                float length = 100.0f;
                Gizmos.DrawLine(anchor, anchor + normal * length);
            }

            Gizmos.Color = Color.Yellow;
            Gizmos.DrawSphere(target, 0.05f);
        }
예제 #6
0
        public SliderJoint CreateSliderJoint(PhysicsSimulator physicsSimulator, Body body1, Vector2 anchor1, Body body2,
                                             Vector2 anchor2, float min, float max)
        {
            SliderJoint sliderJoint = CreateSliderJoint(body1, anchor1, body2, anchor2, min, max);

            physicsSimulator.Add(sliderJoint);
            return(sliderJoint);
        }
        /// <inheritdoc/>
        protected internal override void Initialize()
        {
            SliderJoint joint = InspectedObject as SliderJoint;

            if (joint != null)
            {
                BuildGUI(joint);
            }
        }
        /// <inheritdoc/>
        protected internal override void Initialize()
        {
            SliderJoint joint = (SliderJoint)InspectedObject;

            BuildGUI(joint, true);

            drawer.AddDefault(joint, typeof(SliderJoint));
            drawer.AddField("Enable limit",
                            () => joint.HasFlag(SliderJointFlag.Limit),
                            x => joint.SetFlag(SliderJointFlag.Limit, x));
            drawer.AddConditional("Limit", () => joint.HasFlag(SliderJointFlag.Limit));
        }
예제 #9
0
        /// <summary>
        /// Updates all GUI elements from current values in the joint.
        /// </summary>
        /// <param name="joint">Joint to update the GUI from.</param>
        protected void Refresh(SliderJoint joint)
        {
            if (enableLimitField.Value != joint.EnableLimit)
            {
                enableLimitField.Value = joint.EnableLimit;
                ToggleLimitFields(joint.EnableLimit);
            }

            limitGUI.Limit = joint.Limit;

            base.Refresh(joint);
        }
 private void DrawSliderJoints(SpriteBatch spriteBatch)
 {
     for (int i = 0; i < _physicsSimulator.JointList.Count; i++)
     {
         if (_physicsSimulator.JointList[i] is SliderJoint)
         {
             SliderJoint sliderJoint = (SliderJoint)_physicsSimulator.JointList[i];
             _sliderJointRectangleBrush.Draw(spriteBatch, sliderJoint.WorldAnchor1);
             _sliderJointRectangleBrush.Draw(spriteBatch, sliderJoint.WorldAnchor2);
             _sliderJointLineBrush.Draw(spriteBatch, sliderJoint.WorldAnchor1, sliderJoint.WorldAnchor2);
         }
     }
 }
예제 #11
0
        /// <summary>
        /// Updates all GUI elements from current values in the joint.
        /// </summary>
        /// <param name="joint">Joint to update the GUI from.</param>
        protected void Refresh(SliderJoint joint)
        {
            bool enableLimit = joint.HasFlag(SliderJointFlag.Limit);

            if (enableLimitField.Value != enableLimit)
            {
                enableLimitField.Value = enableLimit;
                ToggleLimitFields(enableLimit);
            }

            limitGUI.Limit = joint.Limit;

            base.Refresh(joint);
        }
예제 #12
0
        internal override void UpdateJoint()
        {
            base.UpdateJoint();
            if (this.joint == null)
            {
                return;
            }

            SliderJoint j = this.joint as SliderJoint;

            j.LocalAnchorB = GetFarseerPoint(this.OtherBody, this.localAnchorB);
            j.LocalAnchorA = GetFarseerPoint(this.ParentBody, this.localAnchorA);
            j.MaxLength    = PhysicsUnit.LengthToPhysical * this.maxLength;
            j.MinLength    = PhysicsUnit.LengthToPhysical * this.minLength;
        }
        internal override void UpdateJoint()
        {
            base.UpdateJoint();
            if (this.joint == null)
            {
                return;
            }

            SliderJoint j = this.joint as SliderJoint;

            j.LocalAnchorB = GetFarseerPoint(this.BodyB, this.localAnchorB);
            j.LocalAnchorA = GetFarseerPoint(this.BodyA, this.localAnchorA);
            j.MaxLength    = PhysicsConvert.ToPhysicalUnit(this.maxLength);
            j.MinLength    = PhysicsConvert.ToPhysicalUnit(this.minLength);
        }
예제 #14
0
        private SliderJointTest()
        {
            BodyFactory.CreateEdge(World, new Vector2(-40, 0), new Vector2(40, 0));

            Body fA = BodyFactory.CreateRectangle(World, 4, 4, 1, new Vector2(-5, 4));

            fA.BodyType = BodyType.Dynamic;

            Body fB = BodyFactory.CreateRectangle(World, 4, 4, 1, new Vector2(5, 4));

            fB.BodyType = BodyType.Dynamic;

            SliderJoint joint = new SliderJoint(fA, fB, Vector2.Zero, Vector2.Zero, 5, 10);

            World.AddJoint(joint);
        }
예제 #15
0
        /// <inheritdoc/>
        protected internal override InspectableState Refresh()
        {
            SliderJoint joint = InspectedObject as SliderJoint;

            if (joint == null)
            {
                return(InspectableState.NotModified);
            }

            Refresh(joint);

            InspectableState oldState = modifyState;

            if (modifyState.HasFlag(InspectableState.Modified))
            {
                modifyState = InspectableState.NotModified;
            }

            return(oldState);
        }
예제 #16
0
        public Joint GetPhysicsJoint(Vector2 scale)
        {
            float scaleD = (scale.X + scale.Y) / 2f;
            Body  body1, body2;

            string[] bodyNames = PrefabUtils.GetEntityAndComponentName(Body1);
            if (bodyNames[0] == null)
            {
                body1 = FatherEntity.PhysicsEntity.GetBody(Body1);
            }
            else
            {
                body1 = GameWorldManager.Instance.GetEntity(bodyNames[0]).PhysicsEntity.GetBody(bodyNames[1]);
            }

            bodyNames = PrefabUtils.GetEntityAndComponentName(Body2);
            if (bodyNames[0] == null)
            {
                body2 = FatherEntity.PhysicsEntity.GetBody(Body2);
            }
            else
            {
                body2 = GameWorldManager.Instance.GetEntity(bodyNames[0]).PhysicsEntity.GetBody(bodyNames[1]);
            }

            switch (Type)
            {
            case JointType.Line:
                LineJoint joint = new LineJoint(body1, body2, UnitsConverter.ToSimUnits(Anchor) * scale, Axis);
                joint.MaxMotorTorque   = MaxMotorTorque;
                joint.MotorEnabled     = MotorEnabled;
                joint.Frequency        = Frequency;
                joint.DampingRatio     = DampingRatio;
                joint.CollideConnected = CollideConnected;

                Platform.Instance.PhysicsWorld.AddJoint(joint);
                return(joint);

            case JointType.Revolute:
                RevoluteJoint joint2 = new RevoluteJoint(body1, body2, UnitsConverter.ToSimUnits(Anchor) * scale, UnitsConverter.ToSimUnits(Anchor2) * scale);
                joint2.CollideConnected = CollideConnected;
                joint2.MaxMotorTorque   = MaxMotorTorque;
                joint2.MotorEnabled     = MotorEnabled;
                Platform.Instance.PhysicsWorld.AddJoint(joint2);

                return(joint2);

            case JointType.Weld:
                WeldJoint joint3 = new WeldJoint(body1, body2, UnitsConverter.ToSimUnits(Anchor) * scale, UnitsConverter.ToSimUnits(Anchor2) * scale);
                joint3.CollideConnected = CollideConnected;
                Platform.Instance.PhysicsWorld.AddJoint(joint3);
                return(joint3);

            case JointType.Slider:
                SliderJoint joint4 = new SliderJoint(body1, body2, UnitsConverter.ToSimUnits(Anchor) * scale, UnitsConverter.ToSimUnits(Anchor2) * scale, UnitsConverter.ToSimUnits(MinLength) * scaleD, UnitsConverter.ToSimUnits(MaxLength) * scaleD);
                joint4.DampingRatio     = DampingRatio;
                joint4.CollideConnected = CollideConnected;
                Platform.Instance.PhysicsWorld.AddJoint(joint4);
                return(joint4);

            case JointType.Distance:
                DistanceJoint joint5 = new DistanceJoint(body1, body2, UnitsConverter.ToSimUnits(Anchor) * scale, UnitsConverter.ToSimUnits(Anchor2) * scale);
                joint5.Frequency        = Frequency;
                joint5.DampingRatio     = DampingRatio;
                joint5.CollideConnected = CollideConnected;
                joint5.Length           = UnitsConverter.ToSimUnits(Length) * scaleD;
                Platform.Instance.PhysicsWorld.AddJoint(joint5);
                return(joint5);

            case JointType.Prismatic:
                PrismaticJoint joint6 = new PrismaticJoint(body1, body2, UnitsConverter.ToSimUnits(Anchor) * scale, UnitsConverter.ToSimUnits(Anchor2) * scale, Axis);
                joint6.CollideConnected = CollideConnected;
                joint6.UpperLimit       = UnitsConverter.ToSimUnits(UpperLimit) * scaleD;
                joint6.LowerLimit       = UnitsConverter.ToSimUnits(LowerLimit) * scaleD;
                joint6.LimitEnabled     = LimitEnabled;
                joint6.MotorEnabled     = MotorEnabled;
                joint6.MaxMotorForce    = MaxMotorForce * scaleD;
                joint6.MotorSpeed       = MotorSpeed * scaleD;

                Platform.Instance.PhysicsWorld.AddJoint(joint6);
                return(joint6);

            default:
                return(null);
            }
        }
예제 #17
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);
        }
예제 #18
0
        public static void AddRollingBeats(Scene scene, TransformNode parentTrans)
        {
            Vector3 size     = new Vector3(10.0f, 0.25f, 0.25f);
            Vector3 location = new Vector3(0, 3, 3);

            GeometryNode bar;
            // //////////////////////////////////////////////////////////////////
            //
            // Create a bar and attach it to the world with a hinge with limits
            //
            // //////////////////////////////////////////////////////////////////
            {
                TransformNode pileTrans = new TransformNode();
                pileTrans.Translation = location;
                pileTrans.Rotation    = Quaternion.CreateFromAxisAngle(Vector3.UnitZ, MathHelper.PiOver2);

                Material barMat = new Material();
                barMat.Diffuse       = Color.Purple.ToVector4();
                barMat.Specular      = Color.White.ToVector4();
                barMat.SpecularPower = 10;

                bar          = new GeometryNode("Bar");
                bar.Model    = new Cylinder(size.Y, size.Y, size.X, 20);
                bar.Material = barMat;
                bar.Model.ShadowAttribute = ShadowAttribute.ReceiveCast;

                bar.AddToPhysicsEngine   = true;
                bar.Physics.Interactable = true;
                bar.Physics.Collidable   = true;
                bar.Physics.Shape        = ShapeType.Cylinder;
                bar.Physics.Mass         = 2.0f;

                parentTrans.AddChild(pileTrans);
                pileTrans.AddChild(bar);

                Vector3 pivot = location + parentTrans.Translation;
                Vector3 pin   = Vector3.UnitY;
                pivot.X -= size.X * 0.5f;

                HingeJoint joint = new HingeJoint(pivot, pin);
                joint.NewtonHingeCallback = doubleDoor;

                ((NewtonPhysics)scene.PhysicsEngine).CreateJoint(bar.Physics, null, joint);
            }

            // /////////////////////////////////////////////////////////////////
            //
            // Add a sliding visualObject with limits
            //
            ////////////////////////////////////////////////////////////////////
            {
                Vector3 beatLocation = location;
                Vector3 beatSize     = new Vector3(0.5f, 2.0f, 2.0f);

                beatLocation.X += size.X * 0.25f;

                TransformNode pileTrans = new TransformNode();
                pileTrans.Translation = beatLocation;

                Material beatMat = new Material();
                beatMat.Diffuse       = Color.Red.ToVector4();
                beatMat.Specular      = Color.White.ToVector4();
                beatMat.SpecularPower = 10;

                GeometryNode beat = new GeometryNode("Beat Slider");
                beat.Model    = new Box(beatSize);
                beat.Material = beatMat;
                beat.Model.ShadowAttribute = ShadowAttribute.ReceiveCast;

                beat.AddToPhysicsEngine   = true;
                beat.Physics.Interactable = true;
                beat.Physics.Collidable   = true;
                beat.Physics.Shape        = ShapeType.Box;
                beat.Physics.Mass         = 2.0f;

                parentTrans.AddChild(pileTrans);
                pileTrans.AddChild(beat);

                Vector3 pivot = beatLocation + parentTrans.Translation;
                Vector3 pin   = Vector3.UnitX;

                sliderLimit.X = ((location.X - beatLocation.X) - size.X * 0.5f);
                sliderLimit.Y = ((location.X - beatLocation.X) + size.X * 0.5f);

                SliderJoint joint = new SliderJoint(pivot, pin);
                sliderUpdate = delegate(IntPtr slider, ref Newton.NewtonHingeSliderUpdateDesc desc)
                {
                    float distance = Newton.NewtonSliderGetJointPosit(slider);
                    if (distance < sliderLimit.X)
                    {
                        // if the distance is smaller than the predefine interval, stop the slider
                        desc.m_Accel = Newton.NewtonSliderCalculateStopAccel(slider, ref desc, sliderLimit.X);
                        return(1);
                    }
                    else if (distance > sliderLimit.Y)
                    {
                        // if the distance is larger than the predefine interval, stop the slider
                        desc.m_Accel = Newton.NewtonSliderCalculateStopAccel(slider, ref desc, sliderLimit.Y);
                        return(1);
                    }

                    // no action need it if the joint angle is with the limits
                    return(0);
                };
                joint.NewtonSliderCallback = sliderUpdate;

                ((NewtonPhysics)scene.PhysicsEngine).CreateJoint(beat.Physics, bar.Physics, joint);
            }

            // /////////////////////////////////////////////////////////////////
            //
            // Add a corkscrew visualObject with limits
            //
            // /////////////////////////////////////////////////////////////////
            {
                Vector3 beatLocation = location;
                Vector3 beatSize     = new Vector3(0.5f, 2.0f, 2.0f);

                beatLocation.X -= size.X * 0.25f;

                TransformNode pileTrans = new TransformNode();
                pileTrans.Translation = beatLocation;

                Material beatMat = new Material();
                beatMat.Diffuse       = Color.YellowGreen.ToVector4();
                beatMat.Specular      = Color.White.ToVector4();
                beatMat.SpecularPower = 10;

                GeometryNode beat = new GeometryNode("Beat Corkscrew");
                beat.Model    = new Box(beatSize);
                beat.Material = beatMat;
                beat.Model.ShadowAttribute = ShadowAttribute.ReceiveCast;

                beat.AddToPhysicsEngine   = true;
                beat.Physics.Interactable = true;
                beat.Physics.Collidable   = true;
                beat.Physics.Shape        = ShapeType.Box;
                beat.Physics.Mass         = 2.0f;

                parentTrans.AddChild(pileTrans);
                pileTrans.AddChild(beat);

                Vector3 pivot = beatLocation + parentTrans.Translation;
                Vector3 pin   = Vector3.UnitX;

                corkscrewLimit.X = ((location.X - beatLocation.X) - size.X * 0.5f);
                corkscrewLimit.Y = ((location.X - beatLocation.X) + size.X * 0.5f);

                CorkscrewJoint joint = new CorkscrewJoint(pivot, pin);
                corkscrewUpdate = delegate(IntPtr corkscrew, Newton.NewtonHingeSliderUpdateDesc[] desc)
                {
                    // no action need it if the joint angle is with the limits
                    uint retCode = 0;

                    float distance = Newton.NewtonCorkscrewGetJointPosit(corkscrew);

                    // The first entry in NewtonHingeSliderUpdateDesc control the screw linear acceleration
                    if (distance < corkscrewLimit.X)
                    {
                        // if the distance is smaller than the predefine interval, stop the slider
                        desc[0].m_Accel = Newton.NewtonCorkscrewCalculateStopAccel(corkscrew,
                                                                                   ref desc[0], corkscrewLimit.X);
                        retCode |= 1;
                    }
                    else if (distance > corkscrewLimit.Y)
                    {
                        // if the distance is larger than the predefine interval, stop the slider
                        desc[0].m_Accel = Newton.NewtonCorkscrewCalculateStopAccel(corkscrew, ref
                                                                                   desc[0], corkscrewLimit.Y);
                        retCode |= 1;
                    }

                    // The second entry in NewtonHingeSliderUpdateDesc control the screw angular acceleration.
                    // Make s small screw motor by setting the angular acceleration of the screw axis
                    // We are not going to limit the angular rotation of the screw, but is we did we should
                    // or return code with 2
                    float omega = Newton.NewtonCorkscrewGetJointOmega(corkscrew);
                    desc[1].m_Accel = 1.5f - 0.2f * omega;

                    // or with 0x10 to tell newton this axis is active
                    retCode |= 2;

                    // return the code
                    return(retCode);
                };
                joint.NewtonCorkscrewCallback = corkscrewUpdate;

                ((NewtonPhysics)scene.PhysicsEngine).CreateJoint(beat.Physics, bar.Physics, joint);
            }

            // /////////////////////////////////////////////////////////////////
            //
            // Add a universal joint visualObject with limits
            //
            // /////////////////////////////////////////////////////////////////
            {
                Vector3 beatLocation = location;
                Vector3 beatSize     = new Vector3(0.5f, 2.0f, 2.0f);

                beatLocation.X -= size.X * 0.45f;

                TransformNode pileTrans = new TransformNode();
                pileTrans.Translation = beatLocation;

                Material beatMat = new Material();
                beatMat.Diffuse       = Color.YellowGreen.ToVector4();
                beatMat.Specular      = Color.White.ToVector4();
                beatMat.SpecularPower = 10;

                GeometryNode beat = new GeometryNode("Beat Universal");
                beat.Model    = new Box(beatSize);
                beat.Material = beatMat;
                beat.Model.ShadowAttribute = ShadowAttribute.ReceiveCast;

                beat.AddToPhysicsEngine   = true;
                beat.Physics.Interactable = true;
                beat.Physics.Collidable   = true;
                beat.Physics.Shape        = ShapeType.Box;
                beat.Physics.Mass         = 2.0f;

                parentTrans.AddChild(pileTrans);
                pileTrans.AddChild(beat);

                Vector3 pivot = beatLocation + parentTrans.Translation;
                Vector3 pin0  = Vector3.UnitX;
                Vector3 pin1  = Vector3.UnitY;

                universalLimit.X = -30.0f * MathHelper.Pi / 180.0f;
                universalLimit.Y = 30.0f * MathHelper.Pi / 180.0f;

                UniversalJoint joint = new UniversalJoint(pivot, pin0, pin1);
                universalUpdate = delegate(IntPtr universal, Newton.NewtonHingeSliderUpdateDesc[] desc)
                {
                    // no action need it if the joint angle is with the limits
                    uint retCode = 0;

                    float omega = Newton.NewtonUniversalGetJointOmega0(universal);
                    desc[0].m_Accel = -1.5f - 0.2f * omega;
                    retCode        |= 1;

                    float angle = Newton.NewtonUniversalGetJointAngle1(universal);
                    if (angle < universalLimit.X)
                    {
                        desc[1].m_Accel = Newton.NewtonUniversalCalculateStopAlpha1(universal, ref desc[1],
                                                                                    universalLimit.X);
                        retCode |= 2;
                    }
                    else if (angle > universalLimit.Y)
                    {
                        desc[1].m_Accel = Newton.NewtonUniversalCalculateStopAlpha1(universal, ref desc[1],
                                                                                    universalLimit.Y);
                        retCode |= 2;
                    }

                    // return the code
                    return(retCode);
                };
                joint.NewtonUniversalCallback = universalUpdate;

                ((NewtonPhysics)scene.PhysicsEngine).CreateJoint(beat.Physics, bar.Physics, joint);
            }
        }
예제 #19
0
    // TODO
    // * Support Urdf axis that aren't directly aligned with the
    //    X, Y, or Z axis
    /// <summary>
    /// <para>ConfigureJoint</para>
    /// Configures the Godot Generic6DOFJoint
    /// properties to match what the Urdf joint
    /// contains.
    /// </summary>
    /// <param name="base_joint">Urdf Joint specifications.</param>
    /// <returns>Godot joint matching specs.</returns>
    private Godot.Joint ConfigureJoint(RosSharp.Urdf.Joint base_joint)
    {
        // The Urdf joint axis specifies the axis of rotation for revolute joints,
        // axis of translation for prismatic joints, and the surface normal
        // for planar joints.
        // If it's not specified accessing it will error out, so we need to
        // manually specify the default (X-axis).
        double[] j_axis;

        try
        {
            j_axis = base_joint.axis.xyz;
        }
        catch
        {
            j_axis = new double[] { 1.0, 0.0, 0.0 };
        }
        GD.Print(base_joint.name + " axis: " + j_axis[0] + " " + j_axis[1] + " " + j_axis[2]);

        JointMaker mkr = new JointMaker();


        // Type comments taken from https://wiki.ros.org/urdf/XML/joint
        switch (base_joint.type)
        {
        case "revolute":
        // A hinge joint that rotates along the axis and has a
        // limited range specified by the upper and lower limits.
        // HingeJoint revJoint = mkr.CreateHingeJoint();
        // // HingeJoint revJoint = new HingeJoint();

        // // revJoint.rot/
        // GD.Print("setting hingejoint flags");

        // revJoint.SetFlag(HingeJoint.Flag.UseLimit, true);
        // revJoint.SetFlag(HingeJoint.Flag.EnableMotor, true);
        // revJoint.SetParam(HingeJoint.Param.MotorTargetVelocity, 0F);
        // revJoint.SetParam(HingeJoint.Param.MotorMaxImpulse, 1024F);
        // revJoint.SetParam(HingeJoint.Param.Bias, 1F);
        // revJoint.SetParam(HingeJoint.Param.LimitLower, (float)base_joint.limit.lower * (180F / (float)Math.PI));
        // revJoint.SetParam(HingeJoint.Param.LimitUpper, (float)base_joint.limit.upper * (180F / (float)Math.PI));

        // return revJoint;
        case "continuous":
            // a continuous hinge joint that rotates around the axis
            // and has no upper and lower limits.
            HingeJoint contJoint = new HingeJoint();

            contJoint.SetFlag(HingeJoint.Flag.UseLimit, false);
            contJoint.SetFlag(HingeJoint.Flag.EnableMotor, true);
            contJoint.SetParam(HingeJoint.Param.MotorTargetVelocity, 0F);

            return(contJoint);

        case "prismatic":
            // a sliding joint that slides along the axis, and has a
            // limited range specified by the upper and lower limits.

            SliderJoint slideJoint = new SliderJoint();

            slideJoint.SetParam(SliderJoint.Param.LinearLimitLower, (float)base_joint.limit.lower);
            slideJoint.SetParam(SliderJoint.Param.LinearLimitUpper, (float)base_joint.limit.upper);

            return(slideJoint);

        case "fixed":
            // This is not really a joint because it cannot move.
            // All degrees of freedom are locked. This type of joint
            // does not require the axis, calibration, dynamics,
            // limits or safety_controller.

            Generic6DOFJoint pinJoint = new Generic6DOFJoint();

            pinJoint.SetFlagX(Generic6DOFJoint.Flag.EnableAngularLimit, true);
            pinJoint.SetFlagY(Generic6DOFJoint.Flag.EnableAngularLimit, true);
            pinJoint.SetFlagZ(Generic6DOFJoint.Flag.EnableAngularLimit, true);
            pinJoint.SetFlagX(Generic6DOFJoint.Flag.EnableLinearLimit, true);
            pinJoint.SetFlagY(Generic6DOFJoint.Flag.EnableLinearLimit, true);
            pinJoint.SetFlagZ(Generic6DOFJoint.Flag.EnableLinearLimit, true);

            return(pinJoint);

        case "floating":
            // This joint allows motion for all 6 degrees of freedom.
            Generic6DOFJoint genJoint = new Generic6DOFJoint();

            genJoint.SetFlagX(Generic6DOFJoint.Flag.EnableAngularLimit, false);
            genJoint.SetFlagY(Generic6DOFJoint.Flag.EnableAngularLimit, false);
            genJoint.SetFlagZ(Generic6DOFJoint.Flag.EnableAngularLimit, false);
            genJoint.SetFlagX(Generic6DOFJoint.Flag.EnableLinearLimit, false);
            genJoint.SetFlagY(Generic6DOFJoint.Flag.EnableLinearLimit, false);
            genJoint.SetFlagZ(Generic6DOFJoint.Flag.EnableLinearLimit, false);

            return(genJoint);

        case "planar":
            // This joint allows motion in a plane perpendicular to the axis.

            Generic6DOFJoint planJoint = new Generic6DOFJoint();
            if (j_axis[0] == 1.0)
            {
                planJoint.SetParamY(
                    Generic6DOFJoint.Param.LinearUpperLimit,
                    (float)base_joint.limit.upper
                    );
                planJoint.SetParamY(
                    Generic6DOFJoint.Param.LinearLowerLimit,
                    (float)base_joint.limit.lower
                    );
                planJoint.SetParamZ(
                    Generic6DOFJoint.Param.LinearUpperLimit,
                    (float)base_joint.limit.upper
                    );
                planJoint.SetParamZ(
                    Generic6DOFJoint.Param.LinearLowerLimit,
                    (float)base_joint.limit.lower
                    );
            }
            if (j_axis[1] == 1.0)
            {
                planJoint.SetParamY(
                    Generic6DOFJoint.Param.LinearUpperLimit,
                    (float)base_joint.limit.upper
                    );
                planJoint.SetParamY(
                    Generic6DOFJoint.Param.LinearLowerLimit,
                    (float)base_joint.limit.lower
                    );
                planJoint.SetParamX(
                    Generic6DOFJoint.Param.LinearUpperLimit,
                    (float)base_joint.limit.upper
                    );
                planJoint.SetParamX(
                    Generic6DOFJoint.Param.LinearLowerLimit,
                    (float)base_joint.limit.lower
                    );
            }
            if (j_axis[2] == 1.0)
            {
                planJoint.SetParamX(
                    Generic6DOFJoint.Param.LinearUpperLimit,
                    (float)base_joint.limit.upper
                    );
                planJoint.SetParamX(
                    Generic6DOFJoint.Param.LinearLowerLimit,
                    (float)base_joint.limit.lower
                    );
                planJoint.SetParamZ(
                    Generic6DOFJoint.Param.LinearUpperLimit,
                    (float)base_joint.limit.upper
                    );
                planJoint.SetParamZ(
                    Generic6DOFJoint.Param.LinearLowerLimit,
                    (float)base_joint.limit.lower
                    );
            }

            return(planJoint);

        default:
            GD.Print("testing: " + base_joint.type);
            break;
        }

        return(null);
    }