private RopeTest()
        {
            Body ground;
            {
                ground = new Body(World);

                EdgeShape shape = new EdgeShape(new Vector2(-40.0f, 0.0f), new Vector2(40.0f, 0.0f));
                ground.CreateFixture(shape);
            }

            {
                Body         prevBody   = ground;
                PolygonShape largeShape = new PolygonShape(PolygonTools.CreateRectangle(1.5f, 1.5f), 100);
                PolygonShape smallShape = new PolygonShape(PolygonTools.CreateRectangle(0.5f, 0.125f), 20);

                const int   N = 10;
                const float y = 15;

                for (int i = 0; i < N; ++i)
                {
                    Body body = BodyFactory.CreateBody(World);
                    body.BodyType = BodyType.Dynamic;
                    body.Position = new Vector2(0.5f + 1.0f * i, y);

                    if (i == N - 1)
                    {
                        Fixture fixture = body.CreateFixture(largeShape);
                        fixture.Friction            = 0.2f;
                        fixture.CollisionCategories = Category.Cat2;
                        fixture.CollidesWith        = Category.All & ~Category.Cat2;
                        body.Position       = new Vector2(1.0f * i, y);
                        body.AngularDamping = 0.4f;
                    }
                    else
                    {
                        Fixture fixture = body.CreateFixture(smallShape);
                        fixture.Friction            = 0.2f;
                        fixture.CollisionCategories = Category.Cat1;
                        fixture.CollidesWith        = Category.All & ~Category.Cat2;
                    }

                    Vector2       anchor = new Vector2(i, y);
                    RevoluteJoint jd     = new RevoluteJoint(prevBody, body, prevBody.GetLocalPoint(ref anchor),
                                                             body.GetLocalPoint(ref anchor));
                    jd.CollideConnected = false;

                    World.AddJoint(jd);

                    prevBody = body;
                }

                _rj = new RopeJoint(ground, prevBody, new Vector2(0, y), Vector2.Zero);

                //FPE: The two following lines are actually not needed as FPE sets the MaxLength to a default value
                const float extraLength = 0.01f;
                _rj.MaxLength = N - 1.0f + extraLength;

                World.AddJoint(_rj);
            }
        }
Exemple #2
0
    private void Simulate()
    {
        // SIMULATION
        for (int i = 0; i < jointCount; i++)
        {
            RopeJoint joint          = joints[i];
            Vector3   positionChange = joint.currentPosition - joint.previousPosition;

            Vector3 extraPreviousPosition = joint.previousPosition;
            joint.previousPosition = joint.currentPosition;
            joint.currentPosition += positionChange + gravityAcceleration * (Time.deltaTime * Time.deltaTime);

            // collision detection
            if (Physics.CheckSphere(joint.currentPosition, 0.1f, collidable))
            {
                joint.currentPosition = extraPreviousPosition;
            }
        }

        // CONSTRAINTS
        for (int i = 0; i < constraintIterations; i++)
        {
            ApplyConstraints();
        }
    }
Exemple #3
0
        public override void HandleInput()
        {
            InputHelper input = game.inputManager.inputHelper;

            if (input.IsNewButtonPress(MouseButtons.LeftButton))
            {
                Vector2 position = ProjectionHelper.PixelToFarseer(input.MousePosition);

                List <Fixture> list = game.farseerManager.world.TestPointAll(position);



                if (list.Count > 0)
                {
                    if (startBody == null)
                    {
                        startBody      = list[0].Body;
                        startBodyLocal = startBody.GetLocalPoint(position);
                    }
                    else
                    {
                        Body    endBody      = list[0].Body;
                        Vector2 endBodyLocal = endBody.GetLocalPoint(position);

                        RopeJoint j = new RopeJoint(startBody, endBody, startBodyLocal, endBodyLocal);
                        j.CollideConnected = true;
                        game.farseerManager.world.AddJoint(j);

                        FormManager.Property.setSelectedObject(j);

                        startBody = null;
                    }
                }
            }
        }
Exemple #4
0
        public static RopeJoint CreateRopeJoint(World world, Body bodyA, Body bodyB, Vector2 anchorA, Vector2 anchorB, bool useWorldCoordinates = false)
        {
            var ropeJoint = new RopeJoint(bodyA, bodyB, anchorA, anchorB, useWorldCoordinates);

            world.addJoint(ropeJoint);
            return(ropeJoint);
        }
Exemple #5
0
        ///// <summary>
        ///// Creates the fixed revolute joint.
        ///// </summary>
        ///// <param name="world">The world.</param>
        ///// <param name="body">The body.</param>
        ///// <param name="bodyAnchor">The body anchor.</param>
        ///// <param name="worldAnchor">The world anchor.</param>
        ///// <returns></returns>
        //public static FixedRevoluteJoint CreateFixedRevoluteJoint(World world, Body body, Vector2 bodyAnchor,
        //                                                          Vector2 worldAnchor)
        //{
        //    FixedRevoluteJoint fixedRevoluteJoint = new FixedRevoluteJoint(body, bodyAnchor, worldAnchor);
        //    world.AddJoint(fixedRevoluteJoint);
        //    return fixedRevoluteJoint;
        //}

        #endregion


        #region Rope Joint

        /// <summary>
        /// Creates a rope joint and adds it to the world
        /// </summary>
        public static RopeJoint CreateRopeJoint(World world, Body bodyA, Body bodyB, Vector2 anchorA, Vector2 anchorB)
        {
            RopeJoint ropeJoint = new RopeJoint(bodyA, bodyB, anchorA, anchorB);

            world.AddJoint(ropeJoint);
            return(ropeJoint);
        }
Exemple #6
0
        public override Joint createJoint()
        {
            var joint = new RopeJoint(bodyA, bodyB, ownerBodyAnchor * FSConvert.displayToSim, otherBodyAnchor * FSConvert.displayToSim);

            joint.collideConnected = collideConnected;
            joint.maxLength        = maxLength * FSConvert.displayToSim;
            return(joint);
        }
Exemple #7
0
        public override Joint CreateJoint()
        {
            var joint = new RopeJoint(BodyA, BodyB, OwnerBodyAnchor * FSConvert.DisplayToSim, OtherBodyAnchor * FSConvert.DisplayToSim);

            joint.CollideConnected = CollideConnected;
            joint.MaxLength        = MaxLength * FSConvert.DisplayToSim;
            return(joint);
        }
Exemple #8
0
        protected override Joint CreateJoint(Body bodyA, Body bodyB)
        {
            if (bodyA == null || bodyB == null)
            {
                return(null);
            }
            RopeJoint joint = new RopeJoint(bodyA, bodyB, Vector2.Zero, Vector2.Zero);

            Scene.PhysicsWorld.AddJoint(joint);
            return(joint);
        }
Exemple #9
0
        public static PayloadChain Connect(SpaceShip spaceShip, Payload payload, Vector2 payloadTarget)
        {
            var dynamicWorld = (DynamicEntityWorld)spaceShip.World;
            var world        = dynamicWorld.PhysicsWorld;

            AABB spaceShipSize;

            spaceShip.Body.FixtureList.First().GetAABB(out spaceShipSize, 0);

            AABB payloadSize;

            payload.Body.FixtureList.First().GetAABB(out payloadSize, 0);

            var chainSize       = new Vector2(1.0f);
            var chainSizeSingle = Math.Max(chainSize.X, chainSize.Y);

            var start        = new Vector2(spaceShip.Position.X - spaceShipSize.Extents.Y, spaceShip.Position.Y);
            var length       = payloadTarget.Length();
            var targetVector = payloadTarget / length;
            var chainVector  = targetVector * chainSizeSingle;

            start += chainVector;
            var chainCount = (int)Math.Ceiling(length / chainSizeSingle);

            var lastBody = spaceShip.Body;
            var chain    = new PayloadChain(spaceShip.Name + "_Chain");
            var elements = new List <ChainElement>();

            for (var i = 0; i < chainCount; i++)
            {
                var chainBody = BodyFactory.CreateBody(world, start + i * chainVector);
                chainBody.BodyType = BodyType.Dynamic;

                var chainFixture = FixtureFactory.AttachRectangle(chainSize.X, chainSize.Y, 0.1f, Vector2.Zero, chainBody);
                chainFixture.CollidesWith = Category.Cat2;

                JointFactory.CreateRevoluteJoint(world, lastBody, chainBody, -chainVector / 2.0f);
                lastBody = chainBody;

                elements.Add(ChainElement.CreateFor(chain, elements.Count, dynamicWorld, chainBody));
            }

            payload.Position = new Vector3(start + chainCount * chainVector + targetVector * 2.5f, 0.0f);
            JointFactory.CreateRevoluteJoint(world, lastBody, payload.Body, new Vector2(0.0f, -2.5f));

            var ropeJoin = new RopeJoint(spaceShip.Body, payload.Body, new Vector2(0.0f, 3.0f), new Vector2(0.0f, -2.5f));

            ropeJoin.CollideConnected = true;
            world.AddJoint(ropeJoin);


            return(chain);
        }
Exemple #10
0
        internal override void UpdateJoint()
        {
            base.UpdateJoint();
            if (this.joint == null)
            {
                return;
            }

            RopeJoint j = this.joint as RopeJoint;

            j.LocalAnchorB = GetFarseerPoint(this.BodyB, this.localAnchorB);
            j.LocalAnchorA = GetFarseerPoint(this.BodyA, this.localAnchorA);
            j.MaxLength    = PhysicsConvert.ToPhysicalUnit(this.maxLength);
        }
Exemple #11
0
        internal override void UpdateJoint()
        {
            base.UpdateJoint();
            if (this.joint == null)
            {
                return;
            }

            RopeJoint j = this.joint as RopeJoint;

            j.LocalAnchorB = GetFarseerPoint(this.OtherBody, this.localAnchorB);
            j.LocalAnchorA = GetFarseerPoint(this.ParentBody, this.localAnchorA);
            j.MaxLength    = PhysicsUnit.LengthToPhysical * this.maxLength;
        }
Exemple #12
0
        public Rope(Vector2 RopeStart, Vector2 RopeEnd)
        {
            path.Add(RopeStart);
            path.Add(RopeEnd);


            ropeText = GameLoop.gameInstance.Content.Load <Texture2D>("Sprites/rope");
            shape    = new PolygonShape(PolygonTools.CreateRectangle(0.05f, 0.1f), 0.6f);

            chainLinks = PathManager.EvenlyDistributeShapesAlongPath(Level.Physics, path, shape, BodyType.Dynamic, 20);

            /*
             * MovingFixture = FixtureFactory.CreateRectangle(Level.Physics, 2, 2, 1);
             *
             * MovingFixture.Body.BodyType = BodyType.Static;
             * MovingFixture.Body.Position = RopeStart;
             *
             */



            foreach (Body chainLink in chainLinks)
            {
                chainLink.LinearDamping = 0.5f;
                foreach (Fixture f in chainLink.FixtureList)
                {
                    f.Friction     = 2.0f;
                    f.CollidesWith = CollisionCategory.None;
                }
            }
            lastBody = chainLinks[(chainLinks.Count - 1)];



            // weld = new WeldJoint(MovingFixture.Body, chainLinks[0], Vector2.Zero, Vector2.Zero);
            // Level.Physics.AddJoint(weld);
            RopeJoint rope = new RopeJoint(chainLinks[0], chainLinks[chainLinks.Count - 1], Vector2.Zero, Vector2.Zero);

            chainLinks[0].BodyType = BodyType.Static;

            MovingBody = chainLinks[0];


            PathManager.AttachBodiesWithRevoluteJoint(Level.Physics, chainLinks, new Vector2(0, -0.1f), new Vector2(0, 0.1f),
                                                      false, false);
        }
Exemple #13
0
        private void AddBallAndChain(Body body)
        {
            // The chain will be divided into several segments along the following path
            var chainPath = new Path();

            chainPath.Add(ConvertUnits.ToSimUnits(332, 332));
            chainPath.Add(ConvertUnits.ToSimUnits(332, 452));

            // Creates the shape for the chain segments
            var chainLinkShape = new PolygonShape(PolygonTools.CreateRectangle(ConvertUnits.ToSimUnits(1), ConvertUnits.ToSimUnits(2)), 0.5f);

            // Creates the bodies for the chain segments
            _chainBodies = PathManager.EvenlyDistributeShapesAlongPath(World, chainPath,
                                                                       new[] { chainLinkShape }, BodyType.Dynamic, 30);

            // Connects the chain segments
            for (var i = 0; i < _chainBodies.Count - 1; i++)
            {
                var joint = new RevoluteJoint(_chainBodies[i], _chainBodies[i + 1], Vector2.Zero, Vector2.Zero);
                World.AddJoint(joint);
            }

            // Connects the start of the chain to the ufo
            var chainStartJoint = new RevoluteJoint(body, _chainBodies.First(), ConvertUnits.ToSimUnits(0, 25), Vector2.Zero);

            World.AddJoint(chainStartJoint);

            // Creates the ball at the end of the chain
            _chainEndBall              = BodyFactory.CreateCircle(World, ConvertUnits.ToSimUnits(10), 3f, bodyType: BodyType.Dynamic);
            _chainEndBall.Position     = ConvertUnits.ToSimUnits(332, 452);
            _chainEndBall.OnCollision += ChainBallOnCollision;

            // Adds the ball to the chain
            var chainEndJoint = new RevoluteJoint(_chainBodies.Last(), _chainEndBall, Vector2.Zero, Vector2.Zero);

            World.AddJoint(chainEndJoint);

            // Adds a rope join that ensures that the chain won't stretch
            var ropeJoint = new RopeJoint(body, _chainEndBall, ConvertUnits.ToSimUnits(0, 25), Vector2.Zero)
            {
                MaxLength = chainPath.GetLength()
            };

            World.AddJoint(ropeJoint);
        }
Exemple #14
0
        public bool Graple()
        {
            Vector2f pos1 = Offset(to2f(character.Body.Position));
            Vector2i pos2 = Mouse.GetPosition(window) + new Vector2i(32, 0);
            float    rad  = (float)Math.Atan2(pos2.X - pos1.X, pos2.Y - pos1.Y);
            Vector2  ray  = RayCast(25, rad);
            float    len  = RayCastDistance(25, rad);

            if (len < 1)
            {
                grapBody                = BodyFactory.CreateCircle(PhysConfig.world, 0.1f, 0.0f, ray);
                grapBody.IsStatic       = true;
                graplingJoint           = new RopeJoint(character.Body, grapBody, new Vector2(), new Vector2());
                graplingJoint.MaxLength = len * 24.8f;
                PhysConfig.world.AddJoint(graplingJoint);
                return(true);
            }
            return(false);
        }
Exemple #15
0
    private void ApplyConstraints()
    {
        // set first joint to be at position of ropeStart
        joints[0].currentPosition = ropeStart;

        // set last joint to be at position of ropeEnd
        joints[jointCount - 1].currentPosition = ropeEnd;

        // neighboring points on rope keep a fixed distance apart from each other (this is where the magic happens)
        for (int i = 0; i < jointCount - 1; i++)
        {
            RopeJoint firstJoint    = joints[i];
            RopeJoint secondJoint   = joints[i + 1];
            Vector3   firstToSecond = secondJoint.currentPosition - firstJoint.currentPosition;
            float     distance      = firstToSecond.magnitude;  // current segment length
            float     error         = distance - segmentLength; // difference between current and ideal segment length
            firstToSecond /= distance;                          // normalize firstToSecond
            Vector3 correction = firstToSecond * (error * 0.5f);

            if (i != 0)
            {
                firstJoint.currentPosition += correction;
            }
            else
            {
                secondJoint.currentPosition -= correction;
            }

            if (i + 1 != jointCount - 1)
            {
                secondJoint.currentPosition -= correction;
            }
            else
            {
                firstJoint.currentPosition += correction;
            }
        }
    }
Exemple #16
0
        private static Joint DeserializeRopeJoint(XElement jointElement, Body bodyA, Body bodyB, World world)
        {
            RopeJoint joint = null;
            Vector2   localAnchorA, localAnchorB;
            float     maxLength = 100.0f;

            localAnchorA = bodyA.WorldCenter;
            localAnchorB = bodyB.WorldCenter;

            foreach (XElement element in jointElement.Elements())
            {
                switch (element.Name.ToString().ToLower())
                {
                case "maxlength":
                    float.TryParse(element.Value, NumberStyles.Float, CultureInfo.InvariantCulture, out maxLength);
                    maxLength = ConvertUnits.ToSimUnits(maxLength);
                    break;

                case "localanchora":
                    localAnchorA = localAnchorA.DeserializeOffset(element);
                    localAnchorA = ConvertUnits.ToSimUnits(localAnchorA);
                    break;

                case "localanchorb":
                    localAnchorB = localAnchorB.DeserializeOffset(element);
                    localAnchorB = ConvertUnits.ToSimUnits(localAnchorB);
                    break;
                }
            }

            joint           = new RopeJoint(bodyA, bodyB, localAnchorA, localAnchorB);
            joint.MaxLength = maxLength;
            world.AddJoint(joint);

            return(joint);
        }
Exemple #17
0
        void DefaultJoints()
        {
            //b.LAnkleDef.body1		= LFoot;
            //b.LAnkleDef.body2		= LCalf;
            //b.RAnkleDef.body1		= RFoot;
            //b.RAnkleDef.body2		= RCalf;
            {                   // ankles
                Vector2 anchor = new Vector2(xScale, yScale) * new Vector2(-.045f, -.75f);
                Joints[(int)BipedJointIndex.LAnkle].LocalAnchorA   = Joints[(int)BipedJointIndex.RAnkle].LocalAnchorA = anchor - Bodies[(int)BipedFixtureIndex.LFoot].Position;
                Joints[(int)BipedJointIndex.LAnkle].LocalAnchorB   = Joints[(int)BipedJointIndex.RAnkle].LocalAnchorB = anchor - Bodies[(int)BipedFixtureIndex.LCalf].Position;
                Joints[(int)BipedJointIndex.LAnkle].ReferenceAngle = Joints[(int)BipedJointIndex.RAnkle].ReferenceAngle = 0.0f;
                Joints[(int)BipedJointIndex.LAnkle].LowerLimit     = Joints[(int)BipedJointIndex.RAnkle].LowerLimit = ReverseAngle(-0.523598776f);
                Joints[(int)BipedJointIndex.LAnkle].UpperLimit     = Joints[(int)BipedJointIndex.RAnkle].UpperLimit = ReverseAngle(0.523598776f);
            }

            //b.LKneeDef.body1		= LCalf;
            //b.LKneeDef.body2		= LThigh;
            //b.RKneeDef.body1		= RCalf;
            //b.RKneeDef.body2		= RThigh;
            {                   // knees
                Vector2 anchor = new Vector2(xScale, yScale) * new Vector2(-.030f, -.355f);
                Joints[(int)BipedJointIndex.LKnee].LocalAnchorA   = Joints[(int)BipedJointIndex.RKnee].LocalAnchorA = anchor - Bodies[(int)BipedFixtureIndex.LCalf].Position;
                Joints[(int)BipedJointIndex.LKnee].LocalAnchorB   = Joints[(int)BipedJointIndex.RKnee].LocalAnchorB = anchor - Bodies[(int)BipedFixtureIndex.LThigh].Position;
                Joints[(int)BipedJointIndex.LKnee].ReferenceAngle = Joints[(int)BipedJointIndex.RKnee].ReferenceAngle = 0.0f;
                Joints[(int)BipedJointIndex.LKnee].LowerLimit     = Joints[(int)BipedJointIndex.RKnee].LowerLimit = ReverseAngle(0);
                Joints[(int)BipedJointIndex.LKnee].UpperLimit     = Joints[(int)BipedJointIndex.RKnee].UpperLimit = ReverseAngle(2.61799388f);
            }

            //b.LHipDef.body1			= LThigh;
            //b.LHipDef.body2			= Pelvis;
            //b.RHipDef.body1			= RThigh;
            //b.RHipDef.body2			= Pelvis;
            {                   // hips
                Vector2 anchor = new Vector2(xScale, yScale) * new Vector2(.005f, -.045f);
                Joints[(int)BipedJointIndex.LHip].LocalAnchorA   = Joints[(int)BipedJointIndex.RHip].LocalAnchorA = anchor - Bodies[(int)BipedFixtureIndex.LThigh].Position;
                Joints[(int)BipedJointIndex.LHip].LocalAnchorB   = Joints[(int)BipedJointIndex.RHip].LocalAnchorB = anchor - Bodies[(int)BipedFixtureIndex.Pelvis].Position;
                Joints[(int)BipedJointIndex.LHip].ReferenceAngle = Joints[(int)BipedJointIndex.RHip].ReferenceAngle = 0.0f;
                Joints[(int)BipedJointIndex.LHip].LowerLimit     = Joints[(int)BipedJointIndex.RHip].LowerLimit = ReverseAngle(-0.76892803f);
                Joints[(int)BipedJointIndex.LHip].UpperLimit     = Joints[(int)BipedJointIndex.RHip].UpperLimit = 0;
            }

            //b.LowerAbsDef.body1		= Pelvis;
            //b.LowerAbsDef.body2		= Stomach;
            {                   // lower abs
                Vector2 anchor = new Vector2(xScale, yScale) * new Vector2(.035f, .135f);
                Joints[(int)BipedJointIndex.LowerAbs].LocalAnchorA   = anchor - Bodies[(int)BipedFixtureIndex.Pelvis].Position;
                Joints[(int)BipedJointIndex.LowerAbs].LocalAnchorB   = anchor - Bodies[(int)BipedFixtureIndex.Stomach].Position;
                Joints[(int)BipedJointIndex.LowerAbs].ReferenceAngle = 0.0f;
                Joints[(int)BipedJointIndex.LowerAbs].LowerLimit     = ReverseAngle(-0.523598776f);
                Joints[(int)BipedJointIndex.LowerAbs].UpperLimit     = ReverseAngle(0.523598776f);
            }

            //b.UpperAbsDef.body1		= Stomach;
            //b.UpperAbsDef.body2		= Chest;
            {                   // upper abs
                Vector2 anchor = new Vector2(xScale, yScale) * new Vector2(.045f, .320f);
                Joints[(int)BipedJointIndex.UpperAbs].LocalAnchorA   = anchor - Bodies[(int)BipedFixtureIndex.Stomach].Position;
                Joints[(int)BipedJointIndex.UpperAbs].LocalAnchorB   = anchor - Bodies[(int)BipedFixtureIndex.Chest].Position;
                Joints[(int)BipedJointIndex.UpperAbs].ReferenceAngle = 0.0f;
                Joints[(int)BipedJointIndex.UpperAbs].LowerLimit     = ReverseAngle(-0.523598776f);
                Joints[(int)BipedJointIndex.UpperAbs].UpperLimit     = ReverseAngle(0.174532925f);
            }

            //b.LowerNeckDef.body1	= Chest;
            //b.LowerNeckDef.body2	= Neck;
            {                   // lower neck
                Vector2 anchor = new Vector2(xScale, yScale) * new Vector2(-.015f, .575f);
                Joints[(int)BipedJointIndex.LowerNeck].LocalAnchorA   = anchor - Bodies[(int)BipedFixtureIndex.Chest].Position;
                Joints[(int)BipedJointIndex.LowerNeck].LocalAnchorB   = anchor - Bodies[(int)BipedFixtureIndex.Neck].Position;
                Joints[(int)BipedJointIndex.LowerNeck].ReferenceAngle = 0.0f;
                Joints[(int)BipedJointIndex.LowerNeck].LowerLimit     = ReverseAngle(-0.174532925f);
                Joints[(int)BipedJointIndex.LowerNeck].UpperLimit     = ReverseAngle(0.174532925f);
            }

            //b.UpperNeckDef.body1	= Chest;
            //b.UpperNeckDef.body2	= Head;
            {                   // upper neck
                Vector2 anchor = new Vector2(xScale, yScale) * new Vector2(-.005f, .630f);
                Joints[(int)BipedJointIndex.UpperNeck].LocalAnchorA   = anchor - Bodies[(int)BipedFixtureIndex.Chest].Position;
                Joints[(int)BipedJointIndex.UpperNeck].LocalAnchorB   = anchor - Bodies[(int)BipedFixtureIndex.Head].Position;
                Joints[(int)BipedJointIndex.UpperNeck].ReferenceAngle = 0.0f;
                Joints[(int)BipedJointIndex.UpperNeck].LowerLimit     = ReverseAngle(-0.610865238f);
                Joints[(int)BipedJointIndex.UpperNeck].UpperLimit     = ReverseAngle(0.785398163f);
            }

            //b.LShoulderDef.body1	= Chest;
            //b.LShoulderDef.body2	= LUpperArm;
            //b.RShoulderDef.body1	= Chest;
            //b.RShoulderDef.body2	= RUpperArm;
            {                   // shoulders
                Vector2 anchor = new Vector2(xScale, yScale) * new Vector2(-.015f, .545f);
                Joints[(int)BipedJointIndex.LShoulder].LocalAnchorA   = Joints[(int)BipedJointIndex.RShoulder].LocalAnchorA = anchor - Bodies[(int)BipedFixtureIndex.Chest].Position;
                Joints[(int)BipedJointIndex.LShoulder].LocalAnchorB   = Joints[(int)BipedJointIndex.RShoulder].LocalAnchorB = anchor - Bodies[(int)BipedFixtureIndex.LUpperArm].Position;
                Joints[(int)BipedJointIndex.LShoulder].ReferenceAngle = Joints[(int)BipedJointIndex.RShoulder].ReferenceAngle = 0.0f;
                Joints[(int)BipedJointIndex.LShoulder].LowerLimit     = Joints[(int)BipedJointIndex.RShoulder].LowerLimit = ReverseAngle(-1.04719755f);
                Joints[(int)BipedJointIndex.LShoulder].UpperLimit     = Joints[(int)BipedJointIndex.RShoulder].UpperLimit = ReverseAngle(3.14159265f);
            }

            //b.LElbowDef.body1		= LForearm;
            //b.LElbowDef.body2		= LUpperArm;
            //b.RElbowDef.body1		= RForearm;
            //b.RElbowDef.body2		= RUpperArm;
            {                   // elbows
                Vector2 anchor = new Vector2(xScale, yScale) * new Vector2(-.005f, .290f);
                Joints[(int)BipedJointIndex.LElbow].LocalAnchorA   = Joints[(int)BipedJointIndex.RElbow].LocalAnchorA = anchor - Bodies[(int)BipedFixtureIndex.LForearm].Position;
                Joints[(int)BipedJointIndex.LElbow].LocalAnchorB   = Joints[(int)BipedJointIndex.RElbow].LocalAnchorB = anchor - Bodies[(int)BipedFixtureIndex.LUpperArm].Position;
                Joints[(int)BipedJointIndex.LElbow].ReferenceAngle = Joints[(int)BipedJointIndex.RElbow].ReferenceAngle = 0.0f;
                Joints[(int)BipedJointIndex.LElbow].LowerLimit     = Joints[(int)BipedJointIndex.RElbow].LowerLimit = ReverseAngle(-2.7925268f);
                Joints[(int)BipedJointIndex.LElbow].UpperLimit     = Joints[(int)BipedJointIndex.RElbow].UpperLimit = 0;
            }

            //b.LWristDef.body1		= LHand;
            //b.LWristDef.body2		= LForearm;
            //b.RWristDef.body1		= RHand;
            //b.RWristDef.body2		= RForearm;
            {                   // wrists
                Vector2 anchor = new Vector2(xScale, yScale) * new Vector2(-.010f, .045f);
                Joints[(int)BipedJointIndex.LWrist].LocalAnchorA   = Joints[(int)BipedJointIndex.RWrist].LocalAnchorA = anchor - Bodies[(int)BipedFixtureIndex.LHand].Position;
                Joints[(int)BipedJointIndex.LWrist].LocalAnchorB   = Joints[(int)BipedJointIndex.RWrist].LocalAnchorB = anchor - Bodies[(int)BipedFixtureIndex.LForearm].Position;
                Joints[(int)BipedJointIndex.LWrist].ReferenceAngle = Joints[(int)BipedJointIndex.RWrist].ReferenceAngle = 0.0f;
                Joints[(int)BipedJointIndex.LWrist].LowerLimit     = Joints[(int)BipedJointIndex.RWrist].LowerLimit = ReverseAngle(-0.174532925f);
                Joints[(int)BipedJointIndex.LWrist].UpperLimit     = Joints[(int)BipedJointIndex.RWrist].UpperLimit = ReverseAngle(0.174532925f);
            }

            {
                RopeJoint rj = new RopeJoint(Bodies[(int)BipedFixtureIndex.RUpperArm], Bodies[(int)BipedFixtureIndex.RHand], Vector2.Zero, Vector2.Zero);
                rj = new RopeJoint(Bodies[(int)BipedFixtureIndex.LUpperArm], Bodies[(int)BipedFixtureIndex.LHand], Vector2.Zero, Vector2.Zero);
            }

            if (xScale < 0)
            {
                foreach (var j in Joints)
                {
                    var old = j.UpperLimit;
                    j.UpperLimit = j.LowerLimit;
                    j.LowerLimit = old;
                }
            }
        }
        private static void Deserialize(World world, Stream stream)
        {
            List <Body>    bodies   = new List <Body>();
            List <Fixture> fixtures = new List <Fixture>();
            List <Joint>   joints   = new List <Joint>();
            List <Shape>   shapes   = new List <Shape>();

            XMLFragmentElement root = XMLFragmentParser.LoadFromStream(stream);

            if (root.Name.ToLower() != "world")
            {
                throw new Exception();
            }

            //Read gravity
            foreach (XMLFragmentElement element in root.Elements)
            {
                if (element.Name.ToLower() == "gravity")
                {
                    world.Gravity = ReadVector(element);
                    break;
                }
            }

            //Read shapes
            foreach (XMLFragmentElement shapeElement in root.Elements)
            {
                if (shapeElement.Name.ToLower() == "shapes")
                {
                    foreach (XMLFragmentElement element in shapeElement.Elements)
                    {
                        if (element.Name.ToLower() != "shape")
                        {
                            throw new Exception();
                        }

                        ShapeType type    = (ShapeType)Enum.Parse(typeof(ShapeType), element.Attributes[0].Value, true);
                        float     density = float.Parse(element.Attributes[1].Value);

                        switch (type)
                        {
                        case ShapeType.Circle:
                        {
                            CircleShape shape = new CircleShape();
                            shape._density = density;

                            foreach (XMLFragmentElement sn in element.Elements)
                            {
                                switch (sn.Name.ToLower())
                                {
                                case "radius":
                                    shape.Radius = float.Parse(sn.Value);
                                    break;

                                case "position":
                                    shape.Position = ReadVector(sn);
                                    break;

                                default:
                                    throw new Exception();
                                }
                            }

                            shapes.Add(shape);
                        }
                        break;

                        case ShapeType.Polygon:
                        {
                            PolygonShape shape = new PolygonShape();
                            shape._density = density;

                            foreach (XMLFragmentElement sn in element.Elements)
                            {
                                switch (sn.Name.ToLower())
                                {
                                case "vertices":
                                {
                                    List <Vector2> verts = new List <Vector2>(sn.Elements.Count);

                                    foreach (XMLFragmentElement vert in sn.Elements)
                                    {
                                        verts.Add(ReadVector(vert));
                                    }

                                    shape.Vertices = new Vertices(verts);
                                }
                                break;

                                case "centroid":
                                    shape.MassData.Centroid = ReadVector(sn);
                                    break;
                                }
                            }

                            shapes.Add(shape);
                        }
                        break;

                        case ShapeType.Edge:
                        {
                            EdgeShape shape = new EdgeShape();
                            shape._density = density;

                            foreach (XMLFragmentElement sn in element.Elements)
                            {
                                switch (sn.Name.ToLower())
                                {
                                case "hasvertex0":
                                    shape.HasVertex0 = bool.Parse(sn.Value);
                                    break;

                                case "hasvertex3":
                                    shape.HasVertex0 = bool.Parse(sn.Value);
                                    break;

                                case "vertex0":
                                    shape.Vertex0 = ReadVector(sn);
                                    break;

                                case "vertex1":
                                    shape.Vertex1 = ReadVector(sn);
                                    break;

                                case "vertex2":
                                    shape.Vertex2 = ReadVector(sn);
                                    break;

                                case "vertex3":
                                    shape.Vertex3 = ReadVector(sn);
                                    break;

                                default:
                                    throw new Exception();
                                }
                            }
                            shapes.Add(shape);
                        }
                        break;

                        case ShapeType.Chain:
                        {
                            ChainShape shape = new ChainShape();
                            shape._density = density;

                            foreach (XMLFragmentElement sn in element.Elements)
                            {
                                switch (sn.Name.ToLower())
                                {
                                case "vertices":
                                {
                                    List <Vector2> verts = new List <Vector2>(sn.Elements.Count);

                                    foreach (XMLFragmentElement vert in sn.Elements)
                                    {
                                        verts.Add(ReadVector(vert));
                                    }

                                    shape.Vertices = new Vertices(verts);
                                }
                                break;

                                case "nextvertex":
                                    shape.NextVertex = ReadVector(sn);
                                    break;

                                case "prevvertex":
                                    shape.PrevVertex = ReadVector(sn);
                                    break;

                                default:
                                    throw new Exception();
                                }
                            }
                            shapes.Add(shape);
                        }
                        break;
                        }
                    }
                }
            }

            //Read fixtures
            foreach (XMLFragmentElement fixtureElement in root.Elements)
            {
                if (fixtureElement.Name.ToLower() == "fixtures")
                {
                    foreach (XMLFragmentElement element in fixtureElement.Elements)
                    {
                        Fixture fixture = new Fixture();

                        if (element.Name.ToLower() != "fixture")
                        {
                            throw new Exception();
                        }

                        fixture.FixtureId = int.Parse(element.Attributes[0].Value);

                        foreach (XMLFragmentElement sn in element.Elements)
                        {
                            switch (sn.Name.ToLower())
                            {
                            case "filterdata":
                                foreach (XMLFragmentElement ssn in sn.Elements)
                                {
                                    switch (ssn.Name.ToLower())
                                    {
                                    case "categorybits":
                                        fixture._collisionCategories = (Category)int.Parse(ssn.Value);
                                        break;

                                    case "maskbits":
                                        fixture._collidesWith = (Category)int.Parse(ssn.Value);
                                        break;

                                    case "groupindex":
                                        fixture._collisionGroup = short.Parse(ssn.Value);
                                        break;

                                    case "CollisionIgnores":
                                        string[] split = ssn.Value.Split('|');
                                        foreach (string s in split)
                                        {
                                            fixture._collisionIgnores.Add(int.Parse(s));
                                        }
                                        break;
                                    }
                                }

                                break;

                            case "friction":
                                fixture.Friction = float.Parse(sn.Value);
                                break;

                            case "issensor":
                                fixture.IsSensor = bool.Parse(sn.Value);
                                break;

                            case "restitution":
                                fixture.Restitution = float.Parse(sn.Value);
                                break;

                            case "userdata":
                                fixture.UserData = ReadSimpleType(sn, null, false);
                                break;
                            }
                        }

                        fixtures.Add(fixture);
                    }
                }
            }

            //Read bodies
            foreach (XMLFragmentElement bodyElement in root.Elements)
            {
                if (bodyElement.Name.ToLower() == "bodies")
                {
                    foreach (XMLFragmentElement element in bodyElement.Elements)
                    {
                        Body body = new Body(world);

                        if (element.Name.ToLower() != "body")
                        {
                            throw new Exception();
                        }

                        body.BodyType = (BodyType)Enum.Parse(typeof(BodyType), element.Attributes[0].Value, true);

                        foreach (XMLFragmentElement sn in element.Elements)
                        {
                            switch (sn.Name.ToLower())
                            {
                            case "active":
                                bool enabled = bool.Parse(sn.Value);
                                if (enabled)
                                {
                                    body._flags |= BodyFlags.Enabled;
                                }
                                else
                                {
                                    body._flags &= ~BodyFlags.Enabled;
                                }
                                break;

                            case "allowsleep":
                                body.SleepingAllowed = bool.Parse(sn.Value);
                                break;

                            case "angle":
                            {
                                Vector2 position = body.Position;
                                body.SetTransformIgnoreContacts(ref position, float.Parse(sn.Value));
                            }
                            break;

                            case "angulardamping":
                                body.AngularDamping = float.Parse(sn.Value);
                                break;

                            case "angularvelocity":
                                body.AngularVelocity = float.Parse(sn.Value);
                                break;

                            case "awake":
                                body.Awake = bool.Parse(sn.Value);
                                break;

                            case "bullet":
                                body.IsBullet = bool.Parse(sn.Value);
                                break;

                            case "fixedrotation":
                                body.FixedRotation = bool.Parse(sn.Value);
                                break;

                            case "lineardamping":
                                body.LinearDamping = float.Parse(sn.Value);
                                break;

                            case "linearvelocity":
                                body.LinearVelocity = ReadVector(sn);
                                break;

                            case "position":
                            {
                                float   rotation = body.Rotation;
                                Vector2 position = ReadVector(sn);
                                body.SetTransformIgnoreContacts(ref position, rotation);
                            }
                            break;

                            case "userdata":
                                body.UserData = ReadSimpleType(sn, null, false);
                                break;

                            case "bindings":
                            {
                                foreach (XMLFragmentElement pair in sn.Elements)
                                {
                                    Fixture fix = fixtures[int.Parse(pair.Attributes[0].Value)];
                                    fix.Shape = shapes[int.Parse(pair.Attributes[1].Value)].Clone();
                                    fix.CloneOnto(body);
                                }
                                break;
                            }
                            }
                        }

                        bodies.Add(body);
                    }
                }
            }

            //Read joints
            foreach (XMLFragmentElement jointElement in root.Elements)
            {
                if (jointElement.Name.ToLower() == "joints")
                {
                    foreach (XMLFragmentElement n in jointElement.Elements)
                    {
                        Joint joint;

                        if (n.Name.ToLower() != "joint")
                        {
                            throw new Exception();
                        }

                        JointType type = (JointType)Enum.Parse(typeof(JointType), n.Attributes[0].Value, true);

                        int    bodyAIndex = -1, bodyBIndex = -1;
                        bool   collideConnected = false;
                        object userData         = null;

                        foreach (XMLFragmentElement sn in n.Elements)
                        {
                            switch (sn.Name.ToLower())
                            {
                            case "bodya":
                                bodyAIndex = int.Parse(sn.Value);
                                break;

                            case "bodyb":
                                bodyBIndex = int.Parse(sn.Value);
                                break;

                            case "collideconnected":
                                collideConnected = bool.Parse(sn.Value);
                                break;

                            case "userdata":
                                userData = ReadSimpleType(sn, null, false);
                                break;
                            }
                        }

                        Body bodyA = bodies[bodyAIndex];
                        Body bodyB = bodies[bodyBIndex];

                        switch (type)
                        {
                        //case JointType.FixedMouse:
                        //    joint = new FixedMouseJoint();
                        //    break;
                        //case JointType.FixedRevolute:
                        //    break;
                        //case JointType.FixedDistance:
                        //    break;
                        //case JointType.FixedLine:
                        //    break;
                        //case JointType.FixedPrismatic:
                        //    break;
                        //case JointType.FixedAngle:
                        //    break;
                        //case JointType.FixedFriction:
                        //    break;
                        case JointType.Distance:
                            joint = new DistanceJoint();
                            break;

                        case JointType.Friction:
                            joint = new FrictionJoint();
                            break;

                        case JointType.Wheel:
                            joint = new WheelJoint();
                            break;

                        case JointType.Prismatic:
                            joint = new PrismaticJoint();
                            break;

                        case JointType.Pulley:
                            joint = new PulleyJoint();
                            break;

                        case JointType.Revolute:
                            joint = new RevoluteJoint();
                            break;

                        case JointType.Weld:
                            joint = new WeldJoint();
                            break;

                        case JointType.Rope:
                            joint = new RopeJoint();
                            break;

                        case JointType.Angle:
                            joint = new AngleJoint();
                            break;

                        case JointType.Motor:
                            joint = new MotorJoint();
                            break;

                        case JointType.Gear:
                            throw new Exception("GearJoint is not supported.");

                        default:
                            throw new Exception("Invalid or unsupported joint.");
                        }

                        joint.CollideConnected = collideConnected;
                        joint.UserData         = userData;
                        joint.BodyA            = bodyA;
                        joint.BodyB            = bodyB;
                        joints.Add(joint);
                        world.AddJoint(joint);

                        foreach (XMLFragmentElement sn in n.Elements)
                        {
                            // check for specific nodes
                            switch (type)
                            {
                            case JointType.Distance:
                            {
                                switch (sn.Name.ToLower())
                                {
                                case "dampingratio":
                                    ((DistanceJoint)joint).DampingRatio = float.Parse(sn.Value);
                                    break;

                                case "frequencyhz":
                                    ((DistanceJoint)joint).Frequency = float.Parse(sn.Value);
                                    break;

                                case "length":
                                    ((DistanceJoint)joint).Length = float.Parse(sn.Value);
                                    break;

                                case "localanchora":
                                    ((DistanceJoint)joint).LocalAnchorA = ReadVector(sn);
                                    break;

                                case "localanchorb":
                                    ((DistanceJoint)joint).LocalAnchorB = ReadVector(sn);
                                    break;
                                }
                            }
                            break;

                            case JointType.Friction:
                            {
                                switch (sn.Name.ToLower())
                                {
                                case "localanchora":
                                    ((FrictionJoint)joint).LocalAnchorA = ReadVector(sn);
                                    break;

                                case "localanchorb":
                                    ((FrictionJoint)joint).LocalAnchorB = ReadVector(sn);
                                    break;

                                case "maxforce":
                                    ((FrictionJoint)joint).MaxForce = float.Parse(sn.Value);
                                    break;

                                case "maxtorque":
                                    ((FrictionJoint)joint).MaxTorque = float.Parse(sn.Value);
                                    break;
                                }
                            }
                            break;

                            case JointType.Wheel:
                            {
                                switch (sn.Name.ToLower())
                                {
                                case "enablemotor":
                                    ((WheelJoint)joint).MotorEnabled = bool.Parse(sn.Value);
                                    break;

                                case "localanchora":
                                    ((WheelJoint)joint).LocalAnchorA = ReadVector(sn);
                                    break;

                                case "localanchorb":
                                    ((WheelJoint)joint).LocalAnchorB = ReadVector(sn);
                                    break;

                                case "motorspeed":
                                    ((WheelJoint)joint).MotorSpeed = float.Parse(sn.Value);
                                    break;

                                case "dampingratio":
                                    ((WheelJoint)joint).DampingRatio = float.Parse(sn.Value);
                                    break;

                                case "maxmotortorque":
                                    ((WheelJoint)joint).MaxMotorTorque = float.Parse(sn.Value);
                                    break;

                                case "frequencyhz":
                                    ((WheelJoint)joint).Frequency = float.Parse(sn.Value);
                                    break;

                                case "axis":
                                    ((WheelJoint)joint).Axis = ReadVector(sn);
                                    break;
                                }
                            }
                            break;

                            case JointType.Prismatic:
                            {
                                switch (sn.Name.ToLower())
                                {
                                case "enablelimit":
                                    ((PrismaticJoint)joint).LimitEnabled = bool.Parse(sn.Value);
                                    break;

                                case "enablemotor":
                                    ((PrismaticJoint)joint).MotorEnabled = bool.Parse(sn.Value);
                                    break;

                                case "localanchora":
                                    ((PrismaticJoint)joint).LocalAnchorA = ReadVector(sn);
                                    break;

                                case "localanchorb":
                                    ((PrismaticJoint)joint).LocalAnchorB = ReadVector(sn);
                                    break;

                                case "axis":
                                    ((PrismaticJoint)joint).Axis = ReadVector(sn);
                                    break;

                                case "maxmotorforce":
                                    ((PrismaticJoint)joint).MaxMotorForce = float.Parse(sn.Value);
                                    break;

                                case "motorspeed":
                                    ((PrismaticJoint)joint).MotorSpeed = float.Parse(sn.Value);
                                    break;

                                case "lowertranslation":
                                    ((PrismaticJoint)joint).LowerLimit = float.Parse(sn.Value);
                                    break;

                                case "uppertranslation":
                                    ((PrismaticJoint)joint).UpperLimit = float.Parse(sn.Value);
                                    break;

                                case "referenceangle":
                                    ((PrismaticJoint)joint).ReferenceAngle = float.Parse(sn.Value);
                                    break;
                                }
                            }
                            break;

                            case JointType.Pulley:
                            {
                                switch (sn.Name.ToLower())
                                {
                                case "worldanchora":
                                    ((PulleyJoint)joint).WorldAnchorA = ReadVector(sn);
                                    break;

                                case "worldanchorb":
                                    ((PulleyJoint)joint).WorldAnchorB = ReadVector(sn);
                                    break;

                                case "lengtha":
                                    ((PulleyJoint)joint).LengthA = float.Parse(sn.Value);
                                    break;

                                case "lengthb":
                                    ((PulleyJoint)joint).LengthB = float.Parse(sn.Value);
                                    break;

                                case "localanchora":
                                    ((PulleyJoint)joint).LocalAnchorA = ReadVector(sn);
                                    break;

                                case "localanchorb":
                                    ((PulleyJoint)joint).LocalAnchorB = ReadVector(sn);
                                    break;

                                case "ratio":
                                    ((PulleyJoint)joint).Ratio = float.Parse(sn.Value);
                                    break;

                                case "constant":
                                    ((PulleyJoint)joint).Constant = float.Parse(sn.Value);
                                    break;
                                }
                            }
                            break;

                            case JointType.Revolute:
                            {
                                switch (sn.Name.ToLower())
                                {
                                case "enablelimit":
                                    ((RevoluteJoint)joint).LimitEnabled = bool.Parse(sn.Value);
                                    break;

                                case "enablemotor":
                                    ((RevoluteJoint)joint).MotorEnabled = bool.Parse(sn.Value);
                                    break;

                                case "localanchora":
                                    ((RevoluteJoint)joint).LocalAnchorA = ReadVector(sn);
                                    break;

                                case "localanchorb":
                                    ((RevoluteJoint)joint).LocalAnchorB = ReadVector(sn);
                                    break;

                                case "maxmotortorque":
                                    ((RevoluteJoint)joint).MaxMotorTorque = float.Parse(sn.Value);
                                    break;

                                case "motorspeed":
                                    ((RevoluteJoint)joint).MotorSpeed = float.Parse(sn.Value);
                                    break;

                                case "lowerangle":
                                    ((RevoluteJoint)joint).LowerLimit = float.Parse(sn.Value);
                                    break;

                                case "upperangle":
                                    ((RevoluteJoint)joint).UpperLimit = float.Parse(sn.Value);
                                    break;

                                case "referenceangle":
                                    ((RevoluteJoint)joint).ReferenceAngle = float.Parse(sn.Value);
                                    break;
                                }
                            }
                            break;

                            case JointType.Weld:
                            {
                                switch (sn.Name.ToLower())
                                {
                                case "localanchora":
                                    ((WeldJoint)joint).LocalAnchorA = ReadVector(sn);
                                    break;

                                case "localanchorb":
                                    ((WeldJoint)joint).LocalAnchorB = ReadVector(sn);
                                    break;
                                }
                            }
                            break;

                            case JointType.Rope:
                            {
                                switch (sn.Name.ToLower())
                                {
                                case "localanchora":
                                    ((RopeJoint)joint).LocalAnchorA = ReadVector(sn);
                                    break;

                                case "localanchorb":
                                    ((RopeJoint)joint).LocalAnchorB = ReadVector(sn);
                                    break;

                                case "maxlength":
                                    ((RopeJoint)joint).MaxLength = float.Parse(sn.Value);
                                    break;
                                }
                            }
                            break;

                            case JointType.Gear:
                                throw new Exception("Gear joint is unsupported");

                            case JointType.Angle:
                            {
                                switch (sn.Name.ToLower())
                                {
                                case "biasfactor":
                                    ((AngleJoint)joint).BiasFactor = float.Parse(sn.Value);
                                    break;

                                case "maximpulse":
                                    ((AngleJoint)joint).MaxImpulse = float.Parse(sn.Value);
                                    break;

                                case "softness":
                                    ((AngleJoint)joint).Softness = float.Parse(sn.Value);
                                    break;

                                case "targetangle":
                                    ((AngleJoint)joint).TargetAngle = float.Parse(sn.Value);
                                    break;
                                }
                            }
                            break;

                            case JointType.Motor:
                                switch (sn.Name.ToLower())
                                {
                                case "angularoffset":
                                    ((MotorJoint)joint).AngularOffset = float.Parse(sn.Value);
                                    break;

                                case "linearoffset":
                                    ((MotorJoint)joint).LinearOffset = ReadVector(sn);
                                    break;

                                case "maxforce":
                                    ((MotorJoint)joint).MaxForce = float.Parse(sn.Value);
                                    break;

                                case "maxtorque":
                                    ((MotorJoint)joint).MaxTorque = float.Parse(sn.Value);
                                    break;

                                case "correctionfactor":
                                    ((MotorJoint)joint).CorrectionFactor = float.Parse(sn.Value);
                                    break;
                                }
                                break;
                            }
                        }
                    }
                }
            }

            world.ProcessChanges();
        }
Exemple #19
0
        private static void SerializeJoint(List <Body> bodies, Joint joint)
        {
            _writer.WriteStartElement("Joint");
            _writer.WriteAttributeString("Type", joint.JointType.ToString());

            WriteElement("BodyA", FindIndex(bodies, joint.BodyA));
            WriteElement("BodyB", FindIndex(bodies, joint.BodyB));

            WriteElement("CollideConnected", joint.CollideConnected);

            WriteElement("Breakpoint", joint.Breakpoint);

            if (joint.UserData != null)
            {
                _writer.WriteStartElement("UserData");
                WriteDynamicType(joint.UserData.GetType(), joint.UserData);
                _writer.WriteEndElement();
            }

            switch (joint.JointType)
            {
            case JointType.Distance:
            {
                DistanceJoint distanceJoint = (DistanceJoint)joint;
                WriteElement("DampingRatio", distanceJoint.DampingRatio);
                WriteElement("FrequencyHz", distanceJoint.Frequency);
                WriteElement("Length", distanceJoint.Length);
                WriteElement("LocalAnchorA", distanceJoint.LocalAnchorA);
                WriteElement("LocalAnchorB", distanceJoint.LocalAnchorB);
            }
            break;

            case JointType.Friction:
            {
                FrictionJoint frictionJoint = (FrictionJoint)joint;
                WriteElement("LocalAnchorA", frictionJoint.LocalAnchorA);
                WriteElement("LocalAnchorB", frictionJoint.LocalAnchorB);
                WriteElement("MaxForce", frictionJoint.MaxForce);
                WriteElement("MaxTorque", frictionJoint.MaxTorque);
            }
            break;

            case JointType.Gear:
                throw new Exception("Gear joint not supported by serialization");

            case JointType.Wheel:
            {
                WheelJoint wheelJoint = (WheelJoint)joint;
                WriteElement("EnableMotor", wheelJoint.MotorEnabled);
                WriteElement("LocalAnchorA", wheelJoint.LocalAnchorA);
                WriteElement("LocalAnchorB", wheelJoint.LocalAnchorB);
                WriteElement("MotorSpeed", wheelJoint.MotorSpeed);
                WriteElement("DampingRatio", wheelJoint.DampingRatio);
                WriteElement("MaxMotorTorque", wheelJoint.MaxMotorTorque);
                WriteElement("FrequencyHz", wheelJoint.Frequency);
                WriteElement("Axis", wheelJoint.Axis);
            }
            break;

            case JointType.Prismatic:
            {
                //NOTE: Does not conform with Box2DScene

                PrismaticJoint prismaticJoint = (PrismaticJoint)joint;
                WriteElement("EnableLimit", prismaticJoint.LimitEnabled);
                WriteElement("EnableMotor", prismaticJoint.MotorEnabled);
                WriteElement("LocalAnchorA", prismaticJoint.LocalAnchorA);
                WriteElement("LocalAnchorB", prismaticJoint.LocalAnchorB);
                WriteElement("Axis", prismaticJoint.Axis);
                WriteElement("LowerTranslation", prismaticJoint.LowerLimit);
                WriteElement("UpperTranslation", prismaticJoint.UpperLimit);
                WriteElement("MaxMotorForce", prismaticJoint.MaxMotorForce);
                WriteElement("MotorSpeed", prismaticJoint.MotorSpeed);
            }
            break;

            case JointType.Pulley:
            {
                PulleyJoint pulleyJoint = (PulleyJoint)joint;
                WriteElement("WorldAnchorA", pulleyJoint.WorldAnchorA);
                WriteElement("WorldAnchorB", pulleyJoint.WorldAnchorB);
                WriteElement("LengthA", pulleyJoint.LengthA);
                WriteElement("LengthB", pulleyJoint.LengthB);
                WriteElement("LocalAnchorA", pulleyJoint.LocalAnchorA);
                WriteElement("LocalAnchorB", pulleyJoint.LocalAnchorB);
                WriteElement("Ratio", pulleyJoint.Ratio);
                WriteElement("Constant", pulleyJoint.Constant);
            }
            break;

            case JointType.Revolute:
            {
                RevoluteJoint revoluteJoint = (RevoluteJoint)joint;
                WriteElement("EnableLimit", revoluteJoint.LimitEnabled);
                WriteElement("EnableMotor", revoluteJoint.MotorEnabled);
                WriteElement("LocalAnchorA", revoluteJoint.LocalAnchorA);
                WriteElement("LocalAnchorB", revoluteJoint.LocalAnchorB);
                WriteElement("LowerAngle", revoluteJoint.LowerLimit);
                WriteElement("MaxMotorTorque", revoluteJoint.MaxMotorTorque);
                WriteElement("MotorSpeed", revoluteJoint.MotorSpeed);
                WriteElement("ReferenceAngle", revoluteJoint.ReferenceAngle);
                WriteElement("UpperAngle", revoluteJoint.UpperLimit);
            }
            break;

            case JointType.Weld:
            {
                WeldJoint weldJoint = (WeldJoint)joint;
                WriteElement("LocalAnchorA", weldJoint.LocalAnchorA);
                WriteElement("LocalAnchorB", weldJoint.LocalAnchorB);
            }
            break;

            //
            // Not part of Box2DScene
            //
            case JointType.Rope:
            {
                RopeJoint ropeJoint = (RopeJoint)joint;
                WriteElement("LocalAnchorA", ropeJoint.LocalAnchorA);
                WriteElement("LocalAnchorB", ropeJoint.LocalAnchorB);
                WriteElement("MaxLength", ropeJoint.MaxLength);
            }
            break;

            case JointType.Angle:
            {
                AngleJoint angleJoint = (AngleJoint)joint;
                WriteElement("BiasFactor", angleJoint.BiasFactor);
                WriteElement("MaxImpulse", angleJoint.MaxImpulse);
                WriteElement("Softness", angleJoint.Softness);
                WriteElement("TargetAngle", angleJoint.TargetAngle);
            }
            break;

            case JointType.Motor:
            {
                MotorJoint motorJoint = (MotorJoint)joint;
                WriteElement("AngularOffset", motorJoint.AngularOffset);
                WriteElement("LinearOffset", motorJoint.LinearOffset);
                WriteElement("MaxForce", motorJoint.MaxForce);
                WriteElement("MaxTorque", motorJoint.MaxTorque);
                WriteElement("CorrectionFactor", motorJoint.CorrectionFactor);
            }
            break;

            default:
                throw new Exception("Joint not supported");
            }

            _writer.WriteEndElement();
        }
Exemple #20
0
        public override void Update(float delta)
        {
#if !EDITOR
            Player playerInstance = Player.Instance;

            #region Awaken Body
            //  If the body has fallen asleep, we need to wake it if the
            //  level rotates.
            if (Camera.Instance.IsLevelRotating)
            {
                if (_pathBodies[_pathBodies.Count - 1].Awake == false)
                {
                    this._pathBodies[_pathBodies.Count - 1].Awake = true;
                }
            }
            #endregion

            if (!_world.JointList.Contains(_ropeJoint))
            {
                if (playerInstance.PlayerState != PlayerState.Dead &&
                    InputManager.Instance.Grab(true) &&
                    _inRange)
                {
                    int   index            = 0;
                    Body  playerBody       = playerInstance.GetWheelBody();
                    float smallestDistance = Math.Abs(
                        Vector2.Subtract(playerBody.Position,
                                         _touchedRopeFixtures[0].Body.Position).Length());

                    //  Starting it at 3 instead of 1 or 2 because they
                    //  shouldn't really be able to grab the top ones
                    for (int i = 3; i < _touchedRopeFixtures.Count; i++)
                    {
                        float distance = Math.Abs(
                            Vector2.Subtract(playerBody.Position,
                                             _touchedRopeFixtures[i].Body.Position).Length());

                        if (distance < smallestDistance)
                        {
                            smallestDistance   = distance;
                            this._grabbedIndex = i;
                        }
                    }

                    this._ropePlayerJoint = new RevoluteJoint(_touchedRopeFixtures[index].Body,
                                                              playerInstance.GetMainBody(), Vector2.Zero, Vector2.Zero);
                    this._world.AddJoint(_ropePlayerJoint);

                    this._ropeJoint = new RopeJoint(_pathBodies[0],
                                                    playerInstance.GetMainBody(), Vector2.Zero, Vector2.Zero);
                    this._world.AddJoint(_ropeJoint);

                    playerInstance.GrabRope();
                }
            }
            else
            {
                Vector2 ropeDims = _ropeJoint.WorldAnchorB - _ropeJoint.WorldAnchorA;
                float   rotation = (float)Math.Atan2(ropeDims.Y, ropeDims.X);

                rotation -= MathHelper.PiOver2;

                playerInstance.SetRotation(rotation);

                if (InputManager.Instance.Jump(true) || InputManager.Instance.Grab(true) ||
                    playerInstance.PlayerState == PlayerState.Dead)
                {
                    _world.RemoveJoint(_ropeJoint);
                    _world.RemoveJoint(_ropePlayerJoint);

                    if (playerInstance.PlayerState == PlayerState.Swinging)
                    {
                        playerInstance.ForceFall();
                    }
                }
            }
#endif
        }