Joint Break

Topics: Developer Forum, User Forum
Nov 9, 2009 at 5:57 PM
Edited Nov 9, 2009 at 6:17 PM

I am hoping to get some help or maybe just a bug.

 

I am in the early stages of development and am working on a creature which can move in my environment.

I have a creature created, but when the creature hits a wall (i.e. IsStatic) it starts a runaway calculation which results in the breakup of the creature and then some of the calculations evaluate to NaN, which caused exceptions.  At the time of collision I am not applying any force.

This makes no sense to me.

Below is code snippet I use to create the wall:  What I would have expected is to hit the wall and be stopped, maybe a small bonce but not break up.

Note: No Gravity

     public Border(float width, float height)
        {
            Width = width;
            Height = height;
            float h2 = height/2f;
            float w2 = width/2f;
            this.Position = new Vector2(w2,h2);

            Body bd = CreateRectangle(Width, 1f, Position - new Vector2(0f, h2 + 0.5f), 1000.0f);
            bd.IsStatic = true;
            bd = CreateRectangle(Width, 1f, Position + new Vector2(0f, h2 + 0.5f), 1000.0f);
            bd.IsStatic = true;
            bd = CreateRectangle(1f, Height, Position - new Vector2(w2 + 0.5f, 0f), 1000.0f);
            bd.IsStatic = true;
            bd = CreateRectangle(1f, Height, Position + new Vector2(w2 + 0.5f, 0f), 1000.0f);
            bd.IsStatic = true;
        }

 

and for the creature:

using System;
using System.Windows.Input;
using FarseerGames.FarseerPhysics.Dynamics;
using FarseerGames.FarseerPhysics.Dynamics.Joints;
using FarseerGames.FarseerPhysics.Dynamics.Springs;
using FarseerGames.FarseerPhysics.Mathematics;

namespace CreatureSim.Sim
{
    public class Agent: Entity
    {
        private const float LegLength = 0.2f;
        private const float LegWidth = 0.01f;
        private const float LegHeightOffset = 0.2f;
        private const float BodyWidth = 0.4f;
        private const float BodyHeight = 0.5f;
        private Body _body;
        private Body _head;
        private Body _legTopLeft;
        private Body _legTopRight;
        private Body _legBottomLeft;
        private Body _legBottomRight;
        private Body _ant1;
        private Body _ant2;

        public override void Load()
        {
            const float damping = 0.001f;
            const float springConst = 0.001f;
            Vector2 pos = this.Position;
            Vector2 headPos = pos + new Vector2(0.0f, BodyHeight / 2.0f);
            _body = CreateRectangle(BodyWidth, BodyHeight, pos, 1.0f);
            _body.LinearDragCoefficient = 0.01f;
            _body.RotationalDragCoefficient = 0.001f;
            _head = CreateTriangle(new Vector2(0.3f, 0.2f),
                                  new Vector2(0.7f, 0.2f),
                                  new Vector2(0.5f, 0.0f),
                                  headPos,
                                  1.0f);
            PinJoint j = new PinJoint(_body, new Vector2(0.0f, BodyHeight / 2.0f), _head, new Vector2(0.0f, 0.0f));
            AddJoint(j);
            AngleSpring spring = new AngleSpring(_body, _head, 0.01f, damping);
            //spring.TargetAngle = 90f;
            AddSpring(spring);

            const float legX = (BodyWidth/2.0f) + (LegLength/2.0f);
            const float legY = LegHeightOffset;
            _legTopLeft = CreateRectangle(LegLength, LegWidth, pos + new Vector2(legX,legY), 0.1f);
            j = new PinJoint(_body, new Vector2((BodyWidth / 2.0f), LegHeightOffset), _legTopLeft, new Vector2(-(LegLength / 2.0f), 0.0f));
            AddJoint(j);
            spring = new AngleSpring(_body, _legTopLeft, springConst, damping);
            //spring.TargetAngle = (float)(Math.PI/4.0);
            AddSpring(spring);

            _legTopRight = CreateRectangle(LegLength, LegWidth, pos + new Vector2(-legX, legY), 0.1f);
            j = new PinJoint(_body, new Vector2(-(BodyWidth / 2.0f), LegHeightOffset), _legTopRight, new Vector2((LegLength / 2.0f), 0.0f));
            AddJoint(j);
            spring = new AngleSpring(_body, _legTopRight, springConst, damping);
            //spring.TargetAngle = -(float)(Math.PI / 4.0);
            AddSpring(spring);

            _legBottomLeft = CreateRectangle(LegLength, LegWidth, pos + new Vector2(legX, -legY), 0.1f);
            j = new PinJoint(_body, new Vector2((BodyWidth / 2.0f), -LegHeightOffset), _legBottomLeft, new Vector2(-(LegLength / 2.0f), 0.0f));
            AddJoint(j);
            spring = new AngleSpring(_body, _legBottomLeft, springConst, damping);
            //spring.TargetAngle = (float)(Math.PI / 4.0);
            AddSpring(spring);

            _legBottomRight = CreateRectangle(LegLength, LegWidth, pos + new Vector2(-legX, -legY), 0.1f);
            j = new PinJoint(_body, new Vector2(-(BodyWidth / 2.0f), -LegHeightOffset), _legBottomRight, new Vector2((LegLength / 2.0f), 0.0f));
            AddJoint(j);
            spring = new AngleSpring(_body, _legBottomRight, springConst, damping);
            //spring.TargetAngle = -(float)(Math.PI / 4.0);
            AddSpring(spring);

            _ant1 = CreateRectangle(0.01f, 0.1f, pos + new Vector2(0.1f + (0.01f / 2.0f), 0.45f + 0.05f), 0.1f);
            j = new PinJoint(_head, new Vector2(0.1f, 0.2f), _ant1, new Vector2(-0.005f, -0.05f));
            AddJoint(j);
            spring = new AngleSpring(_head, _ant1, springConst, damping);
            //spring.TargetAngle = 90f;
            AddSpring(spring);

            _ant2 = CreateRectangle(0.01f, 0.1f, pos + new Vector2(-0.1f - (0.01f / 2.0f), 0.45f + 0.05f), 0.1f);
            j = new PinJoint(_head, new Vector2(-0.1f, 0.2f), _ant2, new Vector2(-0.005f, -0.05f));
            AddJoint(j);
            //spring.TargetAngle = 90f;
            spring = new AngleSpring(_head, _ant2, springConst, damping);
            AddSpring(spring);
        }

        public override void ApplyForces()
        {
            //if (AngularVelocity < 10)
            //{
            //    _body.ApplyForce(new Vector2(0.01f, 0.01f));
            //}
            //else
            //{
            //    Console.WriteLine("Angular Vel Bad");
            //    foreach (var bd in base.BodyList())
            //    {
            //        bd.Enabled = false;
            //        bd.AngularVelocity = 10f;
            //        bd.LinearVelocity = new Vector2(0f,0f);
            //    }
            //}
        }

        public override void PostMove()
        {
            base.PostMove();
        }

        public override void KeyPress(Key key)
        {
            const float force = 0.04f;
            float angle = _body.Rotation;
            float s = force * (float)(Math.Sin(angle));
            float c = force * (float)(Math.Cos(angle));
            switch (key)
            {
                case Key.Q:
                case Key.W:
                case Key.E:
                    //Console.WriteLine("KeyPress {0}", key);
                    _legTopLeft.ApplyForce(new Vector2(-s,c));
                    break;
                case Key.I:
                case Key.O:
                case Key.P:
                    //Console.WriteLine("KeyPress {0}", key);
                    _legTopRight.ApplyForce(new Vector2(-s, c));
                    break;
                case Key.Z:
                case Key.X:
                case Key.C:
                    //Console.WriteLine("KeyPress {0}", key);
                    _legTopLeft.ApplyForce(new Vector2(s, -c));
                    break;
                case Key.B:
                case Key.N:
                case Key.M:
                    //Console.WriteLine("KeyPress {0}", key);
                    _legTopRight.ApplyForce(new Vector2(s, -c));
                    break;
            }
        }
    }
}